forked from flareteam/flare-engine
-
Notifications
You must be signed in to change notification settings - Fork 1
/
PowerManager.h
394 lines (326 loc) · 10.1 KB
/
PowerManager.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
/*
Copyright © 2011-2012 Clint Bellanger
Copyright © 2012 Igor Paliychuk
Copyright © 2012 Stefan Beller
Copyright © 2013 Henrik Andersson
Copyright © 2012-2016 Justin Jacobs
This file is part of FLARE.
FLARE is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
FLARE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
FLARE. If not, see http://www.gnu.org/licenses/
*/
/**
* class PowerManager
*
* Special code for handling spells, special powers, item effects, etc.
*/
#ifndef POWER_MANAGER_H
#define POWER_MANAGER_H
#include "Map.h"
#include "MapCollision.h"
#include "Utils.h"
class Animation;
class AnimationSet;
class EffectDef;
class Hazard;
class PostEffect {
public:
std::string id;
float magnitude;
int duration;
float chance;
bool target_src;
bool is_multiplier;
PostEffect()
: id("")
, magnitude(0)
, duration(0)
, chance(100)
, target_src(false)
, is_multiplier(false) {
}
};
class PowerReplaceByEffect {
public:
int power_id;
int count;
std::string effect_id;
};
class PowerRequiredItem {
public:
ItemID id;
int quantity;
bool equipped;
PowerRequiredItem()
: id(0)
, quantity(0)
, equipped(false)
{}
};
class ChainPower {
public:
enum {
TYPE_PRE = 0,
TYPE_POST,
TYPE_WALL,
};
PowerID id;
uint8_t type;
float chance;
ChainPower()
: id(0)
, type(0)
, chance(100)
{}
};
class Power {
public:
enum {
RESOURCESTATE_ANY = 0,
RESOURCESTATE_ALL = 1,
RESOURCESTATE_ANY_HPMP = 2,
};
enum {
RESOURCESTATE_IGNORE = 0,
RESOURCESTATE_PERCENT = 1,
RESOURCESTATE_NOT_PERCENT = 2
};
class ResourceState {
public:
int state;
float value;
ResourceState()
: state(RESOURCESTATE_IGNORE)
, value(0)
{}
~ResourceState() {}
};
enum {
TYPE_FIXED = 0,
TYPE_MISSILE = 1,
TYPE_REPEATER = 2,
TYPE_SPAWN = 3,
TYPE_TRANSFORM = 4,
TYPE_EFFECT = 5,
TYPE_BLOCK = 6
};
enum {
STATE_INSTANT = 1,
STATE_ATTACK = 2
};
enum {
STARTING_POS_SOURCE = 0,
STARTING_POS_TARGET = 1,
STARTING_POS_MELEE = 2
};
enum {
TRIGGER_BLOCK = 0,
TRIGGER_HIT = 1,
TRIGGER_HALFDEATH = 2,
TRIGGER_JOINCOMBAT = 3,
TRIGGER_DEATH = 4
};
enum {
SPAWN_LIMIT_MODE_FIXED = 0,
SPAWN_LIMIT_MODE_STAT = 1,
SPAWN_LIMIT_MODE_UNLIMITED = 2
};
enum {
STAT_MODIFIER_MODE_MULTIPLY = 0,
STAT_MODIFIER_MODE_ADD = 1,
STAT_MODIFIER_MODE_ABSOLUTE = 2
};
enum {
SOURCE_TYPE_HERO = 0,
SOURCE_TYPE_NEUTRAL = 1,
SOURCE_TYPE_ENEMY = 2,
SOURCE_TYPE_ALLY = 3
};
enum {
SCRIPT_TRIGGER_CAST = 0,
SCRIPT_TRIGGER_HIT = 1,
SCRIPT_TRIGGER_WALL = 2
};
// base info
bool is_empty;
int type; // what kind of activate() this is
std::string name;
std::string description;
int icon; // just the number. The caller menu will have access to the surface.
int new_state; // when using this power the user (avatar/enemy) starts a new state
int state_duration; // can be used to extend the length of a state animation by pausing on the last frame
bool prevent_interrupt; // prevents hits from interrupting the casting state
std::string attack_anim; // name of the animation to play when using this power, if it is not block
bool face; // does the user turn to face the mouse cursor when using this power?
int source_type; //hero, neutral, or enemy
bool beacon; //true if it's just an ememy calling its allies
int count; // number of hazards/effects or spawns created
bool passive; // if unlocked when the user spawns, automatically cast it
int passive_trigger; // only activate passive powers under certain conditions (block, hit, death, etc)
bool meta_power; // this power can't be used on its own and must be replaced via equipment
bool no_actionbar; // prevents this power from being placed on the actionbar
// power requirements
std::set<std::string> requires_flags; // checked against equip_flags granted from items
float requires_mp;
float requires_hp;
std::vector<float> requires_resource_stat;
bool sacrifice;
bool requires_los; // line of sight
bool requires_los_default;
bool requires_empty_target; // target square must be empty
std::vector<PowerRequiredItem> required_items;
bool consumable;
bool requires_targeting; // power only makes sense when using click-to-target
int requires_spawns;
int cooldown; // milliseconds before you can use the power again
ResourceState requires_hp_state;
ResourceState requires_mp_state;
std::vector<ResourceState> requires_resource_stat_state;
int requires_hpmp_state_mode;
int requires_resource_stat_state_mode;
// animation info
std::string animation_name;
int sfx_index;
SoundID sfx_hit;
bool sfx_hit_enable;
bool directional; // sprite sheet contains options for 8 directions, one per row
int visual_random; // sprite sheet contains rows of random options
int visual_option; // sprite sheet contains rows of similar effects. use a specific option
bool aim_assist;
float speed; // for missile hazards, tiles per frame
int lifespan; // how long the hazard/animation lasts
bool on_floor; // the hazard is drawn between the background and object layers
bool complete_animation;
float charge_speed;
float attack_speed;
// hazard traits
bool use_hazard;
bool no_attack;
bool no_aggro;
float radius;
size_t base_damage;
int starting_pos; // enum. (source, target, or melee)
bool relative_pos;
bool multitarget;
bool multihit;
bool expire_with_caster;
bool ignore_zero_damage;
bool lock_target_to_direction;
int movement_type;
float target_range;
bool target_party;
std::vector<std::string> target_categories;
float combat_range;
int mod_accuracy_mode;
float mod_accuracy_value;
int mod_crit_mode;
float mod_crit_value;
int mod_damage_mode;
float mod_damage_value_min;
float mod_damage_value_max;//only used if mode is absolute
//steal effects (in %, eg. hp_steal=50 turns 50% damage done into HP regain.)
float hp_steal;
float mp_steal;
std::vector<float> resource_steal;
//missile traits
float missile_angle;
float angle_variance;
float speed_variance;
//repeater traits
int delay;
int trait_elemental; // enum. of elements
bool trait_armor_penetration;
float trait_crits_impaired; // crit bonus vs. movement impaired enemies (slowed, immobilized, stunned)
bool trait_avoidance_ignore;
int transform_duration;
bool manual_untransform; // true binds to the power another recurrence power
bool keep_equipment;
bool untransform_on_hit;
// special effects
bool buff;
bool buff_teleport;
bool buff_party;
PowerID buff_party_power_id;
std::vector<PostEffect> post_effects;
std::vector<ChainPower> chain_powers;
bool wall_reflect;
// spawn info
std::string spawn_type;
int target_neighbor;
uint8_t spawn_limit_mode;
float spawn_limit_count;
float spawn_limit_ratio;
size_t spawn_limit_stat;
SpawnLevel spawn_level;
// targeting by movement type
bool target_movement_normal;
bool target_movement_flying;
bool target_movement_intangible;
bool walls_block_aoe;
int script_trigger;
std::string script;
std::vector< std::pair<std::string, int> > remove_effects;
std::vector<PowerReplaceByEffect> replace_by_effect;
bool requires_corpse;
bool remove_corpse;
float target_nearest;
std::vector<std::string> disable_equip_slots;
Power();
~Power() {
}
};
class PowerManager {
private:
MapCollision *collider;
void loadEffects();
void loadPowers();
bool isValidEffect(const std::string& type);
int loadSFX(const std::string& filename);
void initHazard(PowerID power_index, StatBlock *src_stats, const FPoint& target, Hazard *haz);
void buff(PowerID power_index, StatBlock *src_stats, const FPoint& target);
void playSound(PowerID power_index);
bool fixed(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool missile(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool repeater(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool spawn(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool transform(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool block(PowerID power_index, StatBlock *src_stats);
void payPowerCost(PowerID power_index, StatBlock *src_stats);
bool activatePassiveByTrigger(PowerID power_id, StatBlock *src_stats, bool& triggered_others);
void activatePassivePostPowers(StatBlock *src_stats);
std::map<PowerID, Animation*> power_animations;
std::vector<Animation*> effect_animations;
public:
static const bool ALLOW_ZERO_ID = true;
explicit PowerManager();
~PowerManager();
void handleNewMap(MapCollision *_collider);
bool activate(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool canUsePower(PowerID id) const;
bool hasValidTarget(PowerID power_index, StatBlock *src_stats, const FPoint& target);
bool effect(StatBlock *target_stats, StatBlock *caster_stats, PowerID power_index, int source_type);
void activatePassives(StatBlock *src_stats);
void activateSinglePassive(StatBlock *src_stats, PowerID id);
PowerID verifyID(PowerID power_id, FileParser* infile, bool allow_zero);
bool checkNearestTargeting(const Power &pow, const StatBlock *src_stats, bool check_corpses);
bool checkRequiredItems(const Power &pow, const StatBlock *src_stats);
bool checkRequiredResourceState(const Power &pow, const StatBlock *src_stats);
bool checkCombatRange(PowerID power_index, StatBlock *src_stats, FPoint target);
bool checkPowerCost(const Power &pow, const StatBlock *src_stats);
PowerID checkReplaceByEffect(PowerID power_index, StatBlock *src_stats);
EffectDef* getEffectDef(const std::string& id);
std::vector<EffectDef> effects;
std::map<PowerID, Power> powers;
std::queue<Hazard *> hazards; // output; read by HazardManager
std::queue<Map_Enemy> map_enemies; // output; read by PowerManager
// shared sounds for power special effects
std::vector<SoundID> sfx;
std::vector<ItemID> used_items;
std::vector<ItemID> used_equipped_items;
};
#endif