void recall::apply_temp_modifier(unit_map& unit_map) { assert(valid()); temp_unit_->set_location(recall_hex_); DBG_WB << "Inserting future recall " << temp_unit_->name() << " [" << temp_unit_->id() << "] at position " << temp_unit_->get_location() << ".\n"; //temporarily remove unit from recall list std::vector<unit>& recalls = resources::teams->at(team_index()).recall_list(); std::vector<unit>::iterator it = find_if_matches_id(recalls, temp_unit_->id()); assert(it != recalls.end()); //Add cost to money spent on recruits. int cost = resources::teams->at(team_index()).recall_cost(); if (it->recall_cost() > -1) { cost = it->recall_cost(); } recalls.erase(it); // Temporarily insert unit into unit_map //unit map takes ownership of temp_unit unit_map.insert(temp_unit_.release()); resources::teams->at(team_index()).get_side_actions()->change_gold_spent_by(cost); // Update gold in top bar resources::screen->invalidate_game_status(); }
const unit * recall_result::get_recall_unit(const team &my_team) { const std::vector<unit>::const_iterator rec = find_if_matches_id(my_team.recall_list(), unit_id_); if (rec == my_team.recall_list().end()) { set_error(E_NOT_AVAILABLE_FOR_RECALLING); return NULL; } return &*rec; }
/** * Redoes this action. * @return true on success; false on an error. */ bool undo_list::dismiss_action::redo(int side) { team ¤t_team = (*resources::teams)[side-1]; if ( !current_team.persistent() ) { ERR_NG << "Trying to redo a dismissal for side " << side << ", which has no recall list!\n"; return false; } recorder.redo(replay_data); replay_data.clear(); std::vector<unit>::iterator unit_it = find_if_matches_id(current_team.recall_list(), dismissed_unit.id()); current_team.recall_list().erase(unit_it); return true; }
/** * Redoes this action. * @return true on success; false on an error. */ bool undo_list::recall_action::redo(int side) { game_display & gui = *resources::screen; team ¤t_team = (*resources::teams)[side-1]; if ( !current_team.persistent() ) { ERR_NG << "Trying to redo a recall for side " << side << ", which has no recall list!\n"; return false; } map_location loc = route.front(); map_location from = recall_from; const std::vector<unit> & recalls = current_team.recall_list(); std::vector<unit>::const_iterator unit_it = find_if_matches_id(recalls, id); if ( unit_it == recalls.end() ) { ERR_NG << "Trying to redo a recall of '" << id << "', but that unit is not in the recall list."; return false; } const std::string &msg = find_recall_location(side, loc, from, *unit_it); if ( msg.empty() ) { recorder.redo(replay_data); replay_data.clear(); set_scontext_synced sco; recall_unit(id, current_team, loc, from, true, false); // Quick error check. (Abuse of [allow_undo]?) if ( loc != route.front() ) { ERR_NG << "When redoing a recall 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; } } else { gui::dialog(gui, "", msg, gui::OK_ONLY).show(); return false; } return true; }
action::error recall::check_validity() const { //Check that destination hex is still free if(resources::units->find(recall_hex_) != resources::units->end()) { return LOCATION_OCCUPIED; } //Check that unit to recall is still in side's recall list const std::vector<unit>& recalls = (*resources::teams)[team_index()].recall_list(); if( find_if_matches_id(recalls, temp_unit_->id()) == recalls.end() ) { return UNIT_UNAVAILABLE; } //Check that there is still enough gold to recall this unit if((*resources::teams)[team_index()].recall_cost() > (*resources::teams)[team_index()].gold()) { return NOT_ENOUGH_GOLD; } //Check that there is a leader available to recall this unit if(!find_recruiter(team_index(),get_recall_hex())) { return NO_LEADER; } return OK; }