The Battle for Wesnoth  1.19.19+dev
attack_type.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "map/location.hpp"
19 #include "tstring.hpp"
20 #include "config.hpp"
21 #include <string>
22 #include <vector>
23 
24 #include <boost/iterator/indirect_iterator.hpp>
25 #include <boost/dynamic_bitset_fwd.hpp>
26 
27 #include "units/abilities.hpp"
28 #include "units/ptr.hpp" // for attack_ptr
30 
32 class unit_type;
33 class specials_context_t;
34 
35 namespace wfl {
36  class map_formula_callable;
37 }
38 
39 //the 'attack type' is the type of attack, how many times it strikes,
40 //and how much damage it does.
41 class attack_type : public std::enable_shared_from_this<attack_type>
42 {
43 public:
44 
45  explicit attack_type(const config& cfg);
46  const t_string& name() const { return description_; }
47  const std::string& id() const { return id_; }
48  const std::string& type() const { return type_; }
49  const std::string& icon() const { return icon_; }
50  const std::string& range() const { return range_; }
51  int min_range() const { return min_range_; }
52  int max_range() const { return max_range_; }
53  std::string accuracy_parry_description() const;
54  std::string accuracy_parry_tooltip() const;
55  int accuracy() const { return accuracy_; }
56  int parry() const { return parry_; }
57  int damage() const { return damage_; }
58  int num_attacks() const { return num_attacks_; }
59  double attack_weight() const { return attack_weight_; }
60  double defense_weight() const { return defense_weight_; }
61  const ability_vector& specials() const { return specials_; }
62 
63  config specials_cfg() const {
65  }
66 
67  void set_name(const t_string& value) { description_ = value; set_changed(true); }
68  void set_id(const std::string& value) { id_ = value; set_changed(true); }
69  void set_type(const std::string& value) { type_ = value; set_changed(true); }
70  void set_icon(const std::string& value) { icon_ = value; set_changed(true); }
71  void set_range(const std::string& value) { range_ = value; set_changed(true); }
72  void set_min_range(int value) { min_range_ = value; set_changed(true); }
73  void set_max_range(int value) { max_range_ = value; set_changed(true); }
74  void set_attack_alignment(const std::string& value) { alignment_ = unit_alignments::get_enum(value); set_changed(true); }
75  void set_accuracy(int value) { accuracy_ = value; set_changed(true); }
76  void set_parry(int value) { parry_ = value; set_changed(true); }
77  void set_damage(int value) { damage_ = value; set_changed(true); }
78  void set_num_attacks(int value) { num_attacks_ = value; set_changed(true); }
79  void set_attack_weight(double value) { attack_weight_ = value; set_changed(true); }
80  void set_defense_weight(double value) { defense_weight_ = value; set_changed(true); }
81  void set_specials_cfg(const config& value) {
83  }
84 
85  std::vector<unit_ability_t::tooltip_info> special_tooltips() const;
86 
87  /** Returns alignment specified by alignment_ variable.
88  */
89  utils::optional<unit_alignments::type> alignment() const { return alignment_; }
90  /** Returns alignment specified by alignment() for filtering when exist.
91  */
92  std::string alignment_str() const { return alignment_ ? unit_alignments::get_string(*alignment_) : ""; }
93 
94  /** Calculates the number of attacks this weapon has, considering specials. */
95  void modified_attacks(unsigned & min_attacks,
96  unsigned & max_attacks) const;
97 
98  /** @return A type()/replacement_type and a list of alternative_types that should be displayed in the selected unit's report. */
99  std::pair<std::string, std::set<std::string>> damage_types() const;
100  /** @return The type of attack used and the resistance value that does the most damage. */
101  std::pair<std::string, int> effective_damage_type() const;
102 
103  /** Returns the damage per attack of this weapon, considering specials. */
104  double modified_damage() const;
105  /** Return the defense value, considering specials.
106  * @param cth The chance_to_hit value modified or not by function.
107  */
108  int modified_chance_to_hit(int cth) const;
109 
110  /** Return the special weapon value, considering specials.
111  * @param abil_list The list of special checked.
112  * @param base_value The value modified or not by function.
113  */
114  int composite_value(const active_ability_list& abil_list, int base_value) const;
115  /**
116  * @param special the tag name to check for
117  * @return list which contains get_weapon_ability and get_specials list for each ability type, with overwritten items removed
118  */
119  active_ability_list get_specials_and_abilities(const std::string& special) const;
120  /** used for abilities used like weapon and true specials
121  * @return True if the ability @a special is active.
122  * @param special The special being checked.
123  */
124  bool has_special_or_ability(const std::string& special) const;
125  /**
126  * @param special id to check.
127  */
128  bool has_active_special_or_ability_id(const std::string& special) const;
129  /** check if special matche
130  * handles the special_(id/type) attributes in weapon filters.
131  * @return True if a speical matching the filter was found.
132  * @param filter contains attributes special_id, special_type, special
133  */
134  bool has_filter_special_or_ability(const config& filter) const;
135  /**
136  * Returns true if this is a dummy attack_type, for example the placeholder that the unit_attack dialog
137  * uses when a defender has no weapon for a given range.
138  */
139  bool attack_empty() const {return (id().empty() && name().empty() && type().empty() && range().empty());}
140  /** remove special if matche condition
141  * @param filter if special check with filter, it will be removed.
142  */
144  /** check if special matche
145  * @return True if special matche with filter(if 'active' filter is true, check if special active).
146  * @param filter if special check with filter, return true.
147  */
149 
150  // In unit_types.cpp:
151 
152  bool matches_filter(const config& filter, const std::string& check_if_recursion = "") const;
153 
154  /** Applies effect modifications described by @a cfg. */
155  void apply_effect(const config& cfg);
156 
157  /**
158  * Generates a description of the effect specified by @a cfg, if applicable.
159  * This covers a subset of the effects which can be applied via @ref apply_effect.
160  */
161  static std::string describe_effect(const config& cfg);
162 
163  int movement_used() const { return movement_used_; }
164  void set_movement_used(int value) { movement_used_ = value; }
165  int attacks_used() const { return attacks_used_; }
166  void set_attacks_used(int value) { attacks_used_ = value; }
167 
168  void write(config& cfg) const;
169  inline config to_config() const { config c; write(c); return c; }
170 
172 
173  // In unit_abilities.cpp:
174 
175  // Configured as a bit field, in case that is useful.
177  /**
178  * Select best damage type based on frequency count for replacement_type.
179  *
180  * @param damage_type_list list of [damage_type] to check.
181  */
182  std::string select_replacement_type(const active_ability_list& damage_type_list) const;
183  /**
184  * Select best damage type based on highest damage for alternative_type.
185  *
186  * @param damage_type_list list of [damage_type] to check.
187  * @param resistance_list list of "resistance" abilities to check for each type of damage checked.
188  */
189  std::pair<std::string, int> select_alternative_type(const active_ability_list& damage_type_list, const active_ability_list& resistance_list) const;
190  /**
191  * Filter a list of abilities or weapon specials, removing any entries that don't own
192  * the overwrite_specials attributes.
193  *
194  * @param overwriters list that may have overwrite_specials attributes.
195  */
197  /**
198  * Check whether @a cfg would be overwritten by any element of @a overwriters.
199  *
200  * @return True if element checked is overwritable.
201  * @param overwriters list used for check if element is overwritable.
202  * @param ab the ability/special checked
203  */
204  bool overwrite_special_checking(active_ability_list& overwriters, const unit_ability_t& ab) const;
205 
206  bool special_active(const unit_ability_t& ab, AFFECTS whom) const;
207 
208  // make more functions proivate after refactoring finished.
209 
210  // Used via specials_context() to control which specials are
211  // considered active.
212  friend class specials_context_t;
214 
215  std::unique_ptr<specials_context_t> fallback_context(const unit_ptr& self = nullptr) const;
216 
217  void set_changed(bool value)
218  {
219  changed_ = value;
220  }
221  bool get_changed() const
222  {
223  return changed_;
224  }
225 private:
226 
228  std::string id_;
229  std::string type_;
230  std::string icon_;
231  std::string range_;
233  utils::optional<unit_alignments::type> alignment_;
234  int damage_;
238 
242  int parry_;
244  bool changed_;
245 };
246 
247 using attack_list = std::vector<attack_ptr>;
248 using attack_itors = boost::iterator_range<boost::indirect_iterator<attack_list::iterator>>;
249 using const_attack_itors = boost::iterator_range<boost::indirect_iterator<attack_list::const_iterator>>;
250 
252  return boost::make_iterator_range(boost::make_indirect_iterator(atks.begin()), boost::make_indirect_iterator(atks.end()));
253 }
254 
256  return boost::make_iterator_range(boost::make_indirect_iterator(atks.begin()), boost::make_indirect_iterator(atks.end()));
257 }
std::vector< ability_ptr > ability_vector
Definition: abilities.hpp:33
boost::iterator_range< boost::indirect_iterator< attack_list::iterator > > attack_itors
std::vector< attack_ptr > attack_list
boost::iterator_range< boost::indirect_iterator< attack_list::const_iterator > > const_attack_itors
attack_itors make_attack_itors(attack_list &atks)
std::string alignment_str() const
Returns alignment specified by alignment() for filtering when exist.
Definition: attack_type.hpp:92
void set_min_range(int value)
Definition: attack_type.hpp:72
active_ability_list overwrite_special_overwriter(active_ability_list overwriters) const
Filter a list of abilities or weapon specials, removing any entries that don't own the overwrite_spec...
Definition: abilities.cpp:1400
double defense_weight() const
Definition: attack_type.hpp:60
void set_num_attacks(int value)
Definition: attack_type.hpp:78
int min_range() const
Definition: attack_type.hpp:51
bool has_active_special_or_ability_id(const std::string &special) const
double attack_weight() const
Definition: attack_type.hpp:59
void add_formula_context(wfl::map_formula_callable &) const
Definition: abilities.cpp:856
const std::string & range() const
Definition: attack_type.hpp:50
void set_attacks_used(int value)
int movement_used() const
bool has_special_or_ability_with_filter(const config &filter) const
check if special matche
void set_accuracy(int value)
Definition: attack_type.hpp:75
bool get_changed() const
std::vector< unit_ability_t::tooltip_info > special_tooltips() const
Returns a vector of names and descriptions for the specials of *this.
const std::string & type() const
Definition: attack_type.hpp:48
void set_movement_used(int value)
std::pair< std::string, int > select_alternative_type(const active_ability_list &damage_type_list, const active_ability_list &resistance_list) const
Select best damage type based on highest damage for alternative_type.
bool has_special_or_ability(const std::string &special) const
used for abilities used like weapon and true specials
int parry() const
Definition: attack_type.hpp:56
std::string accuracy_parry_tooltip() const
std::string accuracy_parry_description() const
Definition: attack_type.cpp:90
std::unique_ptr< specials_context_t > fallback_context(const unit_ptr &self=nullptr) const
double modified_damage() const
Returns the damage per attack of this weapon, considering specials.
void apply_effect(const config &cfg)
Applies effect modifications described by cfg.
bool matches_filter(const config &filter, const std::string &check_if_recursion="") const
Returns whether or not *this matches the given filter.
void set_specials_cfg(const config &value)
Definition: attack_type.hpp:81
std::string select_replacement_type(const active_ability_list &damage_type_list) const
Select best damage type based on frequency count for replacement_type.
config specials_cfg() const
Definition: attack_type.hpp:63
void set_defense_weight(double value)
Definition: attack_type.hpp:80
int num_attacks() const
Definition: attack_type.hpp:58
void set_changed(bool value)
active_ability_list get_specials_and_abilities(const std::string &special) const
std::pair< std::string, std::set< std::string > > damage_types() const
Return a type()/replacement_type and a list of alternative_types that should be displayed in the sele...
std::string type_
std::string icon_
void set_parry(int value)
Definition: attack_type.hpp:76
void set_attack_weight(double value)
Definition: attack_type.hpp:79
void set_damage(int value)
Definition: attack_type.hpp:77
ability_vector specials_
utils::optional< unit_alignments::type > alignment() const
Returns alignment specified by alignment_ variable.
Definition: attack_type.hpp:89
const t_string & name() const
Definition: attack_type.hpp:46
int attacks_used() const
const std::string & id() const
Definition: attack_type.hpp:47
void set_icon(const std::string &value)
Definition: attack_type.hpp:70
bool has_filter_special_or_ability(const config &filter) const
check if special matche handles the special_(id/type) attributes in weapon filters.
int modified_chance_to_hit(int cth) const
Return the defense value, considering specials.
bool special_active(const unit_ability_t &ab, AFFECTS whom) const
bool attack_empty() const
Returns true if this is a dummy attack_type, for example the placeholder that the unit_attack dialog ...
double defense_weight_
std::string id_
double attack_weight_
config to_config() const
void modified_attacks(unsigned &min_attacks, unsigned &max_attacks) const
Calculates the number of attacks this weapon has, considering specials.
std::string range_
void set_id(const std::string &value)
Definition: attack_type.hpp:68
void remove_special_by_filter(const config &filter)
remove special if matche condition
void set_max_range(int value)
Definition: attack_type.hpp:73
specials_context_t * context_
utils::optional< unit_alignments::type > alignment_
attack_type(const config &cfg)
Definition: attack_type.cpp:55
void set_type(const std::string &value)
Definition: attack_type.hpp:69
void write(config &cfg) const
bool overwrite_special_checking(active_ability_list &overwriters, const unit_ability_t &ab) const
Check whether cfg would be overwritten by any element of overwriters.
Definition: abilities.cpp:1436
int accuracy() const
Definition: attack_type.hpp:55
int max_range() const
Definition: attack_type.hpp:52
void set_range(const std::string &value)
Definition: attack_type.hpp:71
int composite_value(const active_ability_list &abil_list, int base_value) const
Return the special weapon value, considering specials.
static std::string describe_effect(const config &cfg)
Generates a description of the effect specified by cfg, if applicable.
const std::string & icon() const
Definition: attack_type.hpp:49
int damage() const
Definition: attack_type.hpp:57
const ability_vector & specials() const
Definition: attack_type.hpp:61
void set_attack_alignment(const std::string &value)
Definition: attack_type.hpp:74
t_string description_
void set_name(const t_string &value)
Definition: attack_type.hpp:67
std::pair< std::string, int > effective_damage_type() const
The type of attack used and the resistance value that does the most damage.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:157
static config vector_to_cfg(const ability_vector &abilities)
Definition: abilities.cpp:283
static ability_vector cfg_to_vector(const config &abilities_cfg, bool inside_attack)
Definition: abilities.cpp:256
A single unit type that the player may recruit.
Definition: types.hpp:43
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
constexpr auto filter
Definition: ranges.hpp:42
Definition: callable.hpp:26
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
Definition: enum_base.hpp:46
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Definition: enum_base.hpp:57
mock_char c