PageRenderTime 2376ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp

https://gitlab.com/wylathdk/TrinityCore_434
C++ | 391 lines | 306 code | 54 blank | 31 comment | 40 complexity | e6e5681070d59f56f2d66ceb9e4aef40 MD5 | raw file
  1. /*
  2. * Copyright (C) 2008-2018 TrinityCore <https://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. Name: Boss_Darkmaster_Gandling
  19. %Complete: 90
  20. Comment: Doors Not yet reopening.
  21. Category: Scholomance
  22. */
  23. #include "ScriptMgr.h"
  24. #include "ScriptedCreature.h"
  25. #include "scholomance.h"
  26. #include "SpellScript.h"
  27. enum Says
  28. {
  29. YELL_SUMMONED = 0
  30. };
  31. enum Spells
  32. {
  33. SPELL_ARCANEMISSILES = 15790,
  34. SPELL_SHADOWSHIELD = 12040,
  35. SPELL_CURSE = 18702,
  36. SPELL_SHADOW_PORTAL = 17950
  37. };
  38. enum Events
  39. {
  40. EVENT_ARCANEMISSILES = 1,
  41. EVENT_SHADOWSHIELD = 2,
  42. EVENT_CURSE = 3,
  43. EVENT_SHADOW_PORTAL = 4
  44. };
  45. class boss_darkmaster_gandling : public CreatureScript
  46. {
  47. public: boss_darkmaster_gandling() : CreatureScript("boss_darkmaster_gandling") { }
  48. struct boss_darkmaster_gandlingAI : public BossAI
  49. {
  50. boss_darkmaster_gandlingAI(Creature* creature) : BossAI(creature, DATA_DARKMASTERGANDLING) { }
  51. void Reset() override
  52. {
  53. _Reset();
  54. if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetGuidData(GO_GATE_GANDLING)))
  55. gate->SetGoState(GO_STATE_ACTIVE);
  56. }
  57. void JustDied(Unit* /*killer*/) override
  58. {
  59. _JustDied();
  60. if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetGuidData(GO_GATE_GANDLING)))
  61. gate->SetGoState(GO_STATE_ACTIVE);
  62. }
  63. void JustEngagedWith(Unit* /*who*/) override
  64. {
  65. _JustEngagedWith();
  66. events.ScheduleEvent(EVENT_ARCANEMISSILES, 4500);
  67. events.ScheduleEvent(EVENT_SHADOWSHIELD, 12000);
  68. events.ScheduleEvent(EVENT_CURSE, 2000);
  69. events.ScheduleEvent(EVENT_SHADOW_PORTAL, 16000);
  70. if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetGuidData(GO_GATE_GANDLING)))
  71. gate->SetGoState(GO_STATE_READY);
  72. }
  73. void IsSummonedBy(Unit* /*summoner*/) override
  74. {
  75. Talk(YELL_SUMMONED);
  76. me->GetMotionMaster()->MoveRandom(5);
  77. }
  78. void UpdateAI(uint32 diff) override
  79. {
  80. if (!UpdateVictim())
  81. return;
  82. events.Update(diff);
  83. if (me->HasUnitState(UNIT_STATE_CASTING))
  84. return;
  85. while (uint32 eventId = events.ExecuteEvent())
  86. {
  87. switch (eventId)
  88. {
  89. case EVENT_ARCANEMISSILES:
  90. DoCastVictim(SPELL_ARCANEMISSILES, true);
  91. events.ScheduleEvent(EVENT_ARCANEMISSILES, 8000);
  92. break;
  93. case EVENT_SHADOWSHIELD:
  94. DoCast(me, SPELL_SHADOWSHIELD);
  95. events.ScheduleEvent(EVENT_SHADOWSHIELD, urand(14000, 28000));
  96. break;
  97. case EVENT_CURSE:
  98. DoCastVictim(SPELL_CURSE, true);
  99. events.ScheduleEvent(EVENT_CURSE, urand(15000, 27000));
  100. break;
  101. case EVENT_SHADOW_PORTAL:
  102. if (HealthAbovePct(3))
  103. {
  104. DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_SHADOW_PORTAL, true);
  105. events.ScheduleEvent(EVENT_SHADOW_PORTAL, urand(17000, 27000));
  106. }
  107. }
  108. if (me->HasUnitState(UNIT_STATE_CASTING))
  109. return;
  110. }
  111. DoMeleeAttackIfReady();
  112. }
  113. };
  114. CreatureAI* GetAI(Creature* creature) const override
  115. {
  116. return GetInstanceAI<boss_darkmaster_gandlingAI>(creature);
  117. }
  118. };
  119. // Script for Shadow Portal spell 17950
  120. enum Rooms
  121. {
  122. ROOM_HALL_OF_SECRETS = 0,
  123. ROOM_HALL_OF_THE_DAMNED = 1,
  124. ROOM_THE_COVEN = 2,
  125. ROOM_THE_SHADOW_VAULT = 3,
  126. ROOM_BAROV_FAMILY_VAULT = 4,
  127. ROOM_VAULT_OF_THE_RAVENIAN = 5
  128. };
  129. enum SPSpells
  130. {
  131. SPELL_SHADOW_PORTAL_HALLOFSECRETS = 17863,
  132. SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED = 17939,
  133. SPELL_SHADOW_PORTAL_THECOVEN = 17943,
  134. SPELL_SHADOW_PORTAL_THESHADOWVAULT = 17944,
  135. SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT = 17946,
  136. SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN = 17948
  137. };
  138. class spell_shadow_portal : public SpellScriptLoader
  139. {
  140. public:
  141. spell_shadow_portal() : SpellScriptLoader("spell_shadow_portal") { }
  142. class spell_shadow_portal_SpellScript : public SpellScript
  143. {
  144. PrepareSpellScript(spell_shadow_portal_SpellScript);
  145. public:
  146. spell_shadow_portal_SpellScript()
  147. {
  148. _instance = nullptr;
  149. }
  150. private:
  151. bool Load() override
  152. {
  153. _instance = GetCaster()->GetInstanceScript();
  154. return _instance != nullptr;
  155. }
  156. void HandleCast(SpellEffIndex /*effIndex*/)
  157. {
  158. Unit* caster = GetCaster();
  159. uint8 attempts = 0;
  160. uint32 spellId = 0;
  161. while (!spellId)
  162. {
  163. if (attempts++ >= 6) break;
  164. switch (urand(0, 5))
  165. {
  166. case ROOM_HALL_OF_SECRETS:
  167. if (GameObject* go = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(GO_GATE_RAVENIAN)))
  168. if (go->GetGoState() == GO_STATE_ACTIVE)
  169. spellId = SPELL_SHADOW_PORTAL_HALLOFSECRETS;
  170. break;
  171. case ROOM_HALL_OF_THE_DAMNED:
  172. if (GameObject* go = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(GO_GATE_THEOLEN)))
  173. if (go->GetGoState() == GO_STATE_ACTIVE)
  174. spellId = SPELL_SHADOW_PORTAL_HALLOFTHEDAMNED;
  175. break;
  176. case ROOM_THE_COVEN:
  177. if (GameObject* go = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(GO_GATE_MALICIA)))
  178. if (go->GetGoState() == GO_STATE_ACTIVE)
  179. spellId = SPELL_SHADOW_PORTAL_THECOVEN;
  180. break;
  181. case ROOM_THE_SHADOW_VAULT:
  182. if (GameObject* go = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(GO_GATE_ILLUCIA)))
  183. if (go->GetGoState() == GO_STATE_ACTIVE)
  184. spellId = SPELL_SHADOW_PORTAL_THESHADOWVAULT;
  185. break;
  186. case ROOM_BAROV_FAMILY_VAULT:
  187. if (GameObject* go = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(GO_GATE_BAROV)))
  188. if (go->GetGoState() == GO_STATE_ACTIVE)
  189. spellId = SPELL_SHADOW_PORTAL_BAROVFAMILYVAULT;
  190. break;
  191. case ROOM_VAULT_OF_THE_RAVENIAN:
  192. if (GameObject* go = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(GO_GATE_POLKELT)))
  193. if (go->GetGoState() == GO_STATE_ACTIVE)
  194. spellId = SPELL_SHADOW_PORTAL_VAULTOFTHERAVENIAN;
  195. break;
  196. }
  197. if (spellId)
  198. GetHitUnit()->CastSpell(GetHitUnit(), spellId);
  199. }
  200. }
  201. void Register() override
  202. {
  203. OnEffectHitTarget += SpellEffectFn(spell_shadow_portal_SpellScript::HandleCast, EFFECT_0, SPELL_EFFECT_DUMMY);
  204. }
  205. InstanceScript* _instance;
  206. };
  207. SpellScript* GetSpellScript() const override
  208. {
  209. return new spell_shadow_portal_SpellScript();
  210. }
  211. };
  212. // Script for Shadow Portal spells 17863, 17939, 17943, 17944, 17946, 17948
  213. Position const SummonPos[18] =
  214. {
  215. // Hall of Secrects
  216. // The Hall of the damned
  217. { 177.9624f, -68.23893f, 84.95197f, 3.228859f },
  218. { 183.7705f, -61.43489f, 84.92424f, 5.148721f },
  219. { 184.7035f, -77.74805f, 84.92424f, 4.660029f },
  220. // The Coven
  221. { 111.7203f, -1.105035f, 85.45985f, 3.961897f },
  222. { 118.0079f, 6.430664f, 85.31169f, 2.408554f },
  223. { 120.0276f, -7.496636f, 85.31169f, 2.984513f },
  224. // The Shadow Vault
  225. { 245.3716f, 0.628038f, 72.73877f, 0.01745329f },
  226. { 240.9920f, 3.405653f, 72.73877f, 6.143559f },
  227. { 240.9543f, -3.182943f, 72.73877f, 0.2268928f },
  228. // Barov Family Vault
  229. { 181.8245f, -42.58117f, 75.4812f, 4.660029f },
  230. { 177.7456f, -42.74745f, 75.4812f, 4.886922f },
  231. { 185.6157f, -42.91200f, 75.4812f, 4.45059f },
  232. // Vault of the Ravenian
  233. };
  234. enum Creatures
  235. {
  236. NPC_RISEN_GUARDIAN = 11598
  237. };
  238. enum ScriptEventId
  239. {
  240. SPELL_EVENT_HALLOFSECRETS = 5618,
  241. SPELL_EVENT_HALLOFTHEDAMNED = 5619,
  242. SPELL_EVENT_THECOVEN = 5620,
  243. SPELL_EVENT_THESHADOWVAULT = 5621,
  244. SPELL_EVENT_BAROVFAMILYVAULT = 5622,
  245. SPELL_EVENT_VAULTOFTHERAVENIAN = 5623
  246. };
  247. class spell_shadow_portal_rooms : public SpellScriptLoader
  248. {
  249. public:
  250. spell_shadow_portal_rooms() : SpellScriptLoader("spell_shadow_portal_rooms") { }
  251. class spell_shadow_portal_rooms_SpellScript : public SpellScript
  252. {
  253. PrepareSpellScript(spell_shadow_portal_rooms_SpellScript);
  254. public:
  255. spell_shadow_portal_rooms_SpellScript()
  256. {
  257. _instance = nullptr;
  258. }
  259. private:
  260. bool Load() override
  261. {
  262. _instance = GetCaster()->GetInstanceScript();
  263. return _instance != nullptr;
  264. }
  265. void HandleSendEvent(SpellEffIndex effIndex)
  266. {
  267. // If only one player in threat list fail spell
  268. Unit* caster = GetCaster();
  269. int8 pos_to_summon = 0;
  270. int8 phase_to_set = 0;
  271. int32 gate_to_close = 0;
  272. switch (GetSpellInfo()->Effects[effIndex].MiscValue)
  273. {
  274. case SPELL_EVENT_HALLOFSECRETS:
  275. pos_to_summon = 0; // Not yet spawned
  276. phase_to_set = 1;
  277. gate_to_close = GO_GATE_RAVENIAN;
  278. break;
  279. case SPELL_EVENT_HALLOFTHEDAMNED:
  280. pos_to_summon = 0;
  281. phase_to_set = 2;
  282. gate_to_close = GO_GATE_THEOLEN;
  283. break;
  284. case SPELL_EVENT_THECOVEN:
  285. pos_to_summon = 3;
  286. phase_to_set = 3;
  287. gate_to_close = GO_GATE_MALICIA;
  288. break;
  289. case SPELL_EVENT_THESHADOWVAULT:
  290. pos_to_summon = 6;
  291. phase_to_set = 4;
  292. gate_to_close = GO_GATE_ILLUCIA;
  293. break;
  294. case SPELL_EVENT_BAROVFAMILYVAULT:
  295. pos_to_summon = 9;
  296. phase_to_set = 5;
  297. gate_to_close = GO_GATE_BAROV;
  298. break;
  299. case SPELL_EVENT_VAULTOFTHERAVENIAN:
  300. pos_to_summon = 0; // Not yet spawned
  301. phase_to_set = 6;
  302. gate_to_close = GO_GATE_POLKELT;
  303. break;
  304. default:
  305. break;
  306. }
  307. if (gate_to_close && (caster->GetMap()->GetId() == 289))
  308. {
  309. for (uint8 i = 0; i < 3; ++i)
  310. {
  311. if (Creature* Summoned = caster->SummonCreature(NPC_RISEN_GUARDIAN, SummonPos[pos_to_summon++], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000))
  312. {
  313. Summoned->GetMotionMaster()->MoveRandom(5);
  314. Summoned->AI()->SetData(0, phase_to_set);
  315. }
  316. }
  317. if (GameObject* gate = ObjectAccessor::GetGameObject(*caster, _instance->GetGuidData(gate_to_close)))
  318. gate->SetGoState(GO_STATE_READY);
  319. }
  320. }
  321. void Register() override
  322. {
  323. OnEffectHit += SpellEffectFn(spell_shadow_portal_rooms_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
  324. }
  325. InstanceScript* _instance;
  326. };
  327. SpellScript* GetSpellScript() const override
  328. {
  329. return new spell_shadow_portal_rooms_SpellScript();
  330. }
  331. };
  332. void AddSC_boss_darkmaster_gandling()
  333. {
  334. new boss_darkmaster_gandling();
  335. new spell_shadow_portal();
  336. new spell_shadow_portal_rooms();
  337. }