The Battle for Wesnoth  1.17.12+dev
attack_type.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "map/location.hpp"
19 #include "tstring.hpp"
20 #include "config.hpp"
21 #include <string>
22 #include <vector>
23 #include <cassert>
24 
25 #include <boost/iterator/indirect_iterator.hpp>
26 #include <boost/range/iterator_range.hpp>
27 #include <boost/dynamic_bitset_fwd.hpp>
28 
29 #include "units/ptr.hpp" // for attack_ptr
30 
31 class unit_ability_list;
32 class unit_type;
33 namespace wfl {
34  class map_formula_callable;
35 }
36 //the 'attack type' is the type of attack, how many times it strikes,
37 //and how much damage it does.
38 class attack_type : public std::enable_shared_from_this<attack_type>
39 {
40 public:
41 
42  explicit attack_type(const config& cfg);
43  const t_string& name() const { return description_; }
44  const std::string& id() const { return id_; }
45  const std::string& type() const { return type_; }
46  const std::string& icon() const { return icon_; }
47  const std::string& range() const { return range_; }
48  int min_range() const { return min_range_; }
49  int max_range() const { return max_range_; }
50  std::string accuracy_parry_description() const;
51  int accuracy() const { return accuracy_; }
52  int parry() const { return parry_; }
53  int damage() const { return damage_; }
54  int num_attacks() const { return num_attacks_; }
55  double attack_weight() const { return attack_weight_; }
56  double defense_weight() const { return defense_weight_; }
57  const config &specials() const { return specials_; }
58 
59  void set_name(const t_string& value) { description_ = value; set_changed(true); }
60  void set_id(const std::string& value) { id_ = value; set_changed(true); }
61  void set_type(const std::string& value) { type_ = value; set_changed(true); }
62  void set_icon(const std::string& value) { icon_ = value; set_changed(true); }
63  void set_range(const std::string& value) { range_ = value; set_changed(true); }
64  void set_accuracy(int value) { accuracy_ = value; set_changed(true); }
65  void set_parry(int value) { parry_ = value; set_changed(true); }
66  void set_damage(int value) { damage_ = value; set_changed(true); }
67  void set_num_attacks(int value) { num_attacks_ = value; set_changed(true); }
68  void set_attack_weight(double value) { attack_weight_ = value; set_changed(true); }
69  void set_defense_weight(double value) { defense_weight_ = value; set_changed(true); }
70  void set_specials(config value) { specials_ = value; set_changed(true); }
71 
72 
73  // In unit_abilities.cpp:
74 
75  /**
76  * @return True iff the special @a special is active.
77  * @param special The special being checked.
78  * @param simple_check If true, check whether the unit has the special. Else, check whether the special is currently active.
79  * @param special_id If true, match @a special against the @c id of special tags.
80  * @param special_tags If true, match @a special against the tag name of special tags.
81  */
82  bool has_special(const std::string& special, bool simple_check=false, bool special_id=true, bool special_tags=true) const;
83  unit_ability_list get_specials(const std::string& special) const;
84  std::vector<std::pair<t_string, t_string>> special_tooltips(boost::dynamic_bitset<>* active_list = nullptr) const;
85  std::string weapon_specials() const;
86  std::string weapon_specials_value(const std::set<std::string> checking_tags) const;
87 
88  /** Calculates the number of attacks this weapon has, considering specials. */
89  void modified_attacks(unsigned & min_attacks,
90  unsigned & max_attacks) const;
91  /** Returns the damage per attack of this weapon, considering specials. */
92  int modified_damage() const;
93 
94  /** Return the special weapon value, considering specials.
95  * @param abil_list The list of special checked.
96  * @param base_value The value modified or not by function.
97  */
98  int composite_value(const unit_ability_list& abil_list, int base_value) const;
99  /** Returns list for weapon like abilities for each ability type. */
100  unit_ability_list get_weapon_ability(const std::string& ability) const;
101  /** Returns list who contains get_weapon_ability and get_specials list for each ability type */
102  unit_ability_list get_specials_and_abilities(const std::string& special) const;
103  /** used for abilities used like weapon
104  * @return True if the ability @a special is active.
105  * @param special The special being checked.
106  * @param special_id If true, match @a special against the @c id of special tags.
107  * @param special_tags If true, match @a special against the tag name of special tags.
108  */
109  bool has_weapon_ability(const std::string& special, bool special_id=true, bool special_tags=true) const;
110  /** used for abilities used like weapon and true specials
111  * @return True if the ability @a special is active.
112  * @param special The special being checked.
113  * @param special_id If true, match @a special against the @c id of special tags.
114  * @param special_tags If true, match @a special against the tag name of special tags.
115  */
116  bool has_special_or_ability(const std::string& special, bool special_id=true, bool special_tags=true) const;
117 
118  // In unit_types.cpp:
119 
120  bool matches_filter(const config& filter) const;
121  bool apply_modification(const config& cfg);
122  bool describe_modification(const config& cfg,std::string* description);
123 
124  int movement_used() const { return movement_used_; }
125  void set_movement_used(int value) { movement_used_ = value; }
126  int attacks_used() const { return attacks_used_; }
127  void set_attacks_used(int value) { attacks_used_ = value; }
128 
129  void write(config& cfg) const;
130  inline config to_config() const { config c; write(c); return c; }
131 
132  void add_formula_context(wfl::map_formula_callable&) const;
133 private:
134  // In unit_abilities.cpp:
135 
136  // Configured as a bit field, in case that is useful.
137  enum AFFECTS { AFFECT_SELF=1, AFFECT_OTHER=2, AFFECT_EITHER=3 };
138  /**
139  * Filter a list of abilities or weapon specials, removing any entries that are overridden by
140  * the overwrite_specials attributes of a second list.
141  *
142  * @param ability The special ability type who is being checked.
143  * @param input list to check, a filtered copy of this list is returned by the function.
144  * @param overwriters list that may have overwrite_specials attributes.
145  * @param filter_self name of [filter_"self/student"] if is abilities or specials who are checked.
146  * @param is_special if true, input contains weapon specials; if false, it contains abilities.
147  */
148  unit_ability_list overwrite_special_checking(const std::string& ability, unit_ability_list input, unit_ability_list overwriters, const std::string& filter_self, bool is_special) const;
149  /** check_self_abilities : return an boolean value for checking of activities of abilities used like weapon
150  * @return True if the special @a special is active.
151  * @param cfg the config to one special ability checked.
152  * @param special The special ability type who is being checked.
153  */
154  bool check_self_abilities(const config& cfg, const std::string& special) const;
155  /** check_adj_abilities : return an boolean value for checking of activities of abilities used like weapon
156  * @return True if the special @a special is active.
157  * @param cfg the config to one special ability checked.
158  * @param special The special ability type who is being checked.
159  * @param dir direction to research a unit adjacent to self_.
160  * @param from unit adjacent to self_ is checked.
161  */
162  bool check_adj_abilities(const config& cfg, const std::string& special, int dir, const unit& from) const;
163  bool special_active(const config& special, AFFECTS whom, const std::string& tag_name,
164  const std::string& filter_self ="filter_self") const;
165 
166 /** weapon_specials_impl_self and weapon_specials_impl_adj : check if special name can be added.
167  * @param[in,out] temp_string the string modified and returned
168  * @param[in] self the unit checked.
169  * @param[in] self_attack the attack used by unit checked in this function.
170  * @param[in] other_attack the attack used by opponent to unit checked.
171  * @param[in] self_loc location of the unit checked.
172  * @param[in] whom determine if unit affected or not by special ability.
173  * @param[in,out] checking_name the reference for checking if a name is already added
174  * @param[in] checking_tags the reference for checking if special ability type can be used
175  * @param[in] leader_bool If true, [leadership] abilities are checked.
176  */
177  static void weapon_specials_impl_self(
178  std::string& temp_string,
179  unit_const_ptr self,
180  const_attack_ptr self_attack,
181  const_attack_ptr other_attack,
182  const map_location& self_loc,
183  AFFECTS whom,
184  std::set<std::string>& checking_name,
185  const std::set<std::string>& checking_tags={},
186  bool leader_bool=false
187  );
188 
189  static void weapon_specials_impl_adj(
190  std::string& temp_string,
191  unit_const_ptr self,
192  const_attack_ptr self_attack,
193  const_attack_ptr other_attack,
194  const map_location& self_loc,
195  AFFECTS whom,
196  std::set<std::string>& checking_name,
197  const std::set<std::string>& checking_tags={},
198  const std::string& affect_adjacents="",
199  bool leader_bool=false
200  );
201  /** check_self_abilities_impl : return an boolean value for checking of activities of abilities used like weapon
202  * @return True if the special @a tag_name is active.
203  * @param self_attack the attack used by unit checked in this function.
204  * @param other_attack the attack used by opponent to unit checked.
205  * @param special the config to one special ability checked.
206  * @param u the unit checked.
207  * @param loc location of the unit checked.
208  * @param whom determine if unit affected or not by special ability.
209  * @param tag_name The special ability type who is being checked.
210  * @param leader_bool If true, [leadership] abilities are checked.
211  */
212  static bool check_self_abilities_impl(
213  const_attack_ptr self_attack,
214  const_attack_ptr other_attack,
215  const config& special,
216  unit_const_ptr u,
217  const map_location& loc,
218  AFFECTS whom,
219  const std::string& tag_name,
220  bool leader_bool=false
221  );
222 
223 
224  /** check_adj_abilities_impl : return an boolean value for checking of activities of abilities used like weapon in unit adjacent to fighter
225  * @return True if the special @a tag_name is active.
226  * @param self_attack the attack used by unit who fight.
227  * @param other_attack the attack used by opponent.
228  * @param special the config to one special ability checked.
229  * @param u the unit who is or not affected by an abilities owned by @a from.
230  * @param from unit adjacent to @a u is checked.
231  * @param dir direction to research a unit adjacent to @a u.
232  * @param loc location of the unit checked.
233  * @param whom determine if unit affected or not by special ability.
234  * @param tag_name The special ability type who is being checked.
235  * @param leader_bool If true, [leadership] abilities are checked.
236  */
237  static bool check_adj_abilities_impl(
238  const_attack_ptr self_attack,
239  const_attack_ptr other_attack,
240  const config& special,
241  unit_const_ptr u,
242  const unit& from,
243  int dir,
244  const map_location& loc,
245  AFFECTS whom,
246  const std::string& tag_name,
247  bool leader_bool=false
248  );
249 
250  static bool special_active_impl(
251  const_attack_ptr self_attack,
252  const_attack_ptr other_attack,
253  const config& special,
254  AFFECTS whom,
255  const std::string& tag_name,
256  const std::string& filter_self ="filter_self"
257  );
258 
259  // Used via specials_context() to control which specials are
260  // considered active.
261  friend class specials_context_t;
262  mutable map_location self_loc_, other_loc_;
265  mutable bool is_attacker_;
267  mutable bool is_for_listing_ = false;
268 public:
270  std::shared_ptr<const attack_type> parent;
271  friend class attack_type;
272  /** Initialize weapon specials context for listing */
273  explicit specials_context_t(const attack_type& weapon, bool attacking);
274  /** Initialize weapon specials context for a unit type */
275  specials_context_t(const attack_type& weapon, const unit_type& self_type, const map_location& loc, bool attacking = true);
276  /** Initialize weapon specials context for a single unit */
277  specials_context_t(const attack_type& weapon, const_attack_ptr other_weapon,
278  unit_const_ptr self, unit_const_ptr other,
279  const map_location& self_loc, const map_location& other_loc,
280  bool attacking);
281  /** Initialize weapon specials context for a pair of units */
282  specials_context_t(const attack_type& weapon, unit_const_ptr self, const map_location& loc, bool attacking);
283  specials_context_t(const specials_context_t&) = delete;
284  bool was_moved = false;
285  public:
286  // Destructor at least needs to be public for all this to work.
289  };
290  // Set up a specials context.
291  // Usage: auto ctx = weapon.specials_context(...);
293  const map_location& unit_loc, const map_location& other_loc,
294  bool attacking, const_attack_ptr other_attack) const {
295  return specials_context_t(*this, other_attack, self, other, unit_loc, other_loc, attacking);
296  }
297  specials_context_t specials_context(unit_const_ptr self, const map_location& loc, bool attacking = true) const {
298  return specials_context_t(*this, self, loc, attacking);
299  }
300  specials_context_t specials_context(const unit_type& self_type, const map_location& loc, bool attacking = true) const {
301  return specials_context_t(*this, self_type, loc, attacking);
302  }
303  specials_context_t specials_context_for_listing(bool attacking = true) const {
304  return specials_context_t(*this, attacking);
305  }
306  void set_changed(bool value)
307  {
308  changed_ = value;
309  }
310  bool get_changed() const
311  {
312  return changed_;
313  }
314 private:
315 
317  std::string id_;
318  std::string type_;
319  std::string icon_;
320  std::string range_;
322  int damage_;
326 
330  int parry_;
332  bool changed_;
333 };
334 
335 using attack_list = std::vector<attack_ptr>;
336 using attack_itors = boost::iterator_range<boost::indirect_iterator<attack_list::iterator>>;
337 using const_attack_itors = boost::iterator_range<boost::indirect_iterator<attack_list::const_iterator>>;
338 
340  return boost::make_iterator_range(boost::make_indirect_iterator(atks.begin()), boost::make_indirect_iterator(atks.end()));
341 }
342 
344  return boost::make_iterator_range(boost::make_indirect_iterator(atks.begin()), boost::make_indirect_iterator(atks.end()));
345 }
std::vector< attack_ptr > attack_list
std::string icon_
const std::string & id() const
Definition: attack_type.hpp:44
std::string type_
This class represents a single unit of a specific type.
Definition: unit.hpp:133
boost::iterator_range< boost::indirect_iterator< attack_list::iterator > > attack_itors
int max_range() const
Definition: attack_type.hpp:49
void set_num_attacks(int value)
Definition: attack_type.hpp:67
int parry() const
Definition: attack_type.hpp:52
unit_const_ptr other_
const std::string & type() const
Definition: attack_type.hpp:45
attack_itors make_attack_itors(attack_list &atks)
Definitions for the interface to Wesnoth Markup Language (WML).
void set_changed(bool value)
int num_attacks() const
Definition: attack_type.hpp:54
A single unit type that the player may recruit.
Definition: types.hpp:45
double defense_weight_
void set_name(const t_string &value)
Definition: attack_type.hpp:59
std::shared_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:27
int min_range() const
Definition: attack_type.hpp:48
void write(std::ostream &out, const configr_of &cfg, unsigned int level)
Definition: parser.cpp:764
int movement_used() const
double attack_weight_
const t_string & name() const
Definition: attack_type.hpp:43
std::string range_
void set_attacks_used(int value)
specials_context_t specials_context(const unit_type &self_type, const map_location &loc, bool attacking=true) const
const std::string & range() const
Definition: attack_type.hpp:47
const std::string & icon() const
Definition: attack_type.hpp:46
bool get_changed() const
config specials_
void set_defense_weight(double value)
Definition: attack_type.hpp:69
void set_specials(config value)
Definition: attack_type.hpp:70
t_string description_
Encapsulates the map of the game.
Definition: location.hpp:38
specials_context_t specials_context(unit_const_ptr self, const map_location &loc, bool attacking=true) const
void set_damage(int value)
Definition: attack_type.hpp:66
int damage() const
Definition: attack_type.hpp:53
int accuracy() const
Definition: attack_type.hpp:51
const config & specials() const
Definition: attack_type.hpp:57
double attack_weight() const
Definition: attack_type.hpp:55
unit_const_ptr self_
double defense_weight() const
Definition: attack_type.hpp:56
friend class specials_context_t
int attacks_used() const
void set_range(const std::string &value)
Definition: attack_type.hpp:63
void set_parry(int value)
Definition: attack_type.hpp:65
std::string id_
Definition: contexts.hpp:44
const_attack_ptr other_attack_
void set_icon(const std::string &value)
Definition: attack_type.hpp:62
void set_id(const std::string &value)
Definition: attack_type.hpp:60
specials_context_t specials_context_for_listing(bool attacking=true) const
config to_config() const
specials_context_t specials_context(unit_const_ptr self, unit_const_ptr other, const map_location &unit_loc, const map_location &other_loc, bool attacking, const_attack_ptr other_attack) const
boost::iterator_range< boost::indirect_iterator< attack_list::const_iterator > > const_attack_itors
void set_movement_used(int value)
std::shared_ptr< const attack_type > parent
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
mock_char c
std::shared_ptr< const attack_type > const_attack_ptr
Definition: ptr.hpp:34
void set_accuracy(int value)
Definition: attack_type.hpp:64
map_location self_loc_
void set_attack_weight(double value)
Definition: attack_type.hpp:68
void set_type(const std::string &value)
Definition: attack_type.hpp:61