forked from cataclysmbnteam/Cataclysm-BN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
martialarts.h
329 lines (251 loc) · 11.3 KB
/
martialarts.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
#pragma once
#ifndef CATA_SRC_MARTIALARTS_H
#define CATA_SRC_MARTIALARTS_H
#include <cstddef>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "bonuses.h"
#include "calendar.h"
#include "input.h"
#include "translations.h"
#include "type_id.h"
#include "ui.h"
enum damage_type : int;
class Character;
class JsonObject;
class effect;
class item;
struct itype;
class weapon_category
{
public:
static void load_weapon_categories( const JsonObject &jo, const std::string &src );
static void reset();
void load( const JsonObject &jo, const std::string &src );
static const std::vector<weapon_category> &get_all();
const weapon_category_id &getId() const {
return id;
}
const translation &name() const {
return name_;
}
private:
friend class generic_factory<weapon_category>;
weapon_category_id id;
bool was_loaded = false;
translation name_;
};
matype_id martial_art_learned_from( const itype & );
struct ma_requirements {
bool was_loaded = false;
bool unarmed_allowed; // does this bonus work when unarmed?
bool melee_allowed; // what about with a melee weapon?
bool unarmed_weapons_allowed; // If unarmed, what about unarmed weapons?
bool strictly_unarmed; // Ignore force_unarmed?
bool wall_adjacent; // Does it only work near a wall?
/** Minimum amount of given skill to trigger this bonus */
std::vector<std::pair<skill_id, int>> min_skill;
/** Minimum amount of given damage type on the weapon
* Note: DT_FIRE currently won't work, not even on flaming weapons!
*/
std::vector<std::pair<damage_type, int>> min_damage;
std::set<mabuff_id> req_buffs; // other buffs required to trigger this bonus
std::set<std::string> req_flags; // any item flags required for this technique
ma_requirements() {
unarmed_allowed = false;
melee_allowed = false;
unarmed_weapons_allowed = true;
strictly_unarmed = false;
wall_adjacent = false;
}
std::string get_description( bool buff = false ) const;
bool is_valid_character( const Character &u ) const;
bool is_valid_weapon( const item &i ) const;
void load( const JsonObject &jo, const std::string &src );
};
class ma_technique
{
public:
ma_technique();
void load( const JsonObject &jo, const std::string &src );
matec_id id;
bool was_loaded = false;
std::string name;
std::string description;
std::string get_description() const;
std::string goal; // the melee goal this achieves
// given a Character's state, does this bonus apply to him?
bool is_valid_character( const Character &u ) const;
std::set<std::string> flags;
// message to be displayed when Character or npc uses the technique
std::string avatar_message;
std::string npc_message;
bool defensive = false;
bool side_switch = false; // moves the target behind user
bool dummy = false;
bool crit_tec = false;
bool crit_ok = false;
ma_requirements reqs;
int down_dur = 0;
int stun_dur = 0;
int knockback_dist = 0;
float knockback_spread = 0.0f; // adding randomness to knockback, like tec_throw
bool powerful_knockback = false;
std::string aoe; // corresponds to an aoe shape, defaults to just the target
bool knockback_follow = false; // Character follows the knocked-back party into their former tile
// offensive
bool disarms = false; // like tec_disarm
bool take_weapon = false; // disarms and equips weapon if hands are free
bool dodge_counter = false; // counter move activated on a dodge
bool block_counter = false; // counter move activated on a block
bool miss_recovery = false; // allows free recovery from misses, like tec_feint
bool grab_break = false; // allows grab_breaks, like tec_break
int weighting = 0; //how often this technique is used
// conditional
bool downed_target = false; // only works on downed enemies
bool stunned_target = false;// only works on stunned enemies
bool wall_adjacent = false; // only works near a wall
bool human_target = false; // only works on humanoid enemies
/** All kinds of bonuses by types to damage, hit etc. */
bonus_container bonuses;
float damage_bonus( const Character &u, damage_type type ) const;
float damage_multiplier( const Character &u, damage_type type ) const;
float move_cost_multiplier( const Character &u ) const;
float move_cost_penalty( const Character &u ) const;
float armor_penetration( const Character &u, damage_type type ) const;
};
class ma_buff
{
public:
ma_buff();
// utility function so to prevent duplicate buff copies, we use this
// instead of add_disease (since all buffs have the same distype)
void apply_buff( Character &u ) const;
// given a Character's state, does this bonus apply to him?
bool is_valid_character( const Character &u ) const;
// apply static bonuses to a Character
void apply_character( Character &u ) const;
// returns the stat bonus for the on-hit stat (for rolls)
int hit_bonus( const Character &u ) const;
int dodge_bonus( const Character &u ) const;
int speed_bonus( const Character &u ) const;
int block_bonus( const Character &u ) const;
int arpen_bonus( const Character &u, damage_type dt ) const;
// returns the armor bonus for various armor stats (equivalent to armor)
int armor_bonus( const Character &guy, damage_type dt ) const;
// returns the stat bonus for the various damage stats (for rolls)
float damage_bonus( const Character &u, damage_type dt ) const;
// returns damage multipliers for the various damage stats (applied after
// bonuses)
float damage_mult( const Character &u, damage_type dt ) const;
// returns various boolean flags
bool is_throw_immune() const;
bool is_quiet() const;
bool is_stealthy() const;
// The ID of the effect that is used to store this buff
efftype_id get_effect_id() const;
// If the effects represents an ma_buff effect, return the ma_buff, otherwise return null.
static const ma_buff *from_effect( const effect &eff );
mabuff_id id;
bool was_loaded = false;
std::string name;
std::string description;
std::string get_description( bool passive = false ) const;
ma_requirements reqs;
// mapped as buff_id -> min stacks of buff
time_duration buff_duration = 0_turns; // total length this buff lasts
int max_stacks = 0; // total number of stacks this buff can have
int dodges_bonus = 0; // extra dodges, like karate
int blocks_bonus = 0; // extra blocks, like karate
/** All kinds of bonuses by types to damage, hit, armor etc. */
bonus_container bonuses;
bool quiet = false;
bool throw_immune = false; // are we immune to throws/grabs?
bool strictly_melee = false; // can we only use it with weapons?
bool stealthy = false; // do we make less noise when moving?
void load( const JsonObject &jo, const std::string &src );
};
class martialart
{
public:
martialart();
void load( const JsonObject &jo, const std::string &src );
// modifies a Character's "current" stats with various types of bonuses
void apply_static_buffs( Character &u ) const;
void apply_onmove_buffs( Character &u ) const;
void apply_onpause_buffs( Character &u ) const;
void apply_onhit_buffs( Character &u ) const;
void apply_onattack_buffs( Character &u ) const;
void apply_ondodge_buffs( Character &u ) const;
void apply_onblock_buffs( Character &u ) const;
void apply_ongethit_buffs( Character &u ) const;
void apply_onmiss_buffs( Character &u ) const;
void apply_oncrit_buffs( Character &u ) const;
void apply_onkill_buffs( Character &u ) const;
// determines if a technique is valid or not for this style
bool has_technique( const Character &u, const matec_id &tec_id ) const;
// determines if a weapon is valid for this style
bool has_weapon( const itype_id & ) const;
// Is this weapon OK with this art?
bool weapon_valid( const item &it ) const;
// Getter for Character style change message
std::string get_initiate_avatar_message() const;
// Getter for NPC style change message
std::string get_initiate_npc_message() const;
matype_id id;
bool was_loaded = false;
translation name;
translation description;
std::vector<std::string> initiate;
std::vector<std::pair<std::string, int>> autolearn_skills;
skill_id primary_skill;
int learn_difficulty = 0;
int arm_block = 0;
int leg_block = 0;
bool arm_block_with_bio_armor_arms = false;
bool leg_block_with_bio_armor_legs = false;
std::set<matec_id> techniques; // all available techniques
std::set<itype_id> weapons; // all style weapons
std::set<weapon_category_id> weapon_category; // all style weapon categories
bool strictly_unarmed = false; // Punch daggers etc.
bool strictly_melee = false; // Must have a weapon.
bool allow_melee = false; // Can use unarmed or with ANY weapon
bool force_unarmed = false; // Don't use ANY weapon - punch or kick if needed
std::vector<mabuff_id> static_buffs; // all buffs triggered by each condition
std::vector<mabuff_id> onmove_buffs;
std::vector<mabuff_id> onpause_buffs;
std::vector<mabuff_id> onhit_buffs;
std::vector<mabuff_id> onattack_buffs;
std::vector<mabuff_id> ondodge_buffs;
std::vector<mabuff_id> onblock_buffs;
std::vector<mabuff_id> ongethit_buffs;
std::vector<mabuff_id> onmiss_buffs;
std::vector<mabuff_id> oncrit_buffs;
std::vector<mabuff_id> onkill_buffs;
};
class ma_style_callback : public uilist_callback
{
private:
size_t offset;
const std::vector<matype_id> &styles;
public:
ma_style_callback( int style_offset, const std::vector<matype_id> &selectable_styles )
: offset( style_offset )
, styles( selectable_styles )
{}
bool key( const input_context &ctxt, const input_event &event, int entnum, uilist *menu ) override;
~ma_style_callback() override = default;
};
void load_technique( const JsonObject &jo, const std::string &src );
void load_martial_art( const JsonObject &jo, const std::string &src );
void check_martialarts();
void clear_techniques_and_martial_arts();
void finialize_martial_arts();
std::string martialart_difficulty( const matype_id &mstyle );
std::vector<matype_id> all_martialart_types();
std::vector<matype_id> autolearn_martialart_types();
/** Returns true if the character can learn the entered martial art */
bool can_autolearn_martial_art( const Character &who, const matype_id &ma_id );
#endif // CATA_SRC_MARTIALARTS_H