wb: update following moves when a recruit is executed

After a recruit action was executed the id of the unit was changed so we
need to update the unitid of all following actions on that unit
This commit is contained in:
gfgtdf 2018-05-01 13:57:07 +02:00 committed by Charles Dang
parent 5847615a77
commit 2174bfc215
7 changed files with 43 additions and 8 deletions

View file

@ -287,7 +287,8 @@ void menu_handler::recruit(int side_num, const map_location& last_hex)
dlg.show();
if(dlg.get_retval() == gui2::retval::OK) {
do_recruit(sample_units[dlg.get_selected_index()]->id(), side_num, last_hex);
map_location recruit_hex = last_hex;
do_recruit(sample_units[dlg.get_selected_index()]->id(), side_num, recruit_hex);
}
}
@ -295,16 +296,17 @@ void menu_handler::repeat_recruit(int side_num, const map_location& last_hex)
{
const std::string& last_recruit = board().get_team(side_num).last_recruit();
if(last_recruit.empty() == false) {
do_recruit(last_recruit, side_num, last_hex);
map_location recruit_hex = last_hex;
do_recruit(last_recruit, side_num, recruit_hex);
}
}
bool menu_handler::do_recruit(const std::string& name, int side_num, const map_location& last_hex)
bool menu_handler::do_recruit(const std::string& name, int side_num, map_location& loc)
{
team& current_team = board().get_team(side_num);
// search for the unit to be recruited in recruits
if(!utils::contains(actions::get_recruits(side_num, last_hex), name)) {
if(!utils::contains(actions::get_recruits(side_num, loc), name)) {
return false;
}
@ -322,7 +324,6 @@ bool menu_handler::do_recruit(const std::string& name, int side_num, const map_l
current_team.last_recruit(name);
const events::command_disabler disable_commands;
map_location loc = last_hex;
map_location recruited_from = map_location::null_location();
std::string msg;

View file

@ -108,7 +108,7 @@ public:
mouse_handler& mousehandler);
///@return Whether or not the recruit was successful
bool do_recruit(const std::string& name, int side_num, const map_location& last_hex);
bool do_recruit(const std::string& name, int side_num, map_location& target_hex);
void do_speak(const std::string& message);
void do_search(const std::string& new_search);
void do_command(const std::string& str);

View file

@ -310,6 +310,12 @@ void move::set_route(const pathfind::marked_route& route)
arrow_->set_path(route_->steps);
}
void move::modify_unit(unit& new_unit)
{
unit_underlying_id_ = new_unit.underlying_id();
unit_id_ = new_unit.id();
}
bool move::calculate_new_route(const map_location& source_hex, const map_location& dest_hex)
{
pathfind::plain_route new_plain_route;

View file

@ -59,6 +59,9 @@ public:
virtual map_location get_source_hex() const;
virtual map_location get_dest_hex() const;
std::size_t raw_uid() const { return unit_underlying_id_; }
void modify_unit(unit& new_unit);
virtual void set_route(const pathfind::marked_route& route);
virtual const pathfind::marked_route& get_route() const { assert(route_); return *route_; }
/// attempts to pathfind a new marked route for this path between these two hexes;

View file

@ -107,14 +107,23 @@ void recruit::execute(bool& success, bool& complete)
{
assert(valid());
temporary_unit_hider const raii(*fake_unit_);
const std::size_t old_id = fake_unit_->underlying_id();
map_location loc = recruit_hex_;
const int side_num = team_index() + 1;
//Give back the spent gold so we don't get "not enough gold" message
resources::gameboard->teams().at(team_index()).get_side_actions()->change_gold_spent_by(-cost_);
bool const result = resources::controller->get_menu_handler().do_recruit(unit_name_, side_num, recruit_hex_);
bool const result = resources::controller->get_menu_handler().do_recruit(unit_name_, side_num, loc);
//If it failed, take back the gold
if (!result) {
resources::gameboard->teams().at(team_index()).get_side_actions()->change_gold_spent_by(cost_);
}
else {
auto mit = resources::gameboard->units().find(loc);
if(mit != resources::gameboard->units().end()) {
viewer_actions()->update_recruited_unit(old_id, *mit);
}
}
success = complete = result;
}

View file

@ -671,6 +671,19 @@ void side_actions::reset_gold_spent()
gold_spent_ = 0;
}
void side_actions::update_recruited_unit(std::size_t old_id, unit& new_unit)
{
for(const_iterator it = begin(); it != end(); ++it) {
if(move_ptr mp = std::dynamic_pointer_cast<move>(*it)) {
if(mp->raw_uid() == old_id) {
actions_.modify(it, [&](action_ptr& p) {
static_cast<move&>(*p).modify_unit(new_unit);
});
}
}
}
}
side_actions::iterator side_actions::safe_insert(std::size_t turn, std::size_t pos, action_ptr act)
{
assert(act);

View file

@ -254,7 +254,8 @@ public:
/** Get the underlying action container */
const action_set& actions() const { return actions_; }
template<typename Modifier>
bool modify(iterator position, Modifier mod) { return actions_.modify(position, mod); }
private:
/**
* Binary search to find the occurring turn of the action pointed by an iterator.
@ -505,6 +506,8 @@ public:
void change_gold_spent_by(int difference);
/** Set gold spent back to zero */
void reset_gold_spent();
/** After a recruit action was executed the id of the unit was changed so we need to update the unitid of all following actions on that unit*/
void update_recruited_unit(std::size_t old_id, unit& new_unit);
void raw_turn_shift();
void synced_turn_shift();