Basic move validation is in place when executing/removing/etc.
Right now an invalid path is simply replaced by a new path is possible; the player might not appreciate and would probably prefer getting a visual warning and redefining it manually.
This commit is contained in:
parent
6050f0d617
commit
35e45bf5ad
6 changed files with 107 additions and 3 deletions
|
@ -84,7 +84,15 @@ public:
|
|||
|
||||
virtual void set_last_action(bool last_action) = 0;
|
||||
|
||||
//TODO: rename this if it ends up only refreshing the future and last action display
|
||||
virtual void update_display() = 0;
|
||||
|
||||
/**
|
||||
* Indicates to an action whether its status is invalid, and whether it should change its
|
||||
* display (and avoid any change to the game state) accordingly
|
||||
*/
|
||||
virtual void set_valid(bool valid) = 0;
|
||||
virtual bool is_valid() = 0;
|
||||
};
|
||||
|
||||
} // end namespace wb
|
||||
|
|
|
@ -187,4 +187,20 @@ void move::update_display()
|
|||
}
|
||||
}
|
||||
|
||||
void move::set_valid(bool valid)
|
||||
{
|
||||
const std::string ARROW_STYLE_VALID = "";
|
||||
const std::string ARROW_STYLE_INVALID = "invalid";
|
||||
|
||||
valid_ = valid;
|
||||
if (valid_)
|
||||
{
|
||||
arrow_->set_style(ARROW_STYLE_VALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
arrow_->set_style(ARROW_STYLE_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace wb
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace wb {
|
|||
*/
|
||||
class move : public action, public boost::enable_shared_from_this<move>
|
||||
{
|
||||
friend class validate_visitor;
|
||||
public: //constants
|
||||
static const double ALPHA_HIGHLIGHT;
|
||||
static const double ALPHA_NORMAL;
|
||||
|
@ -69,6 +70,9 @@ public:
|
|||
virtual void set_last_action(bool last_action) {last_action_ = last_action; update_display(); }
|
||||
virtual void update_display();
|
||||
|
||||
virtual void set_valid(bool valid);
|
||||
virtual bool is_valid() { return valid_; }
|
||||
|
||||
private:
|
||||
unit & unit_;
|
||||
map_location orig_hex_;
|
||||
|
@ -79,6 +83,8 @@ private:
|
|||
|
||||
bool future_display_;
|
||||
bool last_action_;
|
||||
|
||||
bool valid_;
|
||||
};
|
||||
|
||||
} // end namespace wb
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#include "side_actions.hpp"
|
||||
#include "action.hpp"
|
||||
#include "move.hpp"
|
||||
#include "validate_visitor.hpp"
|
||||
|
||||
#include "foreach.hpp"
|
||||
#include "resources.hpp"
|
||||
#include <set>
|
||||
|
||||
namespace wb
|
||||
|
@ -51,7 +53,7 @@ void side_actions::execute_next()
|
|||
update_last_action_display();
|
||||
}
|
||||
|
||||
//TODO: Validate remaining actions here
|
||||
validate_actions();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +65,7 @@ void side_actions::execute(action_ptr action)
|
|||
{
|
||||
remove_action(action);
|
||||
}
|
||||
//TODO: Validate remaining actions here
|
||||
validate_actions();
|
||||
}
|
||||
|
||||
void side_actions::insert_move(unit& subject, const map_location& source_hex, const map_location& target_hex, size_t index, boost::shared_ptr<arrow> arrow,
|
||||
|
@ -72,6 +74,7 @@ void side_actions::insert_move(unit& subject, const map_location& source_hex, co
|
|||
action_ptr action(new move(subject, source_hex, target_hex, arrow, fake_unit));
|
||||
assert(index < end());
|
||||
actions_.insert(actions_.begin() + index, action);
|
||||
validate_actions();
|
||||
update_last_action_display();
|
||||
}
|
||||
|
||||
|
@ -103,6 +106,7 @@ void side_actions::remove_action(size_t index)
|
|||
if (position < actions_.end())
|
||||
{
|
||||
actions_.erase(position);
|
||||
validate_actions();
|
||||
update_last_action_display();
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +122,7 @@ void side_actions::remove_action(action_ptr action)
|
|||
if (*position == action)
|
||||
{
|
||||
actions_.erase(position);
|
||||
validate_actions();
|
||||
update_last_action_display();
|
||||
break;
|
||||
}
|
||||
|
@ -153,6 +158,15 @@ void side_actions::update_last_action_display()
|
|||
}
|
||||
}
|
||||
|
||||
void side_actions::validate_actions()
|
||||
{
|
||||
validate_visitor validator(*resources::units);
|
||||
foreach(action_ptr action, actions_)
|
||||
{
|
||||
action->accept(validator);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to move actions around the queue.
|
||||
* Positive increment = move toward back of the queue and later execution.
|
||||
|
@ -187,6 +201,7 @@ void side_actions::move_in_queue(size_t index, int increment)
|
|||
//be careful, previous iterators have just been invalidated by erase()
|
||||
action_set::iterator destination = after + increment;
|
||||
actions_.insert(destination, action);
|
||||
validate_actions();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ public:
|
|||
*/
|
||||
void update_last_action_display();
|
||||
|
||||
void validate_actions();
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
*/
|
||||
|
||||
#include "validate_visitor.hpp"
|
||||
#include "arrow.hpp"
|
||||
#include "move.hpp"
|
||||
|
||||
#include "pathfind/pathfind.hpp"
|
||||
#include "play_controller.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "team.hpp"
|
||||
|
||||
namespace wb
|
||||
{
|
||||
|
@ -30,9 +37,59 @@ validate_visitor::~validate_visitor()
|
|||
{
|
||||
}
|
||||
|
||||
//FIXME: move this some place it can be accessible from the whole whiteboard
|
||||
static team& get_current_team()
|
||||
{
|
||||
int current_side = resources::controller->current_side();
|
||||
team& current_team = (*resources::teams)[current_side - 1];
|
||||
return current_team;
|
||||
}
|
||||
|
||||
void validate_visitor::visit_move(boost::shared_ptr<move> move)
|
||||
{
|
||||
mapbuilder_visitor::visit_move(move);
|
||||
bool valid = true;
|
||||
|
||||
if (!(move->orig_hex_.valid() && move->dest_hex_.valid()))
|
||||
valid = false;
|
||||
|
||||
if (valid && resources::units->find(move->orig_hex_) == resources::units->end())
|
||||
valid = false;
|
||||
|
||||
pathfind::plain_route route;
|
||||
if (valid)
|
||||
{
|
||||
pathfind::shortest_path_calculator path_calc(move->unit_, get_current_team(), *resources::units,
|
||||
*resources::teams, *resources::game_map);
|
||||
route = pathfind::a_star_search(move->orig_hex_,
|
||||
move->dest_hex_, 10000, &path_calc, resources::game_map->w(), resources::game_map->h());
|
||||
if (route.move_cost >= path_calc.getNoPathValue())
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
if (!std::equal(route.steps.begin(), route.steps.end(), move->arrow_->get_path().begin()))
|
||||
{
|
||||
//new valid path differs from the previous one, replace
|
||||
move->arrow_->set_path(route.steps);
|
||||
|
||||
//TODO: Since this might lengthen the path, we probably need a special conflict state
|
||||
// to warn the player that the initial path is no longer possible.
|
||||
|
||||
}
|
||||
// Now call the superclass to apply the result of this move to the unit map,
|
||||
// so that further pathfinding takes it into account.
|
||||
mapbuilder_visitor::visit_move(move);
|
||||
}
|
||||
else //path invalid
|
||||
{
|
||||
// Don't apply the move's results to the unit map
|
||||
|
||||
// Mark the move as invalid
|
||||
move->set_valid(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue