PageRenderTime 1826ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_ragefire.cpp

https://github.com/chucho/FaceCore
C++ | 402 lines | 320 code | 64 blank | 18 comment | 56 complexity | f9fcb035628856172a20914aa7c3c03c MD5 | raw file
  1. /*
  2. * Copyright (C) 2008-2010 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 "ruby_sanctum.h"
  19. enum BossSpells
  20. {
  21. SPELL_ENRAGE = 78722, //soft enrage + fire nova
  22. SPELL_FLAME_BREATH = 74404,
  23. SPELL_BEACON = 74453, //mark for conflag, in enter to fly phase, 2 in 10, 5 in 25
  24. SPELL_CONFLAGATION = 74452, // after fly up
  25. SPELL_CONFLAGATION_1 = 74454, // Triggered?
  26. SPELL_CONFLAGATION_2 = 74456, // Aura
  27. };
  28. struct Locations
  29. {
  30. float x, y, z;
  31. };
  32. static Locations SpawnLoc[]=
  33. {
  34. {3151.3898f, 636.8519f, 78.7396f}, // 0 Saviana start point
  35. {3149.635f, 668.9644f, 90.507f}, // 1 Saviana fly phase, o=4,69
  36. };
  37. #define TARGETS_10 2
  38. #define TARGETS_25 5
  39. class boss_ragefire : public CreatureScript
  40. {
  41. public:
  42. boss_ragefire() : CreatureScript("boss_ragefire") { }
  43. CreatureAI* GetAI(Creature* pCreature) const
  44. {
  45. return new boss_ragefireAI(pCreature);
  46. }
  47. struct boss_ragefireAI : public ScriptedAI
  48. {
  49. boss_ragefireAI(Creature* pCreature) : ScriptedAI(pCreature)
  50. {
  51. pInstance = (InstanceScript*)pCreature->GetInstanceScript();
  52. Reset();
  53. }
  54. InstanceScript* pInstance;
  55. uint8 nextPoint;
  56. uint8 stage;
  57. uint32 m_uiFlameBreathTimer;
  58. uint32 m_uiEnrage;
  59. uint32 m_uiBeakonTimer;
  60. uint32 m_uiConflagrateTimer;
  61. bool MovementStarted;
  62. bool conflagated;
  63. void Reset()
  64. {
  65. if(!pInstance)
  66. return;
  67. me->SetRespawnDelay(7*DAY);
  68. if (me->isAlive()) pInstance->SetData(TYPE_RAGEFIRE, NOT_STARTED);
  69. m_uiFlameBreathTimer = urand(5*IN_MILLISECONDS,15*IN_MILLISECONDS);
  70. m_uiEnrage = urand(20*IN_MILLISECONDS,40*IN_MILLISECONDS);
  71. m_uiBeakonTimer = urand(12*IN_MILLISECONDS,22*IN_MILLISECONDS);
  72. m_uiConflagrateTimer = 5*IN_MILLISECONDS;
  73. setStage(0);
  74. nextPoint = 0;
  75. conflagated = false;
  76. playerList.clear();
  77. }
  78. void setStage(uint8 phase)
  79. {
  80. stage = phase;
  81. }
  82. uint8 getStage()
  83. {
  84. return stage;
  85. }
  86. void MovementInform(uint32 type, uint32 id)
  87. {
  88. if (!pInstance) return;
  89. if (type != POINT_MOTION_TYPE || !MovementStarted) return;
  90. if (id == nextPoint) {
  91. me->GetMotionMaster()->MovementExpired();
  92. MovementStarted = false;
  93. }
  94. }
  95. void SetFly(bool command = false)
  96. {
  97. if (command)
  98. {
  99. me->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP);
  100. me->SetFlying(true);
  101. }
  102. else
  103. {
  104. me->SetFlying(false);
  105. }
  106. }
  107. void StartMovement(uint32 id)
  108. {
  109. nextPoint = id;
  110. me->GetMotionMaster()->Clear();
  111. me->GetMotionMaster()->MovePoint(id, SpawnLoc[id].x, SpawnLoc[id].y, SpawnLoc[id].z);
  112. MovementStarted = true;
  113. }
  114. void KilledUnit(Unit* pVictim)
  115. {
  116. switch (urand(0,1)) {
  117. case 0:
  118. DoScriptText(-1666401,me,pVictim);
  119. break;
  120. case 1:
  121. DoScriptText(-1666402,me,pVictim);
  122. break;
  123. }
  124. }
  125. void JustReachedHome()
  126. {
  127. if (pInstance)
  128. pInstance->SetData(TYPE_RAGEFIRE, FAIL);
  129. }
  130. void EnterCombat(Unit *who)
  131. {
  132. if(!pInstance) return;
  133. pInstance->SetData(TYPE_RAGEFIRE, IN_PROGRESS);
  134. me->SetInCombatWithZone();
  135. DoScriptText(-1666400,me);
  136. }
  137. void JustDied(Unit *killer)
  138. {
  139. if(!pInstance) return;
  140. pInstance->SetData(TYPE_RAGEFIRE, DONE);
  141. DoScriptText(-1666403,me);
  142. }
  143. void doBeacon(bool command = false)
  144. {
  145. if (command)
  146. {
  147. SelectTargetList(playerList, RAID_MODE(TARGETS_10,TARGETS_25,TARGETS_10,TARGETS_25), SELECT_TARGET_RANDOM, 0, true);
  148. for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
  149. {
  150. Unit *pTemp = (*itr);
  151. me->CastSpell(pTemp, SPELL_BEACON, true);
  152. }
  153. conflagated = true;
  154. }
  155. else
  156. {
  157. me->InterruptNonMeleeSpells(true);
  158. for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
  159. {
  160. Unit *pTemp = (*itr);
  161. me->CastSpell(pTemp, SPELL_CONFLAGATION_2, true);
  162. }
  163. playerList.clear();
  164. conflagated = false;
  165. }
  166. }
  167. void UpdateAI(const uint32 diff)
  168. {
  169. if (!UpdateVictim())
  170. return;
  171. switch (getStage())
  172. {
  173. case 0: //GROUND
  174. if (m_uiFlameBreathTimer <= diff)
  175. {
  176. DoCast(SPELL_FLAME_BREATH);
  177. m_uiFlameBreathTimer = urand(5*IN_MILLISECONDS,15*IN_MILLISECONDS);
  178. } else m_uiFlameBreathTimer -= diff;
  179. if (m_uiEnrage <= diff)
  180. {
  181. DoCast(SPELL_ENRAGE);
  182. m_uiEnrage = urand(20*IN_MILLISECONDS,40*IN_MILLISECONDS);
  183. DoScriptText(-1666405,me);
  184. } else m_uiEnrage -= diff;
  185. if ( HealthBelowPct(81) ) setStage(1);
  186. break;
  187. case 1: //Air phase start
  188. SetCombatMovement(false);
  189. me->InterruptNonMeleeSpells(true);
  190. SetFly(true);
  191. doBeacon(true);
  192. StartMovement(1);
  193. setStage(2);
  194. break;
  195. case 2: // Wait for movement
  196. if (MovementStarted) return;
  197. DoCast(SPELL_CONFLAGATION);
  198. DoScriptText(-1666404,me);
  199. setStage(3);
  200. break;
  201. case 3: // Wait for cast finish
  202. if (!me->IsNonMeleeSpellCasted(false))
  203. {
  204. doBeacon(false);
  205. setStage(4);
  206. }
  207. break;
  208. case 4: // Air phase
  209. if (m_uiFlameBreathTimer <= diff)
  210. {
  211. DoCast(SPELL_FLAME_BREATH);
  212. m_uiFlameBreathTimer = urand(5*IN_MILLISECONDS,15*IN_MILLISECONDS);
  213. } else m_uiFlameBreathTimer -= diff;
  214. if (m_uiBeakonTimer <= diff)
  215. {
  216. doBeacon(true);
  217. DoCast(SPELL_CONFLAGATION);
  218. m_uiBeakonTimer = urand(12*IN_MILLISECONDS,22*IN_MILLISECONDS);
  219. } else m_uiBeakonTimer -= diff;
  220. if (m_uiConflagrateTimer <= diff)
  221. {
  222. if (conflagated)
  223. {
  224. //DoCast(SPELL_CONFLAGATION_1);
  225. doBeacon(false);
  226. }
  227. m_uiConflagrateTimer = 5*IN_MILLISECONDS;
  228. } else m_uiConflagrateTimer -= diff;
  229. if ( HealthBelowPct(61) ) setStage(5);
  230. break;
  231. case 5: //Air phase end
  232. StartMovement(0);
  233. setStage(6);
  234. break;
  235. case 6: // Wait for movement
  236. if (MovementStarted) return;
  237. SetFly(false);
  238. SetCombatMovement(true);
  239. me->GetMotionMaster()->Clear();
  240. me->GetMotionMaster()->MoveChase(me->getVictim());
  241. setStage(7);
  242. break;
  243. case 7: //GROUND
  244. if (m_uiFlameBreathTimer <= diff)
  245. {
  246. DoCast(SPELL_FLAME_BREATH);
  247. m_uiFlameBreathTimer = urand(5*IN_MILLISECONDS,15*IN_MILLISECONDS);
  248. } else m_uiFlameBreathTimer -= diff;
  249. if (m_uiEnrage <= diff)
  250. {
  251. DoCast(SPELL_ENRAGE);
  252. m_uiEnrage = urand(20*IN_MILLISECONDS,40*IN_MILLISECONDS);
  253. DoScriptText(-1666405,me);
  254. } else m_uiEnrage -= diff;
  255. if ( HealthBelowPct(41) ) setStage(8);
  256. break;
  257. case 8: //Air phase start
  258. SetCombatMovement(false);
  259. me->InterruptNonMeleeSpells(true);
  260. SetFly(true);
  261. doBeacon(true);
  262. StartMovement(1);
  263. setStage(9);
  264. break;
  265. case 9: // Wait for movement
  266. if (MovementStarted) return;
  267. DoCast(SPELL_CONFLAGATION);
  268. DoScriptText(-1666404,me);
  269. setStage(10);
  270. break;
  271. case 10: // Wait for cast finish
  272. if (!me->IsNonMeleeSpellCasted(false))
  273. {
  274. doBeacon(false);
  275. setStage(11);
  276. };
  277. break;
  278. case 11: // Air phase
  279. if (m_uiFlameBreathTimer <= diff)
  280. {
  281. DoCast(SPELL_FLAME_BREATH);
  282. m_uiFlameBreathTimer = urand(5*IN_MILLISECONDS,15*IN_MILLISECONDS);
  283. } else m_uiFlameBreathTimer -= diff;
  284. if (m_uiBeakonTimer <= diff)
  285. {
  286. doBeacon(true);
  287. DoCast(SPELL_CONFLAGATION);
  288. m_uiBeakonTimer = urand(12*IN_MILLISECONDS,22*IN_MILLISECONDS);
  289. } else m_uiBeakonTimer -= diff;
  290. if (m_uiConflagrateTimer <= diff)
  291. {
  292. if (conflagated)
  293. {
  294. //DoCast(SPELL_CONFLAGATION_1);
  295. doBeacon(false);
  296. }
  297. m_uiConflagrateTimer = 5*IN_MILLISECONDS;
  298. } else m_uiConflagrateTimer -= diff;
  299. if ( HealthBelowPct(21) ) setStage(12);
  300. break;
  301. case 12: //Air phase end
  302. StartMovement(0);
  303. setStage(13);
  304. break;
  305. case 13: // Wait for movement
  306. if (MovementStarted) return;
  307. SetFly(false);
  308. SetCombatMovement(true);
  309. me->GetMotionMaster()->Clear();
  310. me->GetMotionMaster()->MoveChase(me->getVictim());
  311. setStage(14);
  312. break;
  313. case 14: //GROUND
  314. if (m_uiFlameBreathTimer <= diff)
  315. {
  316. DoCast(SPELL_FLAME_BREATH);
  317. m_uiFlameBreathTimer = urand(5*IN_MILLISECONDS,15*IN_MILLISECONDS);
  318. } else m_uiFlameBreathTimer -= diff;
  319. if (m_uiEnrage <= diff)
  320. {
  321. DoCast(SPELL_ENRAGE);
  322. m_uiEnrage = urand(15*IN_MILLISECONDS,30*IN_MILLISECONDS);
  323. DoScriptText(-1666405,me);
  324. } else m_uiEnrage -= diff;
  325. break;
  326. default:
  327. break;
  328. }
  329. DoMeleeAttackIfReady();
  330. }
  331. private:
  332. std::list<Unit *> playerList;
  333. };
  334. };
  335. void AddSC_boss_ragefire()
  336. {
  337. new boss_ragefire();
  338. }