Extending the "actions" namespace.
This commit is contained in:
parent
c57b546b41
commit
f0d0ee3084
6 changed files with 140 additions and 137 deletions
|
@ -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<std::string> get_recruits_for_location(int side, const map_location &recruit_loc)
|
||||
|
||||
namespace actions {
|
||||
|
||||
|
||||
const std::set<std::string> get_recruits(int side, const map_location &recruit_loc)
|
||||
{
|
||||
const team & current_team = (*resources::teams)[side -1];
|
||||
|
||||
|
@ -388,41 +391,42 @@ const std::set<std::string> 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<const unit*> & result,
|
||||
std::set<size_t> * already_added = NULL)
|
||||
{
|
||||
const team& leader_team = (*resources::teams)[leader.side()-1];
|
||||
const std::vector<unit>& 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<const unit*> & result,
|
||||
std::set<size_t> * 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<unit>& 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<const unit*> get_recalls_for_location(int side, const map_location &recall_loc)
|
||||
const std::vector<const unit*> 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.
|
||||
*/
|
||||
|
|
|
@ -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<std::string> get_recruits_for_location(int side, const map_location &recruit_location);
|
||||
const std::set<std::string> 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<std::string> 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<const unit*> get_recalls_for_location(int side, const map_location &recall_loc);
|
||||
const std::vector<const unit*> 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,
|
||||
|
|
|
@ -669,7 +669,7 @@ void recall_result::do_execute()
|
|||
std::vector<unit>::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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -739,7 +739,7 @@ void menu_handler::recruit(int side_num, const map_location &last_hex)
|
|||
std::vector<std::string> item_keys;
|
||||
std::vector<std::string> items;
|
||||
|
||||
std::set<std::string> recruits = get_recruits_for_location(side_num, last_hex);
|
||||
std::set<std::string> recruits = actions::get_recruits(side_num, last_hex);
|
||||
|
||||
for(std::set<std::string>::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<std::string> recruits = get_recruits_for_location(side_num, last_hex);
|
||||
std::set<std::string> recruits = actions::get_recruits(side_num, last_hex);
|
||||
|
||||
for(std::set<std::string>::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<const unit*> 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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue