diff --git a/src/actions/create.cpp b/src/actions/create.cpp index ae09ce0b3df..ac0891fb621 100644 --- a/src/actions/create.cpp +++ b/src/actions/create.cpp @@ -51,34 +51,33 @@ static lg::log_domain log_engine("engine"); namespace { - -struct castle_cost_calculator : pathfind::cost_calculator -{ - castle_cost_calculator(const gamemap& map, const team & view_team) : - map_(map), - viewer_(view_team), - use_shroud_(view_team.uses_shroud()) - {} - - virtual double cost(const map_location& loc, const double) const + struct castle_cost_calculator : pathfind::cost_calculator { - if(!map_.is_castle(loc)) - return 10000; + castle_cost_calculator(const gamemap& map, const team & view_team) : + map_(map), + viewer_(view_team), + use_shroud_(view_team.uses_shroud()) + {} - if ( use_shroud_ && viewer_.shrouded(loc) ) - return 10000; + virtual double cost(const map_location& loc, const double) const + { + if(!map_.is_castle(loc)) + return 10000; - return 1; - } + if ( use_shroud_ && viewer_.shrouded(loc) ) + return 10000; -private: - const gamemap& map_; - const team& viewer_; - const bool use_shroud_; // Allows faster checks when shroud is disabled. -}; + return 1; + } + private: + const gamemap& map_; + const team& viewer_; + const bool use_shroud_; // Allows faster checks when shroud is disabled. + }; }//anonymous namespace + unit_creator::unit_creator(team &tm, const map_location &start_pos) : add_to_recall_(false),discover_(false),get_village_(false),invalidate_(false), rename_side_(false), show_(false), start_pos_(start_pos), team_(tm) { @@ -325,7 +324,11 @@ bool can_recruit_on(const map_location& leader_loc, const map_location& recruit_ return !rt.steps.empty(); } -const std::set get_recruits_for_location(int side, const map_location &recruit_loc) + +namespace actions { + + +const std::set get_recruits(int side, const map_location &recruit_loc) { const team & current_team = (*resources::teams)[side -1]; @@ -388,41 +391,42 @@ const std::set get_recruits_for_location(int side, const map_locati } -/** - * Adds to @a result those units that @a leader (assumed a leader) can recall. - * If @a already_added is supplied, it contains the underlying IDs of units - * that can be skipped (because they are already in @a result), and the - * underlying ID of units added to @a result will be added to @a already_added. - */ -static void add_leader_filtered_recalls(const unit & leader, - std::vector & result, - std::set * already_added = NULL) -{ - const team& leader_team = (*resources::teams)[leader.side()-1]; - const std::vector& recall_list = leader_team.recall_list(); - const std::string& save_id = leader_team.save_id(); - - BOOST_FOREACH(const unit& recall_unit, recall_list) +namespace { // Helpers for get_recalls_for_location() + /** + * Adds to @a result those units that @a leader (assumed a leader) can recall. + * If @a already_added is supplied, it contains the underlying IDs of units + * that can be skipped (because they are already in @a result), and the + * underlying ID of units added to @a result will be added to @a already_added. + */ + void add_leader_filtered_recalls(const unit & leader, + std::vector & result, + std::set * already_added = NULL) { - // Do not add a unit twice. - size_t underlying_id = recall_unit.underlying_id(); - if ( !already_added || already_added->count(underlying_id) == 0 ) - { - // Only units that match the leader's recall filter are valid. - scoped_recall_unit this_unit("this_unit", save_id, &recall_unit - &recall_list[0]); + const team& leader_team = (*resources::teams)[leader.side()-1]; + const std::vector& recall_list = leader_team.recall_list(); + const std::string& save_id = leader_team.save_id(); - if ( recall_unit.matches_filter(vconfig(leader.recall_filter()), map_location::null_location) ) + BOOST_FOREACH(const unit& recall_unit, recall_list) + { + // Do not add a unit twice. + size_t underlying_id = recall_unit.underlying_id(); + if ( !already_added || already_added->count(underlying_id) == 0 ) { - result.push_back(&recall_unit); - if ( already_added != NULL ) - already_added->insert(underlying_id); + // Only units that match the leader's recall filter are valid. + scoped_recall_unit this_unit("this_unit", save_id, &recall_unit - &recall_list[0]); + + if ( recall_unit.matches_filter(vconfig(leader.recall_filter()), map_location::null_location) ) + { + result.push_back(&recall_unit); + if ( already_added != NULL ) + already_added->insert(underlying_id); + } } } } -} +}// anonymous namespace - -const std::vector get_recalls_for_location(int side, const map_location &recall_loc) +const std::vector get_recalls(int side, const map_location &recall_loc) { LOG_NG << "getting recall list for side " << side << " at location " << recall_loc << "\n"; @@ -655,82 +659,83 @@ std::string find_recruit_location(const int side, map_location& recruit_location } -/** - * Performs a checksum check on a newly recruited/recalled unit. - */ -static void recruit_checksums(const unit &new_unit, bool wml_triggered) -{ - const config* ran_results = get_random_results(); - if ( ran_results != NULL ) { - // When recalling from WML there should be no random results, if we use - // random we might get the replay out of sync. - assert(!wml_triggered); - const std::string checksum = get_checksum(new_unit); - const std::string rc = (*ran_results)["checksum"]; - if ( rc != checksum ) { - std::stringstream error_msg; - error_msg << "SYNC: In recruit " << new_unit.type_id() << - ": has checksum " << checksum << - " while datasource has checksum " << rc << "\n"; - ERR_NG << error_msg.str(); +namespace { // Helpers for place_recruit() + /** + * Performs a checksum check on a newly recruited/recalled unit. + */ + void recruit_checksums(const unit &new_unit, bool wml_triggered) + { + const config* ran_results = get_random_results(); + if ( ran_results != NULL ) { + // When recalling from WML there should be no random results, if we + // use random we might get the replay out of sync. + assert(!wml_triggered); + const std::string checksum = get_checksum(new_unit); + const std::string rc = (*ran_results)["checksum"]; + if ( rc != checksum ) { + std::stringstream error_msg; + error_msg << "SYNC: In recruit " << new_unit.type_id() << + ": has checksum " << checksum << + " while datasource has checksum " << rc << "\n"; + ERR_NG << error_msg.str(); - config cfg_unit1; - new_unit.write(cfg_unit1); - DBG_NG << cfg_unit1; - replay::process_error(error_msg.str()); + config cfg_unit1; + new_unit.write(cfg_unit1); + DBG_NG << cfg_unit1; + replay::process_error(error_msg.str()); + } + + } else if ( wml_triggered == false ) { + config cfg; + cfg["checksum"] = get_checksum(new_unit); + set_random_results(cfg); } - - } else if ( wml_triggered == false ) { - config cfg; - cfg["checksum"] = get_checksum(new_unit); - set_random_results(cfg); } -} -/** - * Locates a leader on side @a side who can recruit at @a recruit_location. - * A leader at @a recruited_from is chosen in preference to others. - */ -static const map_location & find_recruit_leader(int side, - const map_location &recruit_location, const map_location &recruited_from) -{ - const unit_map & units = *resources::units; + /** + * Locates a leader on side @a side who can recruit at @a recruit_location. + * A leader at @a recruited_from is chosen in preference to others. + */ + const map_location & find_recruit_leader(int side, + const map_location &recruit_location, const map_location &recruited_from) + { + const unit_map & units = *resources::units; - // See if the preferred location is an option. - unit_map::const_iterator leader = units.find(recruited_from); - if ( leader != units.end() && leader->can_recruit() && - leader->side() == side && can_recruit_on(*leader, recruit_location) ) - return leader->get_location(); - - // Check all units. - for ( leader = units.begin(); leader != units.end(); ++leader ) - if ( leader->can_recruit() && leader->side() == side && - can_recruit_on(*leader, recruit_location) ) + // See if the preferred location is an option. + unit_map::const_iterator leader = units.find(recruited_from); + if ( leader != units.end() && leader->can_recruit() && + leader->side() == side && can_recruit_on(*leader, recruit_location) ) return leader->get_location(); - // No usable leader found. - return map_location::null_location; -} + // Check all units. + for ( leader = units.begin(); leader != units.end(); ++leader ) + if ( leader->can_recruit() && leader->side() == side && + can_recruit_on(*leader, recruit_location) ) + return leader->get_location(); - -/** - * Tries to make @a un_it valid, and updates @a current_loc. - * Used by place_recruit() after WML might have changed something. - * @returns true if the iterator was made valid. - */ -static bool validate_recruit_iterator(unit_map::iterator & un_it, - map_location & current_loc) -{ - if ( !un_it.valid() ) { - // Maybe WML provided a replacement? - un_it = resources::units->find(current_loc); - if ( un_it == resources::units->end() ) - // The unit is gone. - return false; + // No usable leader found. + return map_location::null_location; } - current_loc = un_it->get_location(); - return true; -} + + /** + * Tries to make @a un_it valid, and updates @a current_loc. + * Used by place_recruit() after WML might have changed something. + * @returns true if the iterator was made valid. + */ + bool validate_recruit_iterator(unit_map::iterator & un_it, + map_location & current_loc) + { + if ( !un_it.valid() ) { + // Maybe WML provided a replacement? + un_it = resources::units->find(current_loc); + if ( un_it == resources::units->end() ) + // The unit is gone. + return false; + } + current_loc = un_it->get_location(); + return true; + } +}// anonymous namespace bool place_recruit(const unit &u, const map_location &recruit_location, const map_location& recruited_from, int cost, bool is_recall, bool show, bool fire_event, bool full_movement, @@ -816,9 +821,6 @@ bool place_recruit(const unit &u, const map_location &recruit_location, const ma } -namespace actions { - - /** * Recruits a unit of the given type for the given side. */ diff --git a/src/actions/create.hpp b/src/actions/create.hpp index e2367a78570..66f0d032fc4 100644 --- a/src/actions/create.hpp +++ b/src/actions/create.hpp @@ -83,6 +83,9 @@ bool can_recruit_on(const map_location& leader_loc, const map_location& recruit_ inline bool can_recruit_on(const unit& leader, const map_location& recruit_loc) { return can_recruit_on(leader.get_location(), recruit_loc, leader.side()); } + +namespace actions { + /** * Finds a location on which to place a unit. * A leader of the @a side must be on a keep @@ -125,7 +128,7 @@ std::string find_recall_location(const int side, map_location& recall_location, * @param recruit_location the hex field being part of the castle the player wants to recruit on or from. * @return a set of units that can be recruited either by the leader on @a recruit_location or by leaders on keeps connected by castle tiles to @a recruit_location. */ -const std::set get_recruits_for_location(int side, const map_location &recruit_location); +const std::set get_recruits(int side, const map_location &recruit_location); /** * Gets the recallable units for a side, restricted by that side's leaders' personal abilities to recall on or from a specific hex field. @@ -134,7 +137,7 @@ const std::set get_recruits_for_location(int side, const map_locati * @param recall_loc the hex field being part of the castle the player wants to recruit on or from. * @return a set of units that can be recalled by @a side on (or from) @a recall_loc or the full recall list of @a side. */ -const std::vector get_recalls_for_location(int side, const map_location &recall_loc); +const std::vector get_recalls(int side, const map_location &recall_loc); /** * Place a unit into the game. @@ -146,9 +149,6 @@ bool place_recruit(const unit &u, const map_location &recruit_location, const ma int cost, bool is_recall, bool show = false, bool fire_event = true, bool full_movement = false, bool wml_triggered = false); - -namespace actions { - /** * Recruits a unit of the given type for the given side. * This is the point at which the code merges for recruits originating from players, diff --git a/src/ai/actions.cpp b/src/ai/actions.cpp index d604c068403..cfc4a9b1730 100644 --- a/src/ai/actions.cpp +++ b/src/ai/actions.cpp @@ -669,7 +669,7 @@ void recall_result::do_execute() std::vector::iterator rec = find_if_matches_id(my_team.recall_list(), unit_id_); assert(rec != my_team.recall_list().end()); - const std::string &err = find_recall_location(get_side(), recall_location_, recall_from_, *rec); + const std::string &err = ::actions::find_recall_location(get_side(), recall_location_, recall_from_, *rec); if(!err.empty()) { set_error(AI_ACTION_FAILURE); return; @@ -863,7 +863,7 @@ void recruit_result::do_execute() 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_, recruit_from_, u->id()); + const std::string recruit_err = ::actions::find_recruit_location(get_side(), recruit_location_, recruit_from_, u->id()); if(recruit_err.empty()) { recorder.add_recruit(num_,recruit_location_,recruit_from_); ::actions::recruit_unit(*u, get_side(), recruit_location_, recruit_from_, preferences::show_ai_moves(), true); diff --git a/src/game_events.cpp b/src/game_events.cpp index 89085fb2cb2..9ba7bcb3b6e 100644 --- a/src/game_events.cpp +++ b/src/game_events.cpp @@ -1957,8 +1957,9 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg) if(resources::game_map->on_board(loc)) { DBG_NG << "...valid location for the recall found. Recalling.\n"; avail.erase(u); // Erase before recruiting, since recruiting can fire more events - place_recruit(to_recruit, loc, leader->get_location(), 0, true, - cfg["show"].to_bool(true), cfg["fire_event"].to_bool(false), true, true); + actions::place_recruit(to_recruit, loc, leader->get_location(), 0, true, + cfg["show"].to_bool(true), cfg["fire_event"].to_bool(false), + true, true); return; } } @@ -1972,8 +1973,8 @@ WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg) DBG_NG << "No usable leader found, but found usable location. Recalling.\n"; avail.erase(u); // Erase before recruiting, since recruiting can fire more events map_location null_location = map_location::null_location; - place_recruit(to_recruit, loc, null_location, 0, true, - cfg["show"].to_bool(true), cfg["fire_event"].to_bool(false), true, true); + actions::place_recruit(to_recruit, loc, null_location, 0, true, cfg["show"].to_bool(true), + cfg["fire_event"].to_bool(false), true, true); return; } } diff --git a/src/menu_events.cpp b/src/menu_events.cpp index 710b9f54836..476263d4836 100644 --- a/src/menu_events.cpp +++ b/src/menu_events.cpp @@ -739,7 +739,7 @@ void menu_handler::recruit(int side_num, const map_location &last_hex) std::vector item_keys; std::vector items; - std::set recruits = get_recruits_for_location(side_num, last_hex); + std::set recruits = actions::get_recruits(side_num, last_hex); for(std::set::const_iterator it = recruits.begin(); it != recruits.end(); ++it) { const unit_type *type = unit_types.find(*it); @@ -819,7 +819,7 @@ bool menu_handler::do_recruit(const std::string &name, int side_num, //search for the unit to be recruited in recruits int recruit_num = 0; - std::set recruits = get_recruits_for_location(side_num, last_hex); + std::set recruits = actions::get_recruits(side_num, last_hex); for(std::set::const_iterator r = recruits.begin(); ; ++r) { if (r == recruits.end()) { @@ -848,7 +848,7 @@ bool menu_handler::do_recruit(const std::string &name, int side_num, map_location recruited_from = map_location::null_location; std::string msg; { wb::future_map_if_active future; //< start planned unit map scope if in planning mode - msg = find_recruit_location(side_num, loc, recruited_from, u_type->id()); + msg = actions::find_recruit_location(side_num, loc, recruited_from, u_type->id()); } // end planned unit map scope if (!msg.empty()) { gui2::show_transient_message(gui_->video(), "", msg); @@ -890,7 +890,7 @@ void menu_handler::recall(int side_num, const map_location &last_hex) std::vector recall_list_team; { wb::future_map future; // ensures recall list has planned recalls removed - recall_list_team = get_recalls_for_location(side_num, last_hex); + recall_list_team = actions::get_recalls(side_num, last_hex); } gui_->draw(); //clear the old menu @@ -1039,7 +1039,7 @@ void menu_handler::recall(int side_num, const map_location &last_hex) map_location recall_from = map_location::null_location; std::string err; { wb::future_map_if_active future; // future unit map removes invisible units from map, don't do this outside of planning mode - err = find_recall_location(side_num, recall_location, recall_from, *(recall_list_team[res])); + err = actions::find_recall_location(side_num, recall_location, recall_from, *(recall_list_team[res])); } // end planned unit map scope if(!err.empty()) { gui2::show_transient_message(gui_->video(), "", err); diff --git a/src/replay.cpp b/src/replay.cpp index 63246b4e597..dbb4975a6ac 100644 --- a/src/replay.cpp +++ b/src/replay.cpp @@ -1015,7 +1015,7 @@ bool do_replay_handle(int side_num, const std::string &do_untill) continue; } - const std::string res = find_recruit_location(side_num, loc, from, u_type->id()); + const std::string res = actions::find_recruit_location(side_num, loc, from, u_type->id()); const int beginning_gold = current_team.gold(); if (res.empty()) {