45 #define DBG_NG LOG_STREAM(debug, log_engine)
46 #define LOG_NG LOG_STREAM(info, log_engine)
47 #define WRN_NG LOG_STREAM(warn, log_engine)
48 #define ERR_NG LOG_STREAM(err, log_engine)
51 #define LOG_CF LOG_STREAM(info, log_config)
54 #define LOG_DP LOG_STREAM(info, log_display)
63 ERR_NG <<
"advance_unit_dialog: unit not found";
66 const unit& u = *u_it;
67 std::vector<unit_const_ptr> previews;
69 for (
const std::string& advance : u.
advances_to()) {
74 std::size_t num_real_advances = previews.size();
75 bool always_display =
false;
78 if (advance[
"always_display"].to_bool()) {
79 always_display =
true;
84 if (previews.size() > 1 || always_display) {
92 assert(
false &&
"Unit advance dialog was cancelled, which should be impossible.");
98 bool animate_unit_advancement(
const map_location &loc, std::size_t choice,
const bool &
fire_event,
const bool animate)
104 LOG_DP <<
"animate_unit_advancement suppressed: invalid unit";
107 else if (!u->advances()) {
108 LOG_DP <<
"animate_unit_advancement suppressed: unit does not advance";
112 const std::vector<std::string>& options = u->advances_to();
113 std::vector<config> mod_options = u->get_modification_advances();
115 assert(options.size() + mod_options.size() > 0);
116 if (choice >= options.size() + mod_options.size()) {
117 LOG_DP <<
"animate_unit_advancement: invalid option, using first option";
126 bool with_bars =
true;
132 if (choice < options.size()) {
134 std::string chosen_unit = options[choice];
138 const config &mod_option = mod_options[choice - options.size()];
160 int get_advancement_index(
const unit& u,
const std::string&
id)
162 const std::vector<std::string>& type_options = u.
advances_to();
164 auto pick_iter = std::find(type_options.begin(), type_options.end(),
id);
165 if(pick_iter != type_options.end()) {
166 return std::distance(type_options.begin(), pick_iter);
171 auto pick_iter = std::find_if(amla_options.begin(), amla_options.end(), [&](
const config& adv){
172 return adv[
"id"].str() == id;
174 if(pick_iter != amla_options.end()) {
175 return type_options.size() + std::distance(amla_options.begin(), pick_iter);
184 unit_advancement_choice(
const map_location& loc,
int total_opt,
int side_num,
bool force_dialog)
185 :
loc_ (loc), nb_options_(total_opt), side_num_(side_num), force_dialog_(force_dialog)
189 virtual ~unit_advancement_choice()
205 if(!
video::headless() && (force_dialog_ || (
t.is_local_human() && !
t.is_droid() && !
t.is_idle() && (is_current_side || !is_mp))))
207 res = advance_unit_dialog(
loc_);
209 else if(is_current_side && (
t.is_local_ai() ||
t.is_network_ai() ||
t.is_empty()))
218 ERR_NG <<
"unit_advancement_choice: unit not found";
223 for(
const auto& adv_id : allowed) {
224 int res_new = get_advancement_index(*u, adv_id);
239 LOG_NG <<
"unit at position " <<
loc_ <<
" chose advancement number " << res;
256 return _(
"waiting for^an advancement choice");
273 for(
int advacment_number = 0; advacment_number < 20; advacment_number++)
283 LOG_NG <<
"Firing pre advance event at " << params.
loc_ <<
".";
289 LOG_NG <<
"pre advance event aborted advancing.";
301 DBG_NG <<
"animate_unit_advancement result = " << result;
304 if (u.
valid() && u->experience() > 80)
306 WRN_NG <<
"Unit has too many (" << u->experience() <<
") XP left; cascade leveling goes on still.";
309 ERR_NG <<
"unit at " << params.
loc_ <<
" tried to advance more than 20 times. Advancing was aborted";
317 " to: " + advance_to);
320 new_unit->set_experience(new_unit->experience_overflow());
321 new_unit->advance_to(*new_type);
322 new_unit->heal_fully();
326 new_unit->set_user_end_turn(
false);
327 new_unit->set_hidden(
false);
338 amla_unit->set_experience(amla_unit->experience_overflow());
339 amla_unit->add_modification(
"advancement", mod_option);
351 std::string original_type = u->type_id();
356 LOG_NG <<
"Firing advance event at " << loc <<
".";
359 if (!u.
valid() || u->experience() < u->max_experience() ||
360 u->type_id() != original_type)
362 LOG_NG <<
"WML has invalidated the advancing unit. Aborting.";
366 loc = u->get_location();
375 auto [new_unit, use_amla] = utils::visit(
385 new_unit->set_location(loc);
390 LOG_CF <<
"Added '" << new_unit->type_id() <<
"' to the encountered units.";
392 u->anim_comp().clear_haloes();
404 LOG_NG <<
"Firing post_advance event at " << loc <<
".";
unit_ptr get_advanced_unit(const unit &u, const std::string &advance_to)
Returns the advanced version of a unit (with traits and items retained).
void advance_unit(map_location loc, const advancement_option &advance_to, bool fire_event)
Function which will advance the unit at loc to 'advance_to'.
unit_ptr get_amla_unit(const unit &u, const config &mod_option)
Returns the AMLA-advanced version of a unit (with traits and items retained).
static lg::log_domain log_engine("engine")
void advance_unit_at(const advance_unit_params ¶ms)
static lg::log_domain log_display("display")
static lg::log_domain log_config("config")
Various functions that implement advancements of units.
utils::variant< std::string, const config * > advancement_option
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
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,...
static manager & get_singleton()
const ai::unit_advancements_aspect & get_advancement_aspect_for_side(side_number side)
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
A config object defines a single node in a WML file, with access to child nodes.
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
void invalidate_all()
Function to invalidate all tiles.
static display * get_singleton()
Returns the display object if a display object exists.
virtual const unit_map & units() const override
bool has_current_player() const
returns where there is currently a well defiend "current player", that is for example not the case du...
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
static game_display * get_singleton()
game_events::wml_event_pump & pump()
pump_result_t 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.
bool show(const unsigned auto_close_time=0)
Shows the window.
int get_selected_index() const
statistics_t & statistics()
int current_side() const
Returns the number of the side whose turn it is.
virtual bool is_networked_mp() const
std::set< std::string > & encountered_units()
int get_random_int(int min, int max)
void advance_unit(const unit &u)
This class stores all the data for a single 'side' (in game nomenclature).
void wait_for_end() const
void add_animation(unit_const_ptr animated_unit, const unit_animation *animation, const map_location &src=map_location::null_location(), bool with_bars=false, const std::string &text="", const color_t text_color={0, 0, 0})
unit_iterator find(std::size_t id)
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
A single unit type that the player may recruit.
This class represents a single unit of a specific type.
static std::string _(const char *str)
@ STATE_PETRIFIED
The unit is poisoned - it loses health each turn.
@ STATE_POISONED
The unit is slowed - it moves slower and does less damage.
std::vector< config > get_modification_advances() const
Gets any non-typed advanced options set by modifications.
const advances_to_t & advances_to() const
Gets the possible types this unit can advance to on level-up.
Standard logging facilities (interface).
std::vector< int > get_sides_not_seeing(const unit &target)
Returns the sides that cannot currently see target.
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.
void pump()
Process all events currently in the queue.
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.
config get_user_choice(const std::string &name, const user_choice &uch, int side=0)
rng * generator
This generator is automatically synced during synced context.
game_events::manager * game_events
play_controller * controller
std::shared_ptr< wb::manager > whiteboard
bool will_certainly_advance(const unit_map::iterator &u)
Encapsulates the logic for deciding whether an iterator u points to a unit that can advance.
int number_of_possible_advances(const unit &u)
Determines the total number of available advancements (of any kind) for a given unit.
constexpr bool decayed_is_same
Equivalent to as std::is_same_v except both types are passed through std::decay first.
bool headless()
The game is running headless.
std::shared_ptr< unit > unit_ptr
Define the game's event mechanism.
advances the unit at loc if it has enough experience, maximum 20 times.
Error used for any general game error, e.g.
Encapsulates the map of the game.
Interface for querying local choices.
virtual config query_user(int side) const =0
virtual std::string description() const
virtual config random_choice(int side) const =0
pointer get_shared_ptr() const
This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax...
unit_type_data unit_types
Various functions implementing vision (through fog of war and shroud).