The Battle for Wesnoth  1.19.18+dev
abilities.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2025
3  by Dominic Bolin <dominic.bolin@exong.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 "map/location.hpp"
19 #include "units/ptr.hpp"
20 #include "units/race.hpp" // for unit_race::GENDER
21 
22 
23 #include <vector>
24 class config;
25 
27 
28 
29 using ability_vector = std::vector<ability_ptr>;
30 
32 {
33 public:
34 
35  enum class active_on_t { offense, defense, both };
36  enum class apply_to_t { self, opponent, attacker, defender, both };
38 
39  enum class affects_t { SELF = 1, OTHER = 2, EITHER = 3 };
40 
41  unit_ability_t(std::string tag, config cfg, bool inside_attack);
42 
43  static ability_ptr create(std::string tag, config cfg, bool inside_attack) {
44  return std::make_shared<unit_ability_t>(tag, cfg, inside_attack);
45  }
46 
47  static void do_compat_fixes(config& cfg, const std::string& tag, bool inside_attack);
48 
49  const std::string& tag() const { return tag_; };
50  const std::string& id() const { return id_; };
51  bool in_specials_tag() const { return in_specials_tag_; };
52  const config& cfg() const { return cfg_; };
53 
54  active_on_t active_on() const { return active_on_; };
55  apply_to_t apply_to() const { return apply_to_; };
56  double priority() const { return priority_; };
57 
58  //has no effect in [specials]
60  //has no effect in [specials]
61  bool affects_self() const { return affects_self_; }
62  //has no effect in [specials]
63  bool affects_enemies() const { return affects_enemies_; }
64 
65  struct tooltip_info
66  {
69  // a unique id used for help topics, generated from name and id.
70  // doesn't include the "ability_" prefix.
71  // TODO: maybe use cfg["unique_id"] at some point?
72  std::string help_topic_id;
73  };
74 
75  //Generates a unique id to be used to identify the help page for this ability.
76  static std::string get_help_topic_id(const config& cfg);
77  std::string get_help_topic_id() const;
78 
79 
80  std::string get_name(bool is_inactive = false, unit_race::GENDER = unit_race::MALE) const;
81  std::string get_description(bool is_inactive = false, unit_race::GENDER = unit_race::MALE) const;
82 
83  //checks whether the ability is active according to the active_on= attribute.
84  bool active_on_matches(bool student_is_attacker) const;
85 
86 
87  //checks whether the ability matches the filter specified in a [filter_special] or [filter_ability]
88  bool matches_filter(const config& filter) const;
89  void write(config& abilities_cfg);
90 
91 
92  static void parse_vector(const config& abilities_cfg, ability_vector& res, bool inside_attack);
93  static config vector_to_cfg(const ability_vector& abilities);
94  static ability_vector cfg_to_vector(const config& abilities_cfg, bool inside_attack);
95 
96 
97  static ability_vector filter_tag(const ability_vector& vec, const std::string& tag);
98  static ability_vector clone(const ability_vector& vec);
99 
100  /**
101  * Substitute gettext variables in name and description of abilities and specials
102  * @param str The string in which the substitution is to be done
103  *
104  * @return The string `str` with all gettext variables substitutes with corresponding special properties
105  */
106  std::string substitute_variables(const std::string& str) const;
107 
108 
109 
111  {
112  public:
116  recursion_guard() = delete;
118 
119  /**
120  * Returns true if a level of recursion was available at the time when guard_against_recursion()
121  * created this object.
122  */
123  operator bool() const;
125  };
126 
127  /**
128  * Tests which might otherwise cause infinite recursion should call this, check that the
129  * returned object evaluates to true, and then keep the object returned as long as the
130  * recursion might occur, similar to a reentrant mutex that's limited to a small number of
131  * reentrances.
132  *
133  * This only expects to be called in a single thread
134  */
136 // recursion_guard guard_against_recursion(const attack_type& a) const;
137 
138 private:
139  std::string tag_;
140  std::string id_;
141  // abilities/specials inside [specials] tag follow a differnt syntax than in [abilities] tags, in paricular [filter_self] inside [specials] is equivalent to [filter_student] in abilities.
148  double priority_;
150 
151  mutable bool currently_checked_;
152 };
153 
154 
155 /** Data typedef for active_ability_list. */
157 {
161  , p_ability_(p_ability)
162  {
163  }
164 
165  /**
166  * Used by the formula in the ability.
167  * The REAL location of the student (not the 'we are assuming the student is at this position' location)
168  * once active_ability_list can contain abilities from different 'students', as it contains abilities from
169  * a unit aswell from its opponents (abilities with apply_to= opponent)
170  */
172  /**
173  * The location of the teacher, that is the unit who owns the ability tags
174  * (different from student because of [affect_adjacent])
175  */
177 
178  const config& ability_cfg() const { return p_ability_->cfg(); }
179  const unit_ability_t& ability() const { return *p_ability_; }
180 private:
181  /** The contents of the ability tag, never nullptr. */
183 };
184 
186 {
187 public:
189 
190  // Implemented in unit_abilities.cpp
191  std::pair<int, map_location> highest(const std::string& key, int def = 0) const
192  {
193  return get_extremum(key, def, std::less<int>());
194  }
195  std::pair<int, map_location> lowest(const std::string& key, int def = 0) const
196  {
197  return get_extremum(key, def, std::greater<int>());
198  }
199 
200  template<typename TComp>
201  std::pair<int, map_location> get_extremum(const std::string& key, int def, const TComp& comp) const;
202 
203  // The following make this class usable with standard library algorithms and such
205  typedef std::vector<active_ability>::const_iterator const_iterator;
206 
207  iterator begin() { return cfgs_.begin(); }
208  const_iterator begin() const { return cfgs_.begin(); }
209  iterator end() { return cfgs_.end(); }
210  const_iterator end() const { return cfgs_.end(); }
211 
212  // Vector access
213  bool empty() const { return cfgs_.empty(); }
214  active_ability& front() { return cfgs_.front(); }
215  const active_ability& front() const { return cfgs_.front(); }
216  active_ability& back() { return cfgs_.back(); }
217  const active_ability& back() const { return cfgs_.back(); }
218  std::size_t size() { return cfgs_.size(); }
219 
220  iterator erase(const iterator& erase_it) { return cfgs_.erase(erase_it); }
221  iterator erase(const iterator& first, const iterator& last) { return cfgs_.erase(first, last); }
222 
223  template<typename... T>
224  void emplace_back(T&&... args) { cfgs_.emplace_back(args...); }
225 
226  const map_location& loc() const { return loc_; }
227 
228  /** Appends the abilities from @a other to @a this, ignores other.loc() */
229  void append(const active_ability_list& other)
230  {
231  std::copy(other.begin(), other.end(), std::back_inserter(cfgs_));
232  }
233 
234  /**
235  * Appends any abilities from @a other for which the given condition returns true to @a this, ignores other.loc().
236  *
237  * @param other where to copy the elements from
238  * @param predicate a single-argument function that takes a reference to an element and returns a bool
239  */
240  template<typename Predicate>
241  void append_if(const active_ability_list& other, const Predicate& predicate)
242  {
243  std::copy_if(other.begin(), other.end(), std::back_inserter(cfgs_), predicate);
244  }
245 
246 private:
247  // Data
248  std::vector<active_ability> cfgs_;
250 };
251 
252 namespace unit_abilities
253 {
254 bool filter_base_matches(const config& cfg, int def);
255 
257 
259 
261 {
263  loc(map_location::null_location()) {}
264  void set(value_modifier t, int val, const config& abil,const map_location &l);
266  int value;
267  const config *ability;
269 };
270 
271 class effect
272 {
273  public:
274  effect(const active_ability_list& list, int def, const const_attack_ptr& attacker = const_attack_ptr(), EFFECTS wham = EFFECT_DEFAULT);
275  // Provide read-only access to the effect list:
276  typedef std::vector<individual_effect>::const_iterator iterator;
277  typedef std::vector<individual_effect>::const_iterator const_iterator;
278 
280  { return composite_value_; }
282  { return composite_double_value_; }
284  { return effect_list_.begin(); }
286  { return effect_list_.end(); }
287  private:
288  /** Part of the constructor, calculates for a group of abilities with equal priority. */
289  void effect_impl(const active_ability_list& list, int def, const const_attack_ptr& att, EFFECTS wham);
290  std::vector<individual_effect> effect_list_;
293 };
294 
295 
296 }
std::vector< ability_ptr > ability_vector
Definition: abilities.hpp:29
double t
Definition: astarsearch.cpp:63
std::vector< active_ability >::iterator iterator
Definition: abilities.hpp:204
void append_if(const active_ability_list &other, const Predicate &predicate)
Appends any abilities from other for which the given condition returns true to this,...
Definition: abilities.hpp:241
active_ability & front()
Definition: abilities.hpp:214
iterator erase(const iterator &first, const iterator &last)
Definition: abilities.hpp:221
std::vector< active_ability >::const_iterator const_iterator
Definition: abilities.hpp:205
std::pair< int, map_location > highest(const std::string &key, int def=0) const
Definition: abilities.hpp:191
std::vector< active_ability > cfgs_
Definition: abilities.hpp:248
iterator erase(const iterator &erase_it)
Definition: abilities.hpp:220
const map_location & loc() const
Definition: abilities.hpp:226
const_iterator begin() const
Definition: abilities.hpp:208
std::pair< int, map_location > get_extremum(const std::string &key, int def, const TComp &comp) const
Definition: abilities.cpp:938
void emplace_back(T &&... args)
Definition: abilities.hpp:224
active_ability & back()
Definition: abilities.hpp:216
const active_ability & front() const
Definition: abilities.hpp:215
active_ability_list(const map_location &loc=map_location())
Definition: abilities.hpp:188
map_location loc_
Definition: abilities.hpp:249
void append(const active_ability_list &other)
Appends the abilities from other to this, ignores other.loc()
Definition: abilities.hpp:229
const_iterator end() const
Definition: abilities.hpp:210
std::pair< int, map_location > lowest(const std::string &key, int def=0) const
Definition: abilities.hpp:195
bool empty() const
Definition: abilities.hpp:213
const active_ability & back() const
Definition: abilities.hpp:217
std::size_t size()
Definition: abilities.hpp:218
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:157
int get_composite_value() const
Definition: abilities.hpp:279
std::vector< individual_effect > effect_list_
Definition: abilities.hpp:290
effect(const active_ability_list &list, int def, const const_attack_ptr &attacker=const_attack_ptr(), EFFECTS wham=EFFECT_DEFAULT)
Definition: abilities.cpp:2157
const_iterator end() const
Definition: abilities.hpp:285
double get_composite_double_value() const
Definition: abilities.hpp:281
std::vector< individual_effect >::const_iterator const_iterator
Definition: abilities.hpp:277
std::vector< individual_effect >::const_iterator iterator
Definition: abilities.hpp:276
const_iterator begin() const
Definition: abilities.hpp:283
void effect_impl(const active_ability_list &list, int def, const const_attack_ptr &att, EFFECTS wham)
Part of the constructor, calculates for a group of abilities with equal priority.
Definition: abilities.cpp:2177
const unit_ability_t * parent
Definition: abilities.hpp:124
recursion_guard(recursion_guard &&)=delete
recursion_guard(const recursion_guard &)=delete
std::string substitute_variables(const std::string &str) const
Substitute gettext variables in name and description of abilities and specials.
Definition: abilities.cpp:301
const std::string & tag() const
Definition: abilities.hpp:49
bool in_specials_tag_
Definition: abilities.hpp:142
apply_to_t apply_to() const
Definition: abilities.hpp:55
static config vector_to_cfg(const ability_vector &abilities)
Definition: abilities.cpp:286
static void do_compat_fixes(config &cfg, const std::string &tag, bool inside_attack)
Definition: abilities.cpp:171
const config & cfg() const
Definition: abilities.hpp:52
static void parse_vector(const config &abilities_cfg, ability_vector &res, bool inside_attack)
Definition: abilities.cpp:252
bool affects_enemies() const
Definition: abilities.hpp:63
std::string get_description(bool is_inactive=false, unit_race::GENDER=unit_race::MALE) const
Definition: abilities.cpp:365
std::string id_
Definition: abilities.hpp:140
bool matches_filter(const config &filter) const
Definition: abilities.cpp:1897
active_on_t active_on() const
Definition: abilities.hpp:54
bool in_specials_tag() const
Definition: abilities.hpp:51
active_on_t active_on_
Definition: abilities.hpp:143
static ability_vector filter_tag(const ability_vector &vec, const std::string &tag)
Definition: abilities.cpp:266
double priority_
Definition: abilities.hpp:148
double priority() const
Definition: abilities.hpp:56
const std::string & id() const
Definition: abilities.hpp:50
unit_ability_t(std::string tag, config cfg, bool inside_attack)
Definition: abilities.cpp:126
static ability_ptr create(std::string tag, config cfg, bool inside_attack)
Definition: abilities.hpp:43
bool currently_checked_
Definition: abilities.hpp:151
affects_allies_t affects_allies_
Definition: abilities.hpp:145
std::string tag_
Definition: abilities.hpp:139
static ability_vector clone(const ability_vector &vec)
Definition: abilities.cpp:277
std::string get_name(bool is_inactive=false, unit_race::GENDER=unit_race::MALE) const
Definition: abilities.cpp:358
std::string get_help_topic_id() const
Definition: abilities.cpp:246
recursion_guard guard_against_recursion(const unit &u) const
Tests which might otherwise cause infinite recursion should call this, check that the returned object...
Definition: abilities.cpp:407
void write(config &abilities_cfg)
Definition: abilities.cpp:296
static ability_vector cfg_to_vector(const config &abilities_cfg, bool inside_attack)
Definition: abilities.cpp:259
affects_allies_t affects_allies() const
Definition: abilities.hpp:59
apply_to_t apply_to_
Definition: abilities.hpp:144
bool affects_enemies_
Definition: abilities.hpp:147
bool active_on_matches(bool student_is_attacker) const
Definition: abilities.cpp:372
bool affects_self() const
Definition: abilities.hpp:61
@ MALE
Definition: race.hpp:28
This class represents a single unit of a specific type.
Definition: unit.hpp:39
const config * cfg
bool filter_base_matches(const config &cfg, int def)
Definition: abilities.cpp:2122
@ EFFECT_WITHOUT_CLAMP_MIN_MAX
Definition: abilities.hpp:258
constexpr auto filter
Definition: ranges.hpp:38
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
std::shared_ptr< const unit_ability_t > const_ability_ptr
Definition: ptr.hpp:39
std::shared_ptr< const attack_type > const_attack_ptr
Definition: ptr.hpp:34
std::shared_ptr< unit_ability_t > ability_ptr
Definition: ptr.hpp:38
Data typedef for active_ability_list.
Definition: abilities.hpp:157
active_ability(const ability_ptr &p_ability, map_location student_loc, map_location teacher_loc)
Definition: abilities.hpp:158
const config & ability_cfg() const
Definition: abilities.hpp:178
map_location teacher_loc
The location of the teacher, that is the unit who owns the ability tags (different from student becau...
Definition: abilities.hpp:176
const unit_ability_t & ability() const
Definition: abilities.hpp:179
const_ability_ptr p_ability_
The contents of the ability tag, never nullptr.
Definition: abilities.hpp:182
map_location student_loc
Used by the formula in the ability.
Definition: abilities.hpp:171
Encapsulates the map of the game.
Definition: location.hpp:46
void set(value_modifier t, int val, const config &abil, const map_location &l)
Definition: abilities.cpp:2114