1 /* 2 Copyright © 2011-2012 Clint Bellanger 3 Copyright © 2012 Igor Paliychuk 4 Copyright © 2012 Stefan Beller 5 Copyright © 2013 Henrik Andersson 6 Copyright © 2012-2016 Justin Jacobs 7 8 This file is part of FLARE. 9 10 FLARE is free software: you can redistribute it and/or modify it under the terms 11 of the GNU General Public License as published by the Free Software Foundation, 12 either version 3 of the License, or (at your option) any later version. 13 14 FLARE is distributed in the hope that it will be useful, but WITHOUT ANY 15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 16 PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License along with 19 FLARE. If not, see http://www.gnu.org/licenses/ 20 */ 21 22 /** 23 * class PowerManager 24 * 25 * Special code for handling spells, special powers, item effects, etc. 26 */ 27 28 #ifndef POWER_MANAGER_H 29 #define POWER_MANAGER_H 30 31 #include "Map.h" 32 #include "MapCollision.h" 33 #include "Utils.h" 34 35 class Animation; 36 class AnimationSet; 37 class EffectDef; 38 class Hazard; 39 40 class PostEffect { 41 public: 42 std::string id; 43 int magnitude; 44 int duration; 45 int chance; 46 bool target_src; 47 PostEffect()48 PostEffect() 49 : id("") 50 , magnitude(0) 51 , duration(0) 52 , chance(100) 53 , target_src(false) { 54 } 55 }; 56 57 class PowerReplaceByEffect { 58 public: 59 int power_id; 60 int count; 61 std::string effect_id; 62 }; 63 64 class PowerRequiredItem { 65 public: 66 ItemID id; 67 int quantity; 68 bool equipped; 69 PowerRequiredItem()70 PowerRequiredItem() 71 : id(0) 72 , quantity(0) 73 , equipped(false) 74 {} 75 }; 76 77 class Power { 78 public: 79 enum { 80 HPMPSTATE_ANY = 0, 81 HPMPSTATE_ALL = 1 82 }; 83 enum { 84 HPMPSTATE_IGNORE = 0, 85 HPMPSTATE_PERCENT = 1, 86 HPMPSTATE_NOT_PERCENT = 2 87 }; 88 class HPMPState { 89 public: 90 int mode; 91 int hp_state; 92 int mp_state; 93 int hp; 94 int mp; HPMPState()95 HPMPState() 96 : mode(HPMPSTATE_ANY) 97 , hp_state(HPMPSTATE_IGNORE) 98 , mp_state(HPMPSTATE_IGNORE) 99 , hp(-1) 100 , mp(-1) 101 {} ~HPMPState()102 ~HPMPState() {} 103 }; 104 105 enum { 106 TYPE_FIXED = 0, 107 TYPE_MISSILE = 1, 108 TYPE_REPEATER = 2, 109 TYPE_SPAWN = 3, 110 TYPE_TRANSFORM = 4, 111 TYPE_EFFECT = 5, 112 TYPE_BLOCK = 6 113 }; 114 115 enum { 116 STATE_INSTANT = 1, 117 STATE_ATTACK = 2 118 }; 119 120 enum { 121 STARTING_POS_SOURCE = 0, 122 STARTING_POS_TARGET = 1, 123 STARTING_POS_MELEE = 2 124 }; 125 126 enum { 127 TRIGGER_BLOCK = 0, 128 TRIGGER_HIT = 1, 129 TRIGGER_HALFDEATH = 2, 130 TRIGGER_JOINCOMBAT = 3, 131 TRIGGER_DEATH = 4 132 }; 133 134 enum { 135 SPAWN_LIMIT_MODE_FIXED = 0, 136 SPAWN_LIMIT_MODE_STAT = 1, 137 SPAWN_LIMIT_MODE_UNLIMITED = 2 138 }; 139 140 enum { 141 SPAWN_LEVEL_MODE_DEFAULT = 0, 142 SPAWN_LEVEL_MODE_FIXED = 1, 143 SPAWN_LEVEL_MODE_STAT = 2, 144 SPAWN_LEVEL_MODE_LEVEL = 3 145 }; 146 147 enum { 148 STAT_MODIFIER_MODE_MULTIPLY = 0, 149 STAT_MODIFIER_MODE_ADD = 1, 150 STAT_MODIFIER_MODE_ABSOLUTE = 2 151 }; 152 153 enum { 154 SOURCE_TYPE_HERO = 0, 155 SOURCE_TYPE_NEUTRAL = 1, 156 SOURCE_TYPE_ENEMY = 2, 157 SOURCE_TYPE_ALLY = 3 158 }; 159 160 enum { 161 SCRIPT_TRIGGER_CAST = 0, 162 SCRIPT_TRIGGER_HIT = 1, 163 SCRIPT_TRIGGER_WALL = 2 164 }; 165 166 // base info 167 bool is_empty; 168 int type; // what kind of activate() this is 169 std::string name; 170 std::string description; 171 int icon; // just the number. The caller menu will have access to the surface. 172 int new_state; // when using this power the user (avatar/enemy) starts a new state 173 int state_duration; // can be used to extend the length of a state animation by pausing on the last frame 174 bool prevent_interrupt; // prevents hits from interrupting the casting state 175 std::string attack_anim; // name of the animation to play when using this power, if it is not block 176 bool face; // does the user turn to face the mouse cursor when using this power? 177 int source_type; //hero, neutral, or enemy 178 bool beacon; //true if it's just an ememy calling its allies 179 int count; // number of hazards/effects or spawns created 180 bool passive; // if unlocked when the user spawns, automatically cast it 181 int passive_trigger; // only activate passive powers under certain conditions (block, hit, death, etc) 182 bool meta_power; // this power can't be used on its own and must be replaced via equipment 183 bool no_actionbar; // prevents this power from being placed on the actionbar 184 185 // power requirements 186 std::set<std::string> requires_flags; // checked against equip_flags granted from items 187 int requires_mp; 188 int requires_hp; 189 bool sacrifice; 190 bool requires_los; // line of sight 191 bool requires_los_default; 192 bool requires_empty_target; // target square must be empty 193 std::vector<PowerRequiredItem> required_items; 194 bool consumable; 195 bool requires_targeting; // power only makes sense when using click-to-target 196 int requires_spawns; 197 int cooldown; // milliseconds before you can use the power again 198 HPMPState requires_max_hpmp; 199 200 // animation info 201 std::string animation_name; 202 int sfx_index; 203 SoundID sfx_hit; 204 bool sfx_hit_enable; 205 bool directional; // sprite sheet contains options for 8 directions, one per row 206 int visual_random; // sprite sheet contains rows of random options 207 int visual_option; // sprite sheet contains rows of similar effects. use a specific option 208 bool aim_assist; 209 float speed; // for missile hazards, tiles per frame 210 int lifespan; // how long the hazard/animation lasts 211 bool on_floor; // the hazard is drawn between the background and object layers 212 bool complete_animation; 213 float charge_speed; 214 float attack_speed; 215 216 // hazard traits 217 bool use_hazard; 218 bool no_attack; 219 bool no_aggro; 220 float radius; 221 size_t base_damage; 222 int starting_pos; // enum. (source, target, or melee) 223 bool relative_pos; 224 bool multitarget; 225 bool multihit; 226 bool expire_with_caster; 227 bool ignore_zero_damage; 228 bool lock_target_to_direction; 229 int movement_type; 230 float target_range; 231 bool target_party; 232 std::vector<std::string> target_categories; 233 float combat_range; 234 235 int mod_accuracy_mode; 236 int mod_accuracy_value; 237 238 int mod_crit_mode; 239 int mod_crit_value; 240 241 int mod_damage_mode; 242 int mod_damage_value_min; 243 int mod_damage_value_max;//only used if mode is absolute 244 245 //steal effects (in %, eg. hp_steal=50 turns 50% damage done into HP regain.) 246 int hp_steal; 247 int mp_steal; 248 249 //missile traits 250 int missile_angle; 251 int angle_variance; 252 float speed_variance; 253 254 //repeater traits 255 int delay; 256 257 int trait_elemental; // enum. of elements 258 bool trait_armor_penetration; 259 int trait_crits_impaired; // crit bonus vs. movement impaired enemies (slowed, immobilized, stunned) 260 bool trait_avoidance_ignore; 261 262 int transform_duration; 263 bool manual_untransform; // true binds to the power another recurrence power 264 bool keep_equipment; 265 bool untransform_on_hit; 266 267 // special effects 268 bool buff; 269 bool buff_teleport; 270 bool buff_party; 271 PowerID buff_party_power_id; 272 273 std::vector<PostEffect> post_effects; 274 275 PowerID pre_power; 276 int pre_power_chance; 277 PowerID post_power; 278 int post_power_chance; 279 PowerID wall_power; 280 int wall_power_chance; 281 bool wall_reflect; 282 283 // spawn info 284 std::string spawn_type; 285 int target_neighbor; 286 int spawn_limit_mode; 287 int spawn_limit_qty; 288 int spawn_limit_every; 289 size_t spawn_limit_stat; 290 291 int spawn_level_mode; 292 int spawn_level_qty; 293 int spawn_level_every; 294 size_t spawn_level_stat; 295 296 // targeting by movement type 297 bool target_movement_normal; 298 bool target_movement_flying; 299 bool target_movement_intangible; 300 301 bool walls_block_aoe; 302 303 int script_trigger; 304 std::string script; 305 306 std::vector< std::pair<std::string, int> > remove_effects; 307 308 std::vector<PowerReplaceByEffect> replace_by_effect; 309 310 bool requires_corpse; 311 bool remove_corpse; 312 313 float target_nearest; 314 315 std::vector<std::string> disable_equip_slots; 316 317 Power(); ~Power()318 ~Power() { 319 } 320 }; 321 322 class PowerManager { 323 private: 324 325 MapCollision *collider; 326 327 void loadEffects(); 328 void loadPowers(); 329 330 bool isValidEffect(const std::string& type); 331 int loadSFX(const std::string& filename); 332 333 void initHazard(PowerID power_index, StatBlock *src_stats, const FPoint& target, Hazard *haz); 334 void buff(PowerID power_index, StatBlock *src_stats, const FPoint& target); 335 void playSound(PowerID power_index); 336 337 bool fixed(PowerID power_index, StatBlock *src_stats, const FPoint& target); 338 bool missile(PowerID power_index, StatBlock *src_stats, const FPoint& target); 339 bool repeater(PowerID power_index, StatBlock *src_stats, const FPoint& target); 340 bool spawn(PowerID power_index, StatBlock *src_stats, const FPoint& target); 341 bool transform(PowerID power_index, StatBlock *src_stats, const FPoint& target); 342 bool block(PowerID power_index, StatBlock *src_stats); 343 344 void payPowerCost(PowerID power_index, StatBlock *src_stats); 345 346 bool activatePassiveByTrigger(PowerID power_id, StatBlock *src_stats, bool& triggered_others); 347 void activatePassivePostPowers(StatBlock *src_stats); 348 349 std::map<PowerID, Animation*> power_animations; 350 std::vector<Animation*> effect_animations; 351 352 public: 353 static const bool ALLOW_ZERO_ID = true; 354 355 explicit PowerManager(); 356 ~PowerManager(); 357 358 void handleNewMap(MapCollision *_collider); 359 bool activate(PowerID power_index, StatBlock *src_stats, const FPoint& target); 360 bool canUsePower(PowerID id) const; 361 bool hasValidTarget(PowerID power_index, StatBlock *src_stats, const FPoint& target); 362 bool effect(StatBlock *target_stats, StatBlock *caster_stats, PowerID power_index, int source_type); 363 void activatePassives(StatBlock *src_stats); 364 void activateSinglePassive(StatBlock *src_stats, PowerID id); 365 PowerID verifyID(PowerID power_id, FileParser* infile, bool allow_zero); 366 bool checkNearestTargeting(const Power &pow, const StatBlock *src_stats, bool check_corpses); 367 bool checkRequiredItems(const Power &pow, const StatBlock *src_stats); 368 bool checkRequiredMaxHPMP(const Power &pow, const StatBlock *src_stats); 369 bool checkCombatRange(PowerID power_index, StatBlock *src_stats, FPoint target); 370 PowerID checkReplaceByEffect(PowerID power_index, StatBlock *src_stats); 371 372 EffectDef* getEffectDef(const std::string& id); 373 374 std::vector<EffectDef> effects; 375 std::map<PowerID, Power> powers; 376 std::queue<Hazard *> hazards; // output; read by HazardManager 377 std::queue<Map_Enemy> map_enemies; // output; read by PowerManager 378 379 // shared sounds for power special effects 380 std::vector<SoundID> sfx; 381 382 std::vector<ItemID> used_items; 383 std::vector<ItemID> used_equipped_items; 384 }; 385 386 #endif 387