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