forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheffect.h
398 lines (321 loc) · 16.7 KB
/
effect.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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
#pragma once
#ifndef CATA_SRC_EFFECT_H
#define CATA_SRC_EFFECT_H
#include <iosfwd>
#include <map>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>
#include "calendar.h"
#include "color.h"
#include "effect_source.h"
#include "hash_utils.h"
#include "translations.h"
#include "type_id.h"
class effect_type;
enum game_message_type : int;
enum class event_type : int;
class JsonObject;
class JsonOut;
/** Handles the large variety of weed messages. */
void weed_msg( Character &p );
enum effect_rating {
e_good, // The effect is good for the one who has it.
e_neutral, // There is no effect or the effect is very nominal. This is the default.
e_bad, // The effect is bad for the one who has it.
e_mixed // The effect has good and bad parts to the one who has it.
};
/** @relates string_id */
template<>
const effect_type &string_id<effect_type>::obj() const;
struct vitamin_rate_effect {
std::vector<std::pair<int, int>> rate;
std::vector<float> absorb_mult;
std::vector<time_duration> tick;
std::vector<std::pair<int, int>> red_rate;
std::vector<float> red_absorb_mult;
std::vector<time_duration> red_tick;
vitamin_id vitamin;
void load( const JsonObject &jo );
void deserialize( const JsonObject &jo );
};
struct vitamin_applied_effect {
cata::optional<std::pair<int, int>> rate = cata::nullopt;
cata::optional<time_duration> tick = cata::nullopt;
cata::optional<float> absorb_mult = cata::nullopt;
vitamin_id vitamin;
};
class effect_type
{
friend void load_effect_type( const JsonObject &jo );
friend class effect;
public:
enum class memorial_gender : int {
male,
female,
};
effect_type() = default;
efftype_id id;
/** Returns if an effect is good or bad for message display. */
effect_rating get_rating() const;
/** Returns true if there is a listed name in the JSON entry for each intensity from
* 1 to max_intensity. */
bool use_name_ints() const;
/** Returns true if there is a listed description in the JSON entry for each intensity
* from 1 to max_intensity with the matching reduced value. */
bool use_desc_ints( bool reduced ) const;
/** Returns the appropriate game_message_type when a new effect is obtained. This is equal to
* an effect's "rating" value. */
game_message_type gain_game_message_type() const;
/** Returns the appropriate game_message_type when an effect is lost. This is opposite to
* an effect's "rating" value. */
game_message_type lose_game_message_type() const;
/** Returns the message displayed when a new effect is obtained. */
std::string get_apply_message() const;
/** Returns the memorial log added when a new effect is obtained. */
std::string get_apply_memorial_log( memorial_gender gender ) const;
/** Returns the message displayed when an effect is removed. */
std::string get_remove_message() const;
/** Returns the memorial log added when an effect is removed. */
std::string get_remove_memorial_log( memorial_gender gender ) const;
/** Returns the effect's description displayed when character conducts blood analysis. */
std::string get_blood_analysis_description() const;
/** Returns true if an effect will only target main body parts (i.e., those with HP). */
bool get_main_parts() const;
bool is_show_in_info() const;
/** Loading helper functions */
bool load_mod_data( const JsonObject &jo, const std::string &member );
bool load_miss_msgs( const JsonObject &jo, const std::string &member );
bool load_decay_msgs( const JsonObject &jo, const std::string &member );
/** Verifies data is accurate */
static void check_consistency();
void verify() const;
/** Registers the effect in the global map */
static void register_ma_buff_effect( const effect_type &eff );
/** Check if the effect type has the specified flag */
bool has_flag( const flag_id &flag ) const;
const time_duration &intensity_duration() const {
return int_dur_factor;
}
protected:
int max_intensity = 0;
int max_effective_intensity = 0;
time_duration max_duration = 365_days;
int dur_add_perc = 0;
int int_add_val = 0;
int int_decay_step = 0;
int int_decay_tick = 0 ;
time_duration int_dur_factor = 0_turns;
bool int_decay_remove = false;
std::set<flag_id> flags;
bool main_parts_only = false;
// Determines if effect should be shown in description.
bool show_in_info = false;
// Determines if effect should show intensity value next to its name in EFFECTS tab.
bool show_intensity = false;
std::vector<trait_id> resist_traits;
std::vector<efftype_id> resist_effects;
std::vector<efftype_id> removes_effects;
std::vector<efftype_id> blocks_effects;
std::vector<std::pair<translation, int>> miss_msgs;
bool pain_sizing = false;
bool hurt_sizing = false;
bool harmful_cough = false;
// TODO: Once addictions are JSON-ized it should be trivial to convert this to a
// "generic" addiction reduces value
bool pkill_addict_reduces = false;
// This flag is hard-coded for specific IDs now
// It needs to be set for monster::move_effects
bool impairs_movement = false;
std::vector<translation> name;
translation speed_mod_name;
std::vector<translation> desc;
std::vector<translation> reduced_desc;
bool part_descs = false;
std::vector<std::pair<translation, game_message_type>> decay_msgs;
effect_rating rating = effect_rating::e_neutral;
translation apply_message;
std::string apply_memorial_log;
translation remove_message;
std::string remove_memorial_log;
translation blood_analysis_description;
translation death_msg;
cata::optional<event_type> death_event;
/** Key tuple order is:("base_mods"/"scaling_mods", reduced: bool, type of mod: "STR", desired argument: "tick") */
std::unordered_map <
std::tuple<std::string, bool, std::string, std::string>, double, cata::tuple_hash > mod_data;
std::vector<vitamin_rate_effect> vitamin_data;
std::vector<std::pair<int, int>> kill_chance;
std::vector<std::pair<int, int>> red_kill_chance;
};
class effect;
// Inheritance here allows forward declaration of the map in class Creature.
// Storing body_part as an int_id to make things easier for hash and JSON
class effects_map : public
std::map<efftype_id, std::map<bodypart_id, effect>>
{
};
class effect
{
public:
effect() : eff_type( nullptr ), duration( 0_turns ), bp( bodypart_str_id::NULL_ID() ),
permanent( false ), intensity( 1 ), start_time( calendar::turn_zero ),
source( effect_source::empty() ) {
}
explicit effect( const effect_type *peff_type ) : eff_type( peff_type ), duration( 0_turns ),
bp( bodypart_str_id::NULL_ID() ),
permanent( false ), intensity( 1 ), start_time( calendar::turn_zero ),
source( effect_source::empty() ) {
}
effect( const effect_source &source, const effect_type *peff_type, const time_duration &dur,
bodypart_str_id part, bool perm, int nintensity, const time_point &nstart_time ) :
eff_type( peff_type ), duration( dur ), bp( part ),
permanent( perm ), intensity( nintensity ), start_time( nstart_time ),
source( source ) {
}
effect( const effect & ) = default;
effect &operator=( const effect & ) = default;
/** Returns true if the effect is the result of `effect()`, ie. an effect that doesn't exist. */
bool is_null() const;
/** Dummy used for "reference to effect()" */
static effect null_effect;
/** Returns the name displayed in the player status window. */
std::string disp_name() const;
/** Returns the description displayed in the player status window. */
std::string disp_desc( bool reduced = false ) const;
/** Returns the short description as set in json. */
std::string disp_short_desc( bool reduced = false ) const;
/** Returns true if a description will be formatted as "Your" + body_part + description. */
bool use_part_descs() const;
/** Returns the effect's matching effect_type. */
const effect_type *get_effect_type() const;
/** Decays effect durations, pushing their id and bp's back to rem_ids and rem_bps for removal later
* if their duration is <= 0. This is called in the middle of a loop through all effects, which is
* why we aren't allowed to remove the effects here. */
void decay( std::vector<efftype_id> &rem_ids, std::vector<bodypart_id> &rem_bps,
const time_point &time, bool player, const effects_map &eff_map = effects_map() );
/** Returns the remaining duration of an effect. */
time_duration get_duration() const;
/** Returns the maximum duration of an effect. */
time_duration get_max_duration() const;
/** Sets the duration, capping at max duration. */
void set_duration( const time_duration &dur, bool alert = false );
/** Mods the duration, capping at max_duration. */
void mod_duration( const time_duration &dur, bool alert = false );
/** Multiplies the duration, capping at max_duration. */
void mult_duration( double dur, bool alert = false );
std::vector<vitamin_applied_effect> vit_effects( bool reduced ) const;
/** Returns the turn the effect was applied. */
time_point get_start_time() const;
/** Returns the targeted body_part of the effect. This is bp_null for untargeted effects. */
bodypart_id get_bp() const;
/** Sets the targeted body_part of an effect. */
void set_bp( const bodypart_str_id &part );
/** Returns true if an effect is permanent, i.e. it's duration does not decrease over time. */
bool is_permanent() const;
/** Makes an effect permanent. Note: This pauses the duration, but does not otherwise change it. */
void pause_effect();
/** Makes an effect not permanent. Note: This un-pauses the duration, but does not otherwise change it. */
void unpause_effect();
/** Returns the intensity of an effect. */
int get_intensity() const;
/** Returns the maximum intensity of an effect. */
int get_max_intensity() const;
/** Returns the maximum effective intensity of an effect. */
int get_max_effective_intensity() const;
/** Returns the current effect intensity, capped to max_effective_intensity. */
int get_effective_intensity() const;
/**
* Sets intensity of effect capped by range [1..max_intensity]
* @param val Value to set intensity to
* @param alert whether decay messages should be displayed
* @return new intensity of the effect after val subjected to above cap
*/
int set_intensity( int val, bool alert = false );
/**
* Modify intensity of effect capped by range [1..max_intensity]
* @param mod Amount to increase current intensity by
* @param alert whether decay messages should be displayed
* @return new intensity of the effect after modification and capping
*/
int mod_intensity( int mod, bool alert = false );
/** Returns the string id of the resist trait to be used in has_trait("id"). */
const std::vector<trait_id> &get_resist_traits() const;
/** Returns the string id of the resist effect to be used in has_effect("id"). */
const std::vector<efftype_id> &get_resist_effects() const;
/** Returns the string ids of the effects removed by this effect to be used in remove_effect("id"). */
const std::vector<efftype_id> &get_removes_effects() const;
/** Returns the string ids of the effects blocked by this effect to be used in add_effect("id"). */
std::vector<efftype_id> get_blocks_effects() const;
/** Returns the matching modifier type from an effect, used for getting actual effect effects. */
int get_mod( const std::string &arg, bool reduced = false ) const;
/** Returns the average return of get_mod for a modifier type. Used in effect description displays. */
int get_avg_mod( const std::string &arg, bool reduced = false ) const;
/** Returns the amount of a modifier type applied when a new effect is first added. */
int get_amount( const std::string &arg, bool reduced = false ) const;
/** Returns the minimum value of a modifier type that get_mod() and get_amount() will push the player to. */
int get_min_val( const std::string &arg, bool reduced = false ) const;
/** Returns the maximum value of a modifier type that get_mod() and get_amount() will push the player to. */
int get_max_val( const std::string &arg, bool reduced = false ) const;
/** Returns true if the given modifier type's trigger chance is affected by size mutations. */
bool get_sizing( const std::string &arg ) const;
/** Returns the approximate percentage chance of a modifier type activating on any given tick, used for descriptions. */
double get_percentage( const std::string &arg, int val, bool reduced = false ) const;
/** Checks to see if a given modifier type can activate, and performs any rolls required to do so. mod is a direct
* multiplier on the overall chance of a modifier type activating. */
bool activated( const time_point &when, const std::string &arg, int val,
bool reduced = false, double mod = 1 ) const;
/** Check if the effect has the specified flag */
bool has_flag( const flag_id &flag ) const;
bool kill_roll( bool reduced ) const;
std::string get_death_message() const;
event_type death_event() const;
/** Returns the modifier caused by addictions. Currently only handles painkiller addictions. */
double get_addict_mod( const std::string &arg, int addict_level ) const;
/** Returns true if the coughs caused by an effect can harm the player directly. */
bool get_harmful_cough() const;
/** Returns the percentage value by further applications of existing effects' duration is multiplied by. */
int get_dur_add_perc() const;
/** Returns the number of turns it takes for the intensity to fall by 1 or 0 if intensity isn't based on duration. */
time_duration get_int_dur_factor() const;
/** Returns the amount an already existing effect intensity is modified by further applications of the same effect. */
int get_int_add_val() const;
/** Returns the step of intensity decay */
int get_int_decay_step() const;
/** Returns the number of ticks between intensity changes */
int get_int_decay_tick() const;
/** Returns if the effect is not protected from intensity decay-based removal */
bool get_int_decay_remove() const;
/** Returns a vector of the miss message messages and chances for use in add_miss_reason() while the effect is in effect. */
const std::vector<std::pair<translation, int>> &get_miss_msgs() const;
/** Returns the value used for display on the speed modifier window in the player status menu. */
std::string get_speed_name() const;
/** Returns if the effect is supposed to be handed in Creature::movement */
bool impairs_movement() const;
/** Returns the effect's matching effect_type id. */
const efftype_id &get_id() const {
return eff_type->id;
}
const effect_source &get_source() const;
void serialize( JsonOut &json ) const;
void deserialize( const JsonObject &jo );
protected:
const effect_type *eff_type;
time_duration duration;
bodypart_str_id bp;
bool permanent;
int intensity;
time_point start_time;
effect_source source;
};
void load_effect_type( const JsonObject &jo );
void reset_effect_types();
const std::map<efftype_id, effect_type> &get_effect_types();
std::string texitify_base_healing_power( int power );
std::string texitify_healing_power( int power );
std::string texitify_bandage_power( int power );
nc_color colorize_bleeding_intensity( int intensity );
#endif // CATA_SRC_EFFECT_H