The Battle for Wesnoth  1.19.18+dev
unit.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "movetype.hpp"
20 #include "units/id.hpp"
21 #include "units/ptr.hpp"
22 #include "units/attack_type.hpp"
23 #include "units/race.hpp"
24 #include "utils/optional_fwd.hpp"
25 #include "utils/variant.hpp"
26 
27 #include <bitset>
28 #include "utils/optional_fwd.hpp"
29 
30 class team;
32 class vconfig;
33 struct color_t;
34 
35 /**
36  * This class represents a *single* unit of a specific type.
37  */
38 class unit : public std::enable_shared_from_this<unit>
39 {
40 public:
41  /**
42  * Clear this unit status cache for all units. Currently only the hidden
43  * status of units is cached this way.
44  */
45  static void clear_status_caches();
46 
47  /** The path to the leader crown overlay. */
48  static const std::string& leader_crown();
49 
50 private:
51  void init(const config& cfg, bool use_traits = false, const vconfig* vcfg = nullptr);
52 
53  void init(const unit_type& t, int side, bool real_unit, unit_race::GENDER gender = unit_race::NUM_GENDERS, const std::string& variation = "");
54 
55  // Copy constructor
56  unit(const unit& u);
57 
58  struct unit_ctor_t {};
59 
60 public:
61  //private default ctor, butusing constructor to allow calling make_shared<unit> in create().
63  unit() = delete;
64 
65 private:
67  {
81  //note that UA_ATTACKS only tracks added/deleted attacks, not modified attacks.
88  UA_COUNT
89  };
90 
92  {
93  changed_attributes_[int(attr)] = true;
94  }
95 
96  bool get_attacks_changed() const;
97 
99  {
100  return changed_attributes_[int(attr)];
101  }
102 
104 
105 public:
106  /** Initializes a unit from a config */
107  static unit_ptr create(const config& cfg, bool use_traits = false, const vconfig* vcfg = nullptr)
108  {
109  unit_ptr res = std::make_shared<unit>(unit_ctor_t());
110  res->init(cfg, use_traits, vcfg);
111  return res;
112  }
113 
114  /**
115  * Initializes a unit from a unit type.
116  *
117  * Only real_unit-s should have random traits, name and gender (to prevent OOS caused by RNG calls)
118  */
119  static unit_ptr create(const unit_type& t, int side, bool real_unit, unit_race::GENDER gender = unit_race::NUM_GENDERS, const std::string& variation = "")
120  {
121  unit_ptr res = std::make_shared<unit>(unit_ctor_t());
122  res->init(t, side, real_unit, gender, variation);
123 
124  return res;
125  }
126 
127  unit_ptr clone() const
128  {
129  return std::shared_ptr<unit>(new unit(*this));
130  }
131 
132  virtual ~unit();
133 
134  unit& operator=(const unit&) = delete;
135 
136  /**
137  * @defgroup unit_advance Advancement functions
138  * @{
139  */
140 
141  /** Advances this unit to another type */
142  void advance_to(const unit_type& t, bool use_traits = false);
143 
144  using advances_to_t = std::vector<std::string>;
145  /**
146  * Gets the possible types this unit can advance to on level-up.
147  *
148  * @returns A list of type IDs this unit may advance to.
149  */
150  const advances_to_t& advances_to() const
151  {
152  return advances_to_;
153  }
154 
155  /**
156  * Gets the names of the possible types this unit can advance to on level-up.
157  *
158  * @returns A list of the names of the types this unit may advance to.
159  */
160  const std::vector<std::string> advances_to_translated() const;
161 
162  /**
163  * Sets this unit's advancement options.
164  *
165  * @param advances_to A list of new type IDs this unit may advance to.
166  */
167  void set_advances_to(const std::vector<std::string>& advances_to);
168 
169  /**
170  * Checks whether this unit has any options to advance to.
171  *
172  * This considers both whether it has types to advance to OR whether any modifications
173  * specify non-type advancement options.
174  *
175  * Note this does not consider unit experience at all, it only checks option availability.
176  * See @ref advances if an experience check is necessary.
177  */
178  bool can_advance() const
179  {
180  return !advances_to_.empty() || !get_modification_advances().empty();
181  }
182 
183  /**
184  * Checks whether this unit is eligible for level-up.
185  *
186  * @retval true This unit has sufficient experience to level up and has advancement
187  * options available.
188  */
189  bool advances() const
190  {
191  return experience_ >= max_experience() && can_advance();
192  }
193 
194  /**
195  * Gets and image path and and associated description for each advancement option.
196  *
197  * Covers both type and modification-based advancements.
198  *
199  * @returns A data map, in image/description format. If the option is a unit type,
200  * advancement, the key is the type's image and the value the type ID.
201  *
202  * If the option is a modification, the key and value are set from config data
203  * (see @ref get_modification_advances).
204  */
205  std::map<std::string, std::string> advancement_icons() const;
206 
207  /**
208  * Gets any non-typed advanced options set by modifications.
209  *
210  * These are usually used to give a unit special advancement options that don't invole transforming to a
211  * new type.
212  *
213  * Note this is not the raw option data. Parsing is performed to ensure each option appears only once.
214  * Use @ref modification_advancements is the raw data is needed.
215  *
216  * @returns A config list of options data. Each option is unique.
217  */
218  std::vector<config> get_modification_advances() const;
219 
220  /**
221  * Gets the image and description data for modification advancements.
222  *
223  * @returns A list of pairs of the image paths(first) and descriptions (second) for
224  * each advancement option.
225  */
226  std::vector<std::pair<std::string, std::string>> amla_icons() const;
227 
228  /** The raw, unparsed data for modification advancements. */
229  const std::vector<config>& modification_advancements() const
230  {
231  return advancements_;
232  }
233 
234  /** Sets the raw modification advancement option data */
235  void set_advancements(std::vector<config> advancements);
236 
237  /**
238  * @}
239  * @defgroup unit_access Basic data setters and getters
240  * @{
241  **/
242 
243 public:
244  /**
245  * The side this unit belongs to.
246  *
247  * Note that side numbers starts from 1, not 0, so be sure to subtract 1 if using as a container index.
248  */
249  int side() const
250  {
251  return side_;
252  }
253 
254  /** Sets the side this unit belongs to. */
255  void set_side(unsigned int new_side)
256  {
257  side_ = new_side;
258  }
259 
260  /** This unit's type, accounting for gender and variation. */
261  const unit_type& type() const
262  {
263  return *type_;
264  }
265 
266  /**
267  * The id of this unit's type.
268  *
269  * If you are dealing with creating units (e.g. recruitment), this is not what you want, as a
270  * variation can change this; use type().parent_id() instead.
271  */
272  const std::string& type_id() const;
273 
274  /** Gets the translatable name of this unit's type. */
275  const t_string& type_name() const
276  {
277  return type_name_;
278  }
279 
280  /**
281  * Gets this unit's id.
282  *
283  * This is a unique string usually set by WML. It should *not* be used for internal tracking in
284  * the unit_map. Use @ref underlying_id for that.
285  */
286  const std::string& id() const
287  {
288  return id_;
289  }
290 
291  /** Sets this unit's string ID. */
292  void set_id(const std::string& id)
293  {
294  id_ = id;
295  }
296 
297  /** This unit's unique internal ID. This should *not* be used for user-facing operations. */
298  std::size_t underlying_id() const
299  {
300  return underlying_id_.value;
301  }
302 
303 private:
304  /** Sets the internal ID. */
305  void set_underlying_id(n_unit::id_manager& id_manager);
306 
307 public:
308  /** Gets this unit's translatable display name. */
309  const t_string& name() const
310  {
311  return name_;
312  }
313 
314  /**
315  * Sets this unit's translatable display name.
316  *
317  * This should only be used internally since it ignores the 'unrenamable' flag.
318  */
319  void set_name(const t_string& name)
320  {
321  name_ = name;
322  }
323 
324  /**
325  * Attempts to rename this unit's translatable display name, taking the 'unrenamable' flag into account.
326  *
327  * If a direct rename is desired, use @ref set_name.
328  * @todo should this also take a t_string?
329  */
330  void rename(const std::string& name)
331  {
332  if(!unrenamable_) {
333  name_ = name;
334  }
335  }
336 
337  /**
338  * Whether this unit can be renamed.
339  *
340  * This flag is considered by @ref rename, but not @ref set_name.
341  */
342  bool unrenamable() const
343  {
344  return unrenamable_;
345  }
346 
347  /**
348  * Sets the 'unrenamable' flag. Usually used for scenario-specific units which should not be renamed.
349  */
351  {
353  }
354 
355  /**
356  * Whether this unit can be dismissed.
357  *
358  * This flag is used by the Unit Recall dialog.
359  */
360  bool dismissable() const
361  {
362  return dismissable_;
363  }
364 
365  /** A message of why this unit cannot be dismissed. */
367  {
368  return dismiss_message_;
369  }
370 
371  /** A detailed description of this unit. */
373  {
374  return description_;
375  }
376 
377  /** A detailed description of this unit. */
378  void set_unit_description(const t_string& new_desc)
379  {
380  description_ = new_desc;
381  }
382 
383  /** The unit's special notes. */
384  std::vector<t_string> unit_special_notes() const;
385 
386  /** The gender of this unit. */
388  {
389  return gender_;
390  }
391 
392  /**
393  * The alignment of this unit.
394  *
395  * This affects the time of day during which this unit's attacks do the most damage.
396  */
398  {
399  return alignment_;
400  }
401 
402  /** Sets the alignment of this unit. */
404  {
407  }
408 
409  /**
410  * Gets this unit's race.
411  *
412  * @returns A pointer to a unit_race object - never nullptr, but it may point
413  * to the null race.
414  */
415  const unit_race* race() const
416  {
417  return race_;
418  }
419 
420  /** The current number of hitpoints this unit has. */
421  int hitpoints() const
422  {
423  return hit_points_;
424  }
425 
426  /** The max number of hitpoints this unit can have. */
427  int max_hitpoints() const
428  {
429  return max_hit_points_;
430  }
431 
432  void set_max_hitpoints(int value)
433  {
435  max_hit_points_ = value;
436  }
437 
438  /** Sets the current hitpoint amount. */
439  void set_hitpoints(int hp)
440  {
441  hit_points_ = hp;
442  }
443 
444  /** The current number of experience points this unit has. */
445  int experience() const
446  {
447  return experience_;
448  }
449 
450  /** The max number of experience points this unit can have. */
451  int max_experience() const
452  {
453  return max_experience_;
454  }
455 
456  void set_max_experience(int value)
457  {
459  max_experience_ = value;
460  }
461 
462  /** The number of experience points this unit needs to level up, or 0 if current XP > max XP. */
463  unsigned int experience_to_advance() const
464  {
465  return std::max(0, max_experience_ - experience_);
466  }
467 
468  /** The number of experience points over max this unit has, or 0 if current XP < max XP. */
469  unsigned int experience_overflow() const
470  {
471  return std::max(0, experience_ - max_experience_);
472  }
473 
474  /** Sets the current experience point amount. */
475  void set_experience(int xp)
476  {
477  experience_ = xp;
478  }
479 
480  /** The current level of this unit. */
481  int level() const
482  {
483  return level_;
484  }
485 
486  /** Sets the current level of this unit. */
487  void set_level(int level)
488  {
490  level_ = level;
491  }
492 
493  /** The ID of the variation of this unit's type. */
494  const std::string& variation() const
495  {
496  return variation_;
497  }
498 
499  /** The ID of the undead variation (ie, dwarf, swimmer) of this unit. */
500  void set_undead_variation(const std::string& value)
501  {
503  undead_variation_ = value;
504  }
505  const std::string& undead_variation() const
506  {
507  return undead_variation_;
508  }
509 
510  /**
511  * An optional profile image to display in Help.
512  *
513  * @returns The specified image, this unit's type's sprite image if empty
514  * or 'unit_image' was set.
515  */
516  std::string small_profile() const;
517 
518  void set_small_profile(const std::string& value)
519  {
521  small_profile_ = value;
522  }
523  /**
524  * An optional profile image displays when this unit is 'speaking' via [message].
525  *
526  * @returns The specified image, this unit's type's sprite image if empty
527  * or 'unit_image' was set.
528  */
529  std::string big_profile() const;
530 
531  void set_big_profile(const std::string& value);
532 
533  /** Whether this unit can recruit other units - ie, are they a leader unit. */
534  bool can_recruit() const
535  {
536  return canrecruit_;
537  }
538 
539  /** Sets whether this unit can recruit other units. */
540  void set_can_recruit(bool canrecruit)
541  {
542  canrecruit_ = canrecruit;
543  }
544 
545  /** The type IDs of the other units this unit may recruit, if possible. */
546  const std::set<std::string>& recruits() const
547  {
548  return recruit_list_;
549  }
550 
551  /** Sets the recruit list. */
552  void set_recruits(const std::vector<std::string>& recruits);
553 
554  /** How much gold is required to recruit this unit. */
555  int cost() const
556  {
557  return unit_value_;
558  }
559 
560  /** How much gold it costs to recall this unit, or -1 if the side's default
561  * recall cost is used. */
562  int recall_cost() const
563  {
564  return recall_cost_;
565  }
566 
567  /** Sets the cost of recalling this unit. */
569  {
571  }
572 
573  /** Gets the filter constraints upon which units this unit may recall, if able. */
574  const config& recall_filter() const
575  {
576  return filter_recall_;
577  }
578 
579  /** Sets the filter constraints upon which units this unit may recall, if able. */
581  {
583  }
584 
585  /**
586  * Gets this unit's role.
587  *
588  * A role is a special string flag usually used to represent a unit's purpose in a scenario.
589  * It can be filtered on.
590  */
591  const std::string& get_role() const
592  {
593  return role_;
594  }
595 
596  /** Sets a unit's role */
597  void set_role(const std::string& role)
598  {
599  role_ = role;
600  }
601 
602  /**
603  * Gets this unit's usage. This is relevant to the AI.
604  *
605  * Usage refers to how the AI may consider utilizing this unit in combat.
606  * @todo document further
607  */
608  std::string usage() const
609  {
610  return usage_.value_or("");
611  }
612 
613  /** Sets this unit's usage. */
614  void set_usage(const std::string& usage)
615  {
616  usage_ = usage;
617  }
618 
619  /**
620  * Gets any user-defined variables this unit 'owns'.
621  *
622  * These are accessible via WML if the unit's data is serialized to a variable. They're strictly
623  * user-facing; internal engine calculations shouldn't use this.
624  */
626  {
627  return variables_;
628  }
629 
630  /** Const overload of @ref variables. */
631  const config& variables() const
632  {
633  return variables_;
634  }
635 
636  /**
637  * Gets whether this unit is currently hidden on the map.
638  *
639  * Hidden units are not drawn on the main map or the minimap. They are
640  * an implementation detail. For the [hides] ability, see invisible().
641  */
642  bool get_hidden() const
643  {
644  return hidden_;
645  }
646 
647  /** Sets whether the unit is hidden on the map. */
648  void set_hidden(bool state) const;
649 
650  /**
651  * The factor by which the HP bar should be scaled.
652  * Convenience wrapper around the unit_type value.
653  */
654  double hp_bar_scaling() const;
655  /**
656  * The factor by which the XP bar should be scaled.
657  * Convenience wrapper around the unit_type value.
658  */
659  double xp_bar_scaling() const;
660 
661  /**
662  * Whether the unit has been instructed to hold its position.
663  * This excludes it from the unit cycling function.
664  * @return true if it is holding position
665  */
666  bool hold_position() const
667  {
668  return hold_position_;
669  }
670 
671  /**
672  * Toggle the unit's hold position status.
673  */
675  {
677  if(hold_position_) {
678  end_turn_ = true;
679  }
680  }
681 
682  /**
683  * Set whether the user ended their turn
684  * @todo Verify meaning and explain better
685  */
686  void set_user_end_turn(bool value = true)
687  {
688  end_turn_ = value;
689  }
690 
691  /**
692  * Toggle whether the user ended their turn
693  * @todo Verify meaning and explain better
694  */
696  {
697  end_turn_ = !end_turn_;
698  if(!end_turn_) {
699  hold_position_ = false;
700  }
701  }
702 
703  /**
704  * Check whether the user ended their turn
705  * @todo Verify meaning and explain better
706  */
707  bool user_end_turn() const
708  {
709  return end_turn_;
710  }
711 
712  /**
713  * Refresh unit for the beginning of a turn
714  */
715  void new_turn();
716 
717  /**
718  * Refresh unit for the end of a turn
719  */
720  void end_turn();
721 
722  /**
723  * Refresh unit for the beginning of a new scenario
724  */
725  void new_scenario();
726 
727  /**
728  * Damage the unit.
729  * @returns true if the unit dies as a result
730  */
731  bool take_hit(int damage)
732  {
733  hit_points_ -= damage;
734  return hit_points_ <= 0;
735  }
736 
737  /**
738  * Heal the unit
739  * @param amount The number of hitpoints to gain
740  */
741  void heal(int amount);
742 
743  /**
744  * Fully heal the unit, restoring it to max hitpoints
745  */
746  void heal_fully()
747  {
749  }
750 
751  /**
752  * Get the status effects currently affecting the unit.
753  * @return A set of status keys
754  */
755  const std::set<std::string> get_states() const;
756 
757  /**
758  * Check if the unit is affected by a status effect
759  * @param state The status effect to check
760  * @returns true if the unit is affected by the status effect
761  */
762  bool get_state(const std::string& state) const;
763 
764  /**
765  * Set whether the unit is affected by a status effect
766  * @param state The status effect to change
767  * @param value Whether the unit should be affected by the status
768  */
769  void set_state(const std::string& state, bool value);
770 
771  /**
772  * Built-in status effects known to the engine
773  */
774  enum state_t {
775  STATE_SLOWED = 0, /** The unit is slowed - it moves slower and does less damage */
776  STATE_POISONED, /** The unit is poisoned - it loses health each turn */
777  STATE_PETRIFIED, /** The unit is petrified - it cannot move or be attacked */
778  STATE_UNCOVERED, /** The unit is uncovered - it was hiding but has been spotted */
779  STATE_NOT_MOVED, /** The unit has not moved @todo Explain better */
780  STATE_UNHEALABLE, /** The unit cannot be healed */
781  STATE_GUARDIAN, /** The unit is a guardian - it won't move unless a target is sighted */
782  STATE_INVULNERABLE, /** The unit is invulnerable - it cannot be hit by any attack */
783  NUMBER_OF_STATES, /** To set the size of known_boolean_states_ */
784  STATE_UNKNOWN = -1 /** A status effect not known to the engine */
785  };
786 
787  /**
788  * Set whether the unit is affected by a status effect
789  * @param state The status effect to change
790  * @param value Whether the unit should be affected by the status
791  */
792  void set_state(state_t state, bool value);
793 
794  /**
795  * Check if the unit is affected by a status effect
796  * @param state The status effect to check
797  * @returns true if the unit is affected by the status effect
798  */
799  bool get_state(state_t state) const;
800 
801  /**
802  * Convert a string status effect ID to a built-in status effect ID
803  * @returns the state_t representing the status, or STATE_UNKNOWN if it's not built-in
804  */
805  static state_t get_known_boolean_state_id(const std::string& state);
806 
807  /**
808  * Convert a built-in status effect ID to a string status effect ID
809  * @returns the string representing the status, or an empty string for STATE_UNKNOWN
810  */
811  static std::string get_known_boolean_state_name(state_t state);
812 
813  /**
814  * Check if the unit has been poisoned
815  * @returns true if it's poisoned
816  */
817  bool poisoned() const
818  {
819  return get_state(STATE_POISONED);
820  }
821 
822  /**
823  * Check if the unit has been petrified
824  * @returns true if it's petrified
825  */
826  bool incapacitated() const
827  {
828  return get_state(STATE_PETRIFIED);
829  }
830 
831  /**
832  * Check if the unit has been slowed
833  * @returns true if it's slowed
834  */
835  bool slowed() const
836  {
837  return get_state(STATE_SLOWED);
838  }
839 
840  /**
841  * @}
842  * @defgroup unit_atk Attack and resistance functions
843  * @{
844  */
845 
846 public:
847  /** Gets an iterator over this unit's attacks. */
849  {
850  return make_attack_itors(attacks_);
851  }
852 
853  /** Const overload of @ref attacks. */
855  {
856  return make_attack_itors(attacks_);
857  }
858 
859  /**
860  * Adds a new attack to the unit.
861  * @param position An iterator pointing to the attack before which to insert the new one.
862  * @param args The arguments for constructing the attack
863  */
864  template<typename... Args>
865  attack_ptr add_attack(attack_itors::iterator position, Args&&... args)
866  {
868  return *attacks_.emplace(position.base(), new attack_type(std::forward<Args>(args)...));
869  }
870 
871  /**
872  * Remove an attack from the unit
873  * @param atk A pointer to the attack to remove
874  * @return true if the attack was removed, false if it didn't exist on the unit
875  */
876  bool remove_attack(const attack_ptr& atk);
877 
878  /**
879  * Set the unit to have no attacks left for this turn.
880  */
881  void remove_attacks_ai();
882 
883  /** The maximum number of attacks this unit may perform per turn, usually 1. */
884  int max_attacks() const
885  {
886  return max_attacks_;
887  }
888 
889  void set_max_attacks(int value)
890  {
892  max_attacks_ = value;
893  }
894 
895  /**
896  * Gets the remaining number of attacks this unit can perform this turn.
897  *
898  * If the 'incapacitated' status is set, this will always be 0.
899  */
900  int attacks_left() const
901  {
902  return (attacks_left_ == 0 || incapacitated()) ? 0 : attacks_left_;
903  }
904 
905  /**
906  * Gets the remaining number of attacks this unit can perform this turn.
907  *
908  * @param base_value If false, consider the `incapacitated` flag.
909  *
910  * @returns If @a base_value is true, the raw value is returned.
911  */
912  int attacks_left(bool base_value) const
913  {
914  return base_value ? attacks_left_ : attacks_left();
915  }
916 
917  /**
918  * Sets the number of attacks this unit has left this turn.
919  * @param left The number of attacks left
920  */
921  void set_attacks(int left)
922  {
923  attacks_left_ = std::max<int>(0, left);
924  }
925 
926  /**
927  * The unit's defense on a given terrain
928  * @param terrain The terrain to check
929  * @param loc location of unit
930  */
931  int defense_modifier(const t_translation::terrain_code& terrain, const map_location& loc) const;
932 
934  {
935  return defense_modifier(terrain, loc_);
936  }
937 
938  /**
939  * For the provided list of resistance abilities, determine the damage resistance based on which are active and any max_value that's present.
940  *
941  * @param resistance_list A list of resistance abilities that the unit has.
942  * @param damage_name The name of the damage type, for example "blade".
943  * @return The resistance value for a unit with the provided resistance abilities to the provided damage type.
944  */
945  int resistance_value(active_ability_list resistance_list, const std::string& damage_name) const;
946 
947  /**
948  * The unit's resistance against a given damage type
949  * @param damage_name The damage type
950  * @param attacker True if this unit is on the offensive (to resolve [resistance] abilities)
951  * @param loc The unit's location (to resolve [resistance] abilities)
952  */
953  int resistance_against(const std::string& damage_name, bool attacker, const map_location& loc) const;
954 
955  /** Gets resistances without any abilities applied. */
957  {
958  return movement_type_.damage_table();
959  }
960 
961 private:
962  bool resistance_filter_matches(const config& cfg, const std::string& damage_name, int res) const;
963 
964  /**
965  * @}
966  * @defgroup unit_trait Trait and upkeep functions
967  * @{
968  */
969 public:
970  /**
971  * Applies mandatory traits (e.g. undead, mechanical) to a unit and then fills in the remaining traits
972  * traits until no more are available (leaders have a restricted set of available traits) or the unit has
973  * its maximum number of traits.
974  *
975  * This routine does not apply the effects of added traits to a unit; that must be done by the caller.
976  *
977  * Note that random numbers used in config files don't work in multiplayer, so leaders should be barred
978  * from all random traits until that is fixed. Later the restrictions will be based on play balance.
979  *
980  * @param must_have_only Whether random or optional traits should be included or not. If false only
981  * mandatory traits will be used.
982  */
983  void generate_traits(bool must_have_only = false);
984 
985  /**
986  * Gets the names of the currently registered traits.
987  *
988  * @returns A list of translatable trait names.
989  */
990  const std::vector<t_string>& trait_names() const
991  {
992  return trait_names_;
993  }
994 
995  /**
996  * Gets the descriptions of the currently registered traits.
997  *
998  * @returns A list of translatable trait descriptions.
999  */
1000  const std::vector<t_string>& trait_descriptions() const
1001  {
1002  return trait_descriptions_;
1003  }
1004 
1005  /**
1006  * Gets the ids of the traits corresponding to those returned by trait_names() and
1007  * trait_descriptions(). Omits hidden traits, which are those with an empty name.
1008  *
1009  * @returns A list of trait IDs.
1010  */
1011  std::vector<std::string> trait_nonhidden_ids() const
1012  {
1013  return trait_nonhidden_ids_;
1014  }
1015 
1016  /** Gets a list of the modification this unit currently has.
1017  * @param mod_type type of modification.
1018  * @returns A list of modification IDs.
1019  */
1020  std::vector<std::string> get_modifications_list(const std::string& mod_type) const;
1021 
1022  /**
1023  * Gets a list of the traits this unit currently has, including hidden traits.
1024  *
1025  * @returns A list of trait IDs.
1026  */
1027  std::vector<std::string> get_traits_list() const
1028  {
1029  return get_modifications_list("trait");
1030  }
1031 
1032  std::vector<std::string> get_objects_list() const
1033  {
1034  return get_modifications_list("object");
1035  }
1036 
1037  std::vector<std::string> get_advancements_list() const
1038  {
1039  return get_modifications_list("advancement");
1040  }
1041 
1042  /**
1043  * Register a trait's name and its description for the UI's use.
1044  *
1045  * The resulting data can be fetched with @ref trait_names and @ref trait_descriptions.
1046  *
1047  * @param trait A config containing the trait's attributes.
1048  * @param description The translatable description of the trait.
1049  */
1050  void add_trait_description(const config& trait, const t_string& description);
1051 
1052  /**
1053  * Gets the amount of gold this unit costs a side per turn.
1054  *
1055  * This fetches an actual numeric gold value:
1056  * - If can_recruit is true, no upkeep is paid (0 is returned).
1057  * - If a special upkeep flag is set, the associated gold amount is returned (see @ref upkeep_value_visitor).
1058  * - If a numeric value is already set, it is returned directly.
1059  *
1060  * @returns A gold value, evaluated based on the state of @ref upkeep_raw.
1061  */
1062  int upkeep() const;
1063 
1065  {
1066  static std::string type() { static std::string v = "full"; return v; }
1067  };
1068 
1070  {
1071  static std::string type() { static std::string v = "loyal"; return v; }
1072  };
1073 
1074  using upkeep_t = utils::variant<upkeep_full, upkeep_loyal, int>;
1075 
1076  /** Visitor helper class to fetch the appropriate upkeep value. */
1078 #ifdef USING_BOOST_VARIANT
1079  : public boost::static_visitor<int>
1080 #endif
1081  {
1082  public:
1083  explicit upkeep_value_visitor(const unit& unit) : u_(unit) {}
1084 
1085  /** Full upkeep equals the unit's level. */
1086  int operator()(const upkeep_full&) const
1087  {
1088  return u_.level();
1089  }
1090 
1091  /** Loyal units cost no upkeep. */
1092  int operator()(const upkeep_loyal&) const
1093  {
1094  return 0;
1095  }
1096 
1097  int operator()(int v) const
1098  {
1099  return v;
1100  }
1101 
1102  private:
1103  const unit& u_;
1104  };
1105 
1106  /** Visitor helper struct to fetch the upkeep type flag if applicable, or the the value otherwise. */
1108 #ifdef USING_BOOST_VARIANT
1109  : public boost::static_visitor<std::string>
1110 #endif
1111  {
1112  template<typename T>
1113  std::enable_if_t<!std::is_same_v<int, T>, std::string>
1114  operator()(T&) const
1115  {
1116  // Any special upkeep type should have an associated @ref type getter in its helper struct.
1117  return T::type();
1118  }
1119 
1120  std::string operator()(int v) const
1121  {
1122  return std::to_string(v);
1123  }
1124  };
1125 
1126  /** Visitor helper class to parse the upkeep value from a config. */
1128 #ifdef USING_BOOST_VARIANT
1129  : public boost::static_visitor<upkeep_t>
1130 #endif
1131  {
1132  public:
1133  template<typename N>
1134  std::enable_if_t<std::is_arithmetic_v<N>, upkeep_t>
1135  operator()(N n) const
1136  {
1137  if(n == 0) return upkeep_loyal();
1138  if(n < 0) throw std::invalid_argument(std::to_string(n));
1139  return static_cast<int>(n);
1140  }
1141 
1142  template<typename B>
1143  std::enable_if_t<std::is_convertible_v<B, bool> && !std::is_arithmetic_v<B>, upkeep_t>
1144  operator()(B b) const
1145  {
1146  throw std::invalid_argument(b.str());
1147  }
1148 
1149  upkeep_t operator()(utils::monostate) const
1150  {
1151  return upkeep_full();
1152  }
1153 
1154  upkeep_t operator()(const std::string& s) const
1155  {
1156  if(s == "loyal" || s == "free")
1157  return upkeep_loyal();
1158  if(s == "full")
1159  return upkeep_full();
1160  throw std::invalid_argument(s);
1161  }
1162  };
1163 
1164  /**
1165  * Gets the raw variant controlling the upkeep value.
1166  *
1167  * This should not usually be called directly. To get an actual numeric value of upkeep use @ref upkeep.
1168  */
1170  {
1171  return upkeep_;
1172  }
1173 
1174  /** Sets the upkeep value to a specific value value. Does not necessarily need to be numeric */
1176  {
1177  upkeep_ = v;
1178  }
1179 
1180  /** Gets whether this unit is loyal - ie, it costs no upkeep. */
1181  bool loyal() const;
1182 
1183  void set_loyal(bool loyal);
1184 
1185  /** Gets whether this unit is fearless - ie, unaffected by time of day. */
1186  bool is_fearless() const
1187  {
1188  return is_fearless_;
1189  }
1190 
1191  /** Gets whether this unit is healthy - ie, always rest heals. */
1192  bool is_healthy() const
1193  {
1194  return is_healthy_;
1195  }
1196 
1197  /**
1198  * If this unit has abilities of @a tag_name type with [affect_adjacent] subtags, returns the radius of the one with the furthest reach.
1199  *
1200  * If the unit has no such abilities, returns zero.
1201  */
1202  std::size_t max_ability_radius_type(const std::string& tag_name) const
1203  {
1204  auto iter = max_ability_radius_type_.find(tag_name);
1205  return iter != max_ability_radius_type_.end() ? iter->second : 0;
1206  }
1207 
1208  /**
1209  * If this unit has abilities with [affect_adjacent] subtags, returns the radius of the one with the furthest reach.
1210  *
1211  * If the unit has no such abilities, returns zero.
1212  */
1213  std::size_t max_ability_radius() const
1214  {
1215  return max_ability_radius_;
1216  }
1217 
1218  /**
1219  * If this unit has abilities with [affect_adjacent] subtags and halo_image or overlay_image attributes, returns the radius of the one with the furthest reach.
1220  *
1221  * If the unit has no such abilities, returns zero.
1222  */
1223  std::size_t max_ability_radius_image() const
1224  {
1226  }
1227 
1228  /**
1229  * @}
1230  * @defgroup unit_mvmt Movement and location functions
1231  * @{
1232  */
1233 
1234 public:
1235  /** The maximum moves this unit has. */
1236  int total_movement() const
1237  {
1238  return max_movement_;
1239  }
1240 
1241  void set_total_movement(int value)
1242  {
1244  max_movement_ = value;
1245  }
1246 
1247  /**
1248  * Gets how far a unit can move, considering the `incapacitated` flag.
1249  *
1250  * @returns The remaining movement, or zero if incapacitated.
1251  */
1252  int movement_left() const
1253  {
1254  return (movement_ == 0 || incapacitated()) ? 0 : movement_;
1255  }
1256 
1257  /**
1258  * Gets how far a unit can move.
1259  *
1260  * @param base_value If false, consider the `incapacitated` flag.
1261  *
1262  * @returns If @a base_value is true, the raw value is returned.
1263  */
1264  int movement_left(bool base_value) const
1265  {
1266  return base_value ? movement_ : movement_left();
1267  }
1268 
1269  /**
1270  * Set this unit's remaining movement to @a moves.
1271  *
1272  * This does not affect maximum movement.
1273  *
1274  * @param moves The new number of moves
1275  * @param unit_action If to true, the "end turn" and "hold position" flags will be cleared
1276  * (as they should be if a unit acts, as opposed to the movement being set
1277  * by the engine for other reasons).
1278  */
1279  void set_movement(int moves, bool unit_action = false);
1280 
1281  /** Checks if this unit has moved. */
1282  bool has_moved() const
1283  {
1284  return movement_left() != total_movement();
1285  }
1286 
1287  /** Sets the unit to have no moves left for this turn. */
1288  void remove_movement_ai();
1289 
1290  /**
1291  * Checks whether this unit is 'resting'.
1292  *
1293  * Resting refers to whether this unit has not moved yet this turn. Note that this can be true even
1294  * if @ref movement_left is not equal to @ref total_movement.
1295  */
1296  bool resting() const
1297  {
1298  return resting_;
1299  }
1300 
1301  /** Sets this unit's resting status. */
1302  void set_resting(bool rest)
1303  {
1304  resting_ = rest;
1305  }
1306 
1307  /** Tests whether the unit has a zone-of-control, considering @ref incapacitated. */
1308  bool emits_zoc() const
1309  {
1310  return emit_zoc_ && !incapacitated();
1311  }
1312 
1313  /** Gets the raw zone-of-control flag, disregarding @ref incapacitated. */
1314  bool get_emit_zoc() const
1315  {
1316  return emit_zoc_;
1317  }
1318 
1319  /** Sets the raw zone-of-control flag. */
1320  void set_emit_zoc(bool val)
1321  {
1323  emit_zoc_ = val;
1324  }
1325 
1326  /** The current map location this unit is at. */
1328  {
1329  return loc_;
1330  }
1331 
1332  /**
1333  * Sets this unit's map location.
1334  *
1335  * Note this should only be called by unit_map or for temporary units.
1336  */
1338  {
1339  loc_ = loc;
1340  }
1341 
1342  /** The current direction this unit is facing within its hex. */
1344  {
1345  return facing_;
1346  }
1347 
1348  /** The this unit's facing. */
1349  void set_facing(map_location::direction dir) const;
1350 
1351  /** Gets whether this unit has a multi-turn destination set. */
1352  bool has_goto() const
1353  {
1354  return get_goto().valid();
1355  }
1356 
1357  /** The map location to which this unit is moving over multiple turns, if any. */
1358  const map_location& get_goto() const
1359  {
1360  return goto_;
1361  }
1362 
1363  /** Sets this unit's long term destination. */
1364  void set_goto(const map_location& new_goto)
1365  {
1366  goto_ = new_goto;
1367  }
1368 
1369  /** Gets the unit's vision points. */
1370  int vision() const
1371  {
1372  return vision_ < 0 ? max_movement_ : vision_;
1373  }
1374 
1375  /** Gets the unit's jamming points. */
1376  int jamming() const
1377  {
1378  return jamming_;
1379  }
1380 
1381  /** Check whether the unit's move has been interrupted. */
1382  bool move_interrupted() const
1383  {
1384  return movement_left() > 0 && interrupted_move_.x >= 0 && interrupted_move_.y >= 0;
1385  }
1386 
1387  /** Get the target location of the unit's interrupted move. */
1389  {
1390  return interrupted_move_;
1391  }
1392 
1393  /** Set the target location of the unit's interrupted move. */
1394  void set_interrupted_move(const map_location& interrupted_move)
1395  {
1396  interrupted_move_ = interrupted_move;
1397  }
1398 
1399  /** Get the unit's movement type. */
1400  const movetype& movement_type() const
1401  {
1402  return movement_type_;
1403  }
1404 
1405  /**
1406  * Get the unit's movement cost on a particular terrain
1407  * @param terrain The terrain to check
1408  * @returns the number of movement points to enter that terrain
1409  */
1410  int movement_cost(const t_translation::terrain_code& terrain) const
1411  {
1413  }
1414 
1415  /**
1416  * Get the unit's vision cost on a particular terrain
1417  * @param terrain The terrain to check
1418  * @returns the number of vision points to see into that terrain
1419  */
1420  int vision_cost(const t_translation::terrain_code& terrain) const
1421  {
1423  }
1424 
1425  /**
1426  * Get the unit's jamming cost on a particular terrain
1427  * @param terrain The terrain to check
1428  * @returns the number of jamming points to jam that terrain
1429  */
1430  int jamming_cost(const t_translation::terrain_code& terrain) const
1431  {
1433  }
1434 
1435  /** Check if the unit is a flying unit. */
1436  bool is_flying() const
1437  {
1438  return movement_type_.is_flying();
1439  }
1440 
1441  /**
1442  * @}
1443  * @defgroup unit_mod Modification functions
1444  * @{
1445  */
1446 
1447 public:
1448  /** Get the raw modifications. */
1450  {
1451  return modifications_;
1452  }
1453 
1454  /** Set the raw modifications. */
1455  const config& get_modifications() const
1456  {
1457  return modifications_;
1458  }
1459 
1460  /**
1461  * Count modifications of a particular type.
1462  * @param type The type of modification to count.
1463  * Valid values are "advancement", "trait", "object"
1464  * @param id The ID of the modification to count
1465  * @return The total number of modifications of that type and ID.
1466  */
1467  std::size_t modification_count(const std::string& type, const std::string& id) const;
1468 
1469  /**
1470  * Count modifications of a particular type.
1471  * @param type The type of modification to count.
1472  * Valid values are "advancement", "trait", "object"
1473  * @return The total number of modifications of that type.
1474  */
1475  std::size_t modification_count(const std::string& type) const;
1476 
1477  std::size_t traits_count() const
1478  {
1479  return modification_count("trait");
1480  }
1481 
1482  std::size_t objects_count() const
1483  {
1484  return modification_count("object");
1485  }
1486 
1487  std::size_t advancements_count() const
1488  {
1489  return modification_count("advancement");
1490  }
1491 
1492  /**
1493  * Add a new modification to the unit.
1494  * @param type The type of modification to add.
1495  * Valid values are "advancement", "trait", "object"
1496  * @param modification The details of the modification
1497  * @param no_add If true, apply the modification but don't save it for unit rebuild time.
1498  * Defaults to false.
1499  */
1500  void add_modification(const std::string& type, const config& modification, bool no_add = false);
1501 
1502  /**
1503  * Clears those modifications whose duration has expired.
1504  *
1505  * @param duration If empty, all temporary modifications (those not lasting forever) expire.
1506  * Otherwise, modifications whose duration equals @a duration expire.
1507  */
1508  void expire_modifications(const std::string& duration);
1509 
1510  static const std::set<std::string> builtin_effects;
1511 
1512  /**
1513  * Apply a builtin effect to the unit.
1514  * @param type The effect to apply. Must be one of the effects in @ref builtin_effects.
1515  * @param effect The details of the effect
1516  */
1517  void apply_builtin_effect(const std::string& type, const config& effect);
1518 
1519  /**
1520  * Construct a string describing a built-in effect.
1521  * @param type The effect to describe. Must be one of the effects in @ref builtin_effects.
1522  * @param effect The details of the effect
1523  */
1524  std::string describe_builtin_effect(const std::string& type, const config& effect);
1525 
1526  /** Re-apply all saved modifications. */
1527  void apply_modifications();
1528 
1529  /**
1530  * @}
1531  * @defgroup unit_img Image and animations functions
1532  * @{
1533  */
1534 
1535 public:
1536  /** @todo Document this */
1538  {
1539  return *anim_comp_;
1540  }
1541 
1542  /** The name of the file to game_display (used in menus). */
1543  std::string absolute_image() const;
1544 
1545  /** The default image to use for animation frames with no defined image. */
1546  std::string default_anim_image() const;
1547 
1548  /** Get the unit's halo image. */
1549  std::string image_halo() const
1550  {
1551  return halo_.value_or("");
1552  }
1553 
1554  std::vector<std::string> halo_or_icon_abilities(const std::string& image_type) const;
1555 
1556  /** Get the [halo] abilities halo image(s). */
1557  std::vector<std::string> halo_abilities() const
1558  {
1559  return halo_or_icon_abilities("halo");
1560  }
1561 
1562  /** Set the unit's halo image. */
1563  void set_image_halo(const std::string& halo);
1564 
1565  /** Get the unit's ellipse image. */
1566  std::string image_ellipse() const
1567  {
1568  return ellipse_.value_or("");
1569  }
1570 
1571  /** Set the unit's ellipse image. */
1572  void set_image_ellipse(const std::string& ellipse)
1573  {
1574  appearance_changed_ = true;
1575  ellipse_ = ellipse;
1576  }
1577 
1578  /**
1579  * Get the source color palette to use when recoloring the unit's image.
1580  */
1581  const std::string& flag_rgb() const;
1582 
1583  /** Constructs a recolor (RC) IPF string for this unit's team color. */
1584  std::string TC_image_mods() const;
1585 
1586  /** Gets any IPF image mods applied by effects. */
1587  const std::string& effect_image_mods() const
1588  {
1589  return image_mods_;
1590  }
1591 
1592  /**
1593  * Gets an IPF string containing all IPF image mods.
1594  *
1595  * @returns An amalgamation of @ref effect_image_mods followed by @ref TC_image_mods.
1596  */
1597  std::string image_mods() const;
1598 
1599  /** Get the unit's overlay images. */
1600  const std::vector<std::string>& overlays() const
1601  {
1602  return overlays_;
1603  }
1604 
1605  /** Get the [overlay] ability overlay images. */
1606  std::vector<std::string> overlays_abilities() const
1607  {
1608  return halo_or_icon_abilities("overlay");
1609  }
1610 
1611  /**
1612  * Color for this unit's *current* hitpoints.
1613  *
1614  * @returns A color between green and red representing how wounded this unit is.
1615  * The maximum_hitpoints are considered as base.
1616  */
1617  color_t hp_color() const;
1618  static color_t hp_color_max();
1619 
1620  /**
1621  * Color for this unit's hitpoints.
1622  *
1623  * @param hitpoints The number of hitpoints the color represents.
1624  * @returns The color considering the current hitpoints as base.
1625  */
1626  color_t hp_color(int hitpoints) const;
1627 
1628  /**
1629  * Color for this unit's XP. See also @ref hp_color
1630  */
1631  color_t xp_color() const;
1632  static color_t xp_color(int xp_to_advance, bool can_advance, bool has_amla);
1633 
1634  /**
1635  * @}
1636  * @defgroup unit_abil Ability functions
1637  * @{
1638  */
1639 
1640 public:
1641  /**
1642  * Checks whether this unit currently possesses or is affected by a given ability.
1643  *
1644  * This means that the ability could be owned by this unit itself or by an adjacent unit, should
1645  * the ability affect an AoE in which this unit happens to be.
1646  *
1647  * @param tag_name The name of the ability to check for.
1648  * @param loc The location around which to check for affected units. This may or
1649  * may not be the location of this unit.
1650  */
1651  bool get_ability_bool(const std::string& tag_name, const map_location& loc) const;
1652 
1653  /**
1654  * Checks whether this unit currently possesses or is affected by a given ability.
1655  *
1656  * This means that the ability could be owned by this unit itself or by an adjacent unit, should
1657  * the ability affect an AoE in which this unit happens to be.
1658  *
1659  * This overload uses the location of this unit for calculations.
1660  *
1661  * @param tag_name The name of the ability to check for.
1662  */
1663  bool get_ability_bool(const std::string& tag_name) const
1664  {
1665  return get_ability_bool(tag_name, loc_);
1666  }
1667 
1668  /** Checks whether this unit currently possesses a given ability, and that that ability is active.
1669  * @return True if the ability @a tag_name is active.
1670  * @param ab the ability checked
1671  * @param loc location of the unit checked.
1672  */
1673  bool get_self_ability_bool(const unit_ability_t& ab, const map_location& loc) const;
1674  /** Checks whether this unit is affected by a given ability, and that that ability is active.
1675  * @return True if the ability @a tag_name is active.
1676  * @param ab the ability checked
1677  * @param loc location of the unit checked.
1678  * @param from unit distant to @a this is checked in case of [affect_adjacent] abilities.
1679  * @param from_loc the 'other unit' location.
1680  * @param dist distance between unit distant and @a this.
1681  * @param dir direction to research a unit distant to @a this.
1682  */
1683  bool get_adj_ability_bool(const unit_ability_t& ab, std::size_t dist, int dir, const map_location& loc, const unit& from, const map_location& from_loc) const;
1684 
1685  /**
1686  * Gets the unit's active abilities of a particular type if it were on a specified location.
1687  * @param tag_name The type of ability to check for
1688  * @param loc The location to use for resolving abilities
1689  * @return A list of active abilities, paired with the location they are active on
1690  */
1691  active_ability_list get_abilities(const std::string& tag_name, const map_location& loc) const;
1692 
1693  /**
1694  * Gets the unit's active abilities of a particular type.
1695  * @param tag_name The type of ability to check for
1696  * @return A list of active abilities, paired with the location they are active on
1697  */
1698  active_ability_list get_abilities(const std::string& tag_name) const
1699  {
1700  return get_abilities(tag_name, loc_);
1701  }
1702 
1704 
1706  }
1707 
1708  const ability_vector& abilities() const {
1709  return abilities_;
1710  }
1711 
1712  ability_vector abilities(const std::string& tag) const {
1714  }
1715 
1716  /**
1717  * Gets the names and descriptions of this unit's abilities. Location-independent variant
1718  * with all abilities shown as active.
1719  *
1720  * @returns A list of quadruples consisting of (in order) id, base name,
1721  * male or female name as appropriate for the unit, and description.
1722  */
1723  std::vector<unit_ability_t::tooltip_info> ability_tooltips() const;
1724 
1725  /**
1726  * Gets the names and descriptions of this unit's abilities.
1727  *
1728  * @param active_list This vector will be the same length as the returned one and will
1729  * indicate whether or not the corresponding ability is active.
1730  *
1731  * @param loc The location on which to resolve the ability.
1732  *
1733  * @returns A list of quadruples consisting of (in order) id, base name,
1734  * male or female name as appropriate for the unit, and description.
1735  */
1736  std::vector<unit_ability_t::tooltip_info>
1737  ability_tooltips(boost::dynamic_bitset<>& active_list, const map_location& loc) const;
1738 
1739  /** Get a list of all abilities by ID. */
1740  std::vector<std::string> get_ability_id_list() const;
1741 
1742  /**
1743  * Check if the unit has an ability of a specific type.
1744  * @param ability The type of ability (tag name) to check for.
1745  * @returns true if the ability is present
1746  */
1747  bool has_ability_type(const std::string& ability) const;
1748 
1749  /**
1750  * Check if the unit has an ability of a specific ID.
1751  * @param ability The ID of ability to check for.
1752  * @returns true if the ability is present
1753  */
1754  bool has_ability_by_id(const std::string& ability) const;
1755 
1756  /**
1757  * Removes a unit's abilities with a specific ID.
1758  * @param ability The type of ability (tag name) to remove.
1759  */
1760  void remove_ability_by_id(const std::string& ability);
1761 
1762  /**
1763  * Removes a unit's abilities with a specific ID or other attribute.
1764  * @param filter the config of ability to remove.
1765  */
1767 
1768 private:
1769 
1770  /**
1771  * Check if an ability is active. Includes checks to prevent excessive recursion.
1772  * @param ab the ability checked
1773  * @param loc The location on which to resolve the ability
1774  * @returns true if it is active
1775  */
1776  bool ability_active(const unit_ability_t& ab, const map_location& loc) const;
1777  /**
1778  * Check if an ability is active. The caller is responsible for preventing excessive recursion, so must hold a recursion_guard.
1779  * @param ab the ability checked
1780  * @param loc The location on which to resolve the ability
1781  * @returns true if it is active
1782  */
1783  bool ability_active_impl(const unit_ability_t& ab, const map_location& loc) const;
1784 
1785  /**
1786  * Check if an ability affects distant units.
1787  * @param ab the ability checked
1788  * @param loc The location on which to resolve the ability
1789  * @param from The "other unit" for filter matching
1790  * @param dist distance between unit distant and @a this.
1791  * @param dir direction to research a unit distant to @a this.
1792  */
1793  bool ability_affects_adjacent(const unit_ability_t& ab, std::size_t dist, int dir, const map_location& loc, const unit& from) const;
1794  /**
1795  * Check if an ability affects the owning unit.
1796  * @param ab the ability checked
1797  * @param loc The location on which to resolve the ability
1798  */
1799  bool ability_affects_self(const unit_ability_t& ab, const map_location& loc) const;
1800 
1801  /**
1802  * filters the weapons that condition the use of abilities for combat ([resistance],[leadership] or abilities used like specials
1803  * (deprecated in two last cases)
1804  */
1805  bool ability_affects_weapon(const unit_ability_t& ab, const const_attack_ptr& weapon, bool is_opp) const;
1806 
1807 public:
1808  /** Generates a random race-appropriate name if one has not already been provided. */
1809  void generate_name();
1810 
1811  // Only see_all = true use caching
1812  bool invisible(const map_location& loc, bool see_all = true) const;
1813 
1814  bool is_visible_to_team(const team& team, bool const see_all = true) const;
1815  /** Return true if the unit would be visible to team if its location were loc. */
1816  bool is_visible_to_team(const map_location& loc, const team& team, bool const see_all = true) const;
1817 
1818  /**
1819  * Serializes the current unit metadata values.
1820  *
1821  * @param cfg The config to write to.
1822  * @param write_all set this to false to not write unchanged attributes.
1823  */
1824  void write(config& cfg, bool write_all = true) const;
1825 
1826  /**
1827  * Mark this unit as clone so it can be inserted to unit_map.
1828  *
1829  * @returns self (for convenience)
1830  */
1831  unit& mark_clone(bool is_temporary);
1832 
1833 
1834  void set_appearance_changed(bool value) { appearance_changed_ = value; }
1835  bool appearance_changed() const { return appearance_changed_; }
1836 
1837 protected:
1838 
1839 private:
1841 
1842  std::vector<std::string> advances_to_;
1843 
1844  /** Never nullptr. Adjusted for gender and variation. */
1846 
1847  /** The displayed name of this unit type. */
1849 
1850  /** Never nullptr, but may point to the null race. */
1852 
1853  std::string id_;
1856 
1857  std::string undead_variation_;
1858  std::string variation_;
1859 
1864 
1865  int level_;
1866 
1869  std::set<std::string> recruit_list_;
1871 
1872  std::string flag_rgb_;
1873  std::string image_mods_;
1874 
1878 
1879  int side_;
1880 
1882 
1885  int vision_;
1887 
1889 
1892  bool resting_;
1893 
1896 
1897  std::set<std::string> states_;
1898 
1899  static const std::size_t num_bool_states = state_t::NUMBER_OF_STATES;
1900 
1901  std::bitset<num_bool_states> known_boolean_states_;
1902  static std::map<std::string, state_t> known_boolean_state_names_;
1903 
1907 
1909 
1910  std::vector<std::string> overlays_;
1911 
1912  std::string role_;
1914 
1915 protected:
1916  // TODO: I think we actually consider this to be part of the gamestate, so it might be better if it's not mutable,
1917  // but it's not easy to separate this guy from the animation code right now.
1919 
1920 private:
1921  std::vector<t_string> trait_names_;
1922  std::vector<t_string> trait_descriptions_;
1923  std::vector<std::string> trait_nonhidden_ids_;
1924 
1927 
1929 
1930  // Unit list/recall list favorite unit marking
1932 
1933 public:
1934  bool favorite() const { return is_favorite_; }
1935 
1937 
1938 private:
1939 
1941 
1942  // Animations:
1944 
1945  std::unique_ptr<unit_animation_component> anim_comp_;
1946 
1947  mutable bool hidden_;
1948 
1951 
1952  std::vector<config> advancements_;
1953 
1955  std::vector<t_string> special_notes_;
1956 
1957  utils::optional<std::string> usage_;
1958  utils::optional<std::string> halo_;
1959  utils::optional<std::string> ellipse_;
1960 
1963 
1965 
1966  std::string profile_;
1967  std::string small_profile_;
1968 
1969  //Used to check whether the moving units during a move needs to be updated
1970  mutable bool appearance_changed_ = true;
1971  std::bitset<UA_COUNT> changed_attributes_;
1972 
1975 
1976  /**
1977  * Hold the visibility status cache for a unit, when not uncovered.
1978  * This is mutable since it is a cache.
1979  */
1980  mutable std::map<map_location, bool> invisibility_cache_;
1981 
1982  /**
1983  * Clears the cache.
1984  *
1985  * Since we don't change the state of the object we're marked const (also
1986  * required since the objects in the cache need to be marked const).
1987  */
1989  {
1990  invisibility_cache_.clear();
1991  }
1992 
1993  /**
1994  * Used for easing checking if unit own a ability of specified type with [affect_adjacent] sub tag.
1995  *
1996  */
1997  std::map<std::string, std::size_t> max_ability_radius_type_;
1998  /**
1999  * Used for easing checking if unit own a ability with [affect_adjacent] sub tag.
2000  *
2001  */
2002  std::size_t max_ability_radius_;
2003  /**
2004  * used if ability own halo_image or overlay_image attributes in same time what [affect_adjacent].
2005  */
2007  void set_has_ability_distant();
2008 };
2009 
2010 /**
2011  * Object which temporarily resets a unit's movement.
2012  *
2013  * @warning A unit whose movement is reset may not be deleted while held in a
2014  * @ref unit_movement_resetter object, so it's best to use thus only in a small scope.
2015  */
2017 {
2020 
2021  unit_movement_resetter(const unit& u, bool operate = true);
2023 
2024 private:
2026  int moves_;
2027 };
2028 
2030 {
2031 /**
2032  * Optional parameter for get_checksum to use the algorithm of an older version of Wesnoth,
2033  * thus preventing spurious OOS warnings while watching old replays.
2034  */
2036  current,
2037  version_1_16_or_older /**< Included some of the flavortext from weapon specials. */
2038 };
2039 
2040 } // namespace backwards_compatibility
2041 
2042 /**
2043  * Gets a checksum for a unit.
2044  *
2045  * In MP games the descriptions are locally generated and might differ, so it
2046  * should be possible to discard them. Not sure whether replays suffer the
2047  * same problem.
2048  *
2049  * @param u this unit
2050  * @param version allows the checksum expected in older replays to be used
2051  *
2052  * @returns the checksum for a unit
2053  */
2054 std::string get_checksum(const unit& u,
std::vector< ability_ptr > ability_vector
Definition: abilities.hpp:33
map_location loc
Definition: move.cpp:172
double t
Definition: astarsearch.cpp:63
boost::iterator_range< boost::indirect_iterator< attack_list::iterator > > attack_itors
std::vector< attack_ptr > attack_list
boost::iterator_range< boost::indirect_iterator< attack_list::const_iterator > > const_attack_itors
attack_itors make_attack_itors(attack_list &atks)
Variant for storing WML attributes.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:157
The basic "size" of the unit - flying, small land, large land, etc.
Definition: movetype.hpp:44
int jamming_cost(const t_translation::terrain_code &terrain, bool slowed=false) const
Returns the cost to "jam" through the indicated terrain.
Definition: movetype.hpp:284
int vision_cost(const t_translation::terrain_code &terrain, bool slowed=false) const
Returns the cost to see through the indicated terrain.
Definition: movetype.hpp:281
int movement_cost(const t_translation::terrain_code &terrain, bool slowed=false) const
Returns the cost to move through the indicated terrain.
Definition: movetype.hpp:278
utils::string_map_res damage_table() const
Returns a map from damage types to resistances.
Definition: movetype.hpp:295
bool is_flying() const
Returns whether or not *this is flagged as a flying movement type.
Definition: movetype.hpp:273
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:74
Visitor helper class to parse the upkeep value from a config.
Definition: unit.hpp:1131
Visitor helper class to fetch the appropriate upkeep value.
Definition: unit.hpp:1081
static config vector_to_cfg(const ability_vector &abilities)
Definition: abilities.cpp:286
static ability_vector filter_tag(const ability_vector &vec, const std::string &tag)
Definition: abilities.cpp:266
@ NUM_GENDERS
Definition: race.hpp:28
A single unit type that the player may recruit.
Definition: types.hpp:43
This class represents a single unit of a specific type.
Definition: unit.hpp:39
unit_ptr clone() const
Definition: unit.hpp:127
unit & operator=(const unit &)=delete
UNIT_ATTRIBUTE
Definition: unit.hpp:67
static void clear_status_caches()
Clear this unit status cache for all units.
Definition: unit.cpp:780
void set_attr_changed(UNIT_ATTRIBUTE attr)
Definition: unit.hpp:91
virtual ~unit()
Definition: unit.cpp:814
bool get_attr_changed(UNIT_ATTRIBUTE attr) const
Definition: unit.hpp:98
void clear_changed_attributes()
Definition: unit.cpp:2864
void init(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Definition: unit.cpp:442
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Definition: unit.hpp:107
static const std::string & leader_crown()
The path to the leader crown overlay.
Definition: unit.cpp:1178
bool get_attacks_changed() const
Definition: unit.cpp:1544
unit()=delete
static unit_ptr create(const unit_type &t, int side, bool real_unit, unit_race::GENDER gender=unit_race::NUM_GENDERS, const std::string &variation="")
Initializes a unit from a unit type.
Definition: unit.hpp:119
A variable-expanding proxy for the config class.
Definition: variable.hpp:45
const config * cfg
int hit_points_
Definition: unit.hpp:1860
const ability_vector & abilities() const
Definition: unit.hpp:1708
int movement_
Definition: unit.hpp:1883
void generate_name()
Generates a random race-appropriate name if one has not already been provided.
Definition: unit.cpp:832
std::vector< t_string > trait_names_
Definition: unit.hpp:1921
int unit_value_
Definition: unit.hpp:1925
int attacks_left_
Definition: unit.hpp:1894
bool generate_name_
Definition: unit.hpp:1962
void clear_visibility_cache() const
Clears the cache.
Definition: unit.hpp:1988
bool ability_active_impl(const unit_ability_t &ab, const map_location &loc) const
Check if an ability is active.
Definition: abilities.cpp:759
bool ability_affects_self(const unit_ability_t &ab, const map_location &loc) const
Check if an ability affects the owning unit.
Definition: abilities.cpp:807
bool ability_active(const unit_ability_t &ab, const map_location &loc) const
Check if an ability is active.
Definition: abilities.cpp:750
ability_vector abilities(const std::string &tag) const
Definition: unit.hpp:1712
movetype movement_type_
Definition: unit.hpp:1888
config variables_
Definition: unit.hpp:1904
bool unrenamable_
Definition: unit.hpp:1875
active_ability_list get_abilities(const std::string &tag_name, const map_location &loc) const
Gets the unit's active abilities of a particular type if it were on a specified location.
Definition: abilities.cpp:669
int experience_
Definition: unit.hpp:1862
int vision_
Definition: unit.hpp:1885
void remove_ability_by_attribute(const config &filter)
Removes a unit's abilities with a specific ID or other attribute.
Definition: unit.cpp:1531
std::string undead_variation_
Definition: unit.hpp:1857
t_string type_name_
The displayed name of this unit type.
Definition: unit.hpp:1848
map_location interrupted_move_
Definition: unit.hpp:1926
ability_vector abilities_
Definition: unit.hpp:1950
unit_movement_resetter(const unit_movement_resetter &)=delete
bool random_traits_
Definition: unit.hpp:1961
void write(config &cfg, bool write_all=true) const
Serializes the current unit metadata values.
Definition: unit.cpp:1555
std::bitset< UA_COUNT > changed_attributes_
Definition: unit.hpp:1971
std::string small_profile_
Definition: unit.hpp:1967
void write_upkeep(config::attribute_value &upkeep) const
Definition: unit.cpp:2859
bool get_ability_bool(const std::string &tag_name, const map_location &loc) const
Checks whether this unit currently possesses or is affected by a given ability.
Definition: abilities.cpp:658
bool ability_affects_adjacent(const unit_ability_t &ab, std::size_t dist, int dir, const map_location &loc, const unit &from) const
Check if an ability affects distant units.
Definition: abilities.cpp:772
void set_favorite(bool favorite)
Definition: unit.hpp:1936
std::string id_
Definition: unit.hpp:1853
std::vector< t_string > special_notes_
Definition: unit.hpp:1955
void set_has_ability_distant()
Definition: unit.cpp:418
bool canrecruit_
Definition: unit.hpp:1868
std::string image_mods_
Definition: unit.hpp:1873
std::map< std::string, std::size_t > max_ability_radius_type_
Used for easing checking if unit own a ability of specified type with [affect_adjacent] sub tag.
Definition: unit.hpp:1997
std::string flag_rgb_
Definition: unit.hpp:1872
static std::map< std::string, state_t > known_boolean_state_names_
Definition: unit.hpp:1902
@ UA_IS_HEALTHY
Definition: unit.hpp:72
@ UA_SMALL_PROFILE
Definition: unit.hpp:85
@ UA_MAX_MP
Definition: unit.hpp:69
@ UA_ATTACKS
Definition: unit.hpp:82
@ UA_ZOC
Definition: unit.hpp:76
@ UA_MOVEMENT_TYPE
Definition: unit.hpp:75
@ UA_PROFILE
Definition: unit.hpp:84
@ UA_LEVEL
Definition: unit.hpp:74
@ UA_MAX_XP
Definition: unit.hpp:71
@ UA_IS_FEARLESS
Definition: unit.hpp:73
@ UA_ADVANCE_TO
Definition: unit.hpp:77
@ UA_MAX_AP
Definition: unit.hpp:70
@ UA_COUNT
Definition: unit.hpp:88
@ UA_ADVANCEMENTS
Definition: unit.hpp:78
@ UA_MAX_HP
Definition: unit.hpp:68
@ UA_ABILITIES
Definition: unit.hpp:86
@ UA_UNDEAD_VARIATION
Definition: unit.hpp:80
@ UA_UPKEEP
Definition: unit.hpp:87
@ UA_NOTES
Definition: unit.hpp:83
@ UA_ALIGNMENT
Definition: unit.hpp:79
void set_appearance_changed(bool value)
Definition: unit.hpp:1834
config events_
Definition: unit.hpp:1905
bool hidden_
Definition: unit.hpp:1947
bool is_healthy_
Definition: unit.hpp:1928
bool is_fearless_
Definition: unit.hpp:1928
utils::optional< std::string > ellipse_
Definition: unit.hpp:1959
const unit_type * type_
Never nullptr.
Definition: unit.hpp:1845
std::bitset< num_bool_states > known_boolean_states_
Definition: unit.hpp:1901
utils::optional< std::string > halo_
Definition: unit.hpp:1958
bool is_favorite_
Definition: unit.hpp:1931
map_location::direction facing_
Definition: unit.hpp:1918
int side_
Definition: unit.hpp:1879
const unit_race * race_
Never nullptr, but may point to the null race.
Definition: unit.hpp:1851
bool appearance_changed_
Definition: unit.hpp:1970
int operator()(const upkeep_loyal &) const
Loyal units cost no upkeep.
Definition: unit.hpp:1092
bool appearance_changed() const
Definition: unit.hpp:1835
unit_alignments::type alignment_
Definition: unit.hpp:1870
bool get_ability_bool(const std::string &tag_name) const
Checks whether this unit currently possesses or is affected by a given ability.
Definition: unit.hpp:1663
bool dismissable_
Definition: unit.hpp:1876
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2619
bool is_visible_to_team(const team &team, bool const see_all=true) const
Definition: unit.cpp:2662
active_ability_list get_abilities(const std::string &tag_name) const
Gets the unit's active abilities of a particular type.
Definition: unit.hpp:1698
std::enable_if_t<!std::is_same_v< int, T >, std::string > operator()(T &) const
Definition: unit.hpp:1114
n_unit::unit_id underlying_id_
Definition: unit.hpp:1855
std::string variation_
Definition: unit.hpp:1858
unit & mark_clone(bool is_temporary)
Mark this unit as clone so it can be inserted to unit_map.
Definition: unit.cpp:2720
bool has_ability_type(const std::string &ability) const
Check if the unit has an ability of a specific type.
Definition: abilities.cpp:815
std::enable_if_t< std::is_convertible_v< B, bool > &&!std::is_arithmetic_v< B >, upkeep_t > operator()(B b) const
Definition: unit.hpp:1144
static const std::size_t num_bool_states
Definition: unit.hpp:1899
config filter_recall_
Definition: unit.hpp:1906
int max_experience_
Definition: unit.hpp:1863
unit_race::GENDER gender_
Definition: unit.hpp:1881
int operator()(int v) const
Definition: unit.hpp:1097
t_string description_
Definition: unit.hpp:1954
std::set< std::string > recruit_list_
Definition: unit.hpp:1869
int level_
Definition: unit.hpp:1865
std::string role_
Definition: unit.hpp:1912
std::map< map_location, bool > invisibility_cache_
Hold the visibility status cache for a unit, when not uncovered.
Definition: unit.hpp:1980
upkeep_t operator()(const std::string &s) const
Definition: unit.hpp:1154
bool end_turn_
Definition: unit.hpp:1891
std::vector< std::string > advances_to_
Definition: unit.hpp:1842
std::unique_ptr< unit_animation_component > anim_comp_
Definition: unit.hpp:1945
std::enable_if_t< std::is_arithmetic_v< N >, upkeep_t > operator()(N n) const
Definition: unit.hpp:1135
int recall_cost_
Definition: unit.hpp:1867
static std::string type()
Definition: unit.hpp:1071
attack_list attacks_
Definition: unit.hpp:1913
std::vector< std::string > get_ability_id_list() const
Get a list of all abilities by ID.
Definition: abilities.cpp:683
void remove_ability_by_id(const std::string &ability)
Removes a unit's abilities with a specific ID.
Definition: unit.cpp:1518
bool ability_affects_weapon(const unit_ability_t &ab, const const_attack_ptr &weapon, bool is_opp) const
filters the weapons that condition the use of abilities for combat ([resistance],[leadership] or abil...
utils::optional< std::string > usage_
Definition: unit.hpp:1957
map_location loc_
Definition: unit.hpp:1840
static std::string type()
Definition: unit.hpp:1066
std::vector< std::string > overlays_
Definition: unit.hpp:1910
config modifications_
Definition: unit.hpp:1949
bool has_ability_by_id(const std::string &ability) const
Check if the unit has an ability of a specific ID.
Definition: unit.cpp:1507
bool hold_position_
Definition: unit.hpp:1890
config abilities_cfg() const
Definition: unit.hpp:1703
bool favorite() const
Definition: unit.hpp:1934
upkeep_value_visitor(const unit &unit)
Definition: unit.hpp:1083
std::string operator()(int v) const
Definition: unit.hpp:1120
bool get_self_ability_bool(const unit_ability_t &ab, const map_location &loc) const
Checks whether this unit currently possesses a given ability, and that that ability is active.
Definition: abilities.cpp:1500
void parse_upkeep(const config::attribute_value &upkeep)
Definition: unit.cpp:2845
std::vector< config > advancements_
Definition: unit.hpp:1952
bool get_adj_ability_bool(const unit_ability_t &ab, std::size_t dist, int dir, const map_location &loc, const unit &from, const map_location &from_loc) const
Checks whether this unit is affected by a given ability, and that that ability is active.
Definition: abilities.cpp:1509
utils::string_map modification_descriptions_
Definition: unit.hpp:1940
upkeep_t operator()(utils::monostate) const
Definition: unit.hpp:1149
unit_checksum_version
Optional parameter for get_checksum to use the algorithm of an older version of Wesnoth,...
Definition: unit.hpp:2035
std::vector< std::string > trait_nonhidden_ids_
Definition: unit.hpp:1923
upkeep_t upkeep_
Definition: unit.hpp:1964
std::vector< unit_ability_t::tooltip_info > ability_tooltips() const
Gets the names and descriptions of this unit's abilities.
Definition: abilities.cpp:721
int operator()(const upkeep_full &) const
Full upkeep equals the unit's level.
Definition: unit.hpp:1086
std::set< std::string > states_
Definition: unit.hpp:1897
std::size_t max_ability_radius_image_
used if ability own halo_image or overlay_image attributes in same time what [affect_adjacent].
Definition: unit.hpp:2006
std::string profile_
Definition: unit.hpp:1966
t_string dismiss_message_
Definition: unit.hpp:1877
int jamming_
Definition: unit.hpp:1886
map_location goto_
Definition: unit.hpp:1926
t_string name_
Definition: unit.hpp:1854
int max_attacks_
Definition: unit.hpp:1895
int max_hit_points_
Definition: unit.hpp:1861
int max_movement_
Definition: unit.hpp:1884
bool resting_
Definition: unit.hpp:1892
std::size_t max_ability_radius_
Used for easing checking if unit own a ability with [affect_adjacent] sub tag.
Definition: unit.hpp:2002
std::vector< t_string > trait_descriptions_
Definition: unit.hpp:1922
bool emit_zoc_
Definition: unit.hpp:1908
unit_movement_resetter & operator=(const unit_movement_resetter &)=delete
@ version_1_16_or_older
Included some of the flavortext from weapon specials.
void set_big_profile(const std::string &value)
Definition: unit.cpp:1948
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:427
void heal(int amount)
Heal the unit.
Definition: unit.cpp:1392
bool user_end_turn() const
Check whether the user ended their turn.
Definition: unit.hpp:707
void set_role(const std::string &role)
Sets a unit's role.
Definition: unit.hpp:597
unit_alignments::type alignment() const
The alignment of this unit.
Definition: unit.hpp:397
void toggle_user_end_turn()
Toggle whether the user ended their turn.
Definition: unit.hpp:695
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:826
void set_state(const std::string &state, bool value)
Set whether the unit is affected by a status effect.
Definition: unit.cpp:1484
int level() const
The current level of this unit.
Definition: unit.hpp:481
std::string usage() const
Gets this unit's usage.
Definition: unit.hpp:608
const std::string & get_role() const
Gets this unit's role.
Definition: unit.hpp:591
const t_string & type_name() const
Gets the translatable name of this unit's type.
Definition: unit.hpp:275
const std::set< std::string > & recruits() const
The type IDs of the other units this unit may recruit, if possible.
Definition: unit.hpp:546
void new_turn()
Refresh unit for the beginning of a turn.
Definition: unit.cpp:1353
void set_max_experience(int value)
Definition: unit.hpp:456
void set_max_hitpoints(int value)
Definition: unit.hpp:432
void set_hitpoints(int hp)
Sets the current hitpoint amount.
Definition: unit.hpp:439
bool unrenamable() const
Whether this unit can be renamed.
Definition: unit.hpp:342
const config & recall_filter() const
Gets the filter constraints upon which units this unit may recall, if able.
Definition: unit.hpp:574
int recall_cost() const
How much gold it costs to recall this unit, or -1 if the side's default recall cost is used.
Definition: unit.hpp:562
std::string big_profile() const
An optional profile image displays when this unit is 'speaking' via [message].
Definition: unit.cpp:1156
static state_t get_known_boolean_state_id(const std::string &state)
Convert a string status effect ID to a built-in status effect ID.
Definition: unit.cpp:1453
void set_level(int level)
Sets the current level of this unit.
Definition: unit.hpp:487
void rename(const std::string &name)
Attempts to rename this unit's translatable display name, taking the 'unrenamable' flag into account.
Definition: unit.hpp:330
void set_hidden(bool state) const
Sets whether the unit is hidden on the map.
Definition: unit.cpp:2816
void set_recall_filter(const config &filter)
Sets the filter constraints upon which units this unit may recall, if able.
Definition: unit.hpp:580
const std::string & variation() const
The ID of the variation of this unit's type.
Definition: unit.hpp:494
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:421
int cost() const
How much gold is required to recruit this unit.
Definition: unit.hpp:555
bool hold_position() const
Whether the unit has been instructed to hold its position.
Definition: unit.hpp:666
static std::string get_known_boolean_state_name(state_t state)
Convert a built-in status effect ID to a string status effect ID.
Definition: unit.cpp:1463
bool slowed() const
Check if the unit has been slowed.
Definition: unit.hpp:835
bool get_state(const std::string &state) const
Check if the unit is affected by a status effect.
Definition: unit.cpp:1425
unsigned int experience_overflow() const
The number of experience points over max this unit has, or 0 if current XP < max XP.
Definition: unit.hpp:469
std::string small_profile() const
An optional profile image to display in Help.
Definition: unit.cpp:1165
void heal_fully()
Fully heal the unit, restoring it to max hitpoints.
Definition: unit.hpp:746
void set_undead_variation(const std::string &value)
The ID of the undead variation (ie, dwarf, swimmer) of this unit.
Definition: unit.hpp:500
void toggle_hold_position()
Toggle the unit's hold position status.
Definition: unit.hpp:674
const std::string & type_id() const
The id of this unit's type.
Definition: unit.cpp:1943
void set_alignment(unit_alignments::type alignment)
Sets the alignment of this unit.
Definition: unit.hpp:403
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
Definition: unit.hpp:642
void set_name(const t_string &name)
Sets this unit's translatable display name.
Definition: unit.hpp:319
void set_can_recruit(bool canrecruit)
Sets whether this unit can recruit other units.
Definition: unit.hpp:540
const std::set< std::string > get_states() const
Get the status effects currently affecting the unit.
Definition: unit.cpp:1408
void set_side(unsigned int new_side)
Sets the side this unit belongs to.
Definition: unit.hpp:255
void new_scenario()
Refresh unit for the beginning of a new scenario.
Definition: unit.cpp:1377
void end_turn()
Refresh unit for the end of a turn.
Definition: unit.cpp:1363
bool take_hit(int damage)
Damage the unit.
Definition: unit.hpp:731
const config & variables() const
Const overload of variables.
Definition: unit.hpp:631
const std::string & undead_variation() const
Definition: unit.hpp:505
const unit_race * race() const
Gets this unit's race.
Definition: unit.hpp:415
const unit_type & type() const
This unit's type, accounting for gender and variation.
Definition: unit.hpp:261
int experience() const
The current number of experience points this unit has.
Definition: unit.hpp:445
t_string block_dismiss_message() const
A message of why this unit cannot be dismissed.
Definition: unit.hpp:366
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition: unit.hpp:534
void set_experience(int xp)
Sets the current experience point amount.
Definition: unit.hpp:475
void set_user_end_turn(bool value=true)
Set whether the user ended their turn.
Definition: unit.hpp:686
const std::string & id() const
Gets this unit's id.
Definition: unit.hpp:286
void set_underlying_id(n_unit::id_manager &id_manager)
Sets the internal ID.
Definition: unit.cpp:2703
int side() const
The side this unit belongs to.
Definition: unit.hpp:249
bool dismissable() const
Whether this unit can be dismissed.
Definition: unit.hpp:360
bool poisoned() const
Check if the unit has been poisoned.
Definition: unit.hpp:817
unsigned int experience_to_advance() const
The number of experience points this unit needs to level up, or 0 if current XP > max XP.
Definition: unit.hpp:463
state_t
Built-in status effects known to the engine.
Definition: unit.hpp:774
double xp_bar_scaling() const
The factor by which the XP bar should be scaled.
Definition: unit.cpp:2833
void set_unit_description(const t_string &new_desc)
A detailed description of this unit.
Definition: unit.hpp:378
void set_unrenamable(bool unrenamable)
Sets the 'unrenamable' flag.
Definition: unit.hpp:350
void set_recruits(const std::vector< std::string > &recruits)
Sets the recruit list.
Definition: unit.cpp:1265
std::vector< t_string > unit_special_notes() const
The unit's special notes.
Definition: unit.cpp:2872
void set_id(const std::string &id)
Sets this unit's string ID.
Definition: unit.hpp:292
config & variables()
Gets any user-defined variables this unit 'owns'.
Definition: unit.hpp:625
void set_recall_cost(int recall_cost)
Sets the cost of recalling this unit.
Definition: unit.hpp:568
std::size_t underlying_id() const
This unit's unique internal ID.
Definition: unit.hpp:298
double hp_bar_scaling() const
The factor by which the HP bar should be scaled.
Definition: unit.cpp:2829
void set_usage(const std::string &usage)
Sets this unit's usage.
Definition: unit.hpp:614
int max_experience() const
The max number of experience points this unit can have.
Definition: unit.hpp:451
void set_small_profile(const std::string &value)
Definition: unit.hpp:518
unit_race::GENDER gender() const
The gender of this unit.
Definition: unit.hpp:387
const t_string & name() const
Gets this unit's translatable display name.
Definition: unit.hpp:309
t_string unit_description() const
A detailed description of this unit.
Definition: unit.hpp:372
@ STATE_SLOWED
Definition: unit.hpp:775
@ STATE_UNKNOWN
To set the size of known_boolean_states_.
Definition: unit.hpp:784
@ STATE_NOT_MOVED
The unit is uncovered - it was hiding but has been spotted.
Definition: unit.hpp:779
@ STATE_GUARDIAN
The unit cannot be healed.
Definition: unit.hpp:781
@ STATE_INVULNERABLE
The unit is a guardian - it won't move unless a target is sighted.
Definition: unit.hpp:782
@ STATE_PETRIFIED
The unit is poisoned - it loses health each turn.
Definition: unit.hpp:777
@ NUMBER_OF_STATES
The unit is invulnerable - it cannot be hit by any attack.
Definition: unit.hpp:783
@ STATE_UNHEALABLE
The unit has not moved.
Definition: unit.hpp:780
@ STATE_POISONED
The unit is slowed - it moves slower and does less damage.
Definition: unit.hpp:776
@ STATE_UNCOVERED
The unit is petrified - it cannot move or be attacked.
Definition: unit.hpp:778
std::vector< std::string > advances_to_t
Definition: unit.hpp:144
std::vector< config > get_modification_advances() const
Gets any non-typed advanced options set by modifications.
Definition: unit.cpp:1872
std::vector< std::pair< std::string, std::string > > amla_icons() const
Gets the image and description data for modification advancements.
Definition: unit.cpp:1855
const advances_to_t & advances_to() const
Gets the possible types this unit can advance to on level-up.
Definition: unit.hpp:150
bool can_advance() const
Checks whether this unit has any options to advance to.
Definition: unit.hpp:178
bool advances() const
Checks whether this unit is eligible for level-up.
Definition: unit.hpp:189
void set_advancements(std::vector< config > advancements)
Sets the raw modification advancement option data.
Definition: unit.cpp:1937
void set_advances_to(const std::vector< std::string > &advances_to)
Sets this unit's advancement options.
Definition: unit.cpp:1287
const std::vector< config > & modification_advancements() const
The raw, unparsed data for modification advancements.
Definition: unit.hpp:229
std::map< std::string, std::string > advancement_icons() const
Gets and image path and and associated description for each advancement option.
Definition: unit.cpp:1815
const std::vector< std::string > advances_to_translated() const
Gets the names of the possible types this unit can advance to on level-up.
Definition: unit.cpp:1272
void advance_to(const unit_type &t, bool use_traits=false)
Advances this unit to another type.
Definition: unit.cpp:1009
int resistance_against(const std::string &damage_name, bool attacker, const map_location &loc) const
The unit's resistance against a given damage type.
Definition: unit.cpp:1806
void remove_attacks_ai()
Set the unit to have no attacks left for this turn.
Definition: unit.cpp:2798
attack_ptr add_attack(attack_itors::iterator position, Args &&... args)
Adds a new attack to the unit.
Definition: unit.hpp:865
bool remove_attack(const attack_ptr &atk)
Remove an attack from the unit.
Definition: unit.cpp:2787
void set_max_attacks(int value)
Definition: unit.hpp:889
int attacks_left(bool base_value) const
Gets the remaining number of attacks this unit can perform this turn.
Definition: unit.hpp:912
int resistance_value(active_ability_list resistance_list, const std::string &damage_name) const
For the provided list of resistance abilities, determine the damage resistance based on which are act...
Definition: unit.cpp:1790
int defense_modifier(const t_translation::terrain_code &terrain) const
Definition: unit.hpp:933
bool resistance_filter_matches(const config &cfg, const std::string &damage_name, int res) const
Definition: unit.cpp:1768
attack_itors attacks()
Gets an iterator over this unit's attacks.
Definition: unit.hpp:848
int defense_modifier(const t_translation::terrain_code &terrain, const map_location &loc) const
The unit's defense on a given terrain.
Definition: unit.cpp:1756
utils::string_map_res get_base_resistances() const
Gets resistances without any abilities applied.
Definition: unit.hpp:956
int max_attacks() const
The maximum number of attacks this unit may perform per turn, usually 1.
Definition: unit.hpp:884
const_attack_itors attacks() const
Const overload of attacks.
Definition: unit.hpp:854
int attacks_left() const
Gets the remaining number of attacks this unit can perform this turn.
Definition: unit.hpp:900
void set_attacks(int left)
Sets the number of attacks this unit has left this turn.
Definition: unit.hpp:921
color_t xp_color() const
Color for this unit's XP.
Definition: unit.cpp:1253
unit_animation_component & anim_comp() const
Definition: unit.hpp:1537
const std::string & effect_image_mods() const
Gets any IPF image mods applied by effects.
Definition: unit.hpp:1587
std::vector< std::string > overlays_abilities() const
Get the [overlay] ability overlay images.
Definition: unit.hpp:1606
color_t hp_color() const
Color for this unit's current hitpoints.
Definition: unit.cpp:1209
std::vector< std::string > halo_abilities() const
Get the [halo] abilities halo image(s).
Definition: unit.hpp:1557
std::string TC_image_mods() const
Constructs a recolor (RC) IPF string for this unit's team color.
Definition: unit.cpp:2772
static color_t hp_color_max()
Definition: unit.cpp:1219
const std::string & flag_rgb() const
Get the source color palette to use when recoloring the unit's image.
Definition: unit.cpp:1183
std::string image_ellipse() const
Get the unit's ellipse image.
Definition: unit.hpp:1566
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
Definition: unit.cpp:2777
std::string default_anim_image() const
The default image to use for animation frames with no defined image.
Definition: unit.cpp:2601
std::string image_halo() const
Get the unit's halo image.
Definition: unit.hpp:1549
const std::vector< std::string > & overlays() const
Get the unit's overlay images.
Definition: unit.hpp:1600
std::string absolute_image() const
The name of the file to game_display (used in menus).
Definition: unit.cpp:2596
void set_image_ellipse(const std::string &ellipse)
Set the unit's ellipse image.
Definition: unit.hpp:1572
std::vector< std::string > halo_or_icon_abilities(const std::string &image_type) const
Definition: abilities.cpp:829
void set_image_halo(const std::string &halo)
Set the unit's halo image.
Definition: unit.cpp:2838
std::size_t advancements_count() const
Definition: unit.hpp:1487
std::size_t traits_count() const
Definition: unit.hpp:1477
void add_modification(const std::string &type, const config &modification, bool no_add=false)
Add a new modification to the unit.
Definition: unit.cpp:2477
static const std::set< std::string > builtin_effects
Definition: unit.hpp:1510
std::string describe_builtin_effect(const std::string &type, const config &effect)
Construct a string describing a built-in effect.
Definition: unit.cpp:1981
const config & get_modifications() const
Set the raw modifications.
Definition: unit.hpp:1455
config & get_modifications()
Get the raw modifications.
Definition: unit.hpp:1449
void apply_modifications()
Re-apply all saved modifications.
Definition: unit.cpp:2606
void expire_modifications(const std::string &duration)
Clears those modifications whose duration has expired.
Definition: unit.cpp:1320
std::size_t objects_count() const
Definition: unit.hpp:1482
void apply_builtin_effect(const std::string &type, const config &effect)
Apply a builtin effect to the unit.
Definition: unit.cpp:2046
std::size_t modification_count(const std::string &type, const std::string &id) const
Count modifications of a particular type.
Definition: unit.cpp:1955
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
Definition: unit.hpp:1308
bool get_emit_zoc() const
Gets the raw zone-of-control flag, disregarding incapacitated.
Definition: unit.hpp:1314
int jamming() const
Gets the unit's jamming points.
Definition: unit.hpp:1376
bool has_goto() const
Gets whether this unit has a multi-turn destination set.
Definition: unit.hpp:1352
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1327
bool has_moved() const
Checks if this unit has moved.
Definition: unit.hpp:1282
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit's movement cost on a particular terrain.
Definition: unit.hpp:1410
const movetype & movement_type() const
Get the unit's movement type.
Definition: unit.hpp:1400
void set_movement(int moves, bool unit_action=false)
Set this unit's remaining movement to moves.
Definition: unit.cpp:1294
const map_location & get_interrupted_move() const
Get the target location of the unit's interrupted move.
Definition: unit.hpp:1388
int vision_cost(const t_translation::terrain_code &terrain) const
Get the unit's vision cost on a particular terrain.
Definition: unit.hpp:1420
void set_resting(bool rest)
Sets this unit's resting status.
Definition: unit.hpp:1302
void set_facing(map_location::direction dir) const
The this unit's facing.
Definition: unit.cpp:1721
void set_total_movement(int value)
Definition: unit.hpp:1241
void set_emit_zoc(bool val)
Sets the raw zone-of-control flag.
Definition: unit.hpp:1320
void set_goto(const map_location &new_goto)
Sets this unit's long term destination.
Definition: unit.hpp:1364
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
Definition: unit.hpp:1252
int movement_left(bool base_value) const
Gets how far a unit can move.
Definition: unit.hpp:1264
int total_movement() const
The maximum moves this unit has.
Definition: unit.hpp:1236
int jamming_cost(const t_translation::terrain_code &terrain) const
Get the unit's jamming cost on a particular terrain.
Definition: unit.hpp:1430
void set_location(const map_location &loc)
Sets this unit's map location.
Definition: unit.hpp:1337
void remove_movement_ai()
Sets the unit to have no moves left for this turn.
Definition: unit.cpp:2807
bool move_interrupted() const
Check whether the unit's move has been interrupted.
Definition: unit.hpp:1382
int vision() const
Gets the unit's vision points.
Definition: unit.hpp:1370
const map_location & get_goto() const
The map location to which this unit is moving over multiple turns, if any.
Definition: unit.hpp:1358
map_location::direction facing() const
The current direction this unit is facing within its hex.
Definition: unit.hpp:1343
bool resting() const
Checks whether this unit is 'resting'.
Definition: unit.hpp:1296
void set_interrupted_move(const map_location &interrupted_move)
Set the target location of the unit's interrupted move.
Definition: unit.hpp:1394
bool is_flying() const
Check if the unit is a flying unit.
Definition: unit.hpp:1436
std::vector< std::string > get_advancements_list() const
Definition: unit.hpp:1037
std::vector< std::string > get_objects_list() const
Definition: unit.hpp:1032
std::vector< std::string > get_modifications_list(const std::string &mod_type) const
Gets a list of the modification this unit currently has.
Definition: unit.cpp:974
int upkeep() const
Gets the amount of gold this unit costs a side per turn.
Definition: unit.cpp:1730
std::vector< std::string > trait_nonhidden_ids() const
Gets the ids of the traits corresponding to those returned by trait_names() and trait_descriptions().
Definition: unit.hpp:1011
std::size_t max_ability_radius_type(const std::string &tag_name) const
If this unit has abilities of tag_name type with [affect_adjacent] subtags, returns the radius of the...
Definition: unit.hpp:1202
void add_trait_description(const config &trait, const t_string &description)
Register a trait's name and its description for the UI's use.
Definition: unit.cpp:2580
bool is_healthy() const
Gets whether this unit is healthy - ie, always rest heals.
Definition: unit.hpp:1192
bool is_fearless() const
Gets whether this unit is fearless - ie, unaffected by time of day.
Definition: unit.hpp:1186
std::size_t max_ability_radius_image() const
If this unit has abilities with [affect_adjacent] subtags and halo_image or overlay_image attributes,...
Definition: unit.hpp:1223
utils::variant< upkeep_full, upkeep_loyal, int > upkeep_t
Definition: unit.hpp:1074
const std::vector< t_string > & trait_descriptions() const
Gets the descriptions of the currently registered traits.
Definition: unit.hpp:1000
std::vector< std::string > get_traits_list() const
Gets a list of the traits this unit currently has, including hidden traits.
Definition: unit.hpp:1027
const std::vector< t_string > & trait_names() const
Gets the names of the currently registered traits.
Definition: unit.hpp:990
void generate_traits(bool must_have_only=false)
Applies mandatory traits (e.g.
Definition: unit.cpp:841
std::size_t max_ability_radius() const
If this unit has abilities with [affect_adjacent] subtags, returns the radius of the one with the fur...
Definition: unit.hpp:1213
upkeep_t upkeep_raw() const
Gets the raw variant controlling the upkeep value.
Definition: unit.hpp:1169
void set_loyal(bool loyal)
Definition: unit.cpp:1745
bool loyal() const
Gets whether this unit is loyal - ie, it costs no upkeep.
Definition: unit.cpp:1740
void set_upkeep(upkeep_t v)
Sets the upkeep value to a specific value value.
Definition: unit.hpp:1175
Definition: halo.cpp:41
std::string tag(std::string_view tag, Args &&... data)
Wraps the given data in the specified tag.
Definition: markup.hpp:45
constexpr auto filter
Definition: ranges.hpp:38
std::map< std::string, t_string, res_compare > string_map_res
std::map< std::string, t_string > string_map
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
std::shared_ptr< const attack_type > const_attack_ptr
Definition: ptr.hpp:34
std::shared_ptr< attack_type > attack_ptr
Definition: ptr.hpp:33
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:61
Encapsulates the map of the game.
Definition: location.hpp:46
bool valid() const
Definition: location.hpp:111
direction
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:48
std::size_t value
Definition: id.hpp:25
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:49
Visitor helper struct to fetch the upkeep type flag if applicable, or the the value otherwise.
Definition: unit.hpp:1111
Object which temporarily resets a unit's movement.
Definition: unit.hpp:2017
static map_location::direction n
static map_location::direction s
std::string get_checksum(const unit &u, backwards_compatibility::unit_checksum_version version=backwards_compatibility::unit_checksum_version::current)
Gets a checksum for a unit.
Definition: unit.cpp:2878
MacOS doesn't support std::visit when targing MacOS < 10.14 (currently we target 10....
#define b