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