The Battle for Wesnoth  1.15.12+dev
attack_type.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 "map/location.hpp"
18 #include "tstring.hpp"
19 #include "config.hpp"
20 #include <string>
21 #include <vector>
22 #include <cassert>
23 
24 #include <boost/iterator/indirect_iterator.hpp>
25 #include <boost/range/iterator_range.hpp>
26 #include <boost/dynamic_bitset_fwd.hpp>
27 
28 #include "units/ptr.hpp" // for attack_ptr
29 
30 class unit_ability_list;
31 class unit_type;
32 namespace wfl {
33  class map_formula_callable;
34 }
35 //the 'attack type' is the type of attack, how many times it strikes,
36 //and how much damage it does.
37 class attack_type : public std::enable_shared_from_this<attack_type>
38 {
39 public:
40 
41  explicit attack_type(const config& cfg);
42  const t_string& name() const { return description_; }
43  const std::string& id() const { return id_; }
44  const std::string& type() const { return type_; }
45  const std::string& icon() const { return icon_; }
46  const std::string& range() const { return range_; }
47  int min_range() const { return min_range_; }
48  int max_range() const { return max_range_; }
49  std::string accuracy_parry_description() const;
50  int accuracy() const { return accuracy_; }
51  int parry() const { return parry_; }
52  int damage() const { return damage_; }
53  int num_attacks() const { return num_attacks_; }
54  double attack_weight() const { return attack_weight_; }
55  double defense_weight() const { return defense_weight_; }
56  const config &specials() const { return specials_; }
57 
58  void set_name(const t_string& value) { description_ = value; set_changed(true); }
59  void set_id(const std::string& value) { id_ = value; set_changed(true); }
60  void set_type(const std::string& value) { type_ = value; set_changed(true); }
61  void set_icon(const std::string& value) { icon_ = value; set_changed(true); }
62  void set_range(const std::string& value) { range_ = value; set_changed(true); }
63  void set_accuracy(int value) { accuracy_ = value; set_changed(true); }
64  void set_parry(int value) { parry_ = value; set_changed(true); }
65  void set_damage(int value) { damage_ = value; set_changed(true); }
66  void set_num_attacks(int value) { num_attacks_ = value; set_changed(true); }
67  void set_attack_weight(double value) { attack_weight_ = value; set_changed(true); }
68  void set_defense_weight(double value) { defense_weight_ = value; set_changed(true); }
69  void set_specials(config value) { specials_ = value; set_changed(true); }
70 
71 
72  // In unit_abilities.cpp:
73 
74  /**
75  * @return True iff the special @a special is active.
76  * @param special The special being checked.
77  * @param simple_check If true, check whether the unit has the special. Else, check whether the special is currently active.
78  * @param special_id If true, match @a special against the @c id of special tags.
79  * @param special_tags If true, match @a special against the tag name of special tags.
80  */
81  bool has_special(const std::string& special, bool simple_check=false, bool special_id=true, bool special_tags=true) const;
82  unit_ability_list get_specials(const std::string& special) const;
83  std::vector<std::pair<t_string, t_string>> special_tooltips(boost::dynamic_bitset<>* active_list = nullptr) const;
84  std::string weapon_specials(bool only_active=false, bool is_backstab=false) const;
85 
86  /** Calculates the number of attacks this weapon has, considering specials. */
87  void modified_attacks(bool is_backstab, unsigned & min_attacks,
88  unsigned & max_attacks) const;
89  /** Returns the damage per attack of this weapon, considering specials. */
90  int modified_damage(bool is_backstab) const;
91  /** Returns list for weapon like abilities for each ability type. */
92  unit_ability_list get_weapon_ability(const std::string& ability) const;
93  /** Returns list who contains get_weapon_ability and get_specials list for each ability type */
94  unit_ability_list get_specials_and_abilities(const std::string& special) const;
95  /** used for abilities used like weapon
96  * @return True if the ability @a special is active.
97  * @param special The special being checked.
98  * @param special_id If true, match @a special against the @c id of special tags.
99  * @param special_tags If true, match @a special against the tag name of special tags.
100  */
101  bool has_weapon_ability(const std::string& special, bool special_id=true, bool special_tags=true) const;
102  /** used for abilities used like weapon and true specials
103  * @return True if the ability @a special is active.
104  * @param special The special being checked.
105  * @param special_id If true, match @a special against the @c id of special tags.
106  * @param special_tags If true, match @a special against the tag name of special tags.
107  */
108  bool has_special_or_ability(const std::string& special, bool special_id=true, bool special_tags=true) const;
109 
110  // In unit_types.cpp:
111 
112  bool matches_filter(const config& filter) const;
113  bool apply_modification(const config& cfg);
114  bool describe_modification(const config& cfg,std::string* description);
115 
116  int movement_used() const { return movement_used_; }
117  void set_movement_used(int value) { movement_used_ = value; }
118 
119  void write(config& cfg) const;
120  inline config to_config() const { config c; write(c); return c; }
121 
122  void add_formula_context(wfl::map_formula_callable&) const;
123 private:
124  // In unit_abilities.cpp:
125 
126  // Configured as a bit field, in case that is useful.
127  enum AFFECTS { AFFECT_SELF=1, AFFECT_OTHER=2, AFFECT_EITHER=3 };
128  /** overwrite_special_checking : return an unit_ability_list list after checking presence or not of overwrite_specials
129  * @param ability The special ability type who is being checked.
130  * @param temp_list the list checked and returned.
131  * @param abil_list list checked for verify presence of overwrite_specials .
132  * @param filter_self name of [filter_"self/student"] if is abilities or specials who are checked
133  */
134  unit_ability_list overwrite_special_checking(const std::string& ability, unit_ability_list temp_list, const unit_ability_list& abil_list, const std::string& filter_self = "filter_self") const;
135  /** check_self_abilities : return an boolean value for checking of activities of abilities used like weapon
136  * @return True if the special @a special is active.
137  * @param cfg the config to one special ability checked.
138  * @param special The special ability type who is being checked.
139  */
140  bool check_self_abilities(const config& cfg, const std::string& special) const;
141  /** check_adj_abilities : return an boolean value for checking of activities of abilities used like weapon
142  * @return True if the special @a special is active.
143  * @param cfg the config to one special ability checked.
144  * @param special The special ability type who is being checked.
145  * @param dir direction to research a unit adjacent to self_.
146  * @param from unit adjacent to self_ is checked.
147  */
148  bool check_adj_abilities(const config& cfg, const std::string& special, int dir, const unit& from) const;
149  bool special_active(const config& special, AFFECTS whom, const std::string& tag_name,
150  bool include_backstab=true, const std::string& filter_self ="filter_self") const;
151 
152  /** check_self_abilities_impl : return an boolean value for checking of activities of abilities used like weapon
153  * @return True if the special @a tag_name is active.
154  * @param self_attack the attack used by unit checked in this function.
155  * @param other_attack the attack used by opponent to unit checked.
156  * @param special the config to one special ability checked.
157  * @param u the unit checked.
158  * @param loc location of the unit checked.
159  * @param whom determine if unit affected or not by special ability.
160  * @param tag_name The special ability type who is being checked.
161  * @param leader_bool If true, [leadership] abilities are checked.
162  */
163  static bool check_self_abilities_impl(
164  const_attack_ptr self_attack,
165  const_attack_ptr other_attack,
166  const config& special,
167  unit_const_ptr u,
168  const map_location& loc,
169  AFFECTS whom,
170  const std::string& tag_name,
171  bool leader_bool=false
172  );
173 
174 
175  /** check_adj_abilities_impl : return an boolean value for checking of activities of abilities used like weapon in unit adjacent to fighter
176  * @return True if the special @a tag_name is active.
177  * @param self_attack the attack used by unit who fight.
178  * @param other_attack the attack used by opponent.
179  * @param special the config to one special ability checked.
180  * @param u the unit who is or not affected by an abilities owned by @a from.
181  * @param from unit adjacent to @a u is checked.
182  * @param dir direction to research a unit adjacent to @a u.
183  * @param loc location of the unit checked.
184  * @param whom determine if unit affected or not by special ability.
185  * @param tag_name The special ability type who is being checked.
186  * @param leader_bool If true, [leadership] abilities are checked.
187  */
188  static bool check_adj_abilities_impl(
189  const_attack_ptr self_attack,
190  const_attack_ptr other_attack,
191  const config& special,
192  unit_const_ptr u,
193  const unit& from,
194  int dir,
195  const map_location& loc,
196  AFFECTS whom,
197  const std::string& tag_name,
198  bool leader_bool=false
199  );
200 
201  static bool special_active_impl(
202  const_attack_ptr self_attack,
203  const_attack_ptr other_attack,
204  const config& special,
205  AFFECTS whom,
206  const std::string& tag_name,
207  bool include_backstab=true,
208  const std::string& filter_self ="filter_self"
209  );
210 
211  // Used via specials_context() to control which specials are
212  // considered active.
213  friend class specials_context_t;
214  mutable map_location self_loc_, other_loc_;
217  mutable bool is_attacker_;
219  mutable bool is_for_listing_ = false;
220 public:
222  std::shared_ptr<const attack_type> parent;
223  friend class attack_type;
224  /** Initialize weapon specials context for listing */
225  explicit specials_context_t(const attack_type& weapon, bool attacking);
226  /** Initialize weapon specials context for a unit type */
227  specials_context_t(const attack_type& weapon, const unit_type& self_type, const map_location& loc, bool attacking = true);
228  /** Initialize weapon specials context for a single unit */
229  specials_context_t(const attack_type& weapon, const_attack_ptr other_weapon,
230  unit_const_ptr self, unit_const_ptr other,
231  const map_location& self_loc, const map_location& other_loc,
232  bool attacking);
233  /** Initialize weapon specials context for a pair of units */
234  specials_context_t(const attack_type& weapon, unit_const_ptr self, const map_location& loc, bool attacking);
235  specials_context_t(const specials_context_t&) = delete;
236  bool was_moved = false;
237  public:
238  // Destructor at least needs to be public for all this to work.
241  };
242  // Set up a specials context.
243  // Usage: auto ctx = weapon.specials_context(...);
245  const map_location& unit_loc, const map_location& other_loc,
246  bool attacking, const_attack_ptr other_attack) const {
247  return specials_context_t(*this, other_attack, self, other, unit_loc, other_loc, attacking);
248  }
249  specials_context_t specials_context(unit_const_ptr self, const map_location& loc, bool attacking = true) const {
250  return specials_context_t(*this, self, loc, attacking);
251  }
252  specials_context_t specials_context(const unit_type& self_type, const map_location& loc, bool attacking = true) const {
253  return specials_context_t(*this, self_type, loc, attacking);
254  }
255  specials_context_t specials_context_for_listing(bool attacking = true) const {
256  return specials_context_t(*this, attacking);
257  }
258  void set_changed(bool value)
259  {
260  changed_ = value;
261  }
262  bool get_changed() const
263  {
264  return changed_;
265  }
266 private:
267 
269  std::string id_;
270  std::string type_;
271  std::string icon_;
272  std::string range_;
274  int damage_;
278 
281  int parry_;
283  bool changed_;
284 };
285 
286 using attack_list = std::vector<attack_ptr>;
287 using attack_itors = boost::iterator_range<boost::indirect_iterator<attack_list::iterator>>;
288 using const_attack_itors = boost::iterator_range<boost::indirect_iterator<attack_list::const_iterator>>;
289 
291  return boost::make_iterator_range(boost::make_indirect_iterator(atks.begin()), boost::make_indirect_iterator(atks.end()));
292 }
293 
295  return boost::make_iterator_range(boost::make_indirect_iterator(atks.begin()), boost::make_indirect_iterator(atks.end()));
296 }
std::vector< attack_ptr > attack_list
std::string icon_
const std::string & id() const
Definition: attack_type.hpp:43
std::string type_
This class represents a single unit of a specific type.
Definition: unit.hpp:120
boost::iterator_range< boost::indirect_iterator< attack_list::iterator > > attack_itors
int max_range() const
Definition: attack_type.hpp:48
void set_num_attacks(int value)
Definition: attack_type.hpp:66
int parry() const
Definition: attack_type.hpp:51
unit_const_ptr other_
const std::string & type() const
Definition: attack_type.hpp:44
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:53
A single unit type that the player may recruit.
Definition: types.hpp:44
double defense_weight_
void set_name(const t_string &value)
Definition: attack_type.hpp:58
std::shared_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:26
int min_range() const
Definition: attack_type.hpp:47
void write(std::ostream &out, const configr_of &cfg, unsigned int level)
Definition: parser.cpp:763
int movement_used() const
double attack_weight_
const t_string & name() const
Definition: attack_type.hpp:42
std::string range_
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:46
const std::string & icon() const
Definition: attack_type.hpp:45
bool get_changed() const
config specials_
void set_defense_weight(double value)
Definition: attack_type.hpp:68
void set_specials(config value)
Definition: attack_type.hpp:69
t_string description_
Encapsulates the map of the game.
Definition: location.hpp:37
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:65
int damage() const
Definition: attack_type.hpp:52
int accuracy() const
Definition: attack_type.hpp:50
const config & specials() const
Definition: attack_type.hpp:56
double attack_weight() const
Definition: attack_type.hpp:54
unit_const_ptr self_
double defense_weight() const
Definition: attack_type.hpp:55
friend class specials_context_t
void set_range(const std::string &value)
Definition: attack_type.hpp:62
void set_parry(int value)
Definition: attack_type.hpp:64
std::string id_
Definition: contexts.hpp:43
const_attack_ptr other_attack_
void set_icon(const std::string &value)
Definition: attack_type.hpp:61
void set_id(const std::string &value)
Definition: attack_type.hpp:59
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:59
mock_char c
std::shared_ptr< const attack_type > const_attack_ptr
Definition: ptr.hpp:33
void set_accuracy(int value)
Definition: attack_type.hpp:63
map_location self_loc_
void set_attack_weight(double value)
Definition: attack_type.hpp:67
void set_type(const std::string &value)
Definition: attack_type.hpp:60