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