/src/server/scripts/Spells/spell_generic.cpp

https://gitlab.com/tkrokli/TrinityCore_434 · C++ · 4156 lines · 3424 code · 585 blank · 147 comment · 325 complexity · 85ae9a833aac52d19732228c4733c1ef MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the
  6. * Free Software Foundation; either version 2 of the License, or (at your
  7. * option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /*
  18. * Scripts for spells with SPELLFAMILY_GENERIC which cannot be included in AI script file
  19. * of creature using it or can't be bound to any player class.
  20. * Ordered alphabetically using scriptname.
  21. * Scriptnames of files in this file should be prefixed with "spell_gen_"
  22. */
  23. #include "ScriptMgr.h"
  24. #include "Battleground.h"
  25. #include "Cell.h"
  26. #include "CellImpl.h"
  27. #include "GridNotifiers.h"
  28. #include "GridNotifiersImpl.h"
  29. #include "Group.h"
  30. #include "InstanceScript.h"
  31. #include "LFGMgr.h"
  32. #include "Pet.h"
  33. #include "ReputationMgr.h"
  34. #include "SkillDiscovery.h"
  35. #include "SpellHistory.h"
  36. #include "SpellScript.h"
  37. #include "SpellAuraEffects.h"
  38. #include "Vehicle.h"
  39. class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader
  40. {
  41. public:
  42. spell_gen_absorb0_hitlimit1() : SpellScriptLoader("spell_gen_absorb0_hitlimit1") { }
  43. class spell_gen_absorb0_hitlimit1_AuraScript : public AuraScript
  44. {
  45. PrepareAuraScript(spell_gen_absorb0_hitlimit1_AuraScript);
  46. public:
  47. spell_gen_absorb0_hitlimit1_AuraScript()
  48. {
  49. limit = 0;
  50. }
  51. private:
  52. uint32 limit;
  53. bool Load() override
  54. {
  55. // Max absorb stored in 1 dummy effect
  56. limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
  57. return true;
  58. }
  59. void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& absorbAmount)
  60. {
  61. absorbAmount = std::min(limit, absorbAmount);
  62. }
  63. void Register() override
  64. {
  65. OnEffectAbsorb += AuraEffectAbsorbFn(spell_gen_absorb0_hitlimit1_AuraScript::Absorb, EFFECT_0);
  66. }
  67. };
  68. AuraScript* GetAuraScript() const override
  69. {
  70. return new spell_gen_absorb0_hitlimit1_AuraScript();
  71. }
  72. };
  73. // 28764 - Adaptive Warding (Frostfire Regalia Set)
  74. enum AdaptiveWarding
  75. {
  76. SPELL_GEN_ADAPTIVE_WARDING_FIRE = 28765,
  77. SPELL_GEN_ADAPTIVE_WARDING_NATURE = 28768,
  78. SPELL_GEN_ADAPTIVE_WARDING_FROST = 28766,
  79. SPELL_GEN_ADAPTIVE_WARDING_SHADOW = 28769,
  80. SPELL_GEN_ADAPTIVE_WARDING_ARCANE = 28770
  81. };
  82. class spell_gen_adaptive_warding : public SpellScriptLoader
  83. {
  84. public:
  85. spell_gen_adaptive_warding() : SpellScriptLoader("spell_gen_adaptive_warding") { }
  86. class spell_gen_adaptive_warding_AuraScript : public AuraScript
  87. {
  88. PrepareAuraScript(spell_gen_adaptive_warding_AuraScript);
  89. bool Validate(SpellInfo const* /*spellInfo*/) override
  90. {
  91. if (!sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FIRE) ||
  92. !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_NATURE) ||
  93. !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FROST) ||
  94. !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_SHADOW) ||
  95. !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_ARCANE))
  96. return false;
  97. return true;
  98. }
  99. bool CheckProc(ProcEventInfo& eventInfo)
  100. {
  101. if (eventInfo.GetDamageInfo()->GetSpellInfo()) // eventInfo.GetSpellInfo()
  102. return false;
  103. // find Mage Armor
  104. if (!GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0x0, 0x0))
  105. return false;
  106. switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask()))
  107. {
  108. case SPELL_SCHOOL_NORMAL:
  109. case SPELL_SCHOOL_HOLY:
  110. return false;
  111. default:
  112. break;
  113. }
  114. return true;
  115. }
  116. void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
  117. {
  118. PreventDefaultAction();
  119. uint32 spellId = 0;
  120. switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask()))
  121. {
  122. case SPELL_SCHOOL_FIRE:
  123. spellId = SPELL_GEN_ADAPTIVE_WARDING_FIRE;
  124. break;
  125. case SPELL_SCHOOL_NATURE:
  126. spellId = SPELL_GEN_ADAPTIVE_WARDING_NATURE;
  127. break;
  128. case SPELL_SCHOOL_FROST:
  129. spellId = SPELL_GEN_ADAPTIVE_WARDING_FROST;
  130. break;
  131. case SPELL_SCHOOL_SHADOW:
  132. spellId = SPELL_GEN_ADAPTIVE_WARDING_SHADOW;
  133. break;
  134. case SPELL_SCHOOL_ARCANE:
  135. spellId = SPELL_GEN_ADAPTIVE_WARDING_ARCANE;
  136. break;
  137. default:
  138. return;
  139. }
  140. GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff);
  141. }
  142. void Register() override
  143. {
  144. DoCheckProc += AuraCheckProcFn(spell_gen_adaptive_warding_AuraScript::CheckProc);
  145. OnEffectProc += AuraEffectProcFn(spell_gen_adaptive_warding_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
  146. }
  147. };
  148. AuraScript* GetAuraScript() const override
  149. {
  150. return new spell_gen_adaptive_warding_AuraScript();
  151. }
  152. };
  153. enum AlchemistStone
  154. {
  155. ALECHEMIST_STONE_HEAL = 21399,
  156. ALECHEMIST_STONE_MANA = 21400,
  157. };
  158. // 17619 - Alchemist Stone
  159. class spell_gen_alchemist_stone : public SpellScriptLoader
  160. {
  161. public:
  162. spell_gen_alchemist_stone() : SpellScriptLoader("spell_gen_alchemist_stone") { }
  163. class spell_gen_alchemist_stone_AuraScript : public AuraScript
  164. {
  165. PrepareAuraScript(spell_gen_alchemist_stone_AuraScript);
  166. bool Validate(SpellInfo const* /*spellInfo*/) override
  167. {
  168. if (!sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_HEAL) ||
  169. !sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_MANA))
  170. return false;
  171. return true;
  172. }
  173. bool CheckProc(ProcEventInfo& eventInfo)
  174. {
  175. return eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_POTION;
  176. }
  177. void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
  178. {
  179. PreventDefaultAction();
  180. uint32 spellId = 0;
  181. int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 0.4f);
  182. if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_HEAL))
  183. spellId = ALECHEMIST_STONE_HEAL;
  184. else if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_ENERGIZE))
  185. spellId = ALECHEMIST_STONE_MANA;
  186. if (!spellId)
  187. return;
  188. GetTarget()->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff);
  189. }
  190. void Register() override
  191. {
  192. DoCheckProc += AuraCheckProcFn(spell_gen_alchemist_stone_AuraScript::CheckProc);
  193. OnEffectProc += AuraEffectProcFn(spell_gen_alchemist_stone_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
  194. }
  195. };
  196. AuraScript* GetAuraScript() const override
  197. {
  198. return new spell_gen_alchemist_stone_AuraScript();
  199. }
  200. };
  201. class spell_gen_allow_cast_from_item_only : public SpellScriptLoader
  202. {
  203. public:
  204. spell_gen_allow_cast_from_item_only() : SpellScriptLoader("spell_gen_allow_cast_from_item_only") { }
  205. class spell_gen_allow_cast_from_item_only_SpellScript : public SpellScript
  206. {
  207. PrepareSpellScript(spell_gen_allow_cast_from_item_only_SpellScript);
  208. SpellCastResult CheckRequirement()
  209. {
  210. if (!GetCastItem())
  211. return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
  212. return SPELL_CAST_OK;
  213. }
  214. void Register() override
  215. {
  216. OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only_SpellScript::CheckRequirement);
  217. }
  218. };
  219. SpellScript* GetSpellScript() const override
  220. {
  221. return new spell_gen_allow_cast_from_item_only_SpellScript();
  222. }
  223. };
  224. enum AnimalBloodPoolSpell
  225. {
  226. SPELL_ANIMAL_BLOOD = 46221,
  227. SPELL_SPAWN_BLOOD_POOL = 63471
  228. };
  229. class spell_gen_animal_blood : public SpellScriptLoader
  230. {
  231. public:
  232. spell_gen_animal_blood() : SpellScriptLoader("spell_gen_animal_blood") { }
  233. class spell_gen_animal_blood_AuraScript : public AuraScript
  234. {
  235. PrepareAuraScript(spell_gen_animal_blood_AuraScript);
  236. bool Validate(SpellInfo const* /*spellInfo*/) override
  237. {
  238. if (!sSpellMgr->GetSpellInfo(SPELL_SPAWN_BLOOD_POOL))
  239. return false;
  240. return true;
  241. }
  242. void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  243. {
  244. // Remove all auras with spell id 46221, except the one currently being applied
  245. while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, ObjectGuid::Empty, ObjectGuid::Empty, 0, GetAura()))
  246. GetUnitOwner()->RemoveOwnedAura(aur);
  247. }
  248. void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  249. {
  250. if (Unit* owner = GetUnitOwner())
  251. if (owner->IsInWater())
  252. owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true);
  253. }
  254. void Register() override
  255. {
  256. AfterEffectApply += AuraEffectRemoveFn(spell_gen_animal_blood_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
  257. AfterEffectRemove += AuraEffectRemoveFn(spell_gen_animal_blood_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
  258. }
  259. };
  260. AuraScript* GetAuraScript() const override
  261. {
  262. return new spell_gen_animal_blood_AuraScript();
  263. }
  264. };
  265. // 41337 Aura of Anger
  266. class spell_gen_aura_of_anger : public SpellScriptLoader
  267. {
  268. public:
  269. spell_gen_aura_of_anger() : SpellScriptLoader("spell_gen_aura_of_anger") { }
  270. class spell_gen_aura_of_anger_AuraScript : public AuraScript
  271. {
  272. PrepareAuraScript(spell_gen_aura_of_anger_AuraScript);
  273. void HandleEffectPeriodicUpdate(AuraEffect* aurEff)
  274. {
  275. if (AuraEffect* aurEff1 = aurEff->GetBase()->GetEffect(EFFECT_1))
  276. aurEff1->ChangeAmount(aurEff1->GetAmount() + 5);
  277. aurEff->SetAmount(100 * aurEff->GetTickNumber());
  278. }
  279. void Register() override
  280. {
  281. OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_aura_of_anger_AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
  282. }
  283. };
  284. AuraScript* GetAuraScript() const override
  285. {
  286. return new spell_gen_aura_of_anger_AuraScript();
  287. }
  288. };
  289. enum ServiceUniform
  290. {
  291. // Spells
  292. SPELL_SERVICE_UNIFORM = 71450,
  293. // Models
  294. MODEL_GOBLIN_MALE = 31002,
  295. MODEL_GOBLIN_FEMALE = 31003
  296. };
  297. class spell_gen_aura_service_uniform : public SpellScriptLoader
  298. {
  299. public:
  300. spell_gen_aura_service_uniform() : SpellScriptLoader("spell_gen_aura_service_uniform") { }
  301. class spell_gen_aura_service_uniform_AuraScript : public AuraScript
  302. {
  303. PrepareAuraScript(spell_gen_aura_service_uniform_AuraScript);
  304. bool Validate(SpellInfo const* /*spellInfo*/) override
  305. {
  306. if (!sSpellMgr->GetSpellInfo(SPELL_SERVICE_UNIFORM))
  307. return false;
  308. return true;
  309. }
  310. void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  311. {
  312. // Apply model goblin
  313. Unit* target = GetTarget();
  314. if (target->GetTypeId() == TYPEID_PLAYER)
  315. {
  316. if (target->getGender() == GENDER_MALE)
  317. target->SetDisplayId(MODEL_GOBLIN_MALE);
  318. else
  319. target->SetDisplayId(MODEL_GOBLIN_FEMALE);
  320. }
  321. }
  322. void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  323. {
  324. Unit* target = GetTarget();
  325. if (target->GetTypeId() == TYPEID_PLAYER)
  326. target->RestoreDisplayId();
  327. }
  328. void Register() override
  329. {
  330. AfterEffectApply += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
  331. AfterEffectRemove += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
  332. }
  333. };
  334. AuraScript* GetAuraScript() const override
  335. {
  336. return new spell_gen_aura_service_uniform_AuraScript();
  337. }
  338. };
  339. class spell_gen_av_drekthar_presence : public SpellScriptLoader
  340. {
  341. public:
  342. spell_gen_av_drekthar_presence() : SpellScriptLoader("spell_gen_av_drekthar_presence") { }
  343. class spell_gen_av_drekthar_presence_AuraScript : public AuraScript
  344. {
  345. PrepareAuraScript(spell_gen_av_drekthar_presence_AuraScript);
  346. bool CheckAreaTarget(Unit* target)
  347. {
  348. switch (target->GetEntry())
  349. {
  350. // alliance
  351. case 14762: // Dun Baldar North Marshal
  352. case 14763: // Dun Baldar South Marshal
  353. case 14764: // Icewing Marshal
  354. case 14765: // Stonehearth Marshal
  355. case 11948: // Vandar Stormspike
  356. // horde
  357. case 14772: // East Frostwolf Warmaster
  358. case 14776: // Tower Point Warmaster
  359. case 14773: // Iceblood Warmaster
  360. case 14777: // West Frostwolf Warmaster
  361. case 11946: // Drek'thar
  362. return true;
  363. default:
  364. return false;
  365. }
  366. }
  367. void Register() override
  368. {
  369. DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_gen_av_drekthar_presence_AuraScript::CheckAreaTarget);
  370. }
  371. };
  372. AuraScript* GetAuraScript() const override
  373. {
  374. return new spell_gen_av_drekthar_presence_AuraScript();
  375. }
  376. };
  377. enum GenericBandage
  378. {
  379. SPELL_RECENTLY_BANDAGED = 11196
  380. };
  381. class spell_gen_bandage : public SpellScriptLoader
  382. {
  383. public:
  384. spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { }
  385. class spell_gen_bandage_SpellScript : public SpellScript
  386. {
  387. PrepareSpellScript(spell_gen_bandage_SpellScript);
  388. bool Validate(SpellInfo const* /*spellInfo*/) override
  389. {
  390. if (!sSpellMgr->GetSpellInfo(SPELL_RECENTLY_BANDAGED))
  391. return false;
  392. return true;
  393. }
  394. SpellCastResult CheckCast()
  395. {
  396. if (Unit* target = GetExplTargetUnit())
  397. {
  398. if (target->HasAura(SPELL_RECENTLY_BANDAGED))
  399. return SPELL_FAILED_TARGET_AURASTATE;
  400. }
  401. return SPELL_CAST_OK;
  402. }
  403. void HandleScript()
  404. {
  405. if (Unit* target = GetHitUnit())
  406. GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true);
  407. }
  408. void Register() override
  409. {
  410. OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast);
  411. AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript);
  412. }
  413. };
  414. SpellScript* GetSpellScript() const override
  415. {
  416. return new spell_gen_bandage_SpellScript();
  417. }
  418. };
  419. enum Bonked
  420. {
  421. SPELL_BONKED = 62991,
  422. SPELL_FOAM_SWORD_DEFEAT = 62994,
  423. SPELL_ON_GUARD = 62972
  424. };
  425. class spell_gen_bonked : public SpellScriptLoader
  426. {
  427. public:
  428. spell_gen_bonked() : SpellScriptLoader("spell_gen_bonked") { }
  429. class spell_gen_bonked_SpellScript : public SpellScript
  430. {
  431. PrepareSpellScript(spell_gen_bonked_SpellScript);
  432. void HandleScript(SpellEffIndex /*effIndex*/)
  433. {
  434. if (Player* target = GetHitPlayer())
  435. {
  436. Aura const* aura = GetHitAura();
  437. if (!(aura && aura->GetStackAmount() == 3))
  438. return;
  439. target->CastSpell(target, SPELL_FOAM_SWORD_DEFEAT, true);
  440. target->RemoveAurasDueToSpell(SPELL_BONKED);
  441. if (Aura const* auraOnGuard = target->GetAura(SPELL_ON_GUARD))
  442. {
  443. if (Item* item = target->GetItemByGuid(auraOnGuard->GetCastItemGUID()))
  444. target->DestroyItemCount(item->GetEntry(), 1, true);
  445. }
  446. }
  447. }
  448. void Register() override
  449. {
  450. OnEffectHitTarget += SpellEffectFn(spell_gen_bonked_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
  451. }
  452. };
  453. SpellScript* GetSpellScript() const override
  454. {
  455. return new spell_gen_bonked_SpellScript();
  456. }
  457. };
  458. /* DOCUMENTATION: Break-Shield spells
  459. Break-Shield spells can be classified in three groups:
  460. - Spells on vehicle bar used by players:
  461. + EFFECT_0: SCRIPT_EFFECT
  462. + EFFECT_1: NONE
  463. + EFFECT_2: NONE
  464. - Spells cast by players triggered by script:
  465. + EFFECT_0: SCHOOL_DAMAGE
  466. + EFFECT_1: SCRIPT_EFFECT
  467. + EFFECT_2: FORCE_CAST
  468. - Spells cast by NPCs on players:
  469. + EFFECT_0: SCHOOL_DAMAGE
  470. + EFFECT_1: SCRIPT_EFFECT
  471. + EFFECT_2: NONE
  472. In the following script we handle the SCRIPT_EFFECT for effIndex EFFECT_0 and EFFECT_1.
  473. - When handling EFFECT_0 we're in the "Spells on vehicle bar used by players" case
  474. and we'll trigger "Spells cast by players triggered by script"
  475. - When handling EFFECT_1 we're in the "Spells cast by players triggered by script"
  476. or "Spells cast by NPCs on players" so we'll search for the first defend layer and drop it.
  477. */
  478. enum BreakShieldSpells
  479. {
  480. SPELL_BREAK_SHIELD_DAMAGE_2K = 62626,
  481. SPELL_BREAK_SHIELD_DAMAGE_10K = 64590,
  482. SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS = 62575, // Also on ToC5 mounts
  483. SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE = 64595,
  484. SPELL_BREAK_SHIELD_TRIGGER_UNK = 66480
  485. };
  486. class spell_gen_break_shield: public SpellScriptLoader
  487. {
  488. public:
  489. spell_gen_break_shield(const char* name) : SpellScriptLoader(name) { }
  490. class spell_gen_break_shield_SpellScript : public SpellScript
  491. {
  492. PrepareSpellScript(spell_gen_break_shield_SpellScript);
  493. void HandleScriptEffect(SpellEffIndex effIndex)
  494. {
  495. Unit* target = GetHitUnit();
  496. switch (effIndex)
  497. {
  498. case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual)
  499. {
  500. uint32 spellId;
  501. switch (GetSpellInfo()->Id)
  502. {
  503. case SPELL_BREAK_SHIELD_TRIGGER_UNK:
  504. case SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE:
  505. spellId = SPELL_BREAK_SHIELD_DAMAGE_10K;
  506. break;
  507. case SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS:
  508. spellId = SPELL_BREAK_SHIELD_DAMAGE_2K;
  509. break;
  510. default:
  511. return;
  512. }
  513. if (Unit* rider = GetCaster()->GetCharmer())
  514. rider->CastSpell(target, spellId, false);
  515. else
  516. GetCaster()->CastSpell(target, spellId, false);
  517. break;
  518. }
  519. case EFFECT_1: // On damaging spells, for removing a defend layer
  520. {
  521. Unit::AuraApplicationMap const& auras = target->GetAppliedAuras();
  522. for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
  523. {
  524. if (Aura* aura = itr->second->GetBase())
  525. {
  526. SpellInfo const* auraInfo = aura->GetSpellInfo();
  527. if (auraInfo && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN))
  528. {
  529. aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
  530. // Remove dummys from rider (Necessary for updating visual shields)
  531. if (Unit* rider = target->GetCharmer())
  532. if (Aura* defend = rider->GetAura(aura->GetId()))
  533. defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
  534. break;
  535. }
  536. }
  537. }
  538. break;
  539. }
  540. default:
  541. break;
  542. }
  543. }
  544. void Register() override
  545. {
  546. OnEffectHitTarget += SpellEffectFn(spell_gen_break_shield_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT);
  547. }
  548. };
  549. SpellScript* GetSpellScript() const override
  550. {
  551. return new spell_gen_break_shield_SpellScript();
  552. }
  553. };
  554. // 46394 Brutallus Burn
  555. class spell_gen_burn_brutallus : public SpellScriptLoader
  556. {
  557. public:
  558. spell_gen_burn_brutallus() : SpellScriptLoader("spell_gen_burn_brutallus") { }
  559. class spell_gen_burn_brutallus_AuraScript : public AuraScript
  560. {
  561. PrepareAuraScript(spell_gen_burn_brutallus_AuraScript);
  562. void HandleEffectPeriodicUpdate(AuraEffect* aurEff)
  563. {
  564. if (aurEff->GetTickNumber() % 11 == 0)
  565. aurEff->SetAmount(aurEff->GetAmount() * 2);
  566. }
  567. void Register() override
  568. {
  569. OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_burn_brutallus_AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
  570. }
  571. };
  572. AuraScript* GetAuraScript() const override
  573. {
  574. return new spell_gen_burn_brutallus_AuraScript();
  575. }
  576. };
  577. enum CannibalizeSpells
  578. {
  579. SPELL_CANNIBALIZE_TRIGGERED = 20578
  580. };
  581. class spell_gen_cannibalize : public SpellScriptLoader
  582. {
  583. public:
  584. spell_gen_cannibalize() : SpellScriptLoader("spell_gen_cannibalize") { }
  585. class spell_gen_cannibalize_SpellScript : public SpellScript
  586. {
  587. PrepareSpellScript(spell_gen_cannibalize_SpellScript);
  588. bool Validate(SpellInfo const* /*spellInfo*/) override
  589. {
  590. if (!sSpellMgr->GetSpellInfo(SPELL_CANNIBALIZE_TRIGGERED))
  591. return false;
  592. return true;
  593. }
  594. SpellCastResult CheckIfCorpseNear()
  595. {
  596. Unit* caster = GetCaster();
  597. float max_range = GetSpellInfo()->GetMaxRange(false);
  598. WorldObject* result = NULL;
  599. // search for nearby enemy corpse in range
  600. Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY);
  601. Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
  602. caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
  603. if (!result)
  604. return SPELL_FAILED_NO_EDIBLE_CORPSES;
  605. return SPELL_CAST_OK;
  606. }
  607. void HandleDummy(SpellEffIndex /*effIndex*/)
  608. {
  609. GetCaster()->CastSpell(GetCaster(), SPELL_CANNIBALIZE_TRIGGERED, false);
  610. }
  611. void Register() override
  612. {
  613. OnEffectHit += SpellEffectFn(spell_gen_cannibalize_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
  614. OnCheckCast += SpellCheckCastFn(spell_gen_cannibalize_SpellScript::CheckIfCorpseNear);
  615. }
  616. };
  617. SpellScript* GetSpellScript() const override
  618. {
  619. return new spell_gen_cannibalize_SpellScript();
  620. }
  621. };
  622. enum ChaosBlast
  623. {
  624. SPELL_CHAOS_BLAST = 37675
  625. };
  626. class spell_gen_chaos_blast : public SpellScriptLoader
  627. {
  628. public:
  629. spell_gen_chaos_blast() : SpellScriptLoader("spell_gen_chaos_blast") { }
  630. class spell_gen_chaos_blast_SpellScript : public SpellScript
  631. {
  632. PrepareSpellScript(spell_gen_chaos_blast_SpellScript);
  633. bool Validate(SpellInfo const* /*spellInfo*/) override
  634. {
  635. if (!sSpellMgr->GetSpellInfo(SPELL_CHAOS_BLAST))
  636. return false;
  637. return true;
  638. }
  639. void HandleDummy(SpellEffIndex /* effIndex */)
  640. {
  641. int32 basepoints0 = 100;
  642. Unit* caster = GetCaster();
  643. if (Unit* target = GetHitUnit())
  644. caster->CastCustomSpell(target, SPELL_CHAOS_BLAST, &basepoints0, NULL, NULL, true);
  645. }
  646. void Register() override
  647. {
  648. OnEffectHitTarget += SpellEffectFn(spell_gen_chaos_blast_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
  649. }
  650. };
  651. SpellScript* GetSpellScript() const override
  652. {
  653. return new spell_gen_chaos_blast_SpellScript();
  654. }
  655. };
  656. enum Clone
  657. {
  658. SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE = 57528
  659. };
  660. class spell_gen_clone : public SpellScriptLoader
  661. {
  662. public:
  663. spell_gen_clone() : SpellScriptLoader("spell_gen_clone") { }
  664. class spell_gen_clone_SpellScript : public SpellScript
  665. {
  666. PrepareSpellScript(spell_gen_clone_SpellScript);
  667. void HandleScriptEffect(SpellEffIndex effIndex)
  668. {
  669. PreventHitDefaultEffect(effIndex);
  670. GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
  671. }
  672. void Register() override
  673. {
  674. if (m_scriptSpellId == SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE)
  675. {
  676. OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_DUMMY);
  677. OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_DUMMY);
  678. }
  679. else
  680. {
  681. OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
  682. OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
  683. }
  684. }
  685. };
  686. SpellScript* GetSpellScript() const override
  687. {
  688. return new spell_gen_clone_SpellScript();
  689. }
  690. };
  691. enum CloneWeaponSpells
  692. {
  693. SPELL_COPY_WEAPON_AURA = 41054,
  694. SPELL_COPY_WEAPON_2_AURA = 63418,
  695. SPELL_COPY_WEAPON_3_AURA = 69893,
  696. SPELL_COPY_OFFHAND_AURA = 45205,
  697. SPELL_COPY_OFFHAND_2_AURA = 69896,
  698. SPELL_COPY_RANGED_AURA = 57594
  699. };
  700. class spell_gen_clone_weapon : public SpellScriptLoader
  701. {
  702. public:
  703. spell_gen_clone_weapon() : SpellScriptLoader("spell_gen_clone_weapon") { }
  704. class spell_gen_clone_weapon_SpellScript : public SpellScript
  705. {
  706. PrepareSpellScript(spell_gen_clone_weapon_SpellScript);
  707. void HandleScriptEffect(SpellEffIndex effIndex)
  708. {
  709. PreventHitDefaultEffect(effIndex);
  710. GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
  711. }
  712. void Register() override
  713. {
  714. OnEffectHitTarget += SpellEffectFn(spell_gen_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  715. }
  716. };
  717. SpellScript* GetSpellScript() const override
  718. {
  719. return new spell_gen_clone_weapon_SpellScript();
  720. }
  721. };
  722. class spell_gen_clone_weapon_aura : public SpellScriptLoader
  723. {
  724. public:
  725. spell_gen_clone_weapon_aura() : SpellScriptLoader("spell_gen_clone_weapon_aura") { }
  726. class spell_gen_clone_weapon_auraScript : public AuraScript
  727. {
  728. PrepareAuraScript(spell_gen_clone_weapon_auraScript);
  729. public:
  730. spell_gen_clone_weapon_auraScript()
  731. {
  732. prevItem = 0;
  733. }
  734. private:
  735. bool Validate(SpellInfo const* /*spellInfo*/) override
  736. {
  737. if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_AURA) ||
  738. !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_2_AURA) ||
  739. !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_3_AURA) ||
  740. !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_AURA) ||
  741. !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_2_AURA) ||
  742. !sSpellMgr->GetSpellInfo(SPELL_COPY_RANGED_AURA))
  743. return false;
  744. return true;
  745. }
  746. void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  747. {
  748. Unit* caster = GetCaster();
  749. Unit* target = GetTarget();
  750. if (!caster)
  751. return;
  752. switch (GetSpellInfo()->Id)
  753. {
  754. case SPELL_COPY_WEAPON_AURA:
  755. case SPELL_COPY_WEAPON_2_AURA:
  756. case SPELL_COPY_WEAPON_3_AURA:
  757. {
  758. prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID);
  759. if (Player* player = caster->ToPlayer())
  760. {
  761. if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
  762. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry());
  763. }
  764. else
  765. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID));
  766. break;
  767. }
  768. case SPELL_COPY_OFFHAND_AURA:
  769. case SPELL_COPY_OFFHAND_2_AURA:
  770. {
  771. prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 1;
  772. if (Player* player = caster->ToPlayer())
  773. {
  774. if (Item* offItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
  775. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, offItem->GetEntry());
  776. }
  777. else
  778. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1));
  779. break;
  780. }
  781. case SPELL_COPY_RANGED_AURA:
  782. {
  783. prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 2;
  784. if (Player* player = caster->ToPlayer())
  785. {
  786. if (Item* rangedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
  787. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, rangedItem->GetEntry());
  788. }
  789. else
  790. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2));
  791. break;
  792. }
  793. default:
  794. break;
  795. }
  796. }
  797. void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  798. {
  799. Unit* target = GetTarget();
  800. switch (GetSpellInfo()->Id)
  801. {
  802. case SPELL_COPY_WEAPON_AURA:
  803. case SPELL_COPY_WEAPON_2_AURA:
  804. case SPELL_COPY_WEAPON_3_AURA:
  805. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, prevItem);
  806. break;
  807. case SPELL_COPY_OFFHAND_AURA:
  808. case SPELL_COPY_OFFHAND_2_AURA:
  809. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, prevItem);
  810. break;
  811. case SPELL_COPY_RANGED_AURA:
  812. target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, prevItem);
  813. break;
  814. default:
  815. break;
  816. }
  817. }
  818. void Register() override
  819. {
  820. OnEffectApply += AuraEffectApplyFn(spell_gen_clone_weapon_auraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
  821. OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
  822. }
  823. private:
  824. uint32 prevItem;
  825. };
  826. AuraScript* GetAuraScript() const override
  827. {
  828. return new spell_gen_clone_weapon_auraScript();
  829. }
  830. };
  831. class spell_gen_count_pct_from_max_hp : public SpellScriptLoader
  832. {
  833. public:
  834. spell_gen_count_pct_from_max_hp(char const* name, int32 damagePct = 0) : SpellScriptLoader(name), _damagePct(damagePct) { }
  835. class spell_gen_count_pct_from_max_hp_SpellScript : public SpellScript
  836. {
  837. PrepareSpellScript(spell_gen_count_pct_from_max_hp_SpellScript);
  838. public:
  839. spell_gen_count_pct_from_max_hp_SpellScript(int32 damagePct) : SpellScript(), _damagePct(damagePct) { }
  840. void RecalculateDamage()
  841. {
  842. if (!_damagePct)
  843. _damagePct = GetHitDamage();
  844. SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(_damagePct));
  845. }
  846. void Register() override
  847. {
  848. OnHit += SpellHitFn(spell_gen_count_pct_from_max_hp_SpellScript::RecalculateDamage);
  849. }
  850. private:
  851. int32 _damagePct;
  852. };
  853. SpellScript* GetSpellScript() const override
  854. {
  855. return new spell_gen_count_pct_from_max_hp_SpellScript(_damagePct);
  856. }
  857. private:
  858. int32 _damagePct;
  859. };
  860. // 63845 - Create Lance
  861. enum CreateLanceSpells
  862. {
  863. SPELL_CREATE_LANCE_ALLIANCE = 63914,
  864. SPELL_CREATE_LANCE_HORDE = 63919
  865. };
  866. class spell_gen_create_lance : public SpellScriptLoader
  867. {
  868. public:
  869. spell_gen_create_lance() : SpellScriptLoader("spell_gen_create_lance") { }
  870. class spell_gen_create_lance_SpellScript : public SpellScript
  871. {
  872. PrepareSpellScript(spell_gen_create_lance_SpellScript);
  873. bool Validate(SpellInfo const* /*spellInfo*/) override
  874. {
  875. if (!sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_ALLIANCE) ||
  876. !sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_HORDE))
  877. return false;
  878. return true;
  879. }
  880. void HandleScript(SpellEffIndex effIndex)
  881. {
  882. PreventHitDefaultEffect(effIndex);
  883. if (Player* target = GetHitPlayer())
  884. {
  885. if (target->GetTeam() == ALLIANCE)
  886. GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_ALLIANCE, true);
  887. else
  888. GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_HORDE, true);
  889. }
  890. }
  891. void Register() override
  892. {
  893. OnEffectHitTarget += SpellEffectFn(spell_gen_create_lance_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  894. }
  895. };
  896. SpellScript* GetSpellScript() const override
  897. {
  898. return new spell_gen_create_lance_SpellScript();
  899. }
  900. };
  901. class spell_gen_creature_permanent_feign_death : public SpellScriptLoader
  902. {
  903. public:
  904. spell_gen_creature_permanent_feign_death() : SpellScriptLoader("spell_gen_creature_permanent_feign_death") { }
  905. class spell_gen_creature_permanent_feign_death_AuraScript : public AuraScript
  906. {
  907. PrepareAuraScript(spell_gen_creature_permanent_feign_death_AuraScript);
  908. void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  909. {
  910. Unit* target = GetTarget();
  911. target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
  912. target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
  913. if (target->GetTypeId() == TYPEID_UNIT)
  914. target->ToCreature()->SetReactState(REACT_PASSIVE);
  915. }
  916. void Register() override
  917. {
  918. OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
  919. }
  920. };
  921. AuraScript* GetAuraScript() const override
  922. {
  923. return new spell_gen_creature_permanent_feign_death_AuraScript();
  924. }
  925. };
  926. enum DalaranDisguiseSpells
  927. {
  928. SPELL_SUNREAVER_DISGUISE_TRIGGER = 69672,
  929. SPELL_SUNREAVER_DISGUISE_FEMALE = 70973,
  930. SPELL_SUNREAVER_DISGUISE_MALE = 70974,
  931. SPELL_SILVER_COVENANT_DISGUISE_TRIGGER = 69673,
  932. SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971,
  933. SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972
  934. };
  935. class spell_gen_dalaran_disguise : public SpellScriptLoader
  936. {
  937. public:
  938. spell_gen_dalaran_disguise(const char* name) : SpellScriptLoader(name) { }
  939. class spell_gen_dalaran_disguise_SpellScript : public SpellScript
  940. {
  941. PrepareSpellScript(spell_gen_dalaran_disguise_SpellScript);
  942. bool Validate(SpellInfo const* spellInfo) override
  943. {
  944. switch (spellInfo->Id)
  945. {
  946. case SPELL_SUNREAVER_DISGUISE_TRIGGER:
  947. if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_FEMALE) ||
  948. !sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_MALE))
  949. return false;
  950. break;
  951. case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER:
  952. if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) ||
  953. !sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_MALE))
  954. return false;
  955. break;
  956. }
  957. return true;
  958. }
  959. void HandleScript(SpellEffIndex /*effIndex*/)
  960. {
  961. if (Player* player = GetHitPlayer())
  962. {
  963. uint8 gender = player->getGender();
  964. uint32 spellId = GetSpellInfo()->Id;
  965. switch (spellId)
  966. {
  967. case SPELL_SUNREAVER_DISGUISE_TRIGGER:
  968. spellId = gender ? SPELL_SUNREAVER_DISGUISE_FEMALE : SPELL_SUNREAVER_DISGUISE_MALE;
  969. break;
  970. case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER:
  971. spellId = gender ? SPELL_SILVER_COVENANT_DISGUISE_FEMALE : SPELL_SILVER_COVENANT_DISGUISE_MALE;
  972. break;
  973. default:
  974. break;
  975. }
  976. GetCaster()->CastSpell(player, spellId, true);
  977. }
  978. }
  979. void Register() override
  980. {
  981. OnEffectHitTarget += SpellEffectFn(spell_gen_dalaran_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  982. }
  983. };
  984. SpellScript* GetSpellScript() const override
  985. {
  986. return new spell_gen_dalaran_disguise_SpellScript();
  987. }
  988. };
  989. enum DefendVisuals
  990. {
  991. SPELL_VISUAL_SHIELD_1 = 63130,
  992. SPELL_VISUAL_SHIELD_2 = 63131,
  993. SPELL_VISUAL_SHIELD_3 = 63132
  994. };
  995. class spell_gen_defend : public SpellScriptLoader
  996. {
  997. public:
  998. spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { }
  999. class spell_gen_defend_AuraScript : public AuraScript
  1000. {
  1001. PrepareAuraScript(spell_gen_defend_AuraScript);
  1002. bool Validate(SpellInfo const* /*spellInfo*/) override
  1003. {
  1004. if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_1))
  1005. return false;
  1006. if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_2))
  1007. return false;
  1008. if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_3))
  1009. return false;
  1010. return true;
  1011. }
  1012. void RefreshVisualShields(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
  1013. {
  1014. if (GetCaster())
  1015. {
  1016. Unit* target = GetTarget();
  1017. for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i)
  1018. target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i);
  1019. target->CastSpell(target, SPELL_VISUAL_SHIELD_1 + GetAura()->GetStackAmount() - 1, true, NULL, aurEff);
  1020. }
  1021. else
  1022. GetTarget()->RemoveAurasDueToSpell(GetId());
  1023. }
  1024. void RemoveVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  1025. {
  1026. for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i)
  1027. GetTarget()->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i);
  1028. }
  1029. void RemoveDummyFromDriver(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  1030. {
  1031. if (Unit* caster = GetCaster())
  1032. if (TempSummon* vehicle = caster->ToTempSummon())
  1033. if (Unit* rider = vehicle->GetSummoner())
  1034. rider->RemoveAurasDueToSpell(GetId());
  1035. }
  1036. void Register() override
  1037. {
  1038. SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId);
  1039. // Defend spells cast by NPCs (add visuals)
  1040. if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
  1041. {
  1042. AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
  1043. OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
  1044. }
  1045. // Remove Defend spell from player when he dismounts
  1046. if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
  1047. OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
  1048. // Defend spells cast by players (add/remove visuals)
  1049. if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)
  1050. {
  1051. AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
  1052. OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
  1053. }
  1054. }
  1055. };
  1056. AuraScript* GetAuraScript() const override
  1057. {
  1058. return new spell_gen_defend_AuraScript();
  1059. }
  1060. };
  1061. class spell_gen_despawn_self : public SpellScriptLoader
  1062. {
  1063. public:
  1064. spell_gen_despawn_self() : SpellScriptLoader("spell_gen_despawn_self") { }
  1065. class spell_gen_despawn_self_SpellScript : public SpellScript
  1066. {
  1067. PrepareSpellScript(spell_gen_despawn_self_SpellScript);
  1068. bool Load() override
  1069. {
  1070. return GetCaster()->GetTypeId() == TYPEID_UNIT;
  1071. }
  1072. void HandleDummy(SpellEffIndex effIndex)
  1073. {
  1074. if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT)
  1075. GetCaster()->ToCreature()->DespawnOrUnsummon();
  1076. }
  1077. void Register() override
  1078. {
  1079. OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_self_SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY);
  1080. }
  1081. };
  1082. SpellScript* GetSpellScript() const override
  1083. {
  1084. return new spell_gen_despawn_self_SpellScript();
  1085. }
  1086. };
  1087. enum DivineStormSpell
  1088. {
  1089. SPELL_DIVINE_STORM = 53385,
  1090. };
  1091. // 70769 Divine Storm!
  1092. class spell_gen_divine_storm_cd_reset : public SpellScriptLoader
  1093. {
  1094. public:
  1095. spell_gen_divine_storm_cd_reset() : SpellScriptLoader("spell_gen_divine_storm_cd_reset") { }
  1096. class spell_gen_divine_storm_cd_reset_SpellScript : public SpellScript
  1097. {
  1098. PrepareSpellScript(spell_gen_divine_storm_cd_reset_SpellScript);
  1099. bool Load() override
  1100. {
  1101. return GetCaster()->GetTypeId() == TYPEID_PLAYER;
  1102. }
  1103. bool Validate(SpellInfo const* /*spellInfo*/) override
  1104. {
  1105. if (!sSpellMgr->GetSpellInfo(SPELL_DIVINE_STORM))
  1106. return false;
  1107. return true;
  1108. }
  1109. void HandleScript(SpellEffIndex /*effIndex*/)
  1110. {
  1111. Player* caster = GetCaster()->ToPlayer();
  1112. if (caster->GetSpellHistory()->HasCooldown(SPELL_DIVINE_STORM))
  1113. caster->GetSpellHistory()->ResetCooldown(SPELL_DIVINE_STORM, true);
  1114. }
  1115. void Register() override
  1116. {
  1117. OnEffectHitTarget += SpellEffectFn(spell_gen_divine_storm_cd_reset_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
  1118. }
  1119. };
  1120. SpellScript* GetSpellScript() const override
  1121. {
  1122. return new spell_gen_divine_storm_cd_reset_SpellScript();
  1123. }
  1124. };
  1125. class spell_gen_ds_flush_knockback : public SpellScriptLoader
  1126. {
  1127. public:
  1128. spell_gen_ds_flush_knockback() : SpellScriptLoader("spell_gen_ds_flush_knockback") { }
  1129. class spell_gen_ds_flush_knockback_SpellScript : public SpellScript
  1130. {
  1131. PrepareSpellScript(spell_gen_ds_flush_knockback_SpellScript);
  1132. void HandleScript(SpellEffIndex /*effIndex*/)
  1133. {
  1134. // Here the target is the water spout and determines the position where the player is knocked from
  1135. if (Unit* target = GetHitUnit())
  1136. {
  1137. if (Player* player = GetCaster()->ToPlayer())
  1138. {
  1139. float horizontalSpeed = 20.0f + (40.0f - GetCaster()->GetDistance(target));
  1140. float verticalSpeed = 8.0f;
  1141. // This method relies on the Dalaran Sewer map disposition and Water Spout position
  1142. // What we do is knock the player from a position exactly behind him and at the end of the pipe
  1143. player->KnockbackFrom(target->GetPositionX(), player->GetPositionY(