PageRenderTime 57ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/3.3.5/src/server/scripts/EasternKingdoms/MoltenCore/boss_ragnaros.cpp

https://github.com/ShadowCore/ShadowCore
C++ | 432 lines | 323 code | 64 blank | 45 comment | 69 complexity | 764b4a771f9b43f3bfdd5339d07cd02c MD5 | raw file
  1. /*
  2. * Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
  3. * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* ScriptData
  19. SDName: Boss_Ragnaros
  20. SD%Complete: 95
  21. SDComment: missing effects in intro (summon, majordomos tele) annd some spells doesnt work correctly
  22. SDCategory: Molten Core
  23. EndScriptData */
  24. #include "ScriptPCH.h"
  25. #include "molten_core.h"
  26. #define SAY_REINFORCEMENTS1 -1409013
  27. #define SAY_REINFORCEMENTS2 -1409014
  28. #define SAY_HAND -1409015
  29. #define SAY_WRATH -1409016
  30. #define SAY_KILL -1409017
  31. #define SAY_MAGMABURST -1409018
  32. #define SPELL_HANDOFRAGNAROS 19780
  33. #define SPELL_WRATHOFRAGNAROS 20566
  34. #define SPELL_LAVABURST 21158
  35. #define SPELL_MAGMABURST 20565 //Ranged attack
  36. #define SPELL_SONSOFFLAME_DUMMY 21108 //Server side effect
  37. #define SPELL_RAGSUBMERGE 21107 //Stealth aura
  38. #define SPELL_RAGEMERGE 20568
  39. #define SPELL_MELTWEAPON 21388
  40. #define SPELL_ELEMENTALFIRE 20564
  41. #define SPELL_ERRUPTION 17731
  42. #define SAY_SUMMON_MAJ -1409008 //intro
  43. #define SAY_ARRIVAL1_RAG -1409009
  44. #define SAY_ARRIVAL2_MAJ -1409010
  45. #define SAY_ARRIVAL3_RAG -1409011
  46. #define SAY_ARRIVAL5_RAG -1409012
  47. #define UNIT_DYNFLAG_ROOTED 8
  48. #define ADD_1X 848.740356
  49. #define ADD_1Y -816.103455
  50. #define ADD_1Z -229.74327
  51. #define ADD_1O 2.615287
  52. #define ADD_2X 852.560791
  53. #define ADD_2Y -849.861511
  54. #define ADD_2Z -228.560974
  55. #define ADD_2O 2.836073
  56. #define ADD_3X 808.710632
  57. #define ADD_3Y -852.845764
  58. #define ADD_3Z -227.914963
  59. #define ADD_3O 0.964207
  60. #define ADD_4X 786.597107
  61. #define ADD_4Y -821.132874
  62. #define ADD_4Z -226.350128
  63. #define ADD_4O 0.949377
  64. #define ADD_5X 796.219116
  65. #define ADD_5Y -800.948059
  66. #define ADD_5Z -226.010361
  67. #define ADD_5O 0.560603
  68. #define ADD_6X 821.602539
  69. #define ADD_6Y -782.744109
  70. #define ADD_6Z -226.023575
  71. #define ADD_6O 6.157440
  72. #define ADD_7X 844.924744
  73. #define ADD_7Y -769.453735
  74. #define ADD_7Z -225.521698
  75. #define ADD_7O 4.4539958
  76. #define ADD_8X 839.823364
  77. #define ADD_8Y -810.869385
  78. #define ADD_8Z -229.683182
  79. #define ADD_8O 4.693108
  80. class boss_ragnaros : public CreatureScript
  81. {
  82. public:
  83. boss_ragnaros() : CreatureScript("boss_ragnaros") { }
  84. CreatureAI* GetAI(Creature* pCreature) const
  85. {
  86. return new boss_ragnarosAI (pCreature);
  87. }
  88. struct boss_ragnarosAI : public BossAI
  89. {
  90. boss_ragnarosAI(Creature *pCreature) : BossAI(pCreature, BOSS_RAGNAROS)
  91. {
  92. Intro_Timer = 0;
  93. Intro = 0;
  94. me->SetReactState(REACT_PASSIVE);
  95. me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  96. SetCombatMovement(false);
  97. }
  98. uint32 WrathOfRagnaros_Timer;
  99. uint32 HandOfRagnaros_Timer;
  100. uint32 LavaBurst_Timer;
  101. uint32 MagmaBurst_Timer;
  102. uint32 ElementalFire_Timer;
  103. uint32 Erruption_Timer;
  104. uint32 Submerge_Timer;
  105. uint32 Attack_Timer;
  106. uint32 Intro_Timer;
  107. uint8 Intro;
  108. bool HasYelledMagmaBurst;
  109. bool HasSubmergedOnce;
  110. bool WasBanished;
  111. bool HasAura;
  112. void Reset()
  113. {
  114. WrathOfRagnaros_Timer = 30000;
  115. HandOfRagnaros_Timer = 25000;
  116. LavaBurst_Timer = 10000;
  117. MagmaBurst_Timer = 2000;
  118. Erruption_Timer = 15000;
  119. ElementalFire_Timer = 3000;
  120. Submerge_Timer = 180000;
  121. Attack_Timer = 90000;
  122. HasYelledMagmaBurst = false;
  123. HasSubmergedOnce = false;
  124. WasBanished = false;
  125. DoCast(me, SPELL_MELTWEAPON, true);
  126. HasAura = true;
  127. me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
  128. }
  129. void KilledUnit(Unit* /*victim*/)
  130. {
  131. if (rand()%5)
  132. return;
  133. DoScriptText(SAY_KILL, me);
  134. }
  135. void EnterCombat(Unit * /*who*/)
  136. {
  137. }
  138. void UpdateAI(const uint32 diff)
  139. {
  140. if (Intro == 1)
  141. {
  142. if (Intro_Timer <= diff)
  143. {
  144. DoScriptText(SAY_ARRIVAL1_RAG, me);
  145. Intro_Timer = 18000;
  146. Intro = 2;
  147. } else Intro_Timer -= diff;
  148. }
  149. else if (Intro == 2)
  150. {
  151. if (Intro_Timer <= diff)
  152. {
  153. DoScriptText(SAY_ARRIVAL3_RAG, me);
  154. Intro_Timer = 19000;
  155. Intro = 3;
  156. } else Intro_Timer -= diff;
  157. }
  158. else if (Intro == 3)
  159. {
  160. if (Intro_Timer <= diff)
  161. {
  162. me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H);
  163. Intro_Timer = 1000;
  164. Intro = 4;
  165. } else Intro_Timer -= diff;
  166. }
  167. else if (Intro == 4)
  168. {
  169. if (Intro_Timer <= diff)
  170. {
  171. DoScriptText(SAY_ARRIVAL5_RAG, me);
  172. if (instance)
  173. if (Creature *pMajordomo = me->GetCreature(*me, instance->GetData64(DATA_MAJORDOMO_GUID)))
  174. me->Kill(pMajordomo);
  175. Intro_Timer = 10000;
  176. Intro = 5;
  177. } else Intro_Timer -= diff;
  178. }
  179. else if (Intro == 5)
  180. {
  181. if (Intro_Timer <= diff)
  182. {
  183. me->SetReactState(REACT_AGGRESSIVE);
  184. me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  185. Intro = 6;
  186. } else Intro_Timer -= diff;
  187. }
  188. else if (Intro == 6)
  189. {
  190. if (instance)
  191. {
  192. if (WasBanished && ((Attack_Timer <= diff) || (instance->GetData(DATA_RAG_ELE_COUNTER)) > 8))
  193. {
  194. //Become unbanished again
  195. me->SetReactState(REACT_AGGRESSIVE);
  196. me->setFaction(14);
  197. me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  198. me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
  199. me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
  200. if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
  201. AttackStart(pTarget);
  202. instance->SetData(DATA_RAG_ELE_COUNTER, 0);
  203. //DoCast(me, SPELL_RAGEMERGE); //"phase spells" didnt worked correctly so Ive commented them and wrote solution witch doesnt need core support
  204. WasBanished = false;
  205. }
  206. else if (WasBanished)
  207. {
  208. Attack_Timer -= diff;
  209. //Do nothing while banished
  210. return;
  211. }
  212. }
  213. //Return since we have no target
  214. if (!UpdateVictim())
  215. return;
  216. //Erruption_Timer
  217. if (LavaBurst_Timer <= diff)
  218. {
  219. DoCast(me->getVictim(), SPELL_ERRUPTION);
  220. Erruption_Timer = urand(20000,45000);
  221. } else Erruption_Timer -= diff;
  222. //WrathOfRagnaros_Timer
  223. if (WrathOfRagnaros_Timer <= diff)
  224. {
  225. DoCast(me->getVictim(), SPELL_WRATHOFRAGNAROS);
  226. if (urand(0,1))
  227. DoScriptText(SAY_WRATH, me);
  228. WrathOfRagnaros_Timer = 25000;
  229. } else WrathOfRagnaros_Timer -= diff;
  230. //HandOfRagnaros_Timer
  231. if (HandOfRagnaros_Timer <= diff)
  232. {
  233. DoCast(me, SPELL_HANDOFRAGNAROS);
  234. if (urand(0,1))
  235. DoScriptText(SAY_HAND, me);
  236. HandOfRagnaros_Timer = 20000;
  237. } else HandOfRagnaros_Timer -= diff;
  238. //LavaBurst_Timer
  239. if (LavaBurst_Timer <= diff)
  240. {
  241. DoCast(me->getVictim(), SPELL_LAVABURST);
  242. LavaBurst_Timer = 10000;
  243. } else LavaBurst_Timer -= diff;
  244. //ElementalFire_Timer
  245. if (ElementalFire_Timer <= diff)
  246. {
  247. DoCast(me->getVictim(), SPELL_ELEMENTALFIRE);
  248. ElementalFire_Timer = urand(10000,14000);
  249. } else ElementalFire_Timer -= diff;
  250. //Submerge_Timer
  251. if (!WasBanished && Submerge_Timer <= diff && instance)
  252. {
  253. //Creature spawning and ragnaros becomming unattackable
  254. //is not very well supported in the core //no it really isnt
  255. //so added normaly spawning and banish workaround and attack again after 90 secs.
  256. me->AttackStop();
  257. DoResetThreat();
  258. me->SetReactState(REACT_PASSIVE);
  259. me->InterruptNonMeleeSpells(false);
  260. //Root self
  261. //DoCast(me, 23973);
  262. me->setFaction(35);
  263. me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  264. me->SetFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
  265. me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
  266. instance->SetData(DATA_RAG_ELE_COUNTER, 0);
  267. if (!HasSubmergedOnce)
  268. {
  269. DoScriptText(SAY_REINFORCEMENTS1, me);
  270. // summon 10 elementals
  271. for (uint8 i = 0; i < 9; ++i)
  272. {
  273. if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
  274. {
  275. if (Creature* pSummoned = me->SummonCreature(12143,pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000))
  276. pSummoned->AI()->AttackStart(pTarget);
  277. }
  278. }
  279. HasSubmergedOnce = true;
  280. WasBanished = true;
  281. //DoCast(me, SPELL_RAGSUBMERGE);
  282. Attack_Timer = 90000;
  283. }
  284. else
  285. {
  286. DoScriptText(SAY_REINFORCEMENTS2, me);
  287. for (uint8 i = 0; i < 9; ++i)
  288. {
  289. if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
  290. {
  291. if (Creature* pSummoned = me->SummonCreature(12143,pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000))
  292. pSummoned->AI()->AttackStart(pTarget);
  293. }
  294. }
  295. WasBanished = true;
  296. //DoCast(me, SPELL_RAGSUBMERGE);
  297. Attack_Timer = 90000;
  298. }
  299. Submerge_Timer = 180000;
  300. } else Submerge_Timer -= diff;
  301. //If we are within range melee the target
  302. if (me->IsWithinMeleeRange(me->getVictim()))
  303. {
  304. //Make sure our attack is ready and we arn't currently casting
  305. if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false))
  306. {
  307. me->AttackerStateUpdate(me->getVictim());
  308. me->resetAttackTimer();
  309. }
  310. }
  311. else
  312. {
  313. //MagmaBurst_Timer
  314. if (MagmaBurst_Timer <= diff)
  315. {
  316. DoCast(me->getVictim(), SPELL_MAGMABURST);
  317. if (!HasYelledMagmaBurst)
  318. {
  319. //Say our dialog
  320. DoScriptText(SAY_MAGMABURST, me);
  321. HasYelledMagmaBurst = true;
  322. }
  323. MagmaBurst_Timer = 2500;
  324. } else MagmaBurst_Timer -= diff;
  325. }
  326. }
  327. else
  328. {
  329. me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
  330. Intro_Timer = 4000;
  331. Intro = 1;
  332. }
  333. }
  334. };
  335. };
  336. class mob_SonOfFlame : public CreatureScript
  337. {
  338. public:
  339. mob_SonOfFlame() : CreatureScript("mob_SonOfFlame") { }
  340. CreatureAI* GetAI(Creature* pCreature) const
  341. {
  342. return new mob_SonOfFlameAI(pCreature);
  343. }
  344. struct mob_SonOfFlameAI : public ScriptedAI //didnt work correctly in EAI for me...
  345. {
  346. mob_SonOfFlameAI(Creature *c) : ScriptedAI(c)
  347. {
  348. pInstance = me->GetInstanceScript();
  349. }
  350. InstanceScript* pInstance;
  351. void JustDied(Unit * /*victim*/)
  352. {
  353. if (pInstance)
  354. pInstance->SetData(DATA_RAG_ELE_COUNTER, 1);
  355. }
  356. void UpdateAI(const uint32 /*diff*/)
  357. {
  358. if (!UpdateVictim())
  359. return;
  360. DoMeleeAttackIfReady();
  361. }
  362. };
  363. };
  364. void AddSC_boss_ragnaros()
  365. {
  366. new boss_ragnaros();
  367. new mob_SonOfFlame();
  368. }