void recall_result::do_execute() { LOG_AI_ACTIONS << "start of execution of: " << *this << std::endl; assert(is_success()); game_info& info = get_info(); team& my_team = get_my_team(info); const events::command_disabler disable_commands; std::vector<unit>::iterator rec = std::find_if(my_team.recall_list().begin(), my_team.recall_list().end(), boost::bind(&unit::matches_id, _1, unit_id_)); assert(rec != my_team.recall_list().end()); const std::string &err = find_recruit_location(get_side(), recall_location_); if(!err.empty()) { set_error(AI_ACTION_FAILURE); return; } else { unit &un = *rec; recorder.add_recall(un.id(), recall_location_); un.set_game_context(&info.units); place_recruit(un, recall_location_, true, true); statistics::recall_unit(un); my_team.spend_gold(game_config::recall_cost); my_team.recall_list().erase(rec); if (resources::screen!=NULL) { resources::screen->invalidate_game_status(); resources::screen->invalidate_all(); } recorder.add_checksum_check(recall_location_); set_gamestate_changed(); try { manager::raise_gamestate_changed(); } catch (...) { is_ok(); //Silences "unchecked result" warning throw; } } }
/** * Redoes this action. * @return true on success; false on an error. */ bool recruit_action::redo(int side) { game_display & gui = *resources::screen; team ¤t_team = resources::gameboard->teams()[side-1]; map_location loc = route.front(); map_location from = recruit_from; const std::string & name = u_type.base_id(); //search for the unit to be recruited in recruits if ( !util::contains(get_recruits(side, loc), name) ) { ERR_NG << "Trying to redo a recruit for side " << side << ", which does not recruit type \"" << name << "\"\n"; assert(false); return false; } current_team.last_recruit(name); const std::string &msg = find_recruit_location(side, loc, from, name); if ( msg.empty() ) { //MP_COUNTDOWN: restore recruitment bonus current_team.set_action_bonus_count(1 + current_team.action_bonus_count()); resources::recorder->redo(replay_data); replay_data.clear(); set_scontext_synced sync; recruit_unit(u_type, side, loc, from, true, false); // Quick error check. (Abuse of [allow_undo]?) if ( loc != route.front() ) { ERR_NG << "When redoing a recruit at " << route.front() << ", the location was moved to " << loc << ".\n"; // Not really fatal, I suppose. Just update the action so // undoing this works. route.front() = loc; } sync.do_final_checkup(); } else { gui2::show_transient_message(gui.video(), "", msg); return false; } return true; }
void recruit_result::do_execute() { LOG_AI_ACTIONS << "start of execution of: " << *this << std::endl; assert(is_success()); game_info& info = get_info(); // We have to add the recruit command now, because when the unit // is created it has to have the recruit command in the recorder // to be able to put random numbers into to generate unit traits. // However, we're not sure if the transaction will be successful, // so use a replay_undo object to cancel it if we don't get // a confirmation for the transaction. recorder.add_recruit(num_,recruit_location_); replay_undo replay_guard(recorder); const unit_type *u = unit_types.find(unit_name_); const events::command_disabler disable_commands; const std::string recruit_err = find_recruit_location(get_side(), recruit_location_); if(recruit_err.empty()) { const unit new_unit(&info.units, u, get_side(), true); place_recruit(new_unit, recruit_location_, false, preferences::show_ai_moves()); statistics::recruit_unit(new_unit); get_my_team(info).spend_gold(u->cost()); // Confirm the transaction - i.e. don't undo recruitment replay_guard.confirm_transaction(); set_gamestate_changed(); try { manager::raise_gamestate_changed(); } catch (...) { is_ok(); //Silences "unchecked result" warning throw; } } else { set_error(AI_ACTION_FAILURE); } }