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