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