54 #define DBG_NG LOG_STREAM(debug, log_engine)
55 #define LOG_NG LOG_STREAM(info, log_engine)
56 #define ERR_NG LOG_STREAM(err, log_engine)
64 LOG_NG <<
"getting recruit list for side " << side <<
" at location " << recruit_loc;
66 std::set<std::string> local_result;
67 std::set<std::string> global_result;
71 bool leader_in_place =
false;
78 if ( find_it != u_end ) {
79 if ( find_it->can_recruit() && find_it->side() == side &&
84 leader_in_place =
true;
85 local_result.insert(find_it->recruits().begin(),
86 find_it->recruits().end());
88 else if ( find_it->is_visible_to_team(current_team,
false) )
95 if ( !leader_in_place ) {
97 for( ; u != u_end; ++u ) {
99 if ( !(u->can_recruit() && u->side() == side) )
104 leader_in_place=
true;
105 local_result.insert(u->recruits().begin(), u->recruits().end());
107 else if ( !leader_in_place )
108 global_result.insert(u->recruits().begin(), u->recruits().end());
113 std::set<std::string> & result = leader_in_place ? local_result : global_result;
116 const std::set<std::string>& recruit_list = current_team.
recruits();
117 result.insert(recruit_list.begin(), recruit_list.end());
131 std::vector< unit_const_ptr > & result,
132 std::set<std::size_t> * already_added =
nullptr)
143 std::size_t underlying_id =
recall_unit.underlying_id();
144 if ( !already_added || already_added->count(underlying_id) == 0 )
151 result.push_back(recall_unit_ptr);
152 if ( already_added !=
nullptr )
153 already_added->insert(underlying_id);
162 LOG_NG <<
"getting recall list for side " << side <<
" at location " << recall_loc;
164 std::vector<unit_const_ptr > result;
173 bool leader_in_place =
false;
181 if ( find_it->can_recruit() && find_it->side() == side &&
200 std::set<std::size_t> valid_local_recalls;
202 for(; u != u_end; ++u) {
204 if (!(u->can_recruit() && u->side() == side))
210 leader_in_place=
true;
212 add_leader_filtered_recalls(u.
get_shared_ptr(), result, &valid_local_recalls);
216 if ( !leader_in_place )
218 std::set<std::size_t> valid_local_recalls;
222 if(!u->can_recruit() || u->side() != side) {
226 add_leader_filtered_recalls(u.get_shared_ptr(), result, &valid_local_recalls);
249 team& recall_team = (*resources::gameboard).get_team(recaller.
side());
263 if ( !permissible.
valid() )
268 alternative = permissible;
280 const unit &unit_recall)
299 if ( u != u_end && u->side() == side ) {
301 check_unit_recall_location(*u, unit_recall, check_location, alternative);
305 for ( u = units.
begin(); best_result < goal_result && u != u_end; ++u ) {
306 if ( u->side() != side )
311 check_unit_recall_location(*u, unit_recall, check_location, alternative);
314 if ( current_result <= best_result )
316 best_result = current_result;
320 recall_from = u->get_location();
325 recall_location = alternative;
332 LOG_NG <<
"finding recall location for side " << side <<
" and unit " << unit_recall.
id();
339 LOG_NG <<
"No leaders on side " << side <<
" when recalling " << unit_recall.
id() <<
".";
340 return _(
"You do not have a leader to recall with.");
343 LOG_NG <<
"No leader is able to recall " << unit_recall.
id() <<
" on side " << side <<
".";
344 return _(
"None of your leaders are able to recall that unit.");
347 LOG_NG <<
"No leader able to recall " << unit_recall.
id() <<
" is on a keep.";
348 return _(
"You must have a leader on a keep who is able to recall that unit.");
351 LOG_NG <<
"No vacant castle tiles around a keep are available for recalling " << unit_recall.
id() <<
"; requested location is " << recall_location <<
".";
352 return _(
"There are no vacant castle tiles in which to recall the unit.");
356 return std::string();
361 ERR_NG <<
"Unrecognized enum in find_recall_location()";
362 return _(
"An unrecognized error has occurred.");
393 if ( !permissible.
valid() )
398 alternative = permissible;
435 if ( u != u_end && u->side() == side ) {
437 check_unit_recruit_location(*u, check_type, check_location, alternative);
441 for ( u = units.
begin(); best_result < goal_result && u != u_end; ++u ) {
442 if ( u->side() != side )
447 check_unit_recruit_location(*u, check_type, check_location, alternative);
450 if ( current_result <= best_result )
452 best_result = current_result;
456 recruited_from = u->get_location();
461 recruit_location = alternative;
468 LOG_NG <<
"finding recruit location for side " << side;
475 LOG_NG <<
"No leaders on side " << side <<
" when recruiting '" <<
unit_type <<
"'.";
476 return _(
"You do not have a leader to recruit with.");
479 LOG_NG <<
"No leader is able to recruit '" <<
unit_type <<
"' on side " << side <<
".";
480 return _(
"None of your leaders are able to recruit this unit.");
483 LOG_NG <<
"No leader able to recruit '" <<
unit_type <<
"' is on a keep.";
484 return _(
"You must have a leader on a keep who is able to recruit the unit.");
487 LOG_NG <<
"No vacant castle tiles around a keep are available for recruiting '" <<
unit_type <<
"'; requested location is " << recruit_location <<
".";
488 return _(
"There are no vacant castle tiles in which to recruit the unit.");
492 return std::string();
497 ERR_NG <<
"Unrecognized enum in find_recruit_location()";
498 return _(
"An unrecognized error has occurred.");
506 void recruit_checksums(
const unit &new_unit,
bool wml_triggered)
513 config original_checksum_config;
522 checksum_equals = original_checksum_config[
"checksum"] == alternate_checksum;
526 const std::string old_checksum = original_checksum_config[
"checksum"];
527 std::stringstream error_msg;
528 error_msg <<
"SYNC: In recruit " << new_unit.
type_id() <<
529 ": has checksum " << checksum <<
530 " while datasource has checksum " << old_checksum <<
"\n";
531 if(old_checksum.empty())
533 error_msg <<
"Original result is \n" << original_checksum_config <<
"\n";
536 new_unit.
write(cfg_unit1);
553 if (leader != units.
end() && leader->can_recruit() &&
555 return leader->get_location();
558 for (leader = units.
begin(); leader != units.
end(); ++leader)
559 if (leader->can_recruit() && leader->side() == side &&
561 return leader->get_location();
575 if ( !un_it.
valid() ) {
582 current_loc = un_it->get_location();
594 int min_dist = std::numeric_limits<int>::max();
596 for ( unit_itor = units.
begin(); unit_itor != units.
end(); ++unit_itor ) {
599 int dist =
distance_between(unit_itor->get_location(),recruit_loc) - unit_itor->level();
600 if (dist < min_dist) {
602 min_loc = unit_itor->get_location();
606 if (min_dist < std::numeric_limits<int>::max()) {
625 LOG_NG <<
"placing new unit on location " << recruit_location;
627 u->set_movement(u->total_movement(),
true);
629 u->set_movement(0,
true);
639 find_recruit_leader(u->side(), recruit_location, recruited_from);
640 u->set_location(recruit_location);
649 set_recruit_facing(new_unit_itor, *u, recruit_location, leader_loc);
651 new_unit_itor->set_facing(facing);
656 recruit_checksums(*u, wml_triggered);
660 if(!new_unit_itor.
valid()) {
665 const std::string event_name = is_recall ?
"prerecall" :
"prerecruit";
666 LOG_NG <<
"firing " << event_name <<
" event";
670 if ( !validate_recruit_iterator(new_unit_itor, current_loc) )
671 return std::tuple(
true, 0,
false);
672 new_unit_itor->set_hidden(
true);
681 new_unit_itor->set_hidden(
false);
690 std::get<0>(res) |= std::get<0>(
actions::get_village(current_loc, new_unit_itor->side(), &std::get<2>(res)));
691 if ( !validate_recruit_iterator(new_unit_itor, current_loc) )
692 return std::tuple(
true, 0,
false);
698 std::get<0>(res) |= clearer.
clear_unit(current_loc, *new_unit_itor);
701 const std::string event_name = is_recall ?
"recall" :
"recruit";
702 LOG_NG <<
"firing " << event_name <<
" event";
709 std::get<0>(res) |= std::get<0>(clearer.
fire_events());
710 if ( new_unit_itor.
valid() )
761 if (recall->recall_cost() < 0) {
766 res =
place_recruit(recall, loc, from, recall->recall_cost(),
Various functions related to moving units.
Class to encapsulate fog/shroud clearing and the resultant sighted events.
game_events::pump_result_t fire_events()
Fires the sighted events that were earlier recorded by fog/shroud clearing.
bool clear_unit(const map_location &view_loc, team &view_team, std::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, std::size_t *enemy_count=nullptr, std::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,...
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.
void clear()
Clears the stack of undoable (and redoable) actions.
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.
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.
int village_owner(const map_location &loc) const
Given the location of a village, will return the 1-based number of the team that currently owns it,...
void redraw_minimap()
Schedule the minimap to be redrawn.
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
static display * get_singleton()
Returns the display object if a display object exists.
virtual const unit_map & units() const override
virtual const gamemap & map() const override
bool can_recruit_on(const map_location &leader_loc, const map_location &recruit_loc, int side) const
Checks to see if a leader at leader_loc could recruit on recruit_loc.
int w() const
Effective map width.
int h() const
Effective map height.
Encapsulates the map of the game.
bool is_castle(const map_location &loc) const
bool is_keep(const map_location &loc) const
statistics_t & statistics()
std::set< std::string > & encountered_units()
unit_ptr extract_if_matches_id(const std::string &unit_id, int *pos=nullptr)
Find a unit by id, and extract from this object if found.
std::size_t find_index(const std::string &unit_id) const
Find the index of a unit by its id.
static void process_error(const std::string &msg)
void recall_unit(const unit &u)
void recruit_unit(const unit &u)
static bool undo_blocked()
This class stores all the data for a single 'side' (in game nomenclature).
bool auto_shroud_updates() const
std::string save_id_or_number() const
void spend_gold(const int amount)
recall_list_manager & recall_list()
const std::set< std::string > & recruits() const
Container associating units to locations.
unit_iterator find(std::size_t id)
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
A single unit type that the player may recruit.
This class represents a single unit of a specific type.
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
A variable-expanding proxy for the config class.
Definitions for the interface to Wesnoth Markup Language (WML).
static lg::log_domain log_engine("engine")
Various functions related to the creation of units (recruits, recalls, and placed units).
map_display and display: classes which take care of displaying the map and game-data on the screen.
static std::string _(const char *str)
void write(config &cfg, bool write_all=true) const
Serializes the current unit metadata values.
@ version_1_16_or_older
Included some of the flavortext from weapon specials.
const std::vector< std::string > & recruits() const
The type IDs of the other units this unit may recruit, if possible.
const config & recall_filter() const
Gets the filter constraints upon which units this unit may recall, if able.
const std::string & type_id() const
The id of this unit's type.
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
const map_location & get_location() const
The current map location this unit is at.
T end(const std::pair< T, T > &p)
std::size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
Standard logging facilities (interface).
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.
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.
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.
place_recruit_result place_recruit(unit_ptr u, const map_location &recruit_location, const map_location &recruited_from, int cost, bool is_recall, map_location::direction facing, bool show, bool fire_event, bool full_movement, bool wml_triggered)
Place a unit into the game.
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...
RECRUIT_CHECK
The possible results of finding a location for recruiting (or recalling).
@ RECRUIT_OK
Recruitment OK, but not at the specified location.
@ RECRUIT_NO_VACANCY
No able leaders are on a keep.
@ RECRUIT_NO_ABLE_LEADER
No leaders exist.
@ RECRUIT_ALTERNATE_LOCATION
No vacant castle tiles around a leader on a keep.
@ RECRUIT_NO_KEEP_LEADER
No leaders able to recall/recruit the given unit/type.
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.
game_events::pump_result_t actor_sighted(const unit &target, const std::vector< int > *cache)
Fires sighted events for the sides that can see target.
bool recall_unit(const std::string &id, team ¤t_team, const map_location &loc, const map_location &from, map_location::direction facing, bool show, bool use_undo)
Recalls the unit with the indicated ID for the provided team.
game_events::pump_result_t 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.
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...
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.
std::tuple< bool, int, bool > place_recruit_result
void pump()
Process all events currently in the queue.
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
bool fire_event(const ui_event event, const std::vector< std::pair< widget *, ui_event >> &event_chain, widget *dispatcher, widget *w, F &&... params)
Helper function for fire_event.
map_location find_vacant_castle(const unit &leader)
Wrapper for find_vacant_tile() when looking for a vacant castle tile near a leader.
game_events::manager * game_events
actions::undo_list * undo_stack
play_controller * controller
filter_context * filter_con
std::shared_ptr< wb::manager > whiteboard
void unit_recruited(const map_location &loc, const map_location &leader_loc)
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
This module contains various pathfinding functions and utilities.
std::shared_ptr< const unit > unit_const_ptr
std::shared_ptr< unit > unit_ptr
Define the game's event mechanism.
static config unit_type(const unit *u)
Encapsulates the map of the game.
static constexpr direction get_opposite_direction(direction d)
direction
Valid directions which can be moved in our hexagonal world.
direction get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
static const map_location & null_location()
pointer get_shared_ptr() const
This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax...
checkup * checkup_instance
Display units performing various actions: moving, attacking, and dying.
Various functions that implement the undoing (and redoing) of in-game commands.
std::string get_checksum(const unit &u, backwards_compatibility::unit_checksum_version version)
Gets a checksum for a unit.
Various functions implementing vision (through fog of war and shroud).