54 #include <boost/scoped_ptr.hpp>
57 #define DBG_NG LOG_STREAM(debug, log_engine)
58 #define LOG_NG LOG_STREAM(info, log_engine)
59 #define ERR_NG LOG_STREAM(err, log_engine)
65 const team & current_team = (*resources::teams)[side -1];
67 LOG_NG <<
"getting recruit list for side " << side <<
" at location " << recruit_loc <<
"\n";
69 std::set<std::string> local_result;
70 std::set<std::string> global_result;
74 bool leader_in_place =
false;
81 if ( find_it != u_end ) {
82 if ( find_it->can_recruit() && find_it->side() == side &&
87 leader_in_place =
true;
88 local_result.insert(find_it->recruits().begin(),
89 find_it->recruits().end());
98 if ( !leader_in_place ) {
100 for( ; u != u_end; ++u ) {
102 if ( !(u->can_recruit() && u->side() == side) )
106 if ( allow_local && dynamic_cast<game_state*>(
resources::filter_con)->can_recruit_on(*u, recruit_loc) ) {
107 leader_in_place=
true;
108 local_result.insert(u->recruits().begin(), u->recruits().end());
110 else if ( !leader_in_place )
111 global_result.insert(u->recruits().begin(), u->recruits().end());
116 std::set<std::string> &
result = leader_in_place ? local_result : global_result;
119 const std::set<std::string>& recruit_list = current_team.
recruits();
120 result.insert(recruit_list.begin(), recruit_list.end());
134 std::vector< unit_const_ptr > &
result,
135 std::set<size_t> * already_added =
nullptr)
137 const team& leader_team = (*resources::teams)[leader->side()-1];
147 if ( !already_added || already_added->count(underlying_id) == 0 )
154 result.push_back(recall_unit_ptr);
155 if ( already_added !=
nullptr )
156 already_added->insert(underlying_id);
165 LOG_NG <<
"getting recall list for side " << side <<
" at location " << recall_loc <<
"\n";
167 std::vector<unit_const_ptr >
result;
176 bool leader_in_place =
false;
184 if ( find_it->can_recruit() && find_it->side() == side &&
203 std::set<size_t> valid_local_recalls;
205 for(; u != u_end; ++u) {
207 if (!(u->can_recruit() && u->side() == side))
213 leader_in_place=
true;
219 if ( !leader_in_place )
224 result.push_back(recall);
239 const unit & recaller,
const unit & recall_unit,
247 team& recall_team = (*resources::teams)[recaller.
side()-1];
261 if ( !permissible.
valid() )
266 alternative = permissible;
278 const unit &unit_recall)
297 if ( u != u_end && u->side() == side ) {
299 check_unit_recall_location(*u, unit_recall, check_location, alternative);
303 for ( u = units.
begin(); best_result < goal_result && u != u_end; ++u ) {
304 if ( u->side() != side )
309 check_unit_recall_location(*u, unit_recall, check_location, alternative);
312 if ( current_result <= best_result )
314 best_result = current_result;
318 recall_from = u->get_location();
323 recall_location = alternative;
330 LOG_NG <<
"finding recall location for side " << side <<
" and unit " << unit_recall.
id() <<
"\n";
337 LOG_NG <<
"No leaders on side " << side <<
" when recalling " << unit_recall.
id() <<
".\n";
338 return _(
"You don’t have a leader to recall with.");
341 LOG_NG <<
"No leader is able to recall " << unit_recall.
id() <<
" on side " << side <<
".\n";
342 return _(
"None of your leaders are able to recall that unit.");
345 LOG_NG <<
"No leader able to recall " << unit_recall.
id() <<
" is on a keep.\n";
346 return _(
"You must have a leader on a keep who is able to recall that unit.");
349 LOG_NG <<
"No vacant castle tiles around a keep are available for recalling " << unit_recall.
id() <<
"; requested location is " << recall_location <<
".\n";
350 return _(
"There are no vacant castle tiles in which to recall the unit.");
359 ERR_NG <<
"Unrecognized enum in find_recall_location()" << std::endl;
360 return _(
"An unrecognized error has occurred.");
379 if ( !unit_type.empty() ) {
391 if ( !permissible.
valid() )
396 alternative = permissible;
433 if ( u != u_end && u->side() == side ) {
435 check_unit_recruit_location(*u, check_type, check_location, alternative);
439 for ( u = units.
begin(); best_result < goal_result && u != u_end; ++u ) {
440 if ( u->side() != side )
445 check_unit_recruit_location(*u, check_type, check_location, alternative);
448 if ( current_result <= best_result )
450 best_result = current_result;
454 recruited_from = u->get_location();
459 recruit_location = alternative;
466 LOG_NG <<
"finding recruit location for side " << side <<
"\n";
473 LOG_NG <<
"No leaders on side " << side <<
" when recruiting '" << unit_type <<
"'.\n";
474 return _(
"You don’t have a leader to recruit with.");
477 LOG_NG <<
"No leader is able to recruit '" << unit_type <<
"' on side " << side <<
".\n";
478 return _(
"None of your leaders are able to recruit that unit.");
481 LOG_NG <<
"No leader able to recruit '" << unit_type <<
"' is on a keep.\n";
482 return _(
"You must have a leader on a keep who is able to recruit the unit.");
485 LOG_NG <<
"No vacant castle tiles around a keep are available for recruiting '" << unit_type <<
"'; requested location is " << recruit_location <<
".\n";
486 return _(
"There are no vacant castle tiles in which to recruit the unit.");
495 ERR_NG <<
"Unrecognized enum in find_recruit_location()" << std::endl;
496 return _(
"An unrecognized error has occurred.");
504 void recruit_checksums(
const unit &new_unit,
bool wml_triggered)
511 config original_checksum_config;
516 const std::string old_checksum = original_checksum_config[
"checksum"];
517 std::stringstream error_msg;
518 error_msg <<
"SYNC: In recruit " << new_unit.
type_id() <<
519 ": has checksum " << checksum <<
520 " while datasource has checksum " << old_checksum <<
"\n";
521 if(old_checksum.empty())
523 error_msg <<
"Original result is \n" << original_checksum_config <<
"\n";
526 new_unit.
write(cfg_unit1);
543 if ( leader != units.
end() && leader->can_recruit() &&
545 return leader->get_location();
548 for ( leader = units.
begin(); leader != units.
end(); ++leader )
549 if ( leader->can_recruit() && leader->side() == side &&
551 return leader->get_location();
565 if ( !un_it.
valid() ) {
572 current_loc = un_it->get_location();
584 int min_dist = INT_MAX;
586 for ( unit_itor = units.
begin(); unit_itor != units.
end(); ++unit_itor ) {
589 int dist =
distance_between(unit_itor->get_location(),recruit_loc) - unit_itor->level();
590 if (dist < min_dist) {
592 min_loc = unit_itor->get_location();
596 if (min_dist < INT_MAX) {
611 int cost,
bool is_recall,
bool show,
bool fire_event,
bool full_movement,
615 LOG_NG <<
"placing new unit on location " << recruit_location <<
"\n";
617 u->set_movement(u->total_movement(),
true);
619 u->set_movement(0,
true);
627 find_recruit_leader(u->side(), recruit_location, recruited_from);
628 u->set_location(recruit_location);
631 assert(add_result.second);
635 set_recruit_facing(new_unit_itor, *u, recruit_location, leader_loc);
638 recruit_checksums(*u, wml_triggered);
644 const std::string event_name = is_recall ?
"prerecall" :
"prerecruit";
645 LOG_NG <<
"firing " << event_name <<
" event\n";
649 if ( !validate_recruit_iterator(new_unit_itor, current_loc) )
651 new_unit_itor->set_hidden(
true);
654 (*resources::teams)[u->side()-1].spend_gold(cost);
660 new_unit_itor->set_hidden(
false);
670 if ( !validate_recruit_iterator(new_unit_itor, current_loc) )
676 if ( !wml_triggered )
677 res.get<0>() |= clearer.
clear_unit(current_loc, *new_unit_itor);
680 const std::string event_name = is_recall ?
"recall" :
"recruit";
681 LOG_NG <<
"firing " << event_name <<
" event\n";
689 if ( new_unit_itor.
valid() )
733 bool show,
bool use_undo)
748 if (recall->recall_cost() < 0) {
753 res =
place_recruit(recall, loc, from, recall->recall_cost(),
void clear()
Clears the stack of undoable (and redoable) actions.
const std::string & id() const
place_recruit_result place_recruit(unit_ptr u, const map_location &recruit_location, const map_location &recruited_from, int cost, bool is_recall, bool show, bool fire_event, bool full_movement, bool wml_triggered)
const map_location & get_location() const
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
size_t underlying_id() const
The unique internal ID of the unit.
bool clear_unit(const map_location &view_loc, team &view_team, size_t viewer_id, int sight_range, bool slowed, const movetype::terrain_costs &costs, const map_location &real_loc, const std::set< map_location > *known_units=nullptr, size_t *enemy_count=nullptr, size_t *friend_count=nullptr, move_unit_spectator *spectator=nullptr, bool instant=true)
Clears shroud (and fog) around the provided location for view_team based on sight_range, costs, and slowed.
map_location find_vacant_castle(const unit &leader)
Wrapper for find_vacant_tile() when looking for a vacant castle tile near a leader.
Various functions implementing vision (through fog of war and shroud).
bool get_village(const map_location &loc, int side, bool *action_timebonus, bool fire_event)
Makes it so the village at the given location is owned by the given side.
const std::set< std::string > & recruits() const
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
bool actor_sighted(const unit &target, const std::vector< int > *cache)
Fires sighted events for the sides that can see target.
Recruitment OK, but not at the specified location.
bool fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
DIRECTION get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
void write(config &cfg) const
RECRUIT_CHECK
The possible results of finding a location for recruiting (or recalling).
static config unit_type(const unit *u)
Definitions for the interface to Wesnoth Markup Language (WML).
void redraw_minimap()
Schedule the minimap to be redrawn.
std::vector< unit_const_ptr > get_recalls(int side, const map_location &recall_loc)
Gets the recallable units for a side, restricted by that side's leaders' personal abilities to recall...
void recruit_unit(const unit &u)
unit_ptr extract_if_matches_id(const std::string &unit_id)
Find a unit by id, and extract from this object if found. Null if not found.
const std::vector< std::string > & recruits() const
const std::string & type_id() const
The id of the type of the unit.
This class stores all the data for a single 'side' (in game nomenclature).
void recruit_unit(const unit_type &u_type, int side_num, const map_location &loc, const map_location &from, bool show, bool use_undo)
Recruits a unit of the given type for the given side.
static UNUSEDNOWARN std::string _(const char *str)
std::vector< team > * teams
pointer get_shared_ptr() const
const std::set< std::string > get_recruits(int side, const map_location &recruit_loc)
Gets the recruitable units from a side's leaders' personal recruit lists who can recruit on or from a...
std::pair< unit_iterator, bool > insert(unit_ptr p)
Adds the unit to the map.
size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
filter_context * filter_con
int w() const
Effective map width.
Encapsulates the map of the game.
static DIRECTION get_opposite_dir(DIRECTION d)
checkup * checkup_instance
boost::tuple< bool, int, bool > place_recruit_result
Place a unit into the game.
static const map_location & null_location()
No vacant castle tiles around a leader on a keep.
game_events::manager * game_events
GLuint GLuint GLsizei count
const std::string & save_id() const
void show(CVideo &video, const std::string &window_id, const t_string &message, const tpoint &mouse)
Shows a tip.
Encapsulates the map of the game.
Various functions related to moving units.
void add_recruit(const unit_const_ptr u, const map_location &loc, const map_location &from, int orig_village_owner, bool time_bonus)
Adds a recruit to the undo stack.
static void process_error(const std::string &msg)
Various functions related to the creation of units (recruits, recalls, and placed units)...
RECRUIT_CHECK check_recall_location(const int side, map_location &recall_location, map_location &recall_from, const unit &unit_recall)
Checks if there is a location on which to recall unit_recall.
int h() const
Effective map height.
No able leaders are on a keep.
std::string get_checksum(const unit &u)
Gets a checksum for a unit.
void add_recall(const unit_const_ptr u, const map_location &loc, const map_location &from, int orig_village_owner, bool time_bonus)
Adds a recall to the undo stack.
Define the game's event mechanism.
std::string find_recall_location(const int side, map_location &recall_location, map_location &recall_from, const unit &unit_recall)
Finds a location on which to recall unit_recall.
RECRUIT_CHECK check_recruit_location(const int side, map_location &recruit_location, map_location &recruited_from, const std::string &unit_type)
Checks if there is a location on which to place a recruited unit.
std::set< std::string > & encountered_units()
bool is_castle(const map_location &loc) const
const config & recall_filter() const
bool fire_event(const tevent event, std::vector< std::pair< twidget *, tevent > > &event_chain, twidget *dispatcher, twidget *widget, F functor)
Helper function for fire_event.
void recall_unit(const unit &u)
game_events::t_pump & pump()
virtual const gamemap & map() const
bool fire_events()
Fires the sighted events that were earlier recorded by fog/shroud clearing.
size_t find_index(const std::string &unit_id) const
Find the index of a unit by its id.
boost::intrusive_ptr< unit > unit_ptr
void unit_recruited(const map_location &loc, const map_location &leader_loc)
A variable-expanding proxy for the config class.
Various functions that implement the undoing (and redoing) of in-game commands.
std::string find_recruit_location(const int side, map_location &recruit_location, map_location &recruited_from, const std::string &unit_type)
Finds a location on which to place a unit.
Standard logging facilities (interface).
bool recall_unit(const std::string &id, team ¤t_team, const map_location &loc, const map_location &from, bool show, bool use_undo)
Recalls the unit with the indicated ID for the provided team.
recall_list_manager & recall_list()
Container associating units to locations.
Class to encapsulate fog/shroud clearing and the resultant sighted events.
boost::shared_ptr< wb::manager > whiteboard
static lg::log_domain log_engine("engine")
actions::undo_list * undo_stack
unit_iterator find(size_t id)
virtual bool local_checkup(const config &expected_data, config &real_data)=0
Compares data to the results calculated during the original game.
A config object defines a single node in a WML file, with access to child nodes.
This module contains various pathfinding functions and utilities.
GLsizei const GLcharARB ** string
Display units performing various actions: moving, attacking, and dying.
bool is_keep(const map_location &loc) const
No leaders able to recall/recruit the given unit/type.