PageRenderTime 222ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp

https://github.com/Teiby1/lastDivision-Repo
C++ | 415 lines | 333 code | 65 blank | 17 comment | 29 complexity | 757d62dce6a38175fab942985b03b2ce MD5 | raw file
  1. /*
  2. * Copyright (C) 2008-2011 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. #include "ScriptPCH.h"
  18. #include "SpellAuraEffects.h"
  19. #include "forge_of_souls.h"
  20. enum Yells
  21. {
  22. SAY_AGGRO = -1632001,
  23. SAY_SLAY_1 = -1632002,
  24. SAY_SLAY_2 = -1632003,
  25. SAY_DEATH = -1632004,
  26. SAY_SOUL_STORM = -1632005,
  27. SAY_CORRUPT_SOUL = -1632006,
  28. };
  29. enum Spells
  30. {
  31. SPELL_MAGIC_S_BANE = 68793,
  32. SPELL_SHADOW_BOLT = 70043,
  33. SPELL_CORRUPT_SOUL = 68839,
  34. SPELL_CONSUME_SOUL = 68861,
  35. SPELL_TELEPORT = 68988,
  36. SPELL_FEAR = 68950,
  37. SPELL_SOULSTORM = 68872,
  38. SPELL_SOULSTORM_CHANNEL = 69008, // pre-fight
  39. SPELL_SOULSTORM_VISUAL = 68870, // pre-cast soulstorm
  40. SPELL_PURPLE_BANISH_VISUAL = 68862 // Used by Soul Fragment (Aura)
  41. };
  42. enum Events
  43. {
  44. EVENT_MAGIC_BANE = 1,
  45. EVENT_SHADOW_BOLT = 2,
  46. EVENT_CORRUPT_SOUL = 3,
  47. EVENT_SOULSTORM = 4,
  48. EVENT_FEAR = 5,
  49. };
  50. enum CombatPhases
  51. {
  52. PHASE_1 = 1,
  53. PHASE_2 = 2
  54. };
  55. class boss_bronjahm : public CreatureScript
  56. {
  57. public:
  58. boss_bronjahm() : CreatureScript("boss_bronjahm") { }
  59. struct boss_bronjahmAI : public BossAI
  60. {
  61. boss_bronjahmAI(Creature* creature) : BossAI(creature, DATA_BRONJAHM)
  62. {
  63. }
  64. void InitializeAI()
  65. {
  66. if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != sObjectMgr->GetScriptId(FoSScriptName))
  67. me->IsAIEnabled = false;
  68. else if (!me->isDead())
  69. Reset();
  70. }
  71. void Reset()
  72. {
  73. events.Reset();
  74. events.SetPhase(PHASE_1);
  75. events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
  76. events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 15000));
  77. events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000, 35000), 0, PHASE_1);
  78. me->CastSpell(me, SPELL_SOULSTORM_CHANNEL, true);
  79. instance->SetBossState(DATA_BRONJAHM, NOT_STARTED);
  80. }
  81. void EnterCombat(Unit* /*who*/)
  82. {
  83. DoScriptText(SAY_AGGRO, me);
  84. me->RemoveAurasDueToSpell(SPELL_SOULSTORM_CHANNEL);
  85. instance->SetBossState(DATA_BRONJAHM, IN_PROGRESS);
  86. }
  87. void JustDied(Unit* /*killer*/)
  88. {
  89. DoScriptText(SAY_DEATH, me);
  90. instance->SetBossState(DATA_BRONJAHM, DONE);
  91. }
  92. void KilledUnit(Unit* who)
  93. {
  94. if (who->GetTypeId() == TYPEID_PLAYER)
  95. DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me);
  96. }
  97. void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
  98. {
  99. if (events.GetPhaseMask() & (1 << PHASE_1) && !HealthAbovePct(30))
  100. {
  101. events.SetPhase(PHASE_2);
  102. DoCast(me, SPELL_TELEPORT);
  103. events.ScheduleEvent(EVENT_FEAR, urand(12000, 16000), 0, PHASE_2);
  104. events.ScheduleEvent(EVENT_SOULSTORM, 700, 0, PHASE_2);
  105. }
  106. }
  107. void JustSummoned(Creature* summon)
  108. {
  109. summons.Summon(summon);
  110. summon->SetReactState(REACT_PASSIVE);
  111. summon->GetMotionMaster()->Clear();
  112. summon->GetMotionMaster()->MoveFollow(me, me->GetObjectSize(), 0.0f);
  113. summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true);
  114. }
  115. void UpdateAI(const uint32 diff)
  116. {
  117. if (!UpdateVictim())
  118. return;
  119. events.Update(diff);
  120. if (me->HasUnitState(UNIT_STAT_CASTING))
  121. return;
  122. while (uint32 eventId = events.ExecuteEvent())
  123. {
  124. switch(eventId)
  125. {
  126. case EVENT_MAGIC_BANE:
  127. DoCastVictim(SPELL_MAGIC_S_BANE);
  128. events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 15000));
  129. break;
  130. case EVENT_SHADOW_BOLT:
  131. if (!me->IsWithinMeleeRange(me->getVictim()))
  132. DoCastVictim(SPELL_SHADOW_BOLT);
  133. events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
  134. break;
  135. case EVENT_CORRUPT_SOUL:
  136. if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
  137. {
  138. DoScriptText(SAY_CORRUPT_SOUL, me);
  139. DoCast(target, SPELL_CORRUPT_SOUL);
  140. }
  141. events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000, 35000), 0, PHASE_1);
  142. break;
  143. case EVENT_SOULSTORM:
  144. DoScriptText(SAY_SOUL_STORM, me);
  145. me->CastSpell(me, SPELL_SOULSTORM_VISUAL, true);
  146. me->CastSpell(me, SPELL_SOULSTORM, false);
  147. break;
  148. case EVENT_FEAR:
  149. if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
  150. me->CastCustomSpell(SPELL_FEAR, SPELLVALUE_MAX_TARGETS, 1, target, false);
  151. events.ScheduleEvent(EVENT_FEAR, urand(8000, 12000), 0, PHASE_2);
  152. break;
  153. default:
  154. break;
  155. }
  156. }
  157. DoMeleeAttackIfReady();
  158. }
  159. };
  160. CreatureAI *GetAI(Creature* creature) const
  161. {
  162. return new boss_bronjahmAI(creature);
  163. }
  164. };
  165. class mob_corrupted_soul_fragment : public CreatureScript
  166. {
  167. public:
  168. mob_corrupted_soul_fragment() : CreatureScript("mob_corrupted_soul_fragment") { }
  169. struct mob_corrupted_soul_fragmentAI : public ScriptedAI
  170. {
  171. mob_corrupted_soul_fragmentAI(Creature* creature) : ScriptedAI(creature)
  172. {
  173. instance = me->GetInstanceScript();
  174. }
  175. void MovementInform(uint32 type, uint32 id)
  176. {
  177. if (type != TARGETED_MOTION_TYPE)
  178. return;
  179. uint64 BronjahmGUID = 0;
  180. if (instance)
  181. {
  182. if (TempSummon* summ = me->ToTempSummon())
  183. {
  184. BronjahmGUID = instance->GetData64(DATA_BRONJAHM);
  185. if (GUID_LOPART(BronjahmGUID) != id)
  186. return;
  187. if (Creature* bronjahm = ObjectAccessor::GetCreature(*me, BronjahmGUID))
  188. me->CastSpell(bronjahm, SPELL_CONSUME_SOUL, true);
  189. summ->GetMotionMaster()->MoveIdle();
  190. summ->UnSummon();
  191. }
  192. }
  193. }
  194. private:
  195. InstanceScript* instance;
  196. };
  197. CreatureAI *GetAI(Creature* creature) const
  198. {
  199. return new mob_corrupted_soul_fragmentAI(creature);
  200. }
  201. };
  202. class spell_bronjahm_magic_bane : public SpellScriptLoader
  203. {
  204. public:
  205. spell_bronjahm_magic_bane() : SpellScriptLoader("spell_bronjahm_magic_bane") { }
  206. class spell_bronjahm_magic_bane_SpellScript : public SpellScript
  207. {
  208. PrepareSpellScript(spell_bronjahm_magic_bane_SpellScript);
  209. void RecalculateDamage()
  210. {
  211. if (GetHitUnit()->getPowerType() != POWER_MANA)
  212. return;
  213. const int32 maxDamage = GetCaster()->GetMap()->GetSpawnMode() == 1 ? 15000 : 10000;
  214. int32 newDamage = GetHitDamage();
  215. newDamage += GetHitUnit()->GetMaxPower(POWER_MANA)/2;
  216. newDamage = std::min<int32>(maxDamage, newDamage);
  217. SetHitDamage(newDamage);
  218. }
  219. void Register()
  220. {
  221. OnHit += SpellHitFn(spell_bronjahm_magic_bane_SpellScript::RecalculateDamage);
  222. }
  223. };
  224. SpellScript* GetSpellScript() const
  225. {
  226. return new spell_bronjahm_magic_bane_SpellScript();
  227. }
  228. };
  229. class spell_bronjahm_consume_soul : public SpellScriptLoader
  230. {
  231. public:
  232. spell_bronjahm_consume_soul() : SpellScriptLoader("spell_bronjahm_consume_soul") { }
  233. class spell_bronjahm_consume_soul_SpellScript : public SpellScript
  234. {
  235. PrepareSpellScript(spell_bronjahm_consume_soul_SpellScript);
  236. void HandleScript(SpellEffIndex effIndex)
  237. {
  238. PreventHitDefaultEffect(effIndex);
  239. GetHitUnit()->CastSpell(GetHitUnit(), GetEffectValue(), true);
  240. }
  241. void Register()
  242. {
  243. OnEffect += SpellEffectFn(spell_bronjahm_consume_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  244. }
  245. };
  246. SpellScript* GetSpellScript() const
  247. {
  248. return new spell_bronjahm_consume_soul_SpellScript();
  249. }
  250. };
  251. class spell_bronjahm_soulstorm_channel : public SpellScriptLoader
  252. {
  253. public:
  254. spell_bronjahm_soulstorm_channel() : SpellScriptLoader("spell_bronjahm_soulstorm_channel") { }
  255. class spell_bronjahm_soulstorm_channel_AuraScript : public AuraScript
  256. {
  257. PrepareAuraScript(spell_bronjahm_soulstorm_channel_AuraScript);
  258. void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
  259. {
  260. PreventDefaultAction();
  261. for (uint32 i = 68904; i <= 68907; ++i)
  262. GetTarget()->CastSpell(GetTarget(), i, true);
  263. }
  264. void Register()
  265. {
  266. OnEffectPeriodic += AuraEffectPeriodicFn(spell_bronjahm_soulstorm_channel_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
  267. }
  268. };
  269. AuraScript* GetAuraScript() const
  270. {
  271. return new spell_bronjahm_soulstorm_channel_AuraScript();
  272. }
  273. };
  274. class spell_bronjahm_soulstorm_visual : public SpellScriptLoader
  275. {
  276. public:
  277. spell_bronjahm_soulstorm_visual() : SpellScriptLoader("spell_bronjahm_soulstorm_visual") { }
  278. class spell_bronjahm_soulstorm_visual_AuraScript : public AuraScript
  279. {
  280. PrepareAuraScript(spell_bronjahm_soulstorm_visual_AuraScript);
  281. void HandlePeriodicTick(AuraEffect const* aurEff)
  282. {
  283. PreventDefaultAction();
  284. if (aurEff->GetTickNumber()%5)
  285. return;
  286. GetTarget()->CastSpell(GetTarget(), 68886, true);
  287. for (uint32 i = 68896; i <= 68898; ++i)
  288. GetTarget()->CastSpell(GetTarget(), i, true);
  289. }
  290. void Register()
  291. {
  292. OnEffectPeriodic += AuraEffectPeriodicFn(spell_bronjahm_soulstorm_visual_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
  293. }
  294. };
  295. AuraScript* GetAuraScript() const
  296. {
  297. return new spell_bronjahm_soulstorm_visual_AuraScript();
  298. }
  299. };
  300. class DistanceCheck
  301. {
  302. public:
  303. explicit DistanceCheck(Unit* _caster) : caster(_caster) { }
  304. bool operator() (Unit* unit)
  305. {
  306. if (caster->GetExactDist2d(unit) <= 10.0f)
  307. return true;
  308. return false;
  309. }
  310. Unit* caster;
  311. };
  312. class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
  313. {
  314. public:
  315. spell_bronjahm_soulstorm_targeting() : SpellScriptLoader("spell_bronjahm_soulstorm_targeting") { }
  316. class spell_bronjahm_soulstorm_targeting_SpellScript : public SpellScript
  317. {
  318. PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript);
  319. void FilterTargetsInitial(std::list<Unit*>& unitList)
  320. {
  321. unitList.remove_if(DistanceCheck(GetCaster()));
  322. sharedUnitList = unitList;
  323. }
  324. // use the same target for first and second effect
  325. void FilterTargetsSubsequent(std::list<Unit*>& unitList)
  326. {
  327. unitList = sharedUnitList;
  328. }
  329. void Register()
  330. {
  331. OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_AREA_ENEMY_DST);
  332. OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_AREA_ENEMY_DST);
  333. }
  334. std::list<Unit*> sharedUnitList;
  335. };
  336. SpellScript* GetSpellScript() const
  337. {
  338. return new spell_bronjahm_soulstorm_targeting_SpellScript();
  339. }
  340. };
  341. void AddSC_boss_bronjahm()
  342. {
  343. new boss_bronjahm();
  344. new mob_corrupted_soul_fragment();
  345. new spell_bronjahm_magic_bane();
  346. new spell_bronjahm_consume_soul();
  347. new spell_bronjahm_soulstorm_channel();
  348. new spell_bronjahm_soulstorm_visual();
  349. new spell_bronjahm_soulstorm_targeting();
  350. }