Guest User

Untitled

a guest
Nov 6th, 2025
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 333.43 KB | Gaming | 0 0
  1. From 3000e53cb260ff0fe2734628b897c96b7fe824fe Mon Sep 17 00:00:00 2001
  2. From: Skuallo <[email protected]>
  3. Date: Thu, 6 Nov 2025 14:58:14 +0100
  4. Subject: [PATCH] =?UTF-8?q?Prueba=20del=20Campe=C3=B3n?=
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8.  
  9. ---
  10. .../boss_argent_challenge.cpp | 1977 ++++++++----
  11. .../TrialOfTheChampion/boss_black_knight.cpp | 1203 ++++---
  12. .../boss_grand_champions.cpp | 2839 +++++++++++------
  13. .../instance_trial_of_the_champion.cpp | 682 ++--
  14. .../trial_of_the_champion.cpp | 1881 ++++++++---
  15. .../trial_of_the_champion.h | 436 ++-
  16. 6 files changed, 5912 insertions(+), 3106 deletions(-)
  17. rewrite src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp (73%)
  18. rewrite src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp (73%)
  19. rewrite src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp (75%)
  20. rewrite src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp (75%)
  21. rewrite src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp (66%)
  22. rewrite src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h (74%)
  23.  
  24. diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
  25. dissimilarity index 73%
  26. index 8f2aa82f27..9c9169ec39 100644
  27. --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
  28. +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
  29. @@ -1,697 +1,1280 @@
  30. -/*
  31. - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
  32. - *
  33. - * This program is free software; you can redistribute it and/or modify it
  34. - * under the terms of the GNU General Public License as published by the
  35. - * Free Software Foundation; either version 2 of the License, or (at your
  36. - * option) any later version.
  37. - *
  38. - * This program is distributed in the hope that it will be useful, but WITHOUT
  39. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  40. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  41. - * more details.
  42. - *
  43. - * You should have received a copy of the GNU General Public License along
  44. - * with this program. If not, see <http://www.gnu.org/licenses/>.
  45. - */
  46. -
  47. -/* ScriptData
  48. -SDName: Argent Challenge Encounter.
  49. -SD%Complete: 50 %
  50. -SDComment: AI for Argent Soldiers are not implemented. AI from bosses need more improvements.
  51. -SDCategory: Trial of the Champion
  52. -EndScriptData */
  53. -
  54. -#include "ScriptMgr.h"
  55. -#include "Containers.h"
  56. -#include "InstanceScript.h"
  57. -#include "MotionMaster.h"
  58. -#include "ObjectAccessor.h"
  59. -#include "ScriptedEscortAI.h"
  60. -#include "SpellScript.h"
  61. -#include "TemporarySummon.h"
  62. -#include "trial_of_the_champion.h"
  63. -/*
  64. -enum Yells
  65. -{
  66. - // Eadric the Pure
  67. - SAY_INTRO = 0,
  68. - SAY_AGGRO = 1,
  69. - EMOTE_RADIANCE = 2,
  70. - EMOTE_HAMMER_RIGHTEOUS = 3,
  71. - SAY_HAMMER_RIGHTEOUS = 4,
  72. - SAY_KILL_PLAYER = 5,
  73. - SAY_DEFEATED = 6,
  74. -
  75. - // Argent Confessor Paletress
  76. - SAY_INTRO_1 = 0,
  77. - SAY_INTRO_2 = 1,
  78. - SAY_AGGRO = 2,
  79. - SAY_MEMORY_SUMMON = 3,
  80. - SAY_MEMORY_DEATH = 4,
  81. - SAY_KILL_PLAYER = 5,
  82. - SAY_DEFEATED = 6,
  83. -
  84. - // Memory of X
  85. - EMOTE_WAKING_NIGHTMARE = 0
  86. -};
  87. -*/
  88. -enum Spells
  89. -{
  90. - // Eadric the Pure
  91. - SPELL_EADRIC_ACHIEVEMENT = 68197,
  92. - SPELL_HAMMER_JUSTICE = 66863,
  93. - SPELL_HAMMER_RIGHTEOUS = 66867,
  94. - SPELL_RADIANCE = 66935,
  95. - SPELL_VENGEANCE = 66865,
  96. -
  97. - // Paletress
  98. - SPELL_SMITE = 66536,
  99. - SPELL_SMITE_H = 67674,
  100. - SPELL_HOLY_FIRE = 66538,
  101. - SPELL_HOLY_FIRE_H = 67676,
  102. - SPELL_RENEW = 66537,
  103. - SPELL_RENEW_H = 67675,
  104. - SPELL_HOLY_NOVA = 66546,
  105. - SPELL_SHIELD = 66515,
  106. - SPELL_CONFESS = 66680,
  107. - SPELL_SUMMON_MEMORY = 66545,
  108. -
  109. - // Memory of X (Summon)
  110. - SPELL_MEMORY_ALGALON = 66715,
  111. - SPELL_MEMORY_ARCHIMONDE = 66704,
  112. - SPELL_MEMORY_CHROMAGGUS = 66697,
  113. - SPELL_MEMORY_CYANIGOSA = 66709,
  114. - SPELL_MEMORY_DELRISSA = 66706,
  115. - SPELL_MEMORY_ECK = 66710,
  116. - SPELL_MEMORY_ENTROPIUS = 66707,
  117. - SPELL_MEMORY_GRUUL = 66702,
  118. - SPELL_MEMORY_HAKKAR = 66698,
  119. - SPELL_MEMORY_HEIGAN = 66712,
  120. - SPELL_MEMORY_HEROD = 66694,
  121. - SPELL_MEMORY_HOGGER = 66543,
  122. - SPELL_MEMORY_IGNIS = 66713,
  123. - SPELL_MEMORY_ILLIDAN = 66705,
  124. - SPELL_MEMORY_INGVAR = 66708,
  125. - SPELL_MEMORY_KALITHRESH = 66700,
  126. - SPELL_MEMORY_LUCIFRON = 66695,
  127. - SPELL_MEMORY_MALCHEZAAR = 66701,
  128. - SPELL_MEMORY_MUTANUS = 66692,
  129. - SPELL_MEMORY_ONYXIA = 66711,
  130. - SPELL_MEMORY_THUNDERAAN = 66696,
  131. - SPELL_MEMORY_VANCLEEF = 66691,
  132. - SPELL_MEMORY_VASHJ = 66703,
  133. - SPELL_MEMORY_VEKNILASH = 66699,
  134. - SPELL_MEMORY_VEZAX = 66714,
  135. -
  136. - // Memory
  137. - SPELL_OLD_WOUNDS = 66620,
  138. - SPELL_OLD_WOUNDS_H = 67679,
  139. - SPELL_SHADOWS_PAST = 66619,
  140. - SPELL_SHADOWS_PAST_H = 67678,
  141. - SPELL_WAKING_NIGHTMARE = 66552,
  142. - SPELL_WAKING_NIGHTMARE_H = 67677
  143. -};
  144. -
  145. -class OrientationCheck
  146. -{
  147. - public:
  148. - explicit OrientationCheck(Unit* _caster) : caster(_caster) { }
  149. - bool operator()(WorldObject* object)
  150. - {
  151. - return !object->isInFront(caster, 2.5f) || !object->IsWithinDist(caster, 40.0f);
  152. - }
  153. -
  154. - private:
  155. - Unit* caster;
  156. -};
  157. -
  158. -// 66862, 67681 - Radiance
  159. -class spell_eadric_radiance : public SpellScriptLoader
  160. -{
  161. - public:
  162. - spell_eadric_radiance() : SpellScriptLoader("spell_eadric_radiance") { }
  163. - class spell_eadric_radiance_SpellScript : public SpellScript
  164. - {
  165. - PrepareSpellScript(spell_eadric_radiance_SpellScript);
  166. -
  167. - void FilterTargets(std::list<WorldObject*>& unitList)
  168. - {
  169. - unitList.remove_if(OrientationCheck(GetCaster()));
  170. - }
  171. -
  172. - void Register() override
  173. - {
  174. - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  175. - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
  176. - }
  177. - };
  178. -
  179. - SpellScript* GetSpellScript() const override
  180. - {
  181. - return new spell_eadric_radiance_SpellScript();
  182. - }
  183. -};
  184. -
  185. -class boss_eadric : public CreatureScript
  186. -{
  187. -public:
  188. - boss_eadric() : CreatureScript("boss_eadric") { }
  189. - struct boss_eadricAI : public ScriptedAI
  190. - {
  191. - boss_eadricAI(Creature* creature) : ScriptedAI(creature)
  192. - {
  193. - Initialize();
  194. - instance = creature->GetInstanceScript();
  195. - creature->SetReactState(REACT_PASSIVE);
  196. - creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  197. - }
  198. -
  199. - void Initialize()
  200. - {
  201. - uiVenganceTimer = 10000;
  202. - uiRadianceTimer = 16000;
  203. - uiHammerJusticeTimer = 25000;
  204. - uiResetTimer = 5000;
  205. -
  206. - bDone = false;
  207. - }
  208. -
  209. - InstanceScript* instance;
  210. -
  211. - uint32 uiVenganceTimer;
  212. - uint32 uiRadianceTimer;
  213. - uint32 uiHammerJusticeTimer;
  214. - uint32 uiResetTimer;
  215. -
  216. - bool bDone;
  217. -
  218. - void Reset() override
  219. - {
  220. - Initialize();
  221. - }
  222. -
  223. - void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  224. - {
  225. - if (damage >= me->GetHealth())
  226. - {
  227. - damage = 0;
  228. - EnterEvadeMode();
  229. - me->SetFaction(FACTION_FRIENDLY);
  230. - bDone = true;
  231. - }
  232. - }
  233. -
  234. - void MovementInform(uint32 MovementType, uint32 /*Data*/) override
  235. - {
  236. - if (MovementType != POINT_MOTION_TYPE)
  237. - return;
  238. -
  239. - instance->SetBossState(BOSS_ARGENT_CHALLENGE_E, DONE);
  240. -
  241. - me->DisappearAndDie();
  242. - }
  243. -
  244. - void UpdateAI(uint32 uiDiff) override
  245. - {
  246. - if (bDone && uiResetTimer <= uiDiff)
  247. - {
  248. - me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
  249. - bDone = false;
  250. - } else uiResetTimer -= uiDiff;
  251. -
  252. - if (!UpdateVictim())
  253. - return;
  254. -
  255. - if (uiHammerJusticeTimer <= uiDiff)
  256. - {
  257. - me->InterruptNonMeleeSpells(true);
  258. -
  259. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
  260. - {
  261. - if (target->IsAlive())
  262. - {
  263. - DoCast(target, SPELL_HAMMER_JUSTICE);
  264. - DoCast(target, SPELL_HAMMER_RIGHTEOUS);
  265. - }
  266. - }
  267. - uiHammerJusticeTimer = 25000;
  268. - } else uiHammerJusticeTimer -= uiDiff;
  269. -
  270. - if (uiVenganceTimer <= uiDiff)
  271. - {
  272. - DoCast(me, SPELL_VENGEANCE);
  273. -
  274. - uiVenganceTimer = 10000;
  275. - } else uiVenganceTimer -= uiDiff;
  276. -
  277. - if (uiRadianceTimer <= uiDiff)
  278. - {
  279. - DoCastAOE(SPELL_RADIANCE);
  280. -
  281. - uiRadianceTimer = 16000;
  282. - } else uiRadianceTimer -= uiDiff;
  283. -
  284. - DoMeleeAttackIfReady();
  285. - }
  286. - };
  287. -
  288. - CreatureAI* GetAI(Creature* creature) const override
  289. - {
  290. - return GetTrialOfTheChampionAI<boss_eadricAI>(creature);
  291. - }
  292. -};
  293. -
  294. -class boss_paletress : public CreatureScript
  295. -{
  296. -public:
  297. - boss_paletress() : CreatureScript("boss_paletress") { }
  298. -
  299. - struct boss_paletressAI : public ScriptedAI
  300. - {
  301. - boss_paletressAI(Creature* creature) : ScriptedAI(creature)
  302. - {
  303. - Initialize();
  304. - instance = creature->GetInstanceScript();
  305. -
  306. - creature->SetReactState(REACT_PASSIVE);
  307. - creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  308. - creature->RestoreFaction();
  309. - }
  310. -
  311. - void Initialize()
  312. - {
  313. - uiHolyFireTimer = urand(9000, 12000);
  314. - uiHolySmiteTimer = urand(5000, 7000);
  315. - uiRenewTimer = urand(2000, 5000);
  316. -
  317. - uiResetTimer = 7000;
  318. -
  319. - bHealth = false;
  320. - bDone = false;
  321. - }
  322. -
  323. - InstanceScript* instance;
  324. - ObjectGuid MemoryGUID;
  325. -
  326. - bool bHealth;
  327. - bool bDone;
  328. -
  329. - uint32 uiHolyFireTimer;
  330. - uint32 uiHolySmiteTimer;
  331. - uint32 uiRenewTimer;
  332. - uint32 uiResetTimer;
  333. -
  334. - void Reset() override
  335. - {
  336. - me->RemoveAllAuras();
  337. -
  338. - Initialize();
  339. -
  340. - if (Creature* pMemory = ObjectAccessor::GetCreature(*me, MemoryGUID))
  341. - if (pMemory->IsAlive())
  342. - pMemory->RemoveFromWorld();
  343. - }
  344. -
  345. - void SetData(uint32 uiId, uint32 /*uiValue*/) override
  346. - {
  347. - if (uiId == 1)
  348. - me->RemoveAura(SPELL_SHIELD);
  349. - }
  350. -
  351. - void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  352. - {
  353. - if (damage >= me->GetHealth())
  354. - {
  355. - damage = 0;
  356. - EnterEvadeMode();
  357. - me->SetFaction(FACTION_FRIENDLY);
  358. - bDone = true;
  359. - }
  360. - }
  361. -
  362. - void MovementInform(uint32 MovementType, uint32 Point) override
  363. - {
  364. - if (MovementType != POINT_MOTION_TYPE || Point != 0)
  365. - return;
  366. -
  367. - instance->SetBossState(BOSS_ARGENT_CHALLENGE_P, DONE);
  368. -
  369. - me->DisappearAndDie();
  370. - }
  371. -
  372. - void UpdateAI(uint32 uiDiff) override
  373. - {
  374. - if (bDone && uiResetTimer <= uiDiff)
  375. - {
  376. - me->GetMotionMaster()->MovePoint(0, 746.87f, 665.87f, 411.75f);
  377. - bDone = false;
  378. - } else uiResetTimer -= uiDiff;
  379. -
  380. - if (!UpdateVictim())
  381. - return;
  382. -
  383. - if (uiHolyFireTimer <= uiDiff)
  384. - {
  385. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
  386. - {
  387. - if (target->IsAlive())
  388. - DoCast(target, SPELL_HOLY_FIRE);
  389. - }
  390. - if (me->HasAura(SPELL_SHIELD))
  391. - uiHolyFireTimer = 13000;
  392. - else
  393. - uiHolyFireTimer = urand(9000, 12000);
  394. - } else uiHolyFireTimer -= uiDiff;
  395. -
  396. - if (uiHolySmiteTimer <= uiDiff)
  397. - {
  398. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 250, true))
  399. - {
  400. - if (target->IsAlive())
  401. - DoCast(target, SPELL_SMITE);
  402. - }
  403. - if (me->HasAura(SPELL_SHIELD))
  404. - uiHolySmiteTimer = 9000;
  405. - else
  406. - uiHolySmiteTimer = urand(5000, 7000);
  407. - } else uiHolySmiteTimer -= uiDiff;
  408. -
  409. - if (me->HasAura(SPELL_SHIELD))
  410. - {
  411. - if (uiRenewTimer <= uiDiff)
  412. - {
  413. - me->InterruptNonMeleeSpells(true);
  414. - uint8 uiTarget = urand(0, 1);
  415. - switch (uiTarget)
  416. - {
  417. - case 0:
  418. - DoCast(me, SPELL_RENEW);
  419. - break;
  420. - case 1:
  421. - if (Creature* pMemory = ObjectAccessor::GetCreature(*me, MemoryGUID))
  422. - if (pMemory->IsAlive())
  423. - DoCast(pMemory, SPELL_RENEW);
  424. - break;
  425. - }
  426. - uiRenewTimer = urand(15000, 17000);
  427. - } else uiRenewTimer -= uiDiff;
  428. - }
  429. -
  430. - if (!bHealth && !HealthAbovePct(25))
  431. - {
  432. - me->InterruptNonMeleeSpells(true);
  433. - DoCastAOE(SPELL_HOLY_NOVA, false);
  434. - DoCast(me, SPELL_SHIELD);
  435. - DoCastAOE(SPELL_SUMMON_MEMORY, false);
  436. - DoCastAOE(SPELL_CONFESS, false);
  437. -
  438. - bHealth = true;
  439. - }
  440. -
  441. - DoMeleeAttackIfReady();
  442. - }
  443. -
  444. - void JustSummoned(Creature* summon) override
  445. - {
  446. - MemoryGUID = summon->GetGUID();
  447. - }
  448. - };
  449. -
  450. - CreatureAI* GetAI(Creature* creature) const override
  451. - {
  452. - return GetTrialOfTheChampionAI<boss_paletressAI>(creature);
  453. - }
  454. -};
  455. -
  456. -class npc_memory : public CreatureScript
  457. -{
  458. -public:
  459. - npc_memory() : CreatureScript("npc_memory") { }
  460. -
  461. - struct npc_memoryAI : public ScriptedAI
  462. - {
  463. - npc_memoryAI(Creature* creature) : ScriptedAI(creature)
  464. - {
  465. - Initialize();
  466. - }
  467. -
  468. - void Initialize()
  469. - {
  470. - uiOldWoundsTimer = 12000;
  471. - uiShadowPastTimer = 5000;
  472. - uiWakingNightmare = 7000;
  473. - }
  474. -
  475. - uint32 uiOldWoundsTimer;
  476. - uint32 uiShadowPastTimer;
  477. - uint32 uiWakingNightmare;
  478. -
  479. - void Reset() override
  480. - {
  481. - Initialize();
  482. - }
  483. -
  484. - void UpdateAI(uint32 uiDiff) override
  485. - {
  486. - if (!UpdateVictim())
  487. - return;
  488. -
  489. - if (uiOldWoundsTimer <= uiDiff)
  490. - {
  491. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
  492. - {
  493. - if (target->IsAlive())
  494. - DoCast(target, SPELL_OLD_WOUNDS);
  495. - }
  496. - uiOldWoundsTimer = 12000;
  497. - }else uiOldWoundsTimer -= uiDiff;
  498. -
  499. - if (uiWakingNightmare <= uiDiff)
  500. - {
  501. - DoCast(me, SPELL_WAKING_NIGHTMARE);
  502. - uiWakingNightmare = 7000;
  503. - }else uiWakingNightmare -= uiDiff;
  504. -
  505. - if (uiShadowPastTimer <= uiDiff)
  506. - {
  507. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
  508. - {
  509. - if (target->IsAlive())
  510. - DoCast(target, SPELL_SHADOWS_PAST);
  511. - }
  512. - uiShadowPastTimer = 5000;
  513. - }else uiShadowPastTimer -= uiDiff;
  514. -
  515. - DoMeleeAttackIfReady();
  516. - }
  517. -
  518. - void JustDied(Unit* /*killer*/) override
  519. - {
  520. - if (TempSummon* summ = me->ToTempSummon())
  521. - if (Unit* summoner = summ->GetSummonerUnit())
  522. - if (summoner->IsAlive())
  523. - summoner->GetAI()->SetData(1, 0);
  524. - }
  525. - };
  526. -
  527. - CreatureAI* GetAI(Creature* creature) const override
  528. - {
  529. - return GetTrialOfTheChampionAI<npc_memoryAI>(creature);
  530. - }
  531. -};
  532. -
  533. -class npc_argent_soldier : public CreatureScript
  534. -{
  535. -public:
  536. - npc_argent_soldier() : CreatureScript("npc_argent_soldier") { }
  537. -
  538. - // THIS AI NEEDS MORE IMPROVEMENTS
  539. - struct npc_argent_soldierAI : public EscortAI
  540. - {
  541. - npc_argent_soldierAI(Creature* creature) : EscortAI(creature)
  542. - {
  543. - instance = creature->GetInstanceScript();
  544. - me->SetReactState(REACT_DEFENSIVE);
  545. - SetDespawnAtEnd(false);
  546. - uiWaypoint = 0;
  547. - }
  548. -
  549. - InstanceScript* instance;
  550. -
  551. - uint8 uiWaypoint;
  552. -
  553. - void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
  554. - {
  555. - if (waypointId == 0)
  556. - {
  557. - switch (uiWaypoint)
  558. - {
  559. - case 0:
  560. - me->SetFacingTo(5.81f);
  561. - break;
  562. - case 1:
  563. - me->SetFacingTo(4.60f);
  564. - break;
  565. - case 2:
  566. - me->SetFacingTo(2.79f);
  567. - break;
  568. - }
  569. - }
  570. - }
  571. -
  572. - void SetData(uint32 uiType, uint32 /*uiData*/) override
  573. - {
  574. - switch (me->GetEntry())
  575. - {
  576. - case NPC_ARGENT_LIGHWIELDER:
  577. - switch (uiType)
  578. - {
  579. - case 0:
  580. - AddWaypoint(0, 712.14f, 628.42f, 411.88f);
  581. - break;
  582. - case 1:
  583. - AddWaypoint(0, 742.44f, 650.29f, 411.79f);
  584. - break;
  585. - case 2:
  586. - AddWaypoint(0, 783.33f, 615.29f, 411.84f);
  587. - break;
  588. - }
  589. - break;
  590. - case NPC_ARGENT_MONK:
  591. - switch (uiType)
  592. - {
  593. - case 0:
  594. - AddWaypoint(0, 713.12f, 632.97f, 411.90f);
  595. - break;
  596. - case 1:
  597. - AddWaypoint(0, 746.73f, 650.24f, 411.56f);
  598. - break;
  599. - case 2:
  600. - AddWaypoint(0, 781.32f, 610.54f, 411.82f);
  601. - break;
  602. - }
  603. - break;
  604. - case NPC_PRIESTESS:
  605. - switch (uiType)
  606. - {
  607. - case 0:
  608. - AddWaypoint(0, 715.06f, 637.07f, 411.91f);
  609. - break;
  610. - case 1:
  611. - AddWaypoint(0, 750.72f, 650.20f, 411.77f);
  612. - break;
  613. - case 2:
  614. - AddWaypoint(0, 779.77f, 607.03f, 411.81f);
  615. - break;
  616. - }
  617. - break;
  618. - }
  619. -
  620. - Start(false, true);
  621. - uiWaypoint = uiType;
  622. - }
  623. -
  624. - void UpdateAI(uint32 uiDiff) override
  625. - {
  626. - EscortAI::UpdateAI(uiDiff);
  627. -
  628. - if (!UpdateVictim())
  629. - return;
  630. -
  631. - DoMeleeAttackIfReady();
  632. - }
  633. -
  634. - void JustDied(Unit* /*killer*/) override
  635. - {
  636. - instance->SetData(DATA_ARGENT_SOLDIER_DEFEATED, instance->GetData(DATA_ARGENT_SOLDIER_DEFEATED) + 1);
  637. - }
  638. - };
  639. -
  640. - CreatureAI* GetAI(Creature* creature) const override
  641. - {
  642. - return GetTrialOfTheChampionAI<npc_argent_soldierAI>(creature);
  643. - }
  644. -};
  645. -
  646. -uint32 const memorySpellId[25] =
  647. -{
  648. - SPELL_MEMORY_ALGALON,
  649. - SPELL_MEMORY_ARCHIMONDE,
  650. - SPELL_MEMORY_CHROMAGGUS,
  651. - SPELL_MEMORY_CYANIGOSA,
  652. - SPELL_MEMORY_DELRISSA,
  653. - SPELL_MEMORY_ECK,
  654. - SPELL_MEMORY_ENTROPIUS,
  655. - SPELL_MEMORY_GRUUL,
  656. - SPELL_MEMORY_HAKKAR,
  657. - SPELL_MEMORY_HEIGAN,
  658. - SPELL_MEMORY_HEROD,
  659. - SPELL_MEMORY_HOGGER,
  660. - SPELL_MEMORY_IGNIS,
  661. - SPELL_MEMORY_ILLIDAN,
  662. - SPELL_MEMORY_INGVAR,
  663. - SPELL_MEMORY_KALITHRESH,
  664. - SPELL_MEMORY_LUCIFRON,
  665. - SPELL_MEMORY_MALCHEZAAR,
  666. - SPELL_MEMORY_MUTANUS,
  667. - SPELL_MEMORY_ONYXIA,
  668. - SPELL_MEMORY_THUNDERAAN,
  669. - SPELL_MEMORY_VANCLEEF,
  670. - SPELL_MEMORY_VASHJ,
  671. - SPELL_MEMORY_VEKNILASH,
  672. - SPELL_MEMORY_VEZAX
  673. -};
  674. -
  675. -// 66545 - Summon Memory
  676. -class spell_paletress_summon_memory : public SpellScriptLoader
  677. -{
  678. - public:
  679. - spell_paletress_summon_memory() : SpellScriptLoader("spell_paletress_summon_memory") { }
  680. -
  681. - class spell_paletress_summon_memory_SpellScript : public SpellScript
  682. - {
  683. - PrepareSpellScript(spell_paletress_summon_memory_SpellScript);
  684. -
  685. - bool Validate(SpellInfo const* /*spellInfo*/) override
  686. - {
  687. - return ValidateSpellInfo(memorySpellId);
  688. - }
  689. -
  690. - void FilterTargets(std::list<WorldObject*>& targets)
  691. - {
  692. - if (targets.empty())
  693. - return;
  694. -
  695. - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
  696. - targets.clear();
  697. - targets.push_back(target);
  698. - }
  699. -
  700. - void HandleScript(SpellEffIndex /*effIndex*/)
  701. - {
  702. - GetHitUnit()->CastSpell(GetHitUnit(), memorySpellId[urand(0, 24)], GetCaster()->GetGUID());
  703. - }
  704. -
  705. - void Register() override
  706. - {
  707. - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_paletress_summon_memory_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  708. - OnEffectHitTarget += SpellEffectFn(spell_paletress_summon_memory_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  709. - }
  710. - };
  711. -
  712. - SpellScript* GetSpellScript() const override
  713. - {
  714. - return new spell_paletress_summon_memory_SpellScript();
  715. - }
  716. -};
  717. -
  718. -void AddSC_boss_argent_challenge()
  719. -{
  720. - new boss_eadric();
  721. - new spell_eadric_radiance();
  722. - new boss_paletress();
  723. - new npc_memory();
  724. - new npc_argent_soldier();
  725. - new spell_paletress_summon_memory();
  726. -}
  727. +/*
  728. + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  729. + *
  730. + * This program is free software; you can redistribute it and/or modify it
  731. + * under the terms of the GNU General Public License as published by the
  732. + * Free Software Foundation; either version 2 of the License, or (at your
  733. + * option) any later version.
  734. + *
  735. + * This program is distributed in the hope that it will be useful, but WITHOUT
  736. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  737. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  738. + * more details.
  739. + *
  740. + * You should have received a copy of the GNU General Public License along
  741. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  742. + */
  743. +
  744. + /* ScriptData
  745. + SDName: Argent Challenge Encounter.
  746. + SD%Complete: 100%
  747. + SDComment:
  748. + SDCategory: Trial of the Champion
  749. + EndScriptData */
  750. +
  751. +#include "Player.h"
  752. +#include "ScriptMgr.h"
  753. +#include "ScriptedCreature.h"
  754. +#include "SpellAuraEffects.h"
  755. +#include "SpellScript.h"
  756. +#include "SpellMgr.h"
  757. +#include "trial_of_the_champion.h"
  758. +#include "TemporarySummon.h"
  759. +
  760. +uint32 SelectRandomMemorySpell()
  761. +{
  762. + static uint32 const memorySpellIds[] = {
  763. + 66715, // SPELL_MEMORY_ALGALON
  764. + 66704, // SPELL_MEMORY_ARCHIMONDE
  765. + 66697, // SPELL_MEMORY_CHROMAGGUS
  766. + 66709, // SPELL_MEMORY_CYANIGOSA
  767. + 66706, // SPELL_MEMORY_DELRISSA
  768. + 66710, // SPELL_MEMORY_ECK
  769. + 66707, // SPELL_MEMORY_ENTROPIUS
  770. + 66702, // SPELL_MEMORY_GRUUL
  771. + 66698, // SPELL_MEMORY_HAKKAR
  772. + 66712, // SPELL_MEMORY_HEIGAN
  773. + 66694, // SPELL_MEMORY_HEROD
  774. + 66543, // SPELL_MEMORY_HOGGER
  775. + 66713, // SPELL_MEMORY_IGNIS
  776. + 66705, // SPELL_MEMORY_ILLIDAN
  777. + 66708, // SPELL_MEMORY_INGVAR
  778. + 66700, // SPELL_MEMORY_KALITHRESH
  779. + 66695, // SPELL_MEMORY_LUCIFRON
  780. + 66701, // SPELL_MEMORY_MALCHEZAAR
  781. + 66692, // SPELL_MEMORY_MUTANUS
  782. + 66711, // SPELL_MEMORY_ONYXIA
  783. + 66696, // SPELL_MEMORY_THUNDERAAN
  784. + 66691, // SPELL_MEMORY_VANCLEEF
  785. + 66703, // SPELL_MEMORY_VASHJ
  786. + 66699, // SPELL_MEMORY_VEKNILASH
  787. + 66714 // SPELL_MEMORY_VEZAX
  788. + };
  789. +
  790. + return memorySpellIds[urand(0, 24)];
  791. +}
  792. +
  793. +enum Yells
  794. +{
  795. + // Eadric the Pure
  796. + SAY_AGGRO_E = 1,
  797. + EMOTE_RADIANCE = 2,
  798. + EMOTE_HAMMER_RIGHTEOUS = 3,
  799. + SAY_HAMMER_RIGHTEOUS = 4,
  800. + SAY_KILL_UNIT_E = 5,
  801. + SAY_DEFEATED_E = 6,
  802. +
  803. + // Argent Confessor Paletress
  804. + SAY_AGGRO_P = 2,
  805. + SAY_MEMORY_SUMMON = 3,
  806. + SAY_MEMORY_DEATH = 4,
  807. + SAY_KILL_UNIT_P = 5,
  808. + SAY_DEFEATED_P = 6,
  809. +
  810. + // Memory of X
  811. + EMOTE_WAKING_NIGHTMARE = 0
  812. +};
  813. +
  814. +enum Events
  815. +{
  816. + // Argent Lightwielder
  817. + EVENT_BLAZING_LIGHT = 1,
  818. + EVENT_CLEAVE,
  819. + EVENT_UNBALANCING_STRIKE,
  820. +
  821. + // Argent Monk
  822. + EVENT_FLURRY_OF_BLOWS,
  823. + EVENT_PUMMEL,
  824. +
  825. + // Argent Priestess
  826. + EVENT_HOLY_SMITE,
  827. + EVENT_SHADOW_WORD_PAIN,
  828. + EVENT_FOUNTAIN,
  829. + EVENT_MIND_CONTROL,
  830. +
  831. + // Argent Confessor Paletress
  832. + EVENT_HOLY_FIRE,
  833. + EVENT_HOLY_SMITE_E,
  834. + EVENT_RENEW,
  835. + EVENT_SUMMON_MEMORY,
  836. +
  837. + // Memory
  838. + EVENT_ENTER_AGGRESSIVE,
  839. + EVENT_OLD_WOUNDS,
  840. + EVENT_SHADOWS_PAST,
  841. + EVENT_WAKING_NIGHTMARE,
  842. +
  843. + // Eadric the Pure
  844. + EVENT_RADIANCE,
  845. + EVENT_HAMMER_OF_JUSTICE,
  846. +
  847. + // Shared
  848. + EVENT_CHALLENGE_DONE
  849. +};
  850. +
  851. +enum Spells
  852. +{
  853. + // Argent Lightwielder
  854. + SPELL_BLAZING_LIGHT = 67247,
  855. + SPELL_CLEAVE = 15284,
  856. + SPELL_UNBALANCING_STRIKE = 67237,
  857. +
  858. + // Argent Monk
  859. + SPELL_FLURRY_OF_BLOWS = 67233,
  860. + SPELL_PUMMEL = 67235,
  861. + SPELL_DIVINE_SHIELD = 67251,
  862. + SPELL_FINAL_MEDITATION = 67255,
  863. +
  864. + // Argent Priestess
  865. + SPELL_HOLY_SMITE = 36176,
  866. + SPELL_SHADOW_WORD_PAIN = 34941,
  867. + SPELL_MIND_CONTROL = 67229,
  868. + SPELL_SUMMON_FOUNTAIN = 67194,
  869. +
  870. + // Eadric the Pure
  871. + SPELL_EADRIC_FACEROLLER = 68197,
  872. + SPELL_HAMMER_JUSTICE = 66863,
  873. + SPELL_HAMMER_JUSTICE_STUN = 66940,
  874. + SPELL_HAMMER_RIGHTEOUS = 66867,
  875. + SPELL_HAMMER_RIGHT_DUMMY = 66904,
  876. + SPELL_HAMMER_RIGHTEOUS_PLR = 66905,
  877. + SPELL_RADIANCE = 66935,
  878. + SPELL_VENGEANCE = 66865,
  879. + SPELL_EADRIC_ACH = 68575, // dummy spell for achievement credit (IDs 4297, 4298, 3778, 4296)
  880. +
  881. + // Paletress
  882. + SPELL_PALETRESS_CONFESSOR = 68206, // achievement id 3802
  883. + SPELL_SMITE = 66536,
  884. + SPELL_HOLY_FIRE = 66538,
  885. + SPELL_RENEW = 66537,
  886. + SPELL_HOLY_NOVA = 66546,
  887. + SPELL_SHIELD = 66515,
  888. + SPELL_SHIELD_REFLECT = 33619,
  889. + SPELL_CONFESS = 66680,
  890. + SPELL_SUMMON_MEMORY = 66545,
  891. + SPELL_PALETRESS_ACH = 68574, // dummy spell for achievement credit (IDs 4297, 4298, 3778, 4296)
  892. +
  893. + // Memory of X (Summon)
  894. + SPELL_MEMORY_ALGALON = 66715,
  895. + SPELL_MEMORY_ARCHIMONDE = 66704,
  896. + SPELL_MEMORY_CHROMAGGUS = 66697,
  897. + SPELL_MEMORY_CYANIGOSA = 66709,
  898. + SPELL_MEMORY_DELRISSA = 66706,
  899. + SPELL_MEMORY_ECK = 66710,
  900. + SPELL_MEMORY_ENTROPIUS = 66707,
  901. + SPELL_MEMORY_GRUUL = 66702,
  902. + SPELL_MEMORY_HAKKAR = 66698,
  903. + SPELL_MEMORY_HEIGAN = 66712,
  904. + SPELL_MEMORY_HEROD = 66694,
  905. + SPELL_MEMORY_HOGGER = 66543,
  906. + SPELL_MEMORY_IGNIS = 66713,
  907. + SPELL_MEMORY_ILLIDAN = 66705,
  908. + SPELL_MEMORY_INGVAR = 66708,
  909. + SPELL_MEMORY_KALITHRESH = 66700,
  910. + SPELL_MEMORY_LUCIFRON = 66695,
  911. + SPELL_MEMORY_MALCHEZAAR = 66701,
  912. + SPELL_MEMORY_MUTANUS = 66692,
  913. + SPELL_MEMORY_ONYXIA = 66711,
  914. + SPELL_MEMORY_THUNDERAAN = 66696,
  915. + SPELL_MEMORY_VANCLEEF = 66691,
  916. + SPELL_MEMORY_VASHJ = 66703,
  917. + SPELL_MEMORY_VEKNILASH = 66699,
  918. + SPELL_MEMORY_VEZAX = 66714,
  919. +
  920. + // Memory
  921. + SPELL_SHADOWFORM = 41408,
  922. + SPELL_SPAWN_VISUAL = 66675,
  923. + SPELL_OLD_WOUNDS = 66620,
  924. + SPELL_SHADOWS_PAST = 66619,
  925. + SPELL_WAKING_NIGHTMARE = 66552
  926. +};
  927. +
  928. +enum PointMovement
  929. +{
  930. + POINT_PREFIGHT = 0,
  931. + POINT_PREPARE,
  932. + POINT_DESPAWN
  933. +};
  934. +
  935. +struct argent_challenge_baseAI : public BossAI
  936. +{
  937. + argent_challenge_baseAI(Creature* creature) : BossAI(creature, DATA_ARGENT_CHALLENGE)
  938. + {
  939. + Initialize();
  940. + creature->SetReactState(REACT_DEFENSIVE);
  941. + }
  942. +
  943. + virtual void Initialize() {}
  944. +
  945. + virtual void OnReset()
  946. + {
  947. + _Reset();
  948. + }
  949. +
  950. + void EnterEvadeMode(EvadeReason /*why*/) final override
  951. + {
  952. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) != SPECIAL &&
  953. + instance->GetBossState(DATA_ARGENT_CHALLENGE) != DONE)
  954. + BossAI::EnterEvadeMode();
  955. + }
  956. +
  957. + void JustReachedHome() final override
  958. + {
  959. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == SPECIAL)
  960. + events.ScheduleEvent(EVENT_CHALLENGE_DONE, 4s);
  961. + else
  962. + me->SetEmoteState(EMOTE_STATE_READY1H);
  963. + }
  964. +
  965. + void Reset() final override
  966. + {
  967. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) != SPECIAL)
  968. + OnReset();
  969. + }
  970. +
  971. + void AttackStart(Unit* who) final override
  972. + {
  973. + if (!me->HasAura(SPELL_SHIELD) && instance->GetBossState(DATA_ARGENT_CHALLENGE) != SPECIAL)
  974. + BossAI::AttackStart(who);
  975. + }
  976. +
  977. + void MovementInform(uint32 type, uint32 id) final override
  978. + {
  979. + if (type != POINT_MOTION_TYPE)
  980. + return;
  981. +
  982. + switch (id)
  983. + {
  984. + case POINT_PREFIGHT:
  985. + if (Creature* announcer = instance->GetCreature(DATA_ANNOUNCER))
  986. + announcer->AI()->SetData(DATA_ARGENT_CHAMPION_PREPARE, 0);
  987. + break;
  988. + case POINT_PREPARE:
  989. + me->SetWalk(false);
  990. + me->SetEmoteState(EMOTE_STATE_READY1H);
  991. + break;
  992. + case POINT_DESPAWN:
  993. + me->DisappearAndDie();
  994. + break;
  995. + default:
  996. + break;
  997. + }
  998. + }
  999. +};
  1000. +
  1001. +enum EadricData
  1002. +{
  1003. + DATA_FACEROLLER_ACHIEVEMENT = 1
  1004. +};
  1005. +
  1006. +class boss_eadric : public CreatureScript
  1007. +{
  1008. +public:
  1009. + boss_eadric() : CreatureScript("boss_eadric") {}
  1010. +
  1011. + struct boss_eadricAI : public argent_challenge_baseAI
  1012. + {
  1013. + boss_eadricAI(Creature* creature) : argent_challenge_baseAI(creature) {}
  1014. +
  1015. + void Initialize() override
  1016. + {
  1017. + _faceroller = false;
  1018. + }
  1019. +
  1020. + void SetData(uint32 type, uint32 data) override
  1021. + {
  1022. + if (type != DATA_FACEROLLER_ACHIEVEMENT)
  1023. + return;
  1024. +
  1025. + _faceroller = (data == 1);
  1026. + }
  1027. +
  1028. + uint32 GetData(uint32 type) const override
  1029. + {
  1030. + if (type != DATA_FACEROLLER_ACHIEVEMENT)
  1031. + return 0;
  1032. +
  1033. + return _faceroller ? 1 : 0;
  1034. + }
  1035. +
  1036. + void OnReset() override
  1037. + {
  1038. + Initialize();
  1039. + argent_challenge_baseAI::OnReset();
  1040. + }
  1041. +
  1042. + void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  1043. + {
  1044. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == DONE)
  1045. + {
  1046. + damage = 0;
  1047. + return;
  1048. + }
  1049. +
  1050. + if (damage >= me->GetHealth())
  1051. + {
  1052. + damage = me->GetHealth() - 1;
  1053. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) != SPECIAL)
  1054. + {
  1055. + instance->SetBossState(DATA_ARGENT_CHALLENGE, SPECIAL);
  1056. + events.Reset();
  1057. + Talk(SAY_DEFEATED_E);
  1058. + }
  1059. + }
  1060. + }
  1061. +
  1062. + void JustEngagedWith(Unit* who) override
  1063. + {
  1064. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == SPECIAL)
  1065. + return;
  1066. +
  1067. + DoCastAOE(SPELL_VENGEANCE);
  1068. + events.ScheduleEvent(EVENT_RADIANCE, 7s, 15s);
  1069. + Talk(SAY_AGGRO_E, who);
  1070. + _JustEngagedWith(who);
  1071. + }
  1072. +
  1073. + void KilledUnit(Unit* who) override
  1074. + {
  1075. + if (who->GetTypeId() == TYPEID_PLAYER)
  1076. + Talk(SAY_KILL_UNIT_E, who);
  1077. + }
  1078. +
  1079. + void UpdateAI(uint32 diff) override
  1080. + {
  1081. + events.Update(diff);
  1082. +
  1083. + if (me->HasUnitState(UNIT_STATE_CASTING))
  1084. + return;
  1085. +
  1086. + while (uint32 eventId = events.ExecuteEvent())
  1087. + {
  1088. + switch (eventId)
  1089. + {
  1090. + case EVENT_RADIANCE:
  1091. + DoCastAOE(SPELL_RADIANCE);
  1092. + Talk(EMOTE_RADIANCE);
  1093. + events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, 20s, 30s);
  1094. + break;
  1095. + case EVENT_HAMMER_OF_JUSTICE:
  1096. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
  1097. + {
  1098. + DoCast(target, SPELL_HAMMER_JUSTICE, true);
  1099. + DoCast(target, SPELL_HAMMER_RIGHTEOUS);
  1100. + Talk(EMOTE_HAMMER_RIGHTEOUS, target);
  1101. + Talk(SAY_HAMMER_RIGHTEOUS);
  1102. + }
  1103. + events.ScheduleEvent(EVENT_RADIANCE, 7s, 15s);
  1104. + break;
  1105. + case EVENT_CHALLENGE_DONE:
  1106. + me->RemoveAllAuras();
  1107. + me->GetThreatManager().ClearAllThreat();
  1108. + me->SetFullHealth();
  1109. + me->RestoreFaction();
  1110. + DoCastAOE(SPELL_EADRIC_ACH, true);
  1111. + DoCastAOE(SPELL_EADRIC_FACEROLLER, true);
  1112. +
  1113. + _JustDied();
  1114. + me->SetWalk(true);
  1115. + me->GetMotionMaster()->MovePoint(POINT_DESPAWN, bossExitPos);
  1116. + break;
  1117. + default:
  1118. + break;
  1119. + }
  1120. + }
  1121. +
  1122. + if (!UpdateVictim())
  1123. + return;
  1124. +
  1125. + DoMeleeAttackIfReady();
  1126. + }
  1127. +
  1128. + private:
  1129. + bool _faceroller;
  1130. + };
  1131. +
  1132. + CreatureAI* GetAI(Creature* creature) const override
  1133. + {
  1134. + return GetTrialOfChampionAI<boss_eadricAI>(creature);
  1135. + }
  1136. +};
  1137. +
  1138. +enum PaletressData
  1139. +{
  1140. + DATA_MEMORY_ENTRY = 1,
  1141. +
  1142. + ACTION_MEMORY_DEATH
  1143. +};
  1144. +
  1145. +class boss_paletress : public CreatureScript
  1146. +{
  1147. +public:
  1148. + boss_paletress() : CreatureScript("boss_paletress") {}
  1149. +
  1150. + struct boss_paletressAI : public argent_challenge_baseAI
  1151. + {
  1152. + boss_paletressAI(Creature* creature) : argent_challenge_baseAI(creature) {}
  1153. +
  1154. + void Initialize() override
  1155. + {
  1156. + argent_challenge_baseAI::Initialize();
  1157. + _memorySummoned = false;
  1158. + }
  1159. +
  1160. + void OnReset() override
  1161. + {
  1162. + me->RemoveAura(SPELL_SHIELD);
  1163. + Initialize();
  1164. + argent_challenge_baseAI::OnReset();
  1165. + }
  1166. +
  1167. + void DoAction(int32 action) override
  1168. + {
  1169. + if (action != ACTION_MEMORY_DEATH)
  1170. + return;
  1171. +
  1172. + me->InterruptNonMeleeSpells(true);
  1173. + Talk(SAY_MEMORY_DEATH);
  1174. + me->GetMotionMaster()->Clear();
  1175. + me->RemoveAura(SPELL_SHIELD);
  1176. + }
  1177. +
  1178. + uint32 GetData(uint32 type) const override
  1179. + {
  1180. + if (type != DATA_MEMORY_ENTRY || _memoryGuid.IsEmpty())
  1181. + return 0;
  1182. +
  1183. + return _memoryGuid.GetEntry();
  1184. + }
  1185. +
  1186. + void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  1187. + {
  1188. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == DONE)
  1189. + {
  1190. + damage = 0;
  1191. + return;
  1192. + }
  1193. +
  1194. + if (!_memorySummoned && !HealthAbovePct(25))
  1195. + {
  1196. + _memorySummoned = true;
  1197. +
  1198. + me->InterruptNonMeleeSpells(true);
  1199. + DoCastAOE(SPELL_HOLY_NOVA);
  1200. + Talk(SAY_MEMORY_SUMMON);
  1201. + DoCastAOE(SPELL_SHIELD);
  1202. + DoCastAOE(SPELL_CONFESS);
  1203. + me->AttackStop();
  1204. + events.ScheduleEvent(EVENT_SUMMON_MEMORY, 2s);
  1205. + }
  1206. +
  1207. + if (damage >= me->GetHealth())
  1208. + {
  1209. + damage = me->GetHealth() - 1;
  1210. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) != SPECIAL)
  1211. + {
  1212. + instance->SetBossState(DATA_ARGENT_CHALLENGE, SPECIAL);
  1213. + events.Reset();
  1214. + Talk(SAY_DEFEATED_P);
  1215. + }
  1216. + }
  1217. + }
  1218. +
  1219. + void JustSummoned(Creature* summon) override
  1220. + {
  1221. + argent_challenge_baseAI::JustSummoned(summon);
  1222. +
  1223. + _memoryGuid = summon->GetGUID();
  1224. + me->GetMotionMaster()->MoveFollow(summon, 30.0f, 0.0f);
  1225. + }
  1226. +
  1227. + void JustEngagedWith(Unit* who) override
  1228. + {
  1229. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == SPECIAL)
  1230. + return;
  1231. +
  1232. + events.ScheduleEvent(EVENT_HOLY_SMITE_E, 2s);
  1233. + events.ScheduleEvent(EVENT_HOLY_FIRE, 9s, 12s);
  1234. + events.ScheduleEvent(EVENT_RENEW, 15s, 17s);
  1235. + Talk(SAY_AGGRO_P, who);
  1236. + _JustEngagedWith(who);
  1237. + }
  1238. +
  1239. + void KilledUnit(Unit* who) override
  1240. + {
  1241. + if (who->GetTypeId() == TYPEID_PLAYER)
  1242. + Talk(SAY_KILL_UNIT_P, who);
  1243. + }
  1244. +
  1245. + void UpdateAI(uint32 diff) override
  1246. + {
  1247. + events.Update(diff);
  1248. +
  1249. + while (uint32 eventId = events.ExecuteEvent())
  1250. + {
  1251. + switch (eventId)
  1252. + {
  1253. + case EVENT_HOLY_SMITE_E:
  1254. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
  1255. + DoCast(target, SPELL_SMITE);
  1256. + events.Repeat(2s, 3s);
  1257. + break;
  1258. + case EVENT_HOLY_FIRE:
  1259. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
  1260. + DoCast(target, SPELL_HOLY_FIRE);
  1261. + events.Repeat(9s, 12s);
  1262. + break;
  1263. + case EVENT_RENEW:
  1264. + me->InterruptNonMeleeSpells(true);
  1265. + if ((rand32() % 2) > 0 && me->GetHealthPct() < 100)
  1266. + DoCastSelf(SPELL_RENEW);
  1267. + else
  1268. + {
  1269. + Creature* memory = ObjectAccessor::GetCreature(*me, _memoryGuid);
  1270. + if (memory && memory->GetHealth() > 1)
  1271. + DoCast(memory, SPELL_RENEW);
  1272. + else
  1273. + DoCastSelf(SPELL_RENEW);
  1274. + }
  1275. +
  1276. + events.Repeat(15s, 17s);
  1277. + break;
  1278. + case EVENT_SUMMON_MEMORY:
  1279. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true))
  1280. + DoCast(target, SPELL_SUMMON_MEMORY, true);
  1281. + break;
  1282. + case EVENT_CHALLENGE_DONE:
  1283. + me->RemoveAllAuras();
  1284. + me->GetThreatManager().ClearAllThreat();
  1285. + me->SetFullHealth();
  1286. + DoCastAOE(SPELL_PALETRESS_ACH, true);
  1287. + me->RestoreFaction();
  1288. +
  1289. + if (IsHeroic())
  1290. + DoCastAOE(SPELL_PALETRESS_CONFESSOR, true);
  1291. +
  1292. + _JustDied();
  1293. + me->SetWalk(true);
  1294. + me->GetMotionMaster()->MovePoint(POINT_DESPAWN, bossExitPos);
  1295. + break;
  1296. + default:
  1297. + break;
  1298. + }
  1299. + }
  1300. +
  1301. + if (!UpdateVictim())
  1302. + return;
  1303. +
  1304. + DoMeleeAttackIfReady();
  1305. + }
  1306. +
  1307. + private:
  1308. + bool _memorySummoned;
  1309. + ObjectGuid _memoryGuid;
  1310. + };
  1311. +
  1312. + CreatureAI* GetAI(Creature* creature) const override
  1313. + {
  1314. + return GetTrialOfChampionAI<boss_paletressAI>(creature);
  1315. + }
  1316. +};
  1317. +
  1318. +class npc_argent_soldier : public CreatureScript
  1319. +{
  1320. +public:
  1321. + npc_argent_soldier() : CreatureScript("npc_argent_soldier") {}
  1322. +
  1323. + struct npc_argent_soldierAI : public ScriptedAI
  1324. + {
  1325. + npc_argent_soldierAI(Creature* creature) : ScriptedAI(creature)
  1326. + {
  1327. + _instance = creature->GetInstanceScript();
  1328. + Initialize();
  1329. + _waypointId = 0;
  1330. + }
  1331. +
  1332. + void Initialize()
  1333. + {
  1334. + _shielded = false;
  1335. + }
  1336. +
  1337. + InstanceScript* _instance;
  1338. + EventMap _events;
  1339. +
  1340. + ObjectGuid _fountainGuid;
  1341. +
  1342. + uint8 _waypointId;
  1343. + bool _shielded;
  1344. +
  1345. + void Reset() override
  1346. + {
  1347. + _events.Reset();
  1348. + Initialize();
  1349. +
  1350. + if (me->GetEntry() == NPC_PRIESTESS)
  1351. + if (Creature* fountain = ObjectAccessor::GetCreature(*me, _fountainGuid))
  1352. + fountain->DisappearAndDie();
  1353. + }
  1354. +
  1355. + void GenerateFinalPosition(Position& finalPos) const
  1356. + {
  1357. + switch (me->GetEntry())
  1358. + {
  1359. + case NPC_ARGENT_LIGHWIELDER:
  1360. + switch (_waypointId)
  1361. + {
  1362. + case 0:
  1363. + finalPos = { 712.14f, 628.42f, 411.88f, 5.81f };
  1364. + break;
  1365. + case 1:
  1366. + finalPos = { 742.44f, 650.29f, 411.79f, 4.60f };
  1367. + break;
  1368. + case 2:
  1369. + finalPos = { 774.94f, 636.64f, 411.89f, 3.78f };
  1370. + break;
  1371. + }
  1372. + break;
  1373. + case NPC_ARGENT_MONK:
  1374. + switch (_waypointId)
  1375. + {
  1376. + case 0:
  1377. + finalPos = { 713.12f, 632.97f, 411.90f, 5.81f };
  1378. + break;
  1379. + case 1:
  1380. + finalPos = { 746.73f, 650.24f, 411.56f, 4.60f };
  1381. + break;
  1382. + case 2:
  1383. + finalPos = { 777.33f, 633.08f, 411.89f, 3.78f };
  1384. + break;
  1385. + }
  1386. + break;
  1387. + case NPC_PRIESTESS:
  1388. + switch (_waypointId)
  1389. + {
  1390. + case 0:
  1391. + finalPos = { 715.06f, 637.07f, 411.91f, 5.81f };
  1392. + break;
  1393. + case 1:
  1394. + finalPos = { 750.72f, 650.20f, 411.77f, 4.60f };
  1395. + break;
  1396. + case 2:
  1397. + finalPos = { 780.13f, 629.18f, 411.89f, 3.78f };
  1398. + break;
  1399. + }
  1400. + break;
  1401. + default:
  1402. + break;
  1403. + }
  1404. + }
  1405. +
  1406. + void JustReachedHome() override
  1407. + {
  1408. + me->SetEmoteState(EMOTE_STATE_READY1H);
  1409. + }
  1410. +
  1411. + void MovementInform(uint32 type, uint32 id) override
  1412. + {
  1413. + if (type != POINT_MOTION_TYPE)
  1414. + return;
  1415. +
  1416. + if (id == POINT_PREFIGHT)
  1417. + {
  1418. + me->SetWalk(false);
  1419. + me->GetMotionMaster()->MoveTargetedHome();
  1420. + if (me->GetEntry() == NPC_ARGENT_MONK)
  1421. + {
  1422. + if (Creature* lightWielder = me->FindNearestCreature(NPC_ARGENT_LIGHWIELDER, 15.0f))
  1423. + {
  1424. + if (lightWielder->GetFollowAngle() != 0.f)
  1425. + {
  1426. + lightWielder->GetMotionMaster()->Clear();
  1427. + lightWielder->GetMotionMaster()->MovePoint(0, lightWielder->GetHomePosition());
  1428. + }
  1429. + }
  1430. +
  1431. + if (Creature* priestess = me->FindNearestCreature(NPC_PRIESTESS, 15.0f))
  1432. + {
  1433. + if (priestess->GetFollowAngle() != 0.f)
  1434. + {
  1435. + priestess->GetMotionMaster()->Clear();
  1436. + priestess->GetMotionMaster()->MovePoint(0, priestess->GetHomePosition());
  1437. + }
  1438. + }
  1439. + }
  1440. + }
  1441. + }
  1442. +
  1443. + void JustSummoned(Creature* summon) override
  1444. + {
  1445. + if (me->GetEntry() == NPC_PRIESTESS)
  1446. + _fountainGuid = summon->GetGUID();
  1447. + }
  1448. +
  1449. + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  1450. + {
  1451. + if (me->GetEntry() == NPC_ARGENT_MONK && damage >= me->GetHealth() && !_shielded)
  1452. + {
  1453. + _shielded = true;
  1454. + damage = me->GetHealth() - 1;
  1455. + me->AttackStop();
  1456. +
  1457. + DoCast(SPELL_DIVINE_SHIELD);
  1458. + DoCast(SPELL_FINAL_MEDITATION);
  1459. + }
  1460. + }
  1461. +
  1462. + void JustDied(Unit* /*killer*/) override
  1463. + {
  1464. + _instance->SetData(DATA_ARGENT_SOLDIER_DEFEATED, _instance->GetData(DATA_ARGENT_SOLDIER_DEFEATED) + 1);
  1465. + if (me->GetEntry() == NPC_PRIESTESS)
  1466. + {
  1467. + if (Creature* fountain = ObjectAccessor::GetCreature(*me, _fountainGuid))
  1468. + fountain->DisappearAndDie();
  1469. + }
  1470. + }
  1471. +
  1472. + void SetData(uint32 type, uint32 /*data*/) override
  1473. + {
  1474. + _waypointId = type;
  1475. + Position homePos;
  1476. + GenerateFinalPosition(homePos);
  1477. +
  1478. + if (homePos.IsPositionValid())
  1479. + {
  1480. + me->SetHomePosition(homePos);
  1481. + me->SetWalk(true);
  1482. + if (me->GetEntry() == NPC_ARGENT_MONK)
  1483. + me->GetMotionMaster()->MovePoint(POINT_PREFIGHT, homePos);
  1484. + }
  1485. + }
  1486. +
  1487. + void JustEngagedWith(Unit* /*who*/) override
  1488. + {
  1489. + switch (me->GetEntry())
  1490. + {
  1491. + case NPC_ARGENT_LIGHWIELDER:
  1492. + _events.ScheduleEvent(EVENT_BLAZING_LIGHT, 10s);
  1493. + _events.ScheduleEvent(EVENT_CLEAVE, 4s, 6s);
  1494. + if (IsHeroic())
  1495. + _events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 8s);
  1496. + break;
  1497. + case NPC_ARGENT_MONK:
  1498. + _events.ScheduleEvent(EVENT_FLURRY_OF_BLOWS, 2s);
  1499. + _events.ScheduleEvent(EVENT_PUMMEL, 12s);
  1500. + break;
  1501. + case NPC_PRIESTESS:
  1502. + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 500ms);
  1503. + _events.ScheduleEvent(EVENT_HOLY_SMITE, 2500ms);
  1504. + _events.ScheduleEvent(EVENT_FOUNTAIN, 10s);
  1505. + if (IsHeroic())
  1506. + _events.ScheduleEvent(EVENT_MIND_CONTROL, 15s);
  1507. + break;
  1508. + default:
  1509. + break;
  1510. + }
  1511. + }
  1512. +
  1513. + void AttackStart(Unit* who) override
  1514. + {
  1515. + if (!(me->GetEntry() == NPC_ARGENT_MONK && me->HasAura(SPELL_DIVINE_SHIELD)))
  1516. + ScriptedAI::AttackStart(who);
  1517. + }
  1518. +
  1519. + void UpdateAI(uint32 diff) override
  1520. + {
  1521. + _events.Update(diff);
  1522. +
  1523. + if (me->HasUnitState(UNIT_STATE_CASTING))
  1524. + return;
  1525. +
  1526. + if (!UpdateVictim())
  1527. + return;
  1528. +
  1529. + while (uint32 eventId = _events.ExecuteEvent())
  1530. + {
  1531. + switch (eventId)
  1532. + {
  1533. + case EVENT_BLAZING_LIGHT:
  1534. + if (Unit* friendly = DoSelectLowestHpFriendly(40.0f))
  1535. + {
  1536. + if (friendly->GetHealthPct() > me->GetHealthPct())
  1537. + DoCastSelf(SPELL_BLAZING_LIGHT);
  1538. + else
  1539. + DoCast(friendly, SPELL_BLAZING_LIGHT);
  1540. + }
  1541. + _events.Repeat(10s);
  1542. + break;
  1543. + case EVENT_CLEAVE:
  1544. + DoCastVictim(SPELL_CLEAVE);
  1545. + _events.Repeat(4s, 6s);
  1546. + break;
  1547. + case EVENT_UNBALANCING_STRIKE:
  1548. + DoCastVictim(SPELL_UNBALANCING_STRIKE);
  1549. + _events.Repeat(15s);
  1550. + break;
  1551. + case EVENT_FLURRY_OF_BLOWS:
  1552. + DoCast(SPELL_FLURRY_OF_BLOWS);
  1553. + _events.Repeat(15s);
  1554. + break;
  1555. + case EVENT_PUMMEL:
  1556. + {
  1557. + Unit* target = nullptr;
  1558. + for (auto* threatTarget : me->GetThreatManager().GetUnsortedThreatList())
  1559. + {
  1560. + if (threatTarget->GetVictim() && threatTarget->GetVictim()->IsWithinDist(me, 5.0f) &&
  1561. + threatTarget->GetVictim()->IsNonMeleeSpellCast(true))
  1562. + {
  1563. + target = threatTarget->GetVictim();
  1564. + break;
  1565. + }
  1566. + }
  1567. +
  1568. + if (target)
  1569. + DoCast(target, SPELL_PUMMEL);
  1570. +
  1571. + _events.Repeat(12s);
  1572. + break;
  1573. + }
  1574. + case EVENT_SHADOW_WORD_PAIN:
  1575. + DoCastVictim(SPELL_SHADOW_WORD_PAIN);
  1576. + _events.Repeat(15s);
  1577. + break;
  1578. + case EVENT_HOLY_SMITE:
  1579. + DoCastVictim(SPELL_HOLY_SMITE);
  1580. + _events.Repeat(4s, 7s);
  1581. + break;
  1582. + case EVENT_FOUNTAIN:
  1583. + DoCastAOE(SPELL_SUMMON_FOUNTAIN);
  1584. + _events.Repeat(50s);
  1585. + break;
  1586. + case EVENT_MIND_CONTROL:
  1587. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 30.0f, true))
  1588. + DoCast(target, SPELL_MIND_CONTROL);
  1589. + _events.Repeat(15s);
  1590. + break;
  1591. + default:
  1592. + break;
  1593. + }
  1594. + }
  1595. +
  1596. + DoMeleeAttackIfReady();
  1597. + }
  1598. + };
  1599. +
  1600. + CreatureAI* GetAI(Creature* creature) const override
  1601. + {
  1602. + return GetTrialOfChampionAI<npc_argent_soldierAI>(creature);
  1603. + }
  1604. +};
  1605. +
  1606. +class npc_fountain_of_light : public CreatureScript
  1607. +{
  1608. +public:
  1609. + npc_fountain_of_light() : CreatureScript("npc_fountain_of_light") {}
  1610. +
  1611. + struct npc_fountain_of_lightAI : public ScriptedAI
  1612. + {
  1613. + npc_fountain_of_lightAI(Creature* creature) : ScriptedAI(creature)
  1614. + {
  1615. + me->SetReactState(REACT_PASSIVE);
  1616. + SetCombatMovement(false);
  1617. + }
  1618. +
  1619. + void JustDied(Unit* /*killer*/) override
  1620. + {
  1621. + me->DespawnOrUnsummon();
  1622. + }
  1623. +
  1624. + void AttackStart(Unit* /*who*/) override {}
  1625. +
  1626. + void UpdateAI(uint32 /*diff*/) override {}
  1627. + };
  1628. +
  1629. + CreatureAI* GetAI(Creature* creature) const override
  1630. + {
  1631. + return GetTrialOfChampionAI<npc_fountain_of_lightAI>(creature);
  1632. + }
  1633. +};
  1634. +
  1635. +class npc_memory : public CreatureScript
  1636. +{
  1637. +public:
  1638. + npc_memory() : CreatureScript("npc_memory") {}
  1639. +
  1640. + struct npc_memoryAI : public ScriptedAI
  1641. + {
  1642. + npc_memoryAI(Creature* creature) : ScriptedAI(creature)
  1643. + {
  1644. + Initialize();
  1645. + me->SetReactState(REACT_PASSIVE);
  1646. + }
  1647. +
  1648. + void Initialize()
  1649. + {
  1650. + DoCastAOE(SPELL_SHADOWFORM);
  1651. + DoCastAOE(SPELL_SPAWN_VISUAL);
  1652. + _events.ScheduleEvent(EVENT_ENTER_AGGRESSIVE, 3s);
  1653. + }
  1654. +
  1655. + void Reset() override
  1656. + {
  1657. + _events.Reset();
  1658. + Initialize();
  1659. + }
  1660. +
  1661. + void JustDied(Unit* /*killer*/) override
  1662. + {
  1663. + if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
  1664. + summoner->GetAI()->DoAction(ACTION_MEMORY_DEATH);
  1665. +
  1666. + me->DespawnOrUnsummon();
  1667. + }
  1668. +
  1669. + void JustEngagedWith(Unit* /*who*/) override
  1670. + {
  1671. + DoZoneInCombat();
  1672. + }
  1673. +
  1674. + void UpdateAI(uint32 diff) override
  1675. + {
  1676. + _events.Update(diff);
  1677. +
  1678. + if (me->HasUnitState(UNIT_STATE_CASTING))
  1679. + return;
  1680. +
  1681. + while (uint32 eventId = _events.ExecuteEvent())
  1682. + {
  1683. + switch (eventId)
  1684. + {
  1685. + case EVENT_ENTER_AGGRESSIVE:
  1686. + me->SetReactState(REACT_AGGRESSIVE);
  1687. + _events.ScheduleEvent(EVENT_OLD_WOUNDS, 11s, 13s);
  1688. + _events.ScheduleEvent(EVENT_SHADOWS_PAST, 5s);
  1689. + _events.ScheduleEvent(EVENT_WAKING_NIGHTMARE, 7s, 10s);
  1690. + break;
  1691. + case EVENT_OLD_WOUNDS:
  1692. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 5.0f, true))
  1693. + DoCast(target, SPELL_OLD_WOUNDS);
  1694. + _events.Repeat(11s, 13s);
  1695. + break;
  1696. + case EVENT_SHADOWS_PAST:
  1697. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true))
  1698. + DoCast(target, SPELL_SHADOWS_PAST);
  1699. + _events.Repeat(5s, 7s);
  1700. + break;
  1701. + case EVENT_WAKING_NIGHTMARE:
  1702. + Talk(EMOTE_WAKING_NIGHTMARE);
  1703. + DoCastAOE(SPELL_WAKING_NIGHTMARE);
  1704. + _events.Repeat(20s, 40s);
  1705. + break;
  1706. + default:
  1707. + break;
  1708. + }
  1709. + }
  1710. +
  1711. + if (!UpdateVictim())
  1712. + return;
  1713. +
  1714. + DoMeleeAttackIfReady();
  1715. + }
  1716. +
  1717. + private:
  1718. + EventMap _events;
  1719. + };
  1720. +
  1721. + CreatureAI* GetAI(Creature* creature) const override
  1722. + {
  1723. + return GetTrialOfChampionAI<npc_memoryAI>(creature);
  1724. + }
  1725. +};
  1726. +
  1727. +class spell_eadric_hammer_of_righteous : public SpellScriptLoader
  1728. +{
  1729. +public:
  1730. + spell_eadric_hammer_of_righteous() : SpellScriptLoader("spell_eadric_hammer_of_righteous") {}
  1731. +
  1732. + class spell_eadric_hammer_of_righteous_SpellScript : public SpellScript
  1733. + {
  1734. + PrepareSpellScript(spell_eadric_hammer_of_righteous_SpellScript);
  1735. +
  1736. + bool Validate(SpellInfo const* /*spellInfo*/) override
  1737. + {
  1738. + if (!sSpellMgr->GetSpellInfo(SPELL_HAMMER_RIGHT_DUMMY) ||
  1739. + !sSpellMgr->GetSpellInfo(SPELL_HAMMER_JUSTICE_STUN))
  1740. + return false;
  1741. + return true;
  1742. + }
  1743. +
  1744. + void HandleOnHit()
  1745. + {
  1746. + if (Unit* target = GetHitUnit())
  1747. + {
  1748. + if (!target->HasAura(SPELL_HAMMER_JUSTICE_STUN))
  1749. + {
  1750. + PreventHitDefaultEffect(EFFECT_0);
  1751. + PreventHitDamage();
  1752. + GetCaster()->CastSpell(target, SPELL_HAMMER_RIGHT_DUMMY, true);
  1753. + }
  1754. + }
  1755. + }
  1756. +
  1757. + void Register() override
  1758. + {
  1759. + OnHit += SpellHitFn(spell_eadric_hammer_of_righteous_SpellScript::HandleOnHit);
  1760. + }
  1761. + };
  1762. +
  1763. + SpellScript* GetSpellScript() const override
  1764. + {
  1765. + return new spell_eadric_hammer_of_righteous_SpellScript();
  1766. + }
  1767. +};
  1768. +
  1769. +class spell_eadric_hammer_of_righteous_faceroller : public SpellScriptLoader
  1770. +{
  1771. +public:
  1772. + spell_eadric_hammer_of_righteous_faceroller() : SpellScriptLoader("spell_eadric_hammer_of_righteous_faceroller") {}
  1773. +
  1774. + class spell_eadric_hammer_of_righteous_faceroller_SpellScript : public SpellScript
  1775. + {
  1776. + PrepareSpellScript(spell_eadric_hammer_of_righteous_faceroller_SpellScript);
  1777. +
  1778. + bool Load() override
  1779. + {
  1780. + Unit* caster = GetCaster();
  1781. + return caster->GetTypeId() == TYPEID_PLAYER && caster->GetMap()->IsHeroic();
  1782. + }
  1783. +
  1784. + void CheckHealth(SpellEffIndex /*effIndex*/)
  1785. + {
  1786. + Creature* creature = GetHitCreature();
  1787. + if (!creature || creature->GetEntry() != NPC_EADRIC)
  1788. + return;
  1789. +
  1790. + if (GetHitDamage() >= static_cast<int32>(GetHitUnit()->GetHealth()))
  1791. + creature->AI()->SetData(DATA_FACEROLLER_ACHIEVEMENT, 1);
  1792. + }
  1793. +
  1794. + void Register() override
  1795. + {
  1796. + OnEffectHitTarget += SpellEffectFn(spell_eadric_hammer_of_righteous_faceroller_SpellScript::CheckHealth, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
  1797. + }
  1798. + };
  1799. +
  1800. + SpellScript* GetSpellScript() const override
  1801. + {
  1802. + return new spell_eadric_hammer_of_righteous_faceroller_SpellScript();
  1803. + }
  1804. +};
  1805. +
  1806. +class spell_eadric_radiance : public SpellScriptLoader
  1807. +{
  1808. +public:
  1809. + spell_eadric_radiance() : SpellScriptLoader("spell_eadric_radiance") {}
  1810. +
  1811. + class spell_eadric_radiance_SpellScript : public SpellScript
  1812. + {
  1813. + PrepareSpellScript(spell_eadric_radiance_SpellScript);
  1814. +
  1815. + void FilterTargets(std::list<WorldObject*>& targets)
  1816. + {
  1817. + Unit* caster = GetCaster();
  1818. +
  1819. + // CORRECCIÓN: Lambda simplificada y corregida
  1820. + targets.remove_if([caster](WorldObject* target) -> bool
  1821. + {
  1822. + if (!target->IsWithinDist(caster, 40.0f))
  1823. + return true;
  1824. +
  1825. + return !target->isInFront(caster, 2.5f);
  1826. + });
  1827. + }
  1828. +
  1829. + void Register() override
  1830. + {
  1831. + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
  1832. + }
  1833. + };
  1834. +
  1835. + SpellScript* GetSpellScript() const override
  1836. + {
  1837. + return new spell_eadric_radiance_SpellScript();
  1838. + }
  1839. +};
  1840. +
  1841. +// 66545 - Summon Memory
  1842. +class spell_paletress_summon_memory : public SpellScriptLoader
  1843. +{
  1844. +public:
  1845. + spell_paletress_summon_memory() : SpellScriptLoader("spell_paletress_summon_memory") {}
  1846. +
  1847. + class spell_paletress_summon_memory_SpellScript : public SpellScript
  1848. + {
  1849. + PrepareSpellScript(spell_paletress_summon_memory_SpellScript);
  1850. +
  1851. + bool Validate(SpellInfo const* /*spellInfo*/) override
  1852. + {
  1853. + return sSpellMgr->GetSpellInfo(SPELL_MEMORY_HOGGER) &&
  1854. + sSpellMgr->GetSpellInfo(SPELL_MEMORY_VANCLEEF);
  1855. + }
  1856. +
  1857. + void FilterTargets(std::list<WorldObject*>& targets)
  1858. + {
  1859. + if (!targets.empty())
  1860. + {
  1861. + auto it = targets.begin();
  1862. + std::advance(it, urand(0, targets.size() - 1));
  1863. + WorldObject* target = *it;
  1864. + targets.clear();
  1865. + targets.push_back(target);
  1866. + }
  1867. + }
  1868. +
  1869. + void HandleScript(SpellEffIndex /*effIndex*/)
  1870. + {
  1871. + uint32 randMemorySpellId = SelectRandomMemorySpell();
  1872. + GetHitUnit()->CastSpell(GetHitUnit(), randMemorySpellId, true);
  1873. + }
  1874. +
  1875. + void Register() override
  1876. + {
  1877. + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_paletress_summon_memory_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  1878. + OnEffectHitTarget += SpellEffectFn(spell_paletress_summon_memory_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
  1879. + }
  1880. + };
  1881. +
  1882. + SpellScript* GetSpellScript() const override
  1883. + {
  1884. + return new spell_paletress_summon_memory_SpellScript();
  1885. + }
  1886. +};
  1887. +
  1888. +class spell_paletress_reflective_shield : public SpellScriptLoader
  1889. +{
  1890. +public:
  1891. + spell_paletress_reflective_shield() : SpellScriptLoader("spell_paletress_reflective_shield") {}
  1892. +
  1893. + class spell_paletress_reflective_shield_AuraScript : public AuraScript
  1894. + {
  1895. + PrepareAuraScript(spell_paletress_reflective_shield_AuraScript);
  1896. +
  1897. + bool Validate(SpellInfo const* /*spellInfo*/) override
  1898. + {
  1899. + if (!sSpellMgr->GetSpellInfo(SPELL_SHIELD_REFLECT))
  1900. + return false;
  1901. + return true;
  1902. + }
  1903. +
  1904. + void HandleScript(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
  1905. + {
  1906. + if (dmgInfo.GetAttacker() == GetTarget())
  1907. + return;
  1908. +
  1909. + int32 bp = CalculatePct(absorbAmount, aurEff->GetSpellEffectInfo().CalcValue());
  1910. + GetTarget()->CastSpell(dmgInfo.GetAttacker(), SPELL_SHIELD_REFLECT, CastSpellExtraArgs(aurEff).AddSpellBP0(bp));
  1911. + }
  1912. +
  1913. + void Register() override
  1914. + {
  1915. + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_paletress_reflective_shield_AuraScript::HandleScript, EFFECT_0);
  1916. + }
  1917. + };
  1918. +
  1919. + AuraScript* GetAuraScript() const override
  1920. + {
  1921. + return new spell_paletress_reflective_shield_AuraScript();
  1922. + }
  1923. +};
  1924. +
  1925. +template <uint32 MemoryEntry>
  1926. +class achievement_argent_confessor : public AchievementCriteriaScript
  1927. +{
  1928. +public:
  1929. + achievement_argent_confessor(char const* name) : AchievementCriteriaScript(name) {}
  1930. +
  1931. + bool OnCheck(Player* /*source*/, Unit* target) override
  1932. + {
  1933. + if (!target || !target->IsAIEnabled())
  1934. + return false;
  1935. +
  1936. + return target->GetAI()->GetData(DATA_MEMORY_ENTRY) == MemoryEntry;
  1937. + }
  1938. +};
  1939. +
  1940. +class achievement_eadric_faceroller : public AchievementCriteriaScript
  1941. +{
  1942. +public:
  1943. + achievement_eadric_faceroller() : AchievementCriteriaScript("achievement_eadric_faceroller") {}
  1944. +
  1945. + bool OnCheck(Player* /*source*/, Unit* target) override
  1946. + {
  1947. + if (!target)
  1948. + return false;
  1949. +
  1950. + if (!target->IsAIEnabled())
  1951. + return false;
  1952. +
  1953. + UnitAI* ai = target->GetAI();
  1954. + if (!ai)
  1955. + return false;
  1956. +
  1957. + uint32 achievementData = ai->GetData(DATA_FACEROLLER_ACHIEVEMENT);
  1958. + return (achievementData == 1);
  1959. + }
  1960. +};
  1961. +
  1962. +void AddSC_boss_argent_challenge()
  1963. +{
  1964. + new boss_eadric();
  1965. + new boss_paletress();
  1966. +
  1967. + new npc_argent_soldier();
  1968. + new npc_fountain_of_light();
  1969. + new npc_memory();
  1970. +
  1971. + new spell_eadric_hammer_of_righteous();
  1972. + new spell_eadric_hammer_of_righteous_faceroller();
  1973. + new spell_eadric_radiance();
  1974. +
  1975. + new spell_paletress_summon_memory();
  1976. + new spell_paletress_reflective_shield();
  1977. +
  1978. + // Achievement scripts for each memory type
  1979. + new achievement_argent_confessor<NPC_MEMORY_HOGGER>("achievement_argent_confessor_hogger");
  1980. + new achievement_argent_confessor<NPC_MEMORY_VANCLEEF>("achievement_argent_confessor_vancleef");
  1981. + new achievement_argent_confessor<NPC_MEMORY_MUTANUS>("achievement_argent_confessor_mutanus");
  1982. + new achievement_argent_confessor<NPC_MEMORY_HEROD>("achievement_argent_confessor_herod");
  1983. + new achievement_argent_confessor<NPC_MEMORY_LUCIFRON>("achievement_argent_confessor_lucifron");
  1984. + new achievement_argent_confessor<NPC_MEMORY_THUNDERAAN>("achievement_argent_confessor_thunderaan");
  1985. + new achievement_argent_confessor<NPC_MEMORY_CHROMAGGUS>("achievement_argent_confessor_chromaggus");
  1986. + new achievement_argent_confessor<NPC_MEMORY_HAKKAR>("achievement_argent_confessor_hakkar");
  1987. + new achievement_argent_confessor<NPC_MEMORY_VEKNILASH>("achievement_argent_confessor_veknilash");
  1988. + new achievement_argent_confessor<NPC_MEMORY_KALITHRESH>("achievement_argent_confessor_kalithresh");
  1989. + new achievement_argent_confessor<NPC_MEMORY_MALCHEZAAR>("achievement_argent_confessor_malchezaar");
  1990. + new achievement_argent_confessor<NPC_MEMORY_GRUUL>("achievement_argent_confessor_gruul");
  1991. + new achievement_argent_confessor<NPC_MEMORY_VASHJ>("achievement_argent_confessor_vashj");
  1992. + new achievement_argent_confessor<NPC_MEMORY_ARCHIMONDE>("achievement_argent_confessor_archimonde");
  1993. + new achievement_argent_confessor<NPC_MEMORY_ILLIDAN>("achievement_argent_confessor_illidan");
  1994. + new achievement_argent_confessor<NPC_MEMORY_DELRISSA>("achievement_argent_confessor_delrissa");
  1995. + new achievement_argent_confessor<NPC_MEMORY_MURU>("achievement_argent_confessor_muru");
  1996. + new achievement_argent_confessor<NPC_MEMORY_INGVAR>("achievement_argent_confessor_ingvar");
  1997. + new achievement_argent_confessor<NPC_MEMORY_CYANIGOSA>("achievement_argent_confessor_cyanigosa");
  1998. + new achievement_argent_confessor<NPC_MEMORY_ECK>("achievement_argent_confessor_eck");
  1999. + new achievement_argent_confessor<NPC_MEMORY_ONYXIA>("achievement_argent_confessor_onyxia");
  2000. + new achievement_argent_confessor<NPC_MEMORY_HEIGAN>("achievement_argent_confessor_heigan");
  2001. + new achievement_argent_confessor<NPC_MEMORY_IGNIS>("achievement_argent_confessor_ignis");
  2002. + new achievement_argent_confessor<NPC_MEMORY_VEZAX>("achievement_argent_confessor_vezax");
  2003. + new achievement_argent_confessor<NPC_MEMORY_ALGALON>("achievement_argent_confessor_algalon");
  2004. +
  2005. + new achievement_eadric_faceroller();
  2006. +}
  2007. diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
  2008. dissimilarity index 73%
  2009. index 7ca324bdd8..0bd578810b 100644
  2010. --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
  2011. +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
  2012. @@ -1,431 +1,772 @@
  2013. -/*
  2014. - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
  2015. - *
  2016. - * This program is free software; you can redistribute it and/or modify it
  2017. - * under the terms of the GNU General Public License as published by the
  2018. - * Free Software Foundation; either version 2 of the License, or (at your
  2019. - * option) any later version.
  2020. - *
  2021. - * This program is distributed in the hope that it will be useful, but WITHOUT
  2022. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  2023. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  2024. - * more details.
  2025. - *
  2026. - * You should have received a copy of the GNU General Public License along
  2027. - * with this program. If not, see <http://www.gnu.org/licenses/>.
  2028. - */
  2029. -
  2030. -/* ScriptData
  2031. -SDName: Boss Black Knight
  2032. -SD%Complete: 80%
  2033. -SDComment: missing yells. not sure about timers.
  2034. -SDCategory: Trial of the Champion
  2035. -EndScriptData */
  2036. -
  2037. -#include "ScriptMgr.h"
  2038. -#include "InstanceScript.h"
  2039. -#include "ScriptedEscortAI.h"
  2040. -#include "SpellInfo.h"
  2041. -#include "SpellScript.h"
  2042. -#include "trial_of_the_champion.h"
  2043. -
  2044. -enum Spells
  2045. -{
  2046. - //phase 1
  2047. - SPELL_PLAGUE_STRIKE = 67884,
  2048. - SPELL_PLAGUE_STRIKE_2 = 67724,
  2049. - SPELL_ICY_TOUCH_H = 67881,
  2050. - SPELL_ICY_TOUCH = 67718,
  2051. - SPELL_DEATH_RESPITE = 67745,
  2052. - SPELL_DEATH_RESPITE_2 = 68306,
  2053. - SPELL_DEATH_RESPITE_3 = 66798,
  2054. - SPELL_OBLITERATE_H = 67883,
  2055. - SPELL_OBLITERATE = 67725,
  2056. - //in this phase should rise herald (the spell is missing)
  2057. -
  2058. - //phase 2 - During this phase, the Black Knight will use the same abilities as in phase 1, except for Death's Respite
  2059. - SPELL_ARMY_DEAD = 67761,
  2060. - SPELL_DESECRATION = 67778,
  2061. - SPELL_DESECRATION_2 = 67778,
  2062. - SPELL_GHOUL_EXPLODE = 67751,
  2063. -
  2064. - //phase 3
  2065. - SPELL_DEATH_BITE_H = 67875,
  2066. - SPELL_DEATH_BITE = 67808,
  2067. - SPELL_MARKED_DEATH = 67882,
  2068. - SPELL_MARKED_DEATH_2 = 67823,
  2069. -
  2070. - SPELL_BLACK_KNIGHT_RES = 67693,
  2071. -
  2072. - SPELL_LEAP = 67749,
  2073. - SPELL_LEAP_H = 67880,
  2074. -
  2075. - SPELL_KILL_CREDIT = 68663
  2076. -};
  2077. -
  2078. -enum Models
  2079. -{
  2080. - MODEL_SKELETON = 29846,
  2081. - MODEL_GHOST = 21300
  2082. -};
  2083. -
  2084. -enum Phases
  2085. -{
  2086. - PHASE_UNDEAD = 1,
  2087. - PHASE_SKELETON = 2,
  2088. - PHASE_GHOST = 3
  2089. -};
  2090. -
  2091. -class boss_black_knight : public CreatureScript
  2092. -{
  2093. -public:
  2094. - boss_black_knight() : CreatureScript("boss_black_knight") { }
  2095. -
  2096. - struct boss_black_knightAI : public ScriptedAI
  2097. - {
  2098. - boss_black_knightAI(Creature* creature) : ScriptedAI(creature), summons(creature)
  2099. - {
  2100. - Initialize();
  2101. - instance = creature->GetInstanceScript();
  2102. - }
  2103. -
  2104. - void Initialize()
  2105. - {
  2106. - bEventInProgress = false;
  2107. - bEvent = false;
  2108. - bSummonArmy = false;
  2109. - bDeathArmyDone = false;
  2110. -
  2111. - uiPhase = PHASE_UNDEAD;
  2112. -
  2113. - uiIcyTouchTimer = urand(5000, 9000);
  2114. - uiPlagueStrikeTimer = urand(10000, 13000);
  2115. - uiDeathRespiteTimer = urand(15000, 16000);
  2116. - uiObliterateTimer = urand(17000, 19000);
  2117. - uiDesecration = urand(15000, 16000);
  2118. - uiDeathArmyCheckTimer = 7000;
  2119. - uiResurrectTimer = 4000;
  2120. - uiGhoulExplodeTimer = 8000;
  2121. - uiDeathBiteTimer = urand(2000, 4000);
  2122. - uiMarkedDeathTimer = urand(5000, 7000);
  2123. - }
  2124. -
  2125. - InstanceScript* instance;
  2126. -
  2127. - SummonList summons;
  2128. -
  2129. - bool bEventInProgress;
  2130. - bool bEvent;
  2131. - bool bSummonArmy;
  2132. - bool bDeathArmyDone;
  2133. -
  2134. - uint8 uiPhase;
  2135. -
  2136. - uint32 uiPlagueStrikeTimer;
  2137. - uint32 uiIcyTouchTimer;
  2138. - uint32 uiDeathRespiteTimer;
  2139. - uint32 uiObliterateTimer;
  2140. - uint32 uiDesecration;
  2141. - uint32 uiResurrectTimer;
  2142. - uint32 uiDeathArmyCheckTimer;
  2143. - uint32 uiGhoulExplodeTimer;
  2144. - uint32 uiDeathBiteTimer;
  2145. - uint32 uiMarkedDeathTimer;
  2146. -
  2147. - void Reset() override
  2148. - {
  2149. - summons.DespawnAll();
  2150. - me->SetDisplayId(me->GetNativeDisplayId());
  2151. - me->ClearUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED);
  2152. -
  2153. - Initialize();
  2154. - }
  2155. -
  2156. - void JustSummoned(Creature* summon) override
  2157. - {
  2158. - summons.Summon(summon);
  2159. - summon->AI()->AttackStart(me->GetVictim());
  2160. - }
  2161. -
  2162. - void SummonedCreatureDespawn(Creature* summon) override
  2163. - {
  2164. - summons.Despawn(summon);
  2165. - }
  2166. -
  2167. - void UpdateAI(uint32 uiDiff) override
  2168. - {
  2169. - //Return since we have no target
  2170. - if (!UpdateVictim())
  2171. - return;
  2172. -
  2173. - if (bEventInProgress)
  2174. - {
  2175. - if (uiResurrectTimer <= uiDiff)
  2176. - {
  2177. - me->SetFullHealth();
  2178. - DoCast(me, SPELL_BLACK_KNIGHT_RES, true);
  2179. - uiPhase++;
  2180. - uiResurrectTimer = 4000;
  2181. - bEventInProgress = false;
  2182. - me->ClearUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED);
  2183. - } else uiResurrectTimer -= uiDiff;
  2184. - }
  2185. -
  2186. - switch (uiPhase)
  2187. - {
  2188. - case PHASE_UNDEAD:
  2189. - case PHASE_SKELETON:
  2190. - {
  2191. - if (uiIcyTouchTimer <= uiDiff)
  2192. - {
  2193. - DoCastVictim(SPELL_ICY_TOUCH);
  2194. - uiIcyTouchTimer = urand(5000, 7000);
  2195. - } else uiIcyTouchTimer -= uiDiff;
  2196. - if (uiPlagueStrikeTimer <= uiDiff)
  2197. - {
  2198. - DoCastVictim(SPELL_ICY_TOUCH);
  2199. - uiPlagueStrikeTimer = urand(12000, 15000);
  2200. - } else uiPlagueStrikeTimer -= uiDiff;
  2201. - if (uiObliterateTimer <= uiDiff)
  2202. - {
  2203. - DoCastVictim(SPELL_OBLITERATE);
  2204. - uiObliterateTimer = urand(17000, 19000);
  2205. - } else uiObliterateTimer -= uiDiff;
  2206. - switch (uiPhase)
  2207. - {
  2208. - case PHASE_UNDEAD:
  2209. - {
  2210. - if (uiDeathRespiteTimer <= uiDiff)
  2211. - {
  2212. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
  2213. - {
  2214. - if (target->IsAlive())
  2215. - DoCast(target, SPELL_DEATH_RESPITE);
  2216. - }
  2217. - uiDeathRespiteTimer = urand(15000, 16000);
  2218. - } else uiDeathRespiteTimer -= uiDiff;
  2219. - break;
  2220. - }
  2221. - case PHASE_SKELETON:
  2222. - {
  2223. - if (!bSummonArmy)
  2224. - {
  2225. - bSummonArmy = true;
  2226. - me->AddUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED);
  2227. - DoCast(me, SPELL_ARMY_DEAD);
  2228. - }
  2229. - if (!bDeathArmyDone)
  2230. - {
  2231. - if (uiDeathArmyCheckTimer <= uiDiff)
  2232. - {
  2233. - me->ClearUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED);
  2234. - uiDeathArmyCheckTimer = 0;
  2235. - bDeathArmyDone = true;
  2236. - } else uiDeathArmyCheckTimer -= uiDiff;
  2237. - }
  2238. - if (uiDesecration <= uiDiff)
  2239. - {
  2240. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
  2241. - {
  2242. - if (target->IsAlive())
  2243. - DoCast(target, SPELL_DESECRATION);
  2244. - }
  2245. - uiDesecration = urand(15000, 16000);
  2246. - } else uiDesecration -= uiDiff;
  2247. - if (uiGhoulExplodeTimer <= uiDiff)
  2248. - {
  2249. - DoCast(me, SPELL_GHOUL_EXPLODE);
  2250. - uiGhoulExplodeTimer = 8000;
  2251. - } else uiGhoulExplodeTimer -= uiDiff;
  2252. - break;
  2253. - }
  2254. - break;
  2255. - }
  2256. - break;
  2257. - }
  2258. - case PHASE_GHOST:
  2259. - {
  2260. - if (uiDeathBiteTimer <= uiDiff)
  2261. - {
  2262. - DoCastAOE(SPELL_DEATH_BITE);
  2263. - uiDeathBiteTimer = urand(2000, 4000);
  2264. - } else uiDeathBiteTimer -= uiDiff;
  2265. - if (uiMarkedDeathTimer <= uiDiff)
  2266. - {
  2267. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
  2268. - {
  2269. - if (target->IsAlive())
  2270. - DoCast(target, SPELL_MARKED_DEATH);
  2271. - }
  2272. - uiMarkedDeathTimer = urand(5000, 7000);
  2273. - } else uiMarkedDeathTimer -= uiDiff;
  2274. - break;
  2275. - }
  2276. - }
  2277. -
  2278. - if (!me->HasUnitState(UNIT_STATE_ROOT) && !me->HealthBelowPct(1))
  2279. - DoMeleeAttackIfReady();
  2280. - }
  2281. -
  2282. - void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  2283. - {
  2284. - if (uiDamage > me->GetHealth() && uiPhase <= PHASE_SKELETON)
  2285. - {
  2286. - uiDamage = 0;
  2287. - me->SetHealth(0);
  2288. - me->AddUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED);
  2289. - summons.DespawnAll();
  2290. - switch (uiPhase)
  2291. - {
  2292. - case PHASE_UNDEAD:
  2293. - me->SetDisplayId(MODEL_SKELETON);
  2294. - break;
  2295. - case PHASE_SKELETON:
  2296. - me->SetDisplayId(MODEL_GHOST);
  2297. - break;
  2298. - }
  2299. - bEventInProgress = true;
  2300. - }
  2301. - }
  2302. -
  2303. - void JustDied(Unit* /*killer*/) override
  2304. - {
  2305. - DoCast(me, SPELL_KILL_CREDIT);
  2306. -
  2307. - instance->SetBossState(BOSS_BLACK_KNIGHT, DONE);
  2308. - }
  2309. - };
  2310. -
  2311. - CreatureAI* GetAI(Creature* creature) const override
  2312. - {
  2313. - return GetTrialOfTheChampionAI<boss_black_knightAI>(creature);
  2314. - }
  2315. -};
  2316. -
  2317. -class npc_risen_ghoul : public CreatureScript
  2318. -{
  2319. -public:
  2320. - npc_risen_ghoul() : CreatureScript("npc_risen_ghoul") { }
  2321. -
  2322. - struct npc_risen_ghoulAI : public ScriptedAI
  2323. - {
  2324. - npc_risen_ghoulAI(Creature* creature) : ScriptedAI(creature)
  2325. - {
  2326. - Initialize();
  2327. - }
  2328. -
  2329. - void Initialize()
  2330. - {
  2331. - uiAttackTimer = 3500;
  2332. - }
  2333. -
  2334. - uint32 uiAttackTimer;
  2335. -
  2336. - void Reset() override
  2337. - {
  2338. - Initialize();
  2339. - }
  2340. -
  2341. - void UpdateAI(uint32 uiDiff) override
  2342. - {
  2343. - if (!UpdateVictim())
  2344. - return;
  2345. -
  2346. - if (uiAttackTimer <= uiDiff)
  2347. - {
  2348. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true))
  2349. - {
  2350. - if (target->IsAlive())
  2351. - DoCast(target, (SPELL_LEAP));
  2352. - }
  2353. - uiAttackTimer = 3500;
  2354. - } else uiAttackTimer -= uiDiff;
  2355. -
  2356. - DoMeleeAttackIfReady();
  2357. - }
  2358. - };
  2359. -
  2360. - CreatureAI* GetAI(Creature* creature) const override
  2361. - {
  2362. - return GetTrialOfTheChampionAI<npc_risen_ghoulAI>(creature);
  2363. - }
  2364. -};
  2365. -
  2366. -class npc_black_knight_skeletal_gryphon : public CreatureScript
  2367. -{
  2368. -public:
  2369. - npc_black_knight_skeletal_gryphon() : CreatureScript("npc_black_knight_skeletal_gryphon") { }
  2370. -
  2371. - struct npc_black_knight_skeletal_gryphonAI : public EscortAI
  2372. - {
  2373. - npc_black_knight_skeletal_gryphonAI(Creature* creature) : EscortAI(creature)
  2374. - {
  2375. - Start(false, true);
  2376. - }
  2377. -
  2378. - void UpdateAI(uint32 uiDiff) override
  2379. - {
  2380. - EscortAI::UpdateAI(uiDiff);
  2381. -
  2382. - UpdateVictim();
  2383. - }
  2384. -
  2385. - };
  2386. -
  2387. - CreatureAI* GetAI(Creature* creature) const override
  2388. - {
  2389. - return GetTrialOfTheChampionAI<npc_black_knight_skeletal_gryphonAI>(creature);
  2390. - }
  2391. -};
  2392. -
  2393. -// 67751 - Ghoul Explode
  2394. -class spell_black_knight_ghoul_explode : public SpellScript
  2395. -{
  2396. - PrepareSpellScript(spell_black_knight_ghoul_explode);
  2397. -
  2398. - bool Validate(SpellInfo const* spellInfo) override
  2399. - {
  2400. - return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) });
  2401. - }
  2402. -
  2403. - void HandleScript(SpellEffIndex /*effIndex*/)
  2404. - {
  2405. - GetHitUnit()->CastSpell(GetHitUnit(), uint32(GetEffectInfo(EFFECT_0).CalcValue()));
  2406. - }
  2407. -
  2408. - void Register() override
  2409. - {
  2410. - OnEffectHitTarget += SpellEffectFn(spell_black_knight_ghoul_explode::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
  2411. - }
  2412. -};
  2413. -
  2414. -// 67754 - Ghoul Explode
  2415. -// 67889 - Ghoul Explode
  2416. -class spell_black_knight_ghoul_explode_risen_ghoul : public SpellScript
  2417. -{
  2418. - PrepareSpellScript(spell_black_knight_ghoul_explode_risen_ghoul);
  2419. -
  2420. - bool Validate(SpellInfo const* spellInfo) override
  2421. - {
  2422. - return ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_1).CalcValue()) });
  2423. - }
  2424. -
  2425. - void HandleScript(SpellEffIndex /*effIndex*/)
  2426. - {
  2427. - GetCaster()->CastSpell(GetCaster(), uint32(GetEffectValue()));
  2428. - }
  2429. -
  2430. - void Register() override
  2431. - {
  2432. - OnEffectHit += SpellEffectFn(spell_black_knight_ghoul_explode_risen_ghoul::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
  2433. - }
  2434. -};
  2435. -
  2436. -void AddSC_boss_black_knight()
  2437. -{
  2438. - new boss_black_knight();
  2439. - new npc_risen_ghoul();
  2440. - new npc_black_knight_skeletal_gryphon();
  2441. - RegisterSpellScript(spell_black_knight_ghoul_explode);
  2442. - RegisterSpellScript(spell_black_knight_ghoul_explode_risen_ghoul);
  2443. -}
  2444. +/*
  2445. + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  2446. + *
  2447. + * This program is free software; you can redistribute it and/or modify it
  2448. + * under the terms of the GNU General Public License as published by the
  2449. + * Free Software Foundation; either version 2 of the License, or (at your
  2450. + * option) any later version.
  2451. + *
  2452. + * This program is distributed in the hope that it will be useful, but WITHOUT
  2453. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  2454. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  2455. + * more details.
  2456. + *
  2457. + * You should have received a copy of the GNU General Public License along
  2458. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  2459. + */
  2460. +
  2461. + /* ScriptData
  2462. + SDName: Boss Black Knight
  2463. + SD%Complete: 100%
  2464. + SDComment:
  2465. + SDCategory: Trial of the Champion
  2466. + EndScriptData */
  2467. +
  2468. +#include "Player.h"
  2469. +#include "ScriptMgr.h"
  2470. +#include "ScriptedCreature.h"
  2471. +#include "ScriptedEscortAI.h"
  2472. +#include "SpellAuraEffects.h"
  2473. +#include "SpellScript.h"
  2474. +#include "SpellMgr.h"
  2475. +#include "trial_of_the_champion.h"
  2476. +
  2477. +enum Yells
  2478. +{
  2479. + SAY_AGGRO = 3,
  2480. + SAY_PHASE_2 = 4,
  2481. + SAY_PHASE_3 = 5,
  2482. + SAY_KILL = 6,
  2483. + SAY_DEATH = 7
  2484. +};
  2485. +
  2486. +enum Events
  2487. +{
  2488. + // The Black Knight
  2489. + EVENT_ICY_TOUCH = 1,
  2490. + EVENT_PLAGUE_STRIKE,
  2491. + EVENT_DEATH_RESPITE,
  2492. + EVENT_OBLITERATE,
  2493. + EVENT_DESECRATION,
  2494. + EVENT_GHOUL_EXPLODE,
  2495. + EVENT_DEATH_BITE,
  2496. + EVENT_MARKED_DEATH,
  2497. + EVENT_RESURRECT,
  2498. + // Ghouls
  2499. + EVENT_CLAW,
  2500. + EVENT_LEAP
  2501. +};
  2502. +
  2503. +enum Spells
  2504. +{
  2505. + // Phase 1
  2506. + SPELL_PLAGUE_STRIKE = 67724,
  2507. + SPELL_ICY_TOUCH = 67718,
  2508. + SPELL_DEATH_RESPITE = 67745,
  2509. + SPELL_OBLITERATE = 67725,
  2510. + SPELL_RAISE_ARELAS = 67705,
  2511. + SPELL_RAISE_JAEREN = 67715,
  2512. +
  2513. + // Phase 2
  2514. + SPELL_ARMY_DEAD = 67761,
  2515. + SPELL_DESECRATION = 67778,
  2516. + SPELL_GHOUL_EXPLODE = 67751,
  2517. +
  2518. + // Phase 3
  2519. + SPELL_DEATH_BITE = 67808,
  2520. + SPELL_MARKED_DEATH = 67882,
  2521. +
  2522. + // Ghouls
  2523. + SPELL_CLAW = 67774,
  2524. + SPELL_LEAP = 67749,
  2525. +
  2526. + SPELL_DEATH_RESPITE_DND = 66798, // casted on announcer
  2527. + SPELL_FEIGN_DEATH = 66804,
  2528. + SPELL_BLACK_KNIGHT_DIE = 67691,
  2529. + SPELL_BLACK_KNIGHT_RES = 67693,
  2530. + SPELL_FROST_FEVER = 67719,
  2531. + SPELL_BLOOD_PLAGUE = 67722,
  2532. + SPELL_EXPLODE = 67729,
  2533. + SPELL_DESECRATION_DND = 67782,
  2534. + SPELL_DESECRATION_ARM = 67803,
  2535. + SPELL_FROST_FEVER_H = 67878,
  2536. + SPELL_BLOOD_PLAGUE_H = 67885,
  2537. + SPELL_EXPLODE_H = 67886,
  2538. + SPELL_KILL_CREDIT = 68663
  2539. +};
  2540. +
  2541. +enum Models
  2542. +{
  2543. + MODEL_SKELETON = 29846,
  2544. + MODEL_GHOST = 21300
  2545. +};
  2546. +
  2547. +enum Equipment
  2548. +{
  2549. + EQUIP_SWORD = 40343
  2550. +};
  2551. +
  2552. +enum Phases
  2553. +{
  2554. + PHASE_UNDEAD = 1,
  2555. + PHASE_SKELETON = 2,
  2556. + PHASE_GHOST = 3
  2557. +};
  2558. +
  2559. +class npc_risen_ghoul : public CreatureScript
  2560. +{
  2561. +public:
  2562. + npc_risen_ghoul() : CreatureScript("npc_risen_ghoul") {}
  2563. +
  2564. + struct npc_risen_ghoulAI : public ScriptedAI
  2565. + {
  2566. + npc_risen_ghoulAI(Creature* creature) : ScriptedAI(creature)
  2567. + {
  2568. + Initialize();
  2569. + instance = creature->GetInstanceScript();
  2570. + }
  2571. +
  2572. + void Initialize()
  2573. + {
  2574. + doExplode = false;
  2575. + }
  2576. +
  2577. + InstanceScript* instance;
  2578. +
  2579. + EventMap events;
  2580. +
  2581. + bool doExplode;
  2582. +
  2583. + void Reset() override
  2584. + {
  2585. + events.Reset();
  2586. + Initialize();
  2587. + }
  2588. +
  2589. + // CORRECCIÓN: SpellHitTarget actualizada
  2590. + void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
  2591. + {
  2592. + if (!target->IsPlayer())
  2593. + return;
  2594. +
  2595. + if (spellInfo->Id == SPELL_EXPLODE || spellInfo->Id == SPELL_EXPLODE_H)
  2596. + {
  2597. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  2598. + // If corpse explosion hits any player during encounter
  2599. + // we cannot give achievement id 3804
  2600. + knight->AI()->SetData(1, 0);
  2601. + }
  2602. + }
  2603. +
  2604. + void DoExplode()
  2605. + {
  2606. + // We trigger the ghoul explode spell casted on us by Black Knight
  2607. + // to get immunity to crowd control forms and we get correct growth aura
  2608. + // the spell script of Ghoul Explode functions normally from here on
  2609. + if (me->HasAura(SPELL_GHOUL_EXPLODE))
  2610. + return;
  2611. + DoCast(me, SPELL_GHOUL_EXPLODE, true);
  2612. + // wtf?
  2613. + if (me->GetEntry() == NPC_RISEN_ARELAS || me->GetEntry() == NPC_RISEN_JAEREN)
  2614. + Talk(urand(0, 2));
  2615. + }
  2616. +
  2617. + // CORRECCIÓN: DamageTaken actualizada
  2618. + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  2619. + {
  2620. + if (HealthBelowPct(31) && !doExplode)
  2621. + {
  2622. + // Ghouls cast explode when they reach 30% health or if Black Knight dies
  2623. + // or if Black Knight forces them to explode
  2624. + doExplode = true;
  2625. + DoExplode();
  2626. + }
  2627. + }
  2628. +
  2629. + // CORRECCIÓN: EnterCombat ? JustEngagedWith
  2630. + void JustEngagedWith(Unit* /*who*/) override
  2631. + {
  2632. + events.ScheduleEvent(EVENT_CLAW, 3s);
  2633. + events.ScheduleEvent(EVENT_LEAP, 2s);
  2634. + DoZoneInCombat();
  2635. + }
  2636. +
  2637. + void JustDied(Unit* /*killer*/) override
  2638. + {
  2639. + me->DespawnOrUnsummon(1s); // CORRECCIÓN: Usar 1s
  2640. + }
  2641. +
  2642. + void KilledUnit(Unit* who) override
  2643. + {
  2644. + if (who == me)
  2645. + return;
  2646. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  2647. + {
  2648. + if (!knight->HasAura(SPELL_BLACK_KNIGHT_DIE))
  2649. + knight->AI()->KilledUnit(who);
  2650. + }
  2651. + }
  2652. +
  2653. + void UpdateAI(uint32 uiDiff) override
  2654. + {
  2655. + events.Update(uiDiff);
  2656. +
  2657. + if (me->HasUnitState(UNIT_STATE_CASTING))
  2658. + return;
  2659. +
  2660. + if (!UpdateVictim())
  2661. + return;
  2662. +
  2663. + while (uint32 eventId = events.ExecuteEvent())
  2664. + {
  2665. + switch (eventId)
  2666. + {
  2667. + case EVENT_CLAW:
  2668. + DoCastVictim(SPELL_CLAW);
  2669. + // CORRECCIÓN: Cambiar SELECT_TARGET_RANDOM por SelectTargetMethod::Random
  2670. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 50.0f, true))
  2671. + {
  2672. + ResetThreatList();
  2673. + AddThreat(target, 10.0f);
  2674. + me->AI()->AttackStart(target);
  2675. + }
  2676. + events.ScheduleEvent(EVENT_CLAW, 12s, 15s);
  2677. + break;
  2678. + case EVENT_LEAP:
  2679. + if (me->GetEntry() == NPC_RISEN_ARELAS || me->GetEntry() == NPC_RISEN_JAEREN)
  2680. + {
  2681. + // CORRECCIÓN: Cambiar SELECT_TARGET_RANDOM por SelectTargetMethod::Random
  2682. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 30.0f, true))
  2683. + DoCast(target, SPELL_LEAP);
  2684. + events.ScheduleEvent(EVENT_LEAP, 8s, 10s);
  2685. + }
  2686. + break;
  2687. + default:
  2688. + break;
  2689. + }
  2690. + }
  2691. + DoMeleeAttackIfReady();
  2692. + }
  2693. + };
  2694. +
  2695. + CreatureAI* GetAI(Creature* creature) const override
  2696. + {
  2697. + return GetTrialOfChampionAI<npc_risen_ghoulAI>(creature);
  2698. + }
  2699. +};
  2700. +
  2701. +class boss_black_knight : public CreatureScript
  2702. +{
  2703. +public:
  2704. + boss_black_knight() : CreatureScript("boss_black_knight") {}
  2705. +
  2706. + struct boss_black_knightAI : public BossAI
  2707. + {
  2708. + boss_black_knightAI(Creature* creature) : BossAI(creature, DATA_BLACK_KNIGHT)
  2709. + {
  2710. + Initialize();
  2711. + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  2712. + me->SetReactState(REACT_PASSIVE);
  2713. + }
  2714. +
  2715. + void Initialize()
  2716. + {
  2717. + uiPhase = PHASE_UNDEAD;
  2718. + achievementCredit = true;
  2719. + }
  2720. +
  2721. + uint8 uiPhase;
  2722. + bool achievementCredit;
  2723. +
  2724. + void Reset() override
  2725. + {
  2726. + me->SetDisplayId(me->GetNativeDisplayId());
  2727. + SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  2728. + _Reset();
  2729. + Initialize();
  2730. + }
  2731. +
  2732. + void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override
  2733. + {
  2734. + BossAI::EnterEvadeMode(why);
  2735. + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  2736. + }
  2737. +
  2738. + // Events are not resetted in this function
  2739. + void LoadEvents()
  2740. + {
  2741. + if (uiPhase == PHASE_GHOST)
  2742. + {
  2743. + // Phase 3
  2744. + events.ScheduleEvent(EVENT_DEATH_BITE, 5s);
  2745. + events.ScheduleEvent(EVENT_MARKED_DEATH, 20s);
  2746. + }
  2747. + else
  2748. + {
  2749. + // Phase 1 and 2
  2750. + events.ScheduleEvent(EVENT_ICY_TOUCH, 6s);
  2751. + if (uiPhase == PHASE_UNDEAD)
  2752. + {
  2753. + // Phase 1 only
  2754. + events.ScheduleEvent(EVENT_DEATH_RESPITE, 8s);
  2755. +
  2756. + // Raising announcer as a ghoul
  2757. + if (Creature* announcer = instance->GetCreature(DATA_ANNOUNCER))
  2758. + {
  2759. + // CORRECCIÓN: Simplificar CastSpell
  2760. + if (announcer->GetEntry() == NPC_JAEREN)
  2761. + announcer->CastSpell(me->GetVictim(), SPELL_RAISE_JAEREN, false);
  2762. + else
  2763. + announcer->CastSpell(me->GetVictim(), SPELL_RAISE_ARELAS, false);
  2764. + }
  2765. + }
  2766. + else
  2767. + {
  2768. + // Phase 2 only
  2769. + events.ScheduleEvent(EVENT_DESECRATION, 5s);
  2770. + events.ScheduleEvent(EVENT_GHOUL_EXPLODE, 8s);
  2771. +
  2772. + // Army of the Dead
  2773. + // disabling movement temporarily so the spell wont get interrupted
  2774. + me->SetControlled(true, UNIT_STATE_ROOT);
  2775. + DoCast(SPELL_ARMY_DEAD);
  2776. + }
  2777. + }
  2778. + }
  2779. +
  2780. + void SetData(uint32 type, uint32 /*data*/) override
  2781. + {
  2782. + if (type == 1)
  2783. + achievementCredit = false;
  2784. + }
  2785. +
  2786. + void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
  2787. + {
  2788. + if (spellInfo->Id == SPELL_BLACK_KNIGHT_RES)
  2789. + {
  2790. + // TODO: According to sniffs, The Black Knight should update
  2791. + // creature template to another entry, not just change his display id
  2792. + // But the other templates are missing correct damage modifiers
  2793. + me->SetFullHealth();
  2794. + me->SetStandState(UNIT_STAND_STATE_STAND);
  2795. + if (uiPhase == PHASE_UNDEAD)
  2796. + {
  2797. + me->SetDisplayId(MODEL_SKELETON);
  2798. + Talk(SAY_PHASE_2);
  2799. + }
  2800. + else if (uiPhase == PHASE_SKELETON)
  2801. + {
  2802. + me->SetDisplayId(MODEL_GHOST);
  2803. + SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
  2804. + Talk(SAY_PHASE_3);
  2805. + }
  2806. + ++uiPhase;
  2807. + LoadEvents();
  2808. + }
  2809. + }
  2810. +
  2811. + void MovementInform(uint32 type, uint32 id) override
  2812. + {
  2813. + if (type != POINT_MOTION_TYPE)
  2814. + return;
  2815. +
  2816. + if (id == 0)
  2817. + {
  2818. + if (Creature* announcer = instance->GetCreature(DATA_ANNOUNCER))
  2819. + announcer->AI()->SetData(DATA_BLACK_KNIGHT_PRECAST, 0);
  2820. + }
  2821. + }
  2822. +
  2823. + void JustSummoned(Creature* summon) override
  2824. + {
  2825. + if (summon->GetEntry() == NPC_DESECRATION_STALKER)
  2826. + {
  2827. + summon->CastSpell(summon, SPELL_DESECRATION_DND, true);
  2828. + summon->CastSpell(summon, SPELL_DESECRATION_ARM, true);
  2829. + return;
  2830. + }
  2831. + summons.Summon(summon);
  2832. + summon->AI()->AttackStart(me->GetVictim());
  2833. + }
  2834. +
  2835. + void SummonedCreatureDespawn(Creature* summon) override
  2836. + {
  2837. + summons.Despawn(summon);
  2838. + }
  2839. +
  2840. + void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  2841. + {
  2842. + if (damage >= me->GetHealth() && uiPhase < PHASE_GHOST)
  2843. + {
  2844. + damage = 0;
  2845. + events.Reset();
  2846. + me->RemoveAllAuras();
  2847. + me->SetHealth(0);
  2848. + me->SetStandState(UNIT_STAND_STATE_DEAD);
  2849. + DoCast(me, SPELL_BLACK_KNIGHT_DIE);
  2850. + for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
  2851. + {
  2852. + Creature* ghoul = ObjectAccessor::GetCreature(*me, *itr);
  2853. + if (ghoul && ghoul->IsAlive() && !ghoul->HasAura(SPELL_GHOUL_EXPLODE))
  2854. + ENSURE_AI(npc_risen_ghoul::npc_risen_ghoulAI, ghoul->AI())->DoExplode();
  2855. + }
  2856. + }
  2857. + }
  2858. +
  2859. + void JustDied(Unit* /*killer*/) override
  2860. + {
  2861. + Talk(SAY_DEATH);
  2862. + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_KILL_CREDIT, 0, me);
  2863. + _JustDied();
  2864. + }
  2865. +
  2866. + void JustEngagedWith(Unit* who) override
  2867. + {
  2868. + LoadEvents();
  2869. + Talk(SAY_AGGRO, who);
  2870. + _JustEngagedWith(who); // CORRECCIÓN: Agregar parámetro
  2871. + }
  2872. +
  2873. + void KilledUnit(Unit* who) override
  2874. + {
  2875. + Talk(SAY_KILL, who);
  2876. + }
  2877. +
  2878. + void UpdateAI(uint32 uiDiff) override
  2879. + {
  2880. + events.Update(uiDiff);
  2881. +
  2882. + if (me->HasUnitState(UNIT_STATE_CASTING))
  2883. + return;
  2884. +
  2885. + if (!UpdateVictim())
  2886. + return;
  2887. +
  2888. + while (uint32 eventId = events.ExecuteEvent())
  2889. + {
  2890. + switch (eventId)
  2891. + {
  2892. + case EVENT_ICY_TOUCH:
  2893. + DoCastVictim(SPELL_ICY_TOUCH);
  2894. + events.ScheduleEvent(EVENT_PLAGUE_STRIKE, 1s);
  2895. + break;
  2896. + case EVENT_PLAGUE_STRIKE:
  2897. + DoCastVictim(SPELL_PLAGUE_STRIKE);
  2898. + events.ScheduleEvent(EVENT_OBLITERATE, 5s);
  2899. + break;
  2900. + case EVENT_OBLITERATE:
  2901. + DoCastVictim(SPELL_OBLITERATE);
  2902. + events.ScheduleEvent(EVENT_ICY_TOUCH, 5s, 8s);
  2903. + break;
  2904. + case EVENT_DEATH_RESPITE:
  2905. + // TODO: fixing this later
  2906. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 50.0f, true))
  2907. + DoCast(target, SPELL_DEATH_RESPITE);
  2908. + events.ScheduleEvent(EVENT_DEATH_RESPITE, 15s, 16s);
  2909. + break;
  2910. + case EVENT_DESECRATION:
  2911. + DoCastVictim(SPELL_DESECRATION);
  2912. + events.ScheduleEvent(EVENT_DESECRATION, 15s, 16s);
  2913. + break;
  2914. + case EVENT_GHOUL_EXPLODE:
  2915. + DoCastAOE(SPELL_GHOUL_EXPLODE);
  2916. + events.ScheduleEvent(EVENT_GHOUL_EXPLODE, 15s, 16s);
  2917. + break;
  2918. + case EVENT_DEATH_BITE:
  2919. + DoCastAOE(SPELL_DEATH_BITE);
  2920. + events.ScheduleEvent(EVENT_DEATH_BITE, 3s);
  2921. + break;
  2922. + case EVENT_MARKED_DEATH:
  2923. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f))
  2924. + DoCast(target, SPELL_MARKED_DEATH);
  2925. + events.ScheduleEvent(EVENT_MARKED_DEATH, 13s, 15s);
  2926. + break;
  2927. + default:
  2928. + break;
  2929. + }
  2930. + }
  2931. + DoMeleeAttackIfReady();
  2932. + }
  2933. + };
  2934. +
  2935. + CreatureAI* GetAI(Creature* creature) const override
  2936. + {
  2937. + return GetTrialOfChampionAI<boss_black_knightAI>(creature);
  2938. + }
  2939. +};
  2940. +
  2941. +class npc_black_knight_skeletal_gryphon : public CreatureScript
  2942. +{
  2943. +public:
  2944. + npc_black_knight_skeletal_gryphon() : CreatureScript("npc_black_knight_skeletal_gryphon") {}
  2945. +
  2946. + struct npc_black_knight_skeletal_gryphonAI : public EscortAI
  2947. + {
  2948. + npc_black_knight_skeletal_gryphonAI(Creature* creature) : EscortAI(creature)
  2949. + {
  2950. + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  2951. + me->SetReactState(REACT_PASSIVE);
  2952. + me->SetCanFly(true);
  2953. + me->SetDisableGravity(true);
  2954. + SetDespawnAtEnd(true);
  2955. +
  2956. + uiWaypointPath = 0;
  2957. + instance = creature->GetInstanceScript();
  2958. + }
  2959. +
  2960. + InstanceScript* instance;
  2961. + uint32 uiWaypointPath;
  2962. +
  2963. + void SetData(uint32 uiType, uint32 /*uiData*/) override
  2964. + {
  2965. + if (uiType == 1)
  2966. + {
  2967. + // Black Knight is flying towards arena
  2968. + AddWaypoint(0, 766.99f, 657.16f, 457.43f);
  2969. + AddWaypoint(1, 747.28f, 659.71f, 440.49f);
  2970. + AddWaypoint(2, 730.03f, 639.59f, 428.16f);
  2971. + AddWaypoint(3, 721.13f, 621.49f, 423.16f);
  2972. + AddWaypoint(4, 731.72f, 599.81f, 421.99f);
  2973. + AddWaypoint(5, 753.71f, 591.09f, 420.63f);
  2974. + AddWaypoint(6, 776.53f, 597.52f, 418.05f);
  2975. + AddWaypoint(7, 787.38f, 617.07f, 417.49f);
  2976. + AddWaypoint(8, 777.06f, 636.98f, 416.57f);
  2977. + AddWaypoint(9, 760.6f, 642.12f, 414.71f);
  2978. + AddWaypoint(10, 752.58f, 632.35f, 411.63f);
  2979. + // The vehicle starts flying away
  2980. + AddWaypoint(11, 748.89f, 633.61f, 415.24f);
  2981. + AddWaypoint(12, 740.42f, 636.31f, 418.32f);
  2982. + AddWaypoint(13, 727.49f, 637.4f, 422.24f);
  2983. + AddWaypoint(14, 716.59f, 617.99f, 422.24f);
  2984. + AddWaypoint(15, 727.18f, 599.29f, 422.24f);
  2985. + AddWaypoint(16, 746.63f, 587.77f, 422.24f);
  2986. + AddWaypoint(17, 765.6f, 599.52f, 422.24f);
  2987. + AddWaypoint(18, 777.01f, 618.79f, 422.24f);
  2988. + AddWaypoint(19, 761.84f, 642.18f, 422.24f);
  2989. + AddWaypoint(20, 746.09f, 670.33f, 429.68f);
  2990. + AddWaypoint(21, 748.02f, 728.22f, 466.68f);
  2991. + AddWaypoint(22, 779.44f, 797.49f, 477.79f);
  2992. + AddWaypoint(23, 859.14f, 807.98f, 477.79f);
  2993. + Start(false, true);
  2994. + }
  2995. + else if (uiType == 2)
  2996. + {
  2997. + me->SetCanFly(true);
  2998. + me->SetDisableGravity(true);
  2999. + SetEscortPaused(false);
  3000. + }
  3001. + }
  3002. +
  3003. + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
  3004. + {
  3005. + if (waypointId == 10)
  3006. + {
  3007. + // Reached to arena
  3008. + SetEscortPaused(true);
  3009. + me->SetCanFly(false);
  3010. + me->SetDisableGravity(false);
  3011. + if (Creature* announcer = instance->GetCreature(DATA_ANNOUNCER))
  3012. + {
  3013. + me->SetFacingToObject(announcer);
  3014. + announcer->AI()->SetData(DATA_BLACK_KNIGHT_PREPARE, 0);
  3015. + }
  3016. + }
  3017. + }
  3018. +
  3019. + void UpdateAI(uint32 uiDiff) override
  3020. + {
  3021. + EscortAI::UpdateAI(uiDiff);
  3022. +
  3023. + UpdateVictim();
  3024. + }
  3025. +
  3026. + };
  3027. +
  3028. + CreatureAI* GetAI(Creature* creature) const override
  3029. + {
  3030. + return GetTrialOfChampionAI<npc_black_knight_skeletal_gryphonAI>(creature);
  3031. + }
  3032. +};
  3033. +
  3034. +class spell_black_knight_deaths_push : public SpellScriptLoader
  3035. +{
  3036. +public:
  3037. + spell_black_knight_deaths_push() : SpellScriptLoader("spell_black_knight_deaths_push") {}
  3038. +
  3039. + class spell_black_knight_deaths_push_AuraScript : public AuraScript
  3040. + {
  3041. + PrepareAuraScript(spell_black_knight_deaths_push_AuraScript);
  3042. +
  3043. + bool Validate(SpellInfo const* /*spellInfo*/) override
  3044. + {
  3045. + if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_RESPITE_DND) ||
  3046. + !sSpellMgr->GetSpellInfo(SPELL_FEIGN_DEATH))
  3047. + return false;
  3048. + return true;
  3049. + }
  3050. +
  3051. + void HandleScript(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  3052. + {
  3053. + // The spell applies a dummy aura with short duration
  3054. + // when the dummy aura is removed, announcer 'dies'
  3055. + GetTarget()->RemoveAura(SPELL_DEATH_RESPITE_DND);
  3056. + GetTarget()->CastSpell(GetTarget(), SPELL_FEIGN_DEATH, true);
  3057. + // CORRECCIÓN: Cambiar UNIT_FLAG_NOT_SELECTABLE por UNIT_FLAG_UNINTERACTIBLE
  3058. + GetTarget()->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
  3059. + }
  3060. +
  3061. + void Register() override
  3062. + {
  3063. + AfterEffectRemove += AuraEffectRemoveFn(spell_black_knight_deaths_push_AuraScript::HandleScript, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
  3064. + }
  3065. + };
  3066. +
  3067. + AuraScript* GetAuraScript() const override
  3068. + {
  3069. + return new spell_black_knight_deaths_push_AuraScript();
  3070. + }
  3071. +};
  3072. +
  3073. +class spell_black_knight_obliterate : public SpellScriptLoader
  3074. +{
  3075. +public:
  3076. + spell_black_knight_obliterate() : SpellScriptLoader("spell_black_knight_obliterate") {}
  3077. +
  3078. + class spell_black_knight_obliterate_SpellScript : public SpellScript
  3079. + {
  3080. + PrepareSpellScript(spell_black_knight_obliterate_SpellScript);
  3081. +
  3082. + bool Validate(SpellInfo const* /*spellInfo*/) override
  3083. + {
  3084. + if (!sSpellMgr->GetSpellInfo(SPELL_BLOOD_PLAGUE) ||
  3085. + !sSpellMgr->GetSpellInfo(SPELL_FROST_FEVER) ||
  3086. + !sSpellMgr->GetSpellInfo(SPELL_BLOOD_PLAGUE_H) ||
  3087. + !sSpellMgr->GetSpellInfo(SPELL_FROST_FEVER_H))
  3088. + return false;
  3089. + return true;
  3090. + }
  3091. +
  3092. + void CalculateDamage()
  3093. + {
  3094. + if (!GetHitUnit())
  3095. + return;
  3096. + uint32 bloodPlague = GetCaster()->GetMap()->IsHeroic() ? SPELL_BLOOD_PLAGUE_H : SPELL_BLOOD_PLAGUE;
  3097. + uint32 frostFever = GetCaster()->GetMap()->IsHeroic() ? SPELL_FROST_FEVER_H : SPELL_FROST_FEVER;
  3098. +
  3099. + int32 damage = GetHitDamage();
  3100. + int32 bonus = 0;
  3101. + if (GetHitUnit()->HasAura(frostFever))
  3102. + {
  3103. + bonus += int32(damage * 0.3f);
  3104. + GetHitUnit()->RemoveAurasDueToSpell(frostFever);
  3105. + }
  3106. + if (GetHitUnit()->HasAura(bloodPlague))
  3107. + {
  3108. + bonus += int32(damage * 0.3f);
  3109. + GetHitUnit()->RemoveAurasDueToSpell(bloodPlague);
  3110. + }
  3111. + SetHitDamage(damage + bonus);
  3112. + }
  3113. +
  3114. + void Register() override
  3115. + {
  3116. + OnHit += SpellHitFn(spell_black_knight_obliterate_SpellScript::CalculateDamage);
  3117. + }
  3118. + };
  3119. +
  3120. + SpellScript* GetSpellScript() const override
  3121. + {
  3122. + return new spell_black_knight_obliterate_SpellScript();
  3123. + }
  3124. +};
  3125. +
  3126. +class spell_black_knight_army_of_the_dead : public SpellScriptLoader
  3127. +{
  3128. +public:
  3129. + spell_black_knight_army_of_the_dead() : SpellScriptLoader("spell_black_knight_army_of_the_dead") {}
  3130. +
  3131. + class spell_black_knight_army_of_the_dead_AuraScript : public AuraScript
  3132. + {
  3133. + PrepareAuraScript(spell_black_knight_army_of_the_dead_AuraScript);
  3134. +
  3135. + void RemoveFlag(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  3136. + {
  3137. + // that is wrong, movement disabled by spell (channel)
  3138. + // On aura remove we must remove disable movement flag
  3139. + if (Unit* caster = GetCaster())
  3140. + caster->SetControlled(false, UNIT_STATE_ROOT);
  3141. + }
  3142. +
  3143. + void Register() override
  3144. + {
  3145. + AfterEffectRemove += AuraEffectRemoveFn(spell_black_knight_army_of_the_dead_AuraScript::RemoveFlag, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
  3146. + }
  3147. + };
  3148. +
  3149. + AuraScript* GetAuraScript() const override
  3150. + {
  3151. + return new spell_black_knight_army_of_the_dead_AuraScript();
  3152. + }
  3153. +};
  3154. +
  3155. +class spell_black_knight_ghoul_explode : public SpellScriptLoader
  3156. +{
  3157. +public:
  3158. + spell_black_knight_ghoul_explode() : SpellScriptLoader("spell_black_knight_ghoul_explode") {}
  3159. +
  3160. + class spell_black_knight_ghoul_explode_AuraScript : public AuraScript
  3161. + {
  3162. + PrepareAuraScript(spell_black_knight_ghoul_explode_AuraScript);
  3163. +
  3164. + bool Validate(SpellInfo const* /*spellInfo*/) override
  3165. + {
  3166. + if (!sSpellMgr->GetSpellInfo(SPELL_EXPLODE))
  3167. + return false;
  3168. + return true;
  3169. + }
  3170. +
  3171. + void CastExplode(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  3172. + {
  3173. + // On Ghoul Explode aura apply, start casting Explode
  3174. + GetTarget()->CastSpell(GetTarget(), SPELL_EXPLODE);
  3175. + }
  3176. +
  3177. + void Register() override
  3178. + {
  3179. + AfterEffectApply += AuraEffectApplyFn(spell_black_knight_ghoul_explode_AuraScript::CastExplode, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
  3180. + }
  3181. + };
  3182. +
  3183. + AuraScript* GetAuraScript() const override
  3184. + {
  3185. + return new spell_black_knight_ghoul_explode_AuraScript();
  3186. + }
  3187. +};
  3188. +
  3189. +// Achievement id 3804 - I've Had Worse
  3190. +class achievement_ive_had_worse : public AchievementCriteriaScript
  3191. +{
  3192. +public:
  3193. + achievement_ive_had_worse() : AchievementCriteriaScript("achievement_ive_had_worse") {}
  3194. +
  3195. + bool OnCheck(Player* /*player*/, Unit* target) override
  3196. + {
  3197. + if (target->GetEntry() != NPC_BLACK_KNIGHT)
  3198. + return false;
  3199. + if (!ENSURE_AI(boss_black_knight::boss_black_knightAI, target->GetAI())->achievementCredit)
  3200. + return false;
  3201. + return true;
  3202. + }
  3203. +};
  3204. +
  3205. +void AddSC_boss_black_knight()
  3206. +{
  3207. + new boss_black_knight();
  3208. + new npc_risen_ghoul();
  3209. + new npc_black_knight_skeletal_gryphon();
  3210. + new spell_black_knight_deaths_push();
  3211. + new spell_black_knight_obliterate();
  3212. + new spell_black_knight_army_of_the_dead();
  3213. + new spell_black_knight_ghoul_explode();
  3214. + new achievement_ive_had_worse();
  3215. +}
  3216. diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
  3217. dissimilarity index 75%
  3218. index 3a789907f5..f0179d0e97 100644
  3219. --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
  3220. +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
  3221. @@ -1,1039 +1,1800 @@
  3222. -/*
  3223. - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
  3224. - *
  3225. - * This program is free software; you can redistribute it and/or modify it
  3226. - * under the terms of the GNU General Public License as published by the
  3227. - * Free Software Foundation; either version 2 of the License, or (at your
  3228. - * option) any later version.
  3229. - *
  3230. - * This program is distributed in the hope that it will be useful, but WITHOUT
  3231. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  3232. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  3233. - * more details.
  3234. - *
  3235. - * You should have received a copy of the GNU General Public License along
  3236. - * with this program. If not, see <http://www.gnu.org/licenses/>.
  3237. - */
  3238. -
  3239. -/* ScriptData
  3240. -SDName: boss_grand_champions
  3241. -SD%Complete: 50 %
  3242. -SDComment: Is missing the ai to make the npcs look for a new mount and use it.
  3243. -SDCategory: Trial Of the Champion
  3244. -EndScriptData */
  3245. -
  3246. -#include "ScriptMgr.h"
  3247. -#include "InstanceScript.h"
  3248. -#include "Map.h"
  3249. -#include "ObjectAccessor.h"
  3250. -#include "Player.h"
  3251. -#include "ScriptedEscortAI.h"
  3252. -#include "trial_of_the_champion.h"
  3253. -#include "Vehicle.h"
  3254. -
  3255. -enum Spells
  3256. -{
  3257. - //Vehicle
  3258. - SPELL_CHARGE = 63010,
  3259. - SPELL_SHIELD_BREAKER = 68504,
  3260. - SPELL_SHIELD = 66482,
  3261. -
  3262. - // Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
  3263. - SPELL_MORTAL_STRIKE = 68783,
  3264. - SPELL_MORTAL_STRIKE_H = 68784,
  3265. - SPELL_BLADESTORM = 63784,
  3266. - SPELL_INTERCEPT = 67540,
  3267. - SPELL_ROLLING_THROW = 47115, //not implemented in the AI yet...
  3268. -
  3269. - // Ambrose Boltspark && Eressea Dawnsinger || Mage
  3270. - SPELL_FIREBALL = 66042,
  3271. - SPELL_FIREBALL_H = 68310,
  3272. - SPELL_BLAST_WAVE = 66044,
  3273. - SPELL_BLAST_WAVE_H = 68312,
  3274. - SPELL_HASTE = 66045,
  3275. - SPELL_POLYMORPH = 66043,
  3276. - SPELL_POLYMORPH_H = 68311,
  3277. -
  3278. - // Colosos && Runok Wildmane || Shaman
  3279. - SPELL_CHAIN_LIGHTNING = 67529,
  3280. - SPELL_CHAIN_LIGHTNING_H = 68319,
  3281. - SPELL_EARTH_SHIELD = 67530,
  3282. - SPELL_HEALING_WAVE = 67528,
  3283. - SPELL_HEALING_WAVE_H = 68318,
  3284. - SPELL_HEX_OF_MENDING = 67534,
  3285. -
  3286. - // Jaelyne Evensong && Zul'tore || Hunter
  3287. - SPELL_DISENGAGE = 68340, //not implemented in the AI yet...
  3288. - SPELL_LIGHTNING_ARROWS = 66083,
  3289. - SPELL_MULTI_SHOT = 66081,
  3290. - SPELL_SHOOT = 65868,
  3291. - SPELL_SHOOT_H = 67988,
  3292. -
  3293. - // Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
  3294. - SPELL_EVISCERATE = 67709,
  3295. - SPELL_EVISCERATE_H = 68317,
  3296. - SPELL_FAN_OF_KNIVES = 67706,
  3297. - SPELL_POISON_BOTTLE = 67701
  3298. -};
  3299. -
  3300. -enum Seats
  3301. -{
  3302. - SEAT_ID_0 = 0
  3303. -};
  3304. -
  3305. -/*
  3306. -struct Point
  3307. -{
  3308. - float x, y, z;
  3309. -};
  3310. -
  3311. -const Point MovementPoint[] =
  3312. -{
  3313. - {746.84f, 623.15f, 411.41f},
  3314. - {747.96f, 620.29f, 411.09f},
  3315. - {750.23f, 618.35f, 411.09f}
  3316. -};
  3317. -*/
  3318. -void AggroAllPlayers(Creature* temp)
  3319. -{
  3320. - Map::PlayerList const& PlList = temp->GetMap()->GetPlayers();
  3321. -
  3322. - if (PlList.isEmpty())
  3323. - return;
  3324. -
  3325. - for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
  3326. - {
  3327. - if (Player* player = i->GetSource())
  3328. - {
  3329. - if (player->IsGameMaster())
  3330. - continue;
  3331. -
  3332. - if (player->IsAlive())
  3333. - {
  3334. - temp->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  3335. - temp->SetImmuneToPC(true);
  3336. - temp->SetReactState(REACT_AGGRESSIVE);
  3337. - temp->EngageWithTarget(player);
  3338. - }
  3339. - }
  3340. - }
  3341. -}
  3342. -
  3343. -bool GrandChampionsOutVehicle(Creature* me)
  3344. -{
  3345. - InstanceScript* instance = me->GetInstanceScript();
  3346. -
  3347. - if (!instance)
  3348. - return false;
  3349. -
  3350. - Creature* pGrandChampion1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1));
  3351. - Creature* pGrandChampion2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_2));
  3352. - Creature* pGrandChampion3 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_3));
  3353. -
  3354. - if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
  3355. - {
  3356. - if (!pGrandChampion1->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) &&
  3357. - !pGrandChampion2->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) &&
  3358. - !pGrandChampion3->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
  3359. - return true;
  3360. - }
  3361. -
  3362. - return false;
  3363. -}
  3364. -
  3365. -/*
  3366. -* Generic AI for vehicles used by npcs in ToC, it needs more improvements. *
  3367. -* Script Complete: 25%. *
  3368. -*/
  3369. -
  3370. -class generic_vehicleAI_toc5 : public CreatureScript
  3371. -{
  3372. -public:
  3373. - generic_vehicleAI_toc5() : CreatureScript("generic_vehicleAI_toc5") { }
  3374. -
  3375. - struct generic_vehicleAI_toc5AI : public EscortAI
  3376. - {
  3377. - generic_vehicleAI_toc5AI(Creature* creature) : EscortAI(creature)
  3378. - {
  3379. - Initialize();
  3380. - SetDespawnAtEnd(false);
  3381. - uiWaypointPath = 0;
  3382. -
  3383. - instance = creature->GetInstanceScript();
  3384. - }
  3385. -
  3386. - void Initialize()
  3387. - {
  3388. - uiChargeTimer = 5000;
  3389. - uiShieldBreakerTimer = 8000;
  3390. - uiBuffTimer = urand(30000, 60000);
  3391. - }
  3392. -
  3393. - InstanceScript* instance;
  3394. -
  3395. - uint32 uiChargeTimer;
  3396. - uint32 uiShieldBreakerTimer;
  3397. - uint32 uiBuffTimer;
  3398. -
  3399. - uint32 uiWaypointPath;
  3400. -
  3401. - void Reset() override
  3402. - {
  3403. - Initialize();
  3404. - }
  3405. -
  3406. - void SetData(uint32 uiType, uint32 /*uiData*/) override
  3407. - {
  3408. - switch (uiType)
  3409. - {
  3410. - case 1:
  3411. - AddWaypoint(0, 747.36f, 634.07f, 411.572f);
  3412. - AddWaypoint(1, 780.43f, 607.15f, 411.82f);
  3413. - AddWaypoint(2, 785.99f, 599.41f, 411.92f);
  3414. - AddWaypoint(3, 778.44f, 601.64f, 411.79f);
  3415. - uiWaypointPath = 1;
  3416. - break;
  3417. - case 2:
  3418. - AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  3419. - AddWaypoint(1, 768.72f, 581.01f, 411.92f);
  3420. - AddWaypoint(2, 763.55f, 590.52f, 411.71f);
  3421. - uiWaypointPath = 2;
  3422. - break;
  3423. - case 3:
  3424. - AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  3425. - AddWaypoint(1, 784.02f, 645.33f, 412.39f);
  3426. - AddWaypoint(2, 775.67f, 641.91f, 411.91f);
  3427. - uiWaypointPath = 3;
  3428. - break;
  3429. - }
  3430. -
  3431. - if (uiType <= 3)
  3432. - Start(false, true);
  3433. - }
  3434. -
  3435. - void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
  3436. - {
  3437. - switch (waypointId)
  3438. - {
  3439. - case 2:
  3440. - if (uiWaypointPath == 3 || uiWaypointPath == 2)
  3441. - instance->SetData(DATA_MOVEMENT_DONE, instance->GetData(DATA_MOVEMENT_DONE)+1);
  3442. - break;
  3443. - case 3:
  3444. - instance->SetData(DATA_MOVEMENT_DONE, instance->GetData(DATA_MOVEMENT_DONE)+1);
  3445. - break;
  3446. - }
  3447. - }
  3448. -
  3449. - void JustEngagedWith(Unit* /*who*/) override
  3450. - {
  3451. - DoCastSpellShield();
  3452. - }
  3453. -
  3454. - void DoCastSpellShield()
  3455. - {
  3456. - for (uint8 i = 0; i < 3; ++i)
  3457. - DoCast(me, SPELL_SHIELD, true);
  3458. - }
  3459. -
  3460. - void UpdateAI(uint32 uiDiff) override
  3461. - {
  3462. - EscortAI::UpdateAI(uiDiff);
  3463. -
  3464. - if (!UpdateVictim())
  3465. - return;
  3466. -
  3467. - if (uiBuffTimer <= uiDiff)
  3468. - {
  3469. - if (!me->HasAura(SPELL_SHIELD))
  3470. - DoCastSpellShield();
  3471. -
  3472. - uiBuffTimer = urand(30000, 45000);
  3473. - }else uiBuffTimer -= uiDiff;
  3474. -
  3475. - if (uiChargeTimer <= uiDiff)
  3476. - {
  3477. - Map::PlayerList const& players = me->GetMap()->GetPlayers();
  3478. - if (!players.isEmpty())
  3479. - {
  3480. - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  3481. - {
  3482. - Player* player = itr->GetSource();
  3483. - if (player && !player->IsGameMaster() && me->IsInRange(player, 8.0f, 25.0f, false))
  3484. - {
  3485. - ResetThreatList();
  3486. - AddThreat(player, 1.0f);
  3487. - DoCast(player, SPELL_CHARGE);
  3488. - break;
  3489. - }
  3490. - }
  3491. - }
  3492. - uiChargeTimer = 5000;
  3493. - }else uiChargeTimer -= uiDiff;
  3494. -
  3495. - //dosen't work at all
  3496. - if (uiShieldBreakerTimer <= uiDiff)
  3497. - {
  3498. - Vehicle* pVehicle = me->GetVehicleKit();
  3499. - if (!pVehicle)
  3500. - return;
  3501. -
  3502. - if (Unit* pPassenger = pVehicle->GetPassenger(SEAT_ID_0))
  3503. - {
  3504. - Map::PlayerList const& players = me->GetMap()->GetPlayers();
  3505. - if (!players.isEmpty())
  3506. - {
  3507. - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  3508. - {
  3509. - Player* player = itr->GetSource();
  3510. - if (player && !player->IsGameMaster() && me->IsInRange(player, 10.0f, 30.0f, false))
  3511. - {
  3512. - pPassenger->CastSpell(player, SPELL_SHIELD_BREAKER, true);
  3513. - break;
  3514. - }
  3515. - }
  3516. - }
  3517. - }
  3518. - uiShieldBreakerTimer = 7000;
  3519. - }else uiShieldBreakerTimer -= uiDiff;
  3520. -
  3521. - DoMeleeAttackIfReady();
  3522. - }
  3523. - };
  3524. -
  3525. - CreatureAI* GetAI(Creature* creature) const override
  3526. - {
  3527. - return GetTrialOfTheChampionAI<generic_vehicleAI_toc5AI>(creature);
  3528. - }
  3529. -};
  3530. -
  3531. -class boss_warrior_toc5 : public CreatureScript
  3532. -{
  3533. -public:
  3534. - boss_warrior_toc5() : CreatureScript("boss_warrior_toc5") { }
  3535. -
  3536. - // Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
  3537. - struct boss_warrior_toc5AI : public ScriptedAI
  3538. - {
  3539. - boss_warrior_toc5AI(Creature* creature) : ScriptedAI(creature)
  3540. - {
  3541. - Initialize();
  3542. - instance = creature->GetInstanceScript();
  3543. -
  3544. - bDone = false;
  3545. - bHome = false;
  3546. -
  3547. - uiPhase = 0;
  3548. - uiPhaseTimer = 0;
  3549. -
  3550. - me->SetReactState(REACT_PASSIVE);
  3551. - // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
  3552. - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  3553. - me->SetImmuneToPC(true);
  3554. - }
  3555. -
  3556. - void Initialize()
  3557. - {
  3558. - uiBladeStormTimer = urand(15000, 20000);
  3559. - uiInterceptTimer = 7000;
  3560. - uiMortalStrikeTimer = urand(8000, 12000);
  3561. - }
  3562. -
  3563. - InstanceScript* instance;
  3564. -
  3565. - uint8 uiPhase;
  3566. - uint32 uiPhaseTimer;
  3567. -
  3568. - uint32 uiBladeStormTimer;
  3569. - uint32 uiInterceptTimer;
  3570. - uint32 uiMortalStrikeTimer;
  3571. -
  3572. - bool bDone;
  3573. - bool bHome;
  3574. -
  3575. - void Reset() override
  3576. - {
  3577. - Initialize();
  3578. - }
  3579. -
  3580. - void JustReachedHome() override
  3581. - {
  3582. - ScriptedAI::JustReachedHome();
  3583. -
  3584. - if (!bHome)
  3585. - return;
  3586. -
  3587. - uiPhaseTimer = 15000;
  3588. - uiPhase = 1;
  3589. -
  3590. - bHome = false;
  3591. - }
  3592. -
  3593. - void UpdateAI(uint32 uiDiff) override
  3594. - {
  3595. - if (!bDone && GrandChampionsOutVehicle(me))
  3596. - {
  3597. - bDone = true;
  3598. -
  3599. - if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  3600. - me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
  3601. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  3602. - me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
  3603. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  3604. - me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
  3605. -
  3606. - EnterEvadeMode();
  3607. - bHome = true;
  3608. - }
  3609. -
  3610. - if (uiPhaseTimer <= uiDiff)
  3611. - {
  3612. - if (uiPhase == 1)
  3613. - {
  3614. - AggroAllPlayers(me);
  3615. - uiPhase = 0;
  3616. - }
  3617. - }else uiPhaseTimer -= uiDiff;
  3618. -
  3619. - if (!UpdateVictim() || !me->m_movementInfo.transport.guid.IsEmpty())
  3620. - return;
  3621. -
  3622. - if (uiInterceptTimer <= uiDiff)
  3623. - {
  3624. - Map::PlayerList const& players = me->GetMap()->GetPlayers();
  3625. - if (!players.isEmpty())
  3626. - {
  3627. - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  3628. - {
  3629. - Player* player = itr->GetSource();
  3630. - if (player && !player->IsGameMaster() && me->IsInRange(player, 8.0f, 25.0f, false))
  3631. - {
  3632. - ResetThreatList();
  3633. - AddThreat(player, 5.0f);
  3634. - DoCast(player, SPELL_INTERCEPT);
  3635. - break;
  3636. - }
  3637. - }
  3638. - }
  3639. - uiInterceptTimer = 7000;
  3640. - } else uiInterceptTimer -= uiDiff;
  3641. -
  3642. - if (uiBladeStormTimer <= uiDiff)
  3643. - {
  3644. - DoCastVictim(SPELL_BLADESTORM);
  3645. - uiBladeStormTimer = urand(15000, 20000);
  3646. - } else uiBladeStormTimer -= uiDiff;
  3647. -
  3648. - if (uiMortalStrikeTimer <= uiDiff)
  3649. - {
  3650. - DoCastVictim(SPELL_MORTAL_STRIKE);
  3651. - uiMortalStrikeTimer = urand(8000, 12000);
  3652. - } else uiMortalStrikeTimer -= uiDiff;
  3653. -
  3654. - DoMeleeAttackIfReady();
  3655. - }
  3656. -
  3657. - void JustDied(Unit* /*killer*/) override
  3658. - {
  3659. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, DONE);
  3660. - }
  3661. - };
  3662. -
  3663. - CreatureAI* GetAI(Creature* creature) const override
  3664. - {
  3665. - return GetTrialOfTheChampionAI<boss_warrior_toc5AI>(creature);
  3666. - }
  3667. -};
  3668. -
  3669. -class boss_mage_toc5 : public CreatureScript
  3670. -{
  3671. -public:
  3672. - boss_mage_toc5() : CreatureScript("boss_mage_toc5") { }
  3673. -
  3674. - // Ambrose Boltspark && Eressea Dawnsinger || Mage
  3675. - struct boss_mage_toc5AI : public ScriptedAI
  3676. - {
  3677. - boss_mage_toc5AI(Creature* creature) : ScriptedAI(creature)
  3678. - {
  3679. - Initialize();
  3680. - instance = creature->GetInstanceScript();
  3681. -
  3682. - bDone = false;
  3683. - bHome = false;
  3684. -
  3685. - uiPhase = 0;
  3686. - uiPhaseTimer = 0;
  3687. -
  3688. - me->SetReactState(REACT_PASSIVE);
  3689. - // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
  3690. - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  3691. - me->SetImmuneToPC(true);
  3692. - }
  3693. -
  3694. - void Initialize()
  3695. - {
  3696. - uiFireBallTimer = 5000;
  3697. - uiPolymorphTimer = 8000;
  3698. - uiBlastWaveTimer = 12000;
  3699. - uiHasteTimer = 22000;
  3700. - }
  3701. -
  3702. - InstanceScript* instance;
  3703. -
  3704. - uint8 uiPhase;
  3705. - uint32 uiPhaseTimer;
  3706. -
  3707. - uint32 uiFireBallTimer;
  3708. - uint32 uiBlastWaveTimer;
  3709. - uint32 uiHasteTimer;
  3710. - uint32 uiPolymorphTimer;
  3711. -
  3712. - bool bDone;
  3713. - bool bHome;
  3714. -
  3715. - void Reset() override
  3716. - {
  3717. - Initialize();
  3718. - }
  3719. -
  3720. - void JustReachedHome() override
  3721. - {
  3722. - ScriptedAI::JustReachedHome();
  3723. -
  3724. - if (!bHome)
  3725. - return;
  3726. -
  3727. - uiPhaseTimer = 15000;
  3728. - uiPhase = 1;
  3729. -
  3730. - bHome = false;
  3731. - }
  3732. -
  3733. - void UpdateAI(uint32 uiDiff) override
  3734. - {
  3735. - if (!bDone && GrandChampionsOutVehicle(me))
  3736. - {
  3737. - bDone = true;
  3738. -
  3739. - if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  3740. - me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
  3741. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  3742. - me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
  3743. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  3744. - me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
  3745. -
  3746. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
  3747. -
  3748. - EnterEvadeMode();
  3749. - bHome = true;
  3750. - }
  3751. -
  3752. - if (uiPhaseTimer <= uiDiff)
  3753. - {
  3754. - if (uiPhase == 1)
  3755. - {
  3756. - AggroAllPlayers(me);
  3757. - uiPhase = 0;
  3758. - }
  3759. - }else uiPhaseTimer -= uiDiff;
  3760. -
  3761. - if (uiFireBallTimer <= uiDiff)
  3762. - {
  3763. - if (me->GetVictim())
  3764. - DoCastVictim(SPELL_FIREBALL);
  3765. - uiFireBallTimer = 5000;
  3766. - } else uiFireBallTimer -= uiDiff;
  3767. -
  3768. - if (!UpdateVictim() || !me->m_movementInfo.transport.guid.IsEmpty())
  3769. - return;
  3770. -
  3771. - if (uiFireBallTimer <= uiDiff)
  3772. - {
  3773. - DoCastVictim(SPELL_FIREBALL);
  3774. - uiFireBallTimer = 5000;
  3775. - } else uiFireBallTimer -= uiDiff;
  3776. -
  3777. - if (uiPolymorphTimer <= uiDiff)
  3778. - {
  3779. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
  3780. - DoCast(target, SPELL_POLYMORPH);
  3781. - uiPolymorphTimer = 8000;
  3782. - } else uiPolymorphTimer -= uiDiff;
  3783. -
  3784. - if (uiBlastWaveTimer <= uiDiff)
  3785. - {
  3786. - DoCastAOE(SPELL_BLAST_WAVE, false);
  3787. - uiBlastWaveTimer = 13000;
  3788. - } else uiBlastWaveTimer -= uiDiff;
  3789. -
  3790. - if (uiHasteTimer <= uiDiff)
  3791. - {
  3792. - me->InterruptNonMeleeSpells(true);
  3793. -
  3794. - DoCast(me, SPELL_HASTE);
  3795. - uiHasteTimer = 22000;
  3796. - } else uiHasteTimer -= uiDiff;
  3797. -
  3798. - DoMeleeAttackIfReady();
  3799. - }
  3800. -
  3801. - void JustDied(Unit* /*killer*/) override
  3802. - {
  3803. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, DONE);
  3804. - }
  3805. - };
  3806. -
  3807. - CreatureAI* GetAI(Creature* creature) const override
  3808. - {
  3809. - return GetTrialOfTheChampionAI<boss_mage_toc5AI>(creature);
  3810. - }
  3811. -};
  3812. -
  3813. -class boss_shaman_toc5 : public CreatureScript
  3814. -{
  3815. -public:
  3816. - boss_shaman_toc5() : CreatureScript("boss_shaman_toc5") { }
  3817. -
  3818. - // Colosos && Runok Wildmane || Shaman
  3819. - struct boss_shaman_toc5AI : public ScriptedAI
  3820. - {
  3821. - boss_shaman_toc5AI(Creature* creature) : ScriptedAI(creature)
  3822. - {
  3823. - Initialize();
  3824. - instance = creature->GetInstanceScript();
  3825. -
  3826. - bDone = false;
  3827. - bHome = false;
  3828. -
  3829. - uiPhase = 0;
  3830. - uiPhaseTimer = 0;
  3831. -
  3832. - me->SetReactState(REACT_PASSIVE);
  3833. - // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
  3834. - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  3835. - me->SetImmuneToPC(true);
  3836. - }
  3837. -
  3838. - void Initialize()
  3839. - {
  3840. - uiChainLightningTimer = 16000;
  3841. - uiHealingWaveTimer = 12000;
  3842. - uiEartShieldTimer = urand(30000, 35000);
  3843. - uiHexMendingTimer = urand(20000, 25000);
  3844. - }
  3845. -
  3846. - InstanceScript* instance;
  3847. -
  3848. - uint8 uiPhase;
  3849. - uint32 uiPhaseTimer;
  3850. -
  3851. - uint32 uiChainLightningTimer;
  3852. - uint32 uiEartShieldTimer;
  3853. - uint32 uiHealingWaveTimer;
  3854. - uint32 uiHexMendingTimer;
  3855. -
  3856. - bool bDone;
  3857. - bool bHome;
  3858. -
  3859. - void Reset() override
  3860. - {
  3861. - Initialize();
  3862. - }
  3863. -
  3864. - void JustEngagedWith(Unit* who) override
  3865. - {
  3866. - DoCast(me, SPELL_EARTH_SHIELD);
  3867. - DoCast(who, SPELL_HEX_OF_MENDING);
  3868. - };
  3869. -
  3870. - void JustReachedHome() override
  3871. - {
  3872. - ScriptedAI::JustReachedHome();
  3873. -
  3874. - if (!bHome)
  3875. - return;
  3876. -
  3877. - uiPhaseTimer = 15000;
  3878. - uiPhase = 1;
  3879. -
  3880. - bHome = false;
  3881. - }
  3882. -
  3883. - void UpdateAI(uint32 uiDiff) override
  3884. - {
  3885. - if (!bDone && GrandChampionsOutVehicle(me))
  3886. - {
  3887. - bDone = true;
  3888. -
  3889. - if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  3890. - me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
  3891. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  3892. - me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
  3893. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  3894. - me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
  3895. -
  3896. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
  3897. -
  3898. - EnterEvadeMode();
  3899. - bHome = true;
  3900. - }
  3901. -
  3902. - if (uiPhaseTimer <= uiDiff)
  3903. - {
  3904. - if (uiPhase == 1)
  3905. - {
  3906. - AggroAllPlayers(me);
  3907. - uiPhase = 0;
  3908. - }
  3909. - }else uiPhaseTimer -= uiDiff;
  3910. -
  3911. - if (!UpdateVictim() || !me->m_movementInfo.transport.guid.IsEmpty())
  3912. - return;
  3913. -
  3914. - if (uiChainLightningTimer <= uiDiff)
  3915. - {
  3916. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
  3917. - DoCast(target, SPELL_CHAIN_LIGHTNING);
  3918. -
  3919. - uiChainLightningTimer = 16000;
  3920. - } else uiChainLightningTimer -= uiDiff;
  3921. -
  3922. - if (uiHealingWaveTimer <= uiDiff)
  3923. - {
  3924. - bool bChance = roll_chance_i(50);
  3925. -
  3926. - if (!bChance)
  3927. - {
  3928. - if (Unit* pFriend = DoSelectLowestHpFriendly(40))
  3929. - DoCast(pFriend, SPELL_HEALING_WAVE);
  3930. - } else
  3931. - DoCast(me, SPELL_HEALING_WAVE);
  3932. -
  3933. - uiHealingWaveTimer = 12000;
  3934. - } else uiHealingWaveTimer -= uiDiff;
  3935. -
  3936. - if (uiEartShieldTimer <= uiDiff)
  3937. - {
  3938. - DoCast(me, SPELL_EARTH_SHIELD);
  3939. -
  3940. - uiEartShieldTimer = urand(30000, 35000);
  3941. - } else uiEartShieldTimer -= uiDiff;
  3942. -
  3943. - if (uiHexMendingTimer <= uiDiff)
  3944. - {
  3945. - DoCastVictim(SPELL_HEX_OF_MENDING, true);
  3946. -
  3947. - uiHexMendingTimer = urand(20000, 25000);
  3948. - } else uiHexMendingTimer -= uiDiff;
  3949. -
  3950. - DoMeleeAttackIfReady();
  3951. - }
  3952. -
  3953. - void JustDied(Unit* /*killer*/) override
  3954. - {
  3955. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, DONE);
  3956. - }
  3957. - };
  3958. -
  3959. - CreatureAI* GetAI(Creature* creature) const override
  3960. - {
  3961. - return GetTrialOfTheChampionAI<boss_shaman_toc5AI>(creature);
  3962. - }
  3963. -};
  3964. -
  3965. -class boss_hunter_toc5 : public CreatureScript
  3966. -{
  3967. -public:
  3968. - boss_hunter_toc5() : CreatureScript("boss_hunter_toc5") { }
  3969. -
  3970. - // Jaelyne Evensong && Zul'tore || Hunter
  3971. - struct boss_hunter_toc5AI : public ScriptedAI
  3972. - {
  3973. - boss_hunter_toc5AI(Creature* creature) : ScriptedAI(creature)
  3974. - {
  3975. - Initialize();
  3976. - instance = creature->GetInstanceScript();
  3977. -
  3978. - bDone = false;
  3979. - bHome = false;
  3980. -
  3981. - uiPhase = 0;
  3982. - uiPhaseTimer = 0;
  3983. -
  3984. - me->SetReactState(REACT_PASSIVE);
  3985. - // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
  3986. - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  3987. - me->SetImmuneToPC(true);
  3988. - }
  3989. -
  3990. - void Initialize()
  3991. - {
  3992. - uiShootTimer = 12000;
  3993. - uiMultiShotTimer = 0;
  3994. - uiLightningArrowsTimer = 7000;
  3995. -
  3996. - uiTargetGUID.Clear();
  3997. -
  3998. - bShoot = false;
  3999. - }
  4000. -
  4001. - InstanceScript* instance;
  4002. -
  4003. - uint8 uiPhase;
  4004. - uint32 uiPhaseTimer;
  4005. -
  4006. - uint32 uiShootTimer;
  4007. - uint32 uiMultiShotTimer;
  4008. - uint32 uiLightningArrowsTimer;
  4009. -
  4010. - ObjectGuid uiTargetGUID;
  4011. -
  4012. - bool bShoot;
  4013. - bool bDone;
  4014. - bool bHome;
  4015. -
  4016. - void Reset() override
  4017. - {
  4018. - Initialize();
  4019. - }
  4020. -
  4021. - void JustReachedHome() override
  4022. - {
  4023. - ScriptedAI::JustReachedHome();
  4024. -
  4025. - if (!bHome)
  4026. - return;
  4027. -
  4028. - uiPhaseTimer = 15000;
  4029. - uiPhase = 1;
  4030. -
  4031. - bHome = false;
  4032. - }
  4033. -
  4034. - void UpdateAI(uint32 uiDiff) override
  4035. - {
  4036. - if (!bDone && GrandChampionsOutVehicle(me))
  4037. - {
  4038. - bDone = true;
  4039. -
  4040. - if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  4041. - me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
  4042. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  4043. - me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
  4044. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  4045. - me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
  4046. -
  4047. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
  4048. -
  4049. - EnterEvadeMode();
  4050. - bHome = true;
  4051. - }
  4052. -
  4053. - if (uiPhaseTimer <= uiDiff)
  4054. - {
  4055. - if (uiPhase == 1)
  4056. - {
  4057. - AggroAllPlayers(me);
  4058. - uiPhase = 0;
  4059. - }
  4060. - }else uiPhaseTimer -= uiDiff;
  4061. -
  4062. - if (!UpdateVictim() || !me->m_movementInfo.transport.guid.IsEmpty())
  4063. - return;
  4064. -
  4065. - if (uiLightningArrowsTimer <= uiDiff)
  4066. - {
  4067. - DoCastAOE(SPELL_LIGHTNING_ARROWS, false);
  4068. - uiLightningArrowsTimer = 7000;
  4069. - } else uiLightningArrowsTimer -= uiDiff;
  4070. -
  4071. - if (uiShootTimer <= uiDiff)
  4072. - {
  4073. - if (Unit* target = SelectTarget(SelectTargetMethod::MaxDistance, 0, 30.0f))
  4074. - {
  4075. - uiTargetGUID = target->GetGUID();
  4076. - DoCast(target, SPELL_SHOOT);
  4077. - }
  4078. - uiShootTimer = 12000;
  4079. - uiMultiShotTimer = 3000;
  4080. - bShoot = true;
  4081. - } else uiShootTimer -= uiDiff;
  4082. -
  4083. - if (bShoot && uiMultiShotTimer <= uiDiff)
  4084. - {
  4085. - me->InterruptNonMeleeSpells(true);
  4086. - Unit* target = ObjectAccessor::GetUnit(*me, uiTargetGUID);
  4087. -
  4088. - if (target && me->IsInRange(target, 5.0f, 30.0f, false))
  4089. - {
  4090. - DoCast(target, SPELL_MULTI_SHOT);
  4091. - }
  4092. - else
  4093. - {
  4094. - Map::PlayerList const& players = me->GetMap()->GetPlayers();
  4095. - if (!players.isEmpty())
  4096. - {
  4097. - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  4098. - {
  4099. - Player* player = itr->GetSource();
  4100. - if (player && !player->IsGameMaster() && me->IsInRange(player, 5.0f, 30.0f, false))
  4101. - {
  4102. - DoCast(player, SPELL_MULTI_SHOT);
  4103. - break;
  4104. - }
  4105. - }
  4106. - }
  4107. - }
  4108. - bShoot = false;
  4109. - } else uiMultiShotTimer -= uiDiff;
  4110. -
  4111. - DoMeleeAttackIfReady();
  4112. - }
  4113. -
  4114. - void JustDied(Unit* /*killer*/) override
  4115. - {
  4116. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, DONE);
  4117. - }
  4118. - };
  4119. -
  4120. - CreatureAI* GetAI(Creature* creature) const override
  4121. - {
  4122. - return GetTrialOfTheChampionAI<boss_hunter_toc5AI>(creature);
  4123. - }
  4124. -};
  4125. -
  4126. -class boss_rouge_toc5 : public CreatureScript
  4127. -{
  4128. -public:
  4129. - boss_rouge_toc5() : CreatureScript("boss_rouge_toc5") { }
  4130. -
  4131. - // Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
  4132. - struct boss_rouge_toc5AI : public ScriptedAI
  4133. - {
  4134. - boss_rouge_toc5AI(Creature* creature) : ScriptedAI(creature)
  4135. - {
  4136. - Initialize();
  4137. - instance = creature->GetInstanceScript();
  4138. -
  4139. - bDone = false;
  4140. - bHome = false;
  4141. -
  4142. - uiPhase = 0;
  4143. - uiPhaseTimer = 0;
  4144. -
  4145. - me->SetReactState(REACT_PASSIVE);
  4146. - // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
  4147. - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  4148. - me->SetImmuneToPC(true);
  4149. - }
  4150. -
  4151. - void Initialize()
  4152. - {
  4153. - uiEviscerateTimer = 8000;
  4154. - uiFanKivesTimer = 14000;
  4155. - uiPosionBottleTimer = 19000;
  4156. - }
  4157. -
  4158. - InstanceScript* instance;
  4159. -
  4160. - uint8 uiPhase;
  4161. - uint32 uiPhaseTimer;
  4162. - uint32 uiEviscerateTimer;
  4163. - uint32 uiFanKivesTimer;
  4164. - uint32 uiPosionBottleTimer;
  4165. -
  4166. - bool bDone;
  4167. - bool bHome;
  4168. -
  4169. - void Reset() override
  4170. - {
  4171. - Initialize();
  4172. - }
  4173. -
  4174. - void JustReachedHome() override
  4175. - {
  4176. - ScriptedAI::JustReachedHome();
  4177. -
  4178. - if (!bHome)
  4179. - return;
  4180. -
  4181. - uiPhaseTimer = 15000;
  4182. - uiPhase = 1;
  4183. -
  4184. - bHome = false;
  4185. - }
  4186. -
  4187. - void UpdateAI(uint32 uiDiff) override
  4188. - {
  4189. - if (!bDone && GrandChampionsOutVehicle(me))
  4190. - {
  4191. - bDone = true;
  4192. -
  4193. - if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  4194. - me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
  4195. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  4196. - me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
  4197. - else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  4198. - me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
  4199. -
  4200. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
  4201. -
  4202. - EnterEvadeMode();
  4203. - bHome = true;
  4204. - }
  4205. -
  4206. - if (uiPhaseTimer <= uiDiff)
  4207. - {
  4208. - if (uiPhase == 1)
  4209. - {
  4210. - AggroAllPlayers(me);
  4211. - uiPhase = 0;
  4212. - }
  4213. - } else uiPhaseTimer -= uiDiff;
  4214. -
  4215. - if (!UpdateVictim() || !me->m_movementInfo.transport.guid.IsEmpty())
  4216. - return;
  4217. -
  4218. - if (uiEviscerateTimer <= uiDiff)
  4219. - {
  4220. - DoCastVictim(SPELL_EVISCERATE);
  4221. - uiEviscerateTimer = 8000;
  4222. - } else uiEviscerateTimer -= uiDiff;
  4223. -
  4224. - if (uiFanKivesTimer <= uiDiff)
  4225. - {
  4226. - DoCastAOE(SPELL_FAN_OF_KNIVES, false);
  4227. - uiFanKivesTimer = 14000;
  4228. - } else uiFanKivesTimer -= uiDiff;
  4229. -
  4230. - if (uiPosionBottleTimer <= uiDiff)
  4231. - {
  4232. - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
  4233. - DoCast(target, SPELL_POISON_BOTTLE);
  4234. - uiPosionBottleTimer = 19000;
  4235. - } else uiPosionBottleTimer -= uiDiff;
  4236. -
  4237. - DoMeleeAttackIfReady();
  4238. - }
  4239. -
  4240. - void JustDied(Unit* /*killer*/) override
  4241. - {
  4242. - instance->SetBossState(BOSS_GRAND_CHAMPIONS, DONE);
  4243. - }
  4244. - };
  4245. -
  4246. - CreatureAI* GetAI(Creature* creature) const override
  4247. - {
  4248. - return GetTrialOfTheChampionAI<boss_rouge_toc5AI>(creature);
  4249. - }
  4250. -};
  4251. -
  4252. -void AddSC_boss_grand_champions()
  4253. -{
  4254. - new generic_vehicleAI_toc5();
  4255. - new boss_warrior_toc5();
  4256. - new boss_mage_toc5();
  4257. - new boss_shaman_toc5();
  4258. - new boss_hunter_toc5();
  4259. - new boss_rouge_toc5();
  4260. -}
  4261. +/*
  4262. + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  4263. + * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  4264. + *
  4265. + * This program is free software; you can redistribute it and/or modify it
  4266. + * under the terms of the GNU General Public License as published by the
  4267. + * Free Software Foundation; either version 2 of the License, or (at your
  4268. + * option) any later version.
  4269. + *
  4270. + * This program is distributed in the hope that it will be useful, but WITHOUT
  4271. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  4272. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  4273. + * more details.
  4274. + *
  4275. + * You should have received a copy of the GNU General Public License along
  4276. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  4277. + */
  4278. +
  4279. + /* ScriptData
  4280. + SDName: boss_grand_champions
  4281. + SD%Complete: 99%
  4282. + SDComment: Cosmetic things missing
  4283. + SDCategory: Trial Of the Champion
  4284. + EndScriptData */
  4285. +
  4286. +#include "GridNotifiers.h"
  4287. +#include "Player.h"
  4288. +#include "ScriptedCreature.h"
  4289. +#include "ScriptedEscortAI.h"
  4290. +#include "ScriptMgr.h"
  4291. +#include "SpellAuraEffects.h"
  4292. +#include "SpellScript.h"
  4293. +#include "SpellMgr.h"
  4294. +#include "Vehicle.h"
  4295. +#include "trial_of_the_champion.h"
  4296. +
  4297. +enum Events
  4298. +{
  4299. + // Grand Champion
  4300. + EVENT_WALK_TO_MOUNT = 1,
  4301. + EVENT_START_ATTACK_JOUST,
  4302. + EVENT_TRAMPLE,
  4303. + EVENT_EVADE_MODE,
  4304. + EVENT_START_ATTACK_REAL,
  4305. + EVENT_DESPAWN,
  4306. + // General vehicle AI
  4307. + EVENT_BUFF_SHIELD,
  4308. + EVENT_BUFF_FLAG,
  4309. + EVENT_MOUNT_CHARGE,
  4310. + EVENT_SHIELD_BREAKER,
  4311. + // Warrior - Grand Champion
  4312. + EVENT_BLADESTORM,
  4313. + EVENT_INTERCEPT,
  4314. + EVENT_MORTAL_STRIKE,
  4315. + EVENT_ROLLING_THROW,
  4316. + // Mage - Grand Champion
  4317. + EVENT_FIREBALL,
  4318. + EVENT_BLASTWAVE,
  4319. + EVENT_HASTE,
  4320. + EVENT_POLYMORPH,
  4321. + // Shaman - Grand Champion
  4322. + EVENT_DEF_CHECK,
  4323. + EVENT_CHAIN_LIGHTNING,
  4324. + EVENT_HEALING_WAVE,
  4325. + EVENT_EARTH_SHIELD,
  4326. + EVENT_HEX_MENDING,
  4327. + // Hunter - Grand Champion
  4328. + EVENT_MULTI_SHOT,
  4329. + EVENT_LIGHTNING_ARROWS,
  4330. + EVENT_DISENGAGE,
  4331. + // Rogue - Grand Champion
  4332. + EVENT_DEADLY_POISON,
  4333. + EVENT_EVISCERATE,
  4334. + EVENT_FAN_OF_KNIVES,
  4335. + EVENT_POISON_BOTTLE
  4336. +};
  4337. +
  4338. +enum Spells
  4339. +{
  4340. + // Vehicle
  4341. + SPELL_CHARGE_GRAND_CHAMP = 68321,
  4342. + SPELL_CHARGE_LESSER_CHAMP = 63010,
  4343. + SPELL_SHIELD_BREAKER = 68504,
  4344. + SPELL_SHIELD_GRAND_CHAMP = 62719,
  4345. + SPELL_SHIELD_LESSER_CHAMP = 64100,
  4346. + SPELL_TRAMPLE_DUMMY_AURA = 67870, // triggers trample aura every 1 second, used by all vehicles
  4347. + SPELL_TRAMPLE_AURA = 67868, // actual trample stun
  4348. +
  4349. + // General
  4350. + SPELL_ACHIEVEMENT_CREDIT = 68572, // dummy spell for achievement credit (IDs 4297, 4298, 3778, 4296)
  4351. + SPELL_KNEEL = 68442,
  4352. +
  4353. + // Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
  4354. + SPELL_MORTAL_STRIKE = 68783,
  4355. + SPELL_BLADESTORM = 67541,
  4356. + SPELL_INTERCEPT = 67540,
  4357. + SPELL_ROLLING_THROW = 67546,
  4358. +
  4359. + // Ambrose Boltspark && Eressea Dawnsinger || Mage
  4360. + SPELL_FIREBALL = 66042,
  4361. + SPELL_BLAST_WAVE = 66044,
  4362. + SPELL_HASTE = 66045,
  4363. + SPELL_POLYMORPH = 66043,
  4364. +
  4365. + // Colosos && Runok Wildmane || Shaman
  4366. + SPELL_CHAIN_LIGHTNING = 67529,
  4367. + SPELL_EARTH_SHIELD = 67530,
  4368. + SPELL_HEALING_WAVE = 67528,
  4369. + SPELL_HEX_OF_MENDING = 67534,
  4370. +
  4371. + // Jaelyne Evensong && Zul'tore || Hunter
  4372. + SPELL_DISENGAGE = 68339, // 68340 is correct disengage but spell needs to be scripted
  4373. + SPELL_LIGHTNING_ARROWS = 66083,
  4374. + SPELL_LIGHTNING_ARROWS_AURA = 66085,
  4375. + SPELL_MULTI_SHOT = 66081,
  4376. + SPELL_SHOOT = 66079,
  4377. +
  4378. + // Lana Stouthammer && Deathstalker Visceri || Rouge
  4379. + SPELL_EVISCERATE = 67709,
  4380. + SPELL_FAN_OF_KNIVES = 67706,
  4381. + SPELL_POISON_BOTTLE = 67701,
  4382. + SPELL_DEADLY_POISON = 67711
  4383. +};
  4384. +
  4385. +enum Texts
  4386. +{
  4387. + EMOTE_TRAMPLE = 0
  4388. +};
  4389. +
  4390. +enum PointMovement
  4391. +{
  4392. + POINT_REMOUNT = 0,
  4393. + POINT_DESPAWN
  4394. +};
  4395. +
  4396. +void EnterAggressiveMode(Creature* temp)
  4397. +{
  4398. + temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  4399. + temp->SetReactState(REACT_AGGRESSIVE);
  4400. +}
  4401. +
  4402. +void DoCastPennant(Creature* me)
  4403. +{
  4404. + switch (me->GetEntry())
  4405. + {
  4406. + case NPC_MOKRA:
  4407. + me->CastSpell(me, SPELL_PENNANT_ORGRIMMAR);
  4408. + break;
  4409. + case NPC_ERESSEA:
  4410. + me->CastSpell(me, SPELL_PENNANT_SILVERMOON);
  4411. + break;
  4412. + case NPC_RUNOK:
  4413. + me->CastSpell(me, SPELL_PENNANT_THUNDER_BLUFF);
  4414. + break;
  4415. + case NPC_ZULTORE:
  4416. + me->CastSpell(me, SPELL_PENNANT_SEN_JIN);
  4417. + break;
  4418. + case NPC_VISCERI:
  4419. + me->CastSpell(me, SPELL_PENNANT_UNDERCITY);
  4420. + break;
  4421. + case NPC_JACOB:
  4422. + me->CastSpell(me, SPELL_PENNANT_STORMWIND);
  4423. + break;
  4424. + case NPC_AMBROSE:
  4425. + me->CastSpell(me, SPELL_PENNANT_GNOMEREGAN);
  4426. + break;
  4427. + case NPC_COLOSOS:
  4428. + me->CastSpell(me, SPELL_PENNANT_EXODAR);
  4429. + break;
  4430. + case NPC_JAELYNE:
  4431. + me->CastSpell(me, SPELL_PENNANT_DARNASSUS);
  4432. + break;
  4433. + case NPC_LANA:
  4434. + me->CastSpell(me, SPELL_PENNANT_IRONFORGE);
  4435. + break;
  4436. + default:
  4437. + break;
  4438. + }
  4439. + if (me->GetVehicleBase())
  4440. + me->CastSpell(me->GetVehicleBase(), SPELL_TRAMPLE_DUMMY_AURA, true);
  4441. +}
  4442. +
  4443. +Creature* FindMyMount(Creature* me, bool newMount = false)
  4444. +{
  4445. + InstanceScript* instance = me->GetInstanceScript();
  4446. + if (newMount)
  4447. + {
  4448. + // Summoning a new vehicle if all others are used
  4449. + // can but should not occur
  4450. + uint32 tmpEntry = instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE ? VEHICLE_ARGENT_BATTLEWORG_COSMETIC : VEHICLE_ARGENT_WARHORSE_COSMETIC;
  4451. + if (Creature* mount = me->SummonCreature(tmpEntry, bossExitPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10s))
  4452. + {
  4453. + if (instance->GetGuidData(DATA_GRAND_CHAMPION_1) == me->GetGUID())
  4454. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1, mount->GetGUID());
  4455. + else if (instance->GetGuidData(DATA_GRAND_CHAMPION_2) == me->GetGUID())
  4456. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2, mount->GetGUID());
  4457. + else if (instance->GetGuidData(DATA_GRAND_CHAMPION_3) == me->GetGUID())
  4458. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3, mount->GetGUID());
  4459. + mount->SetOrientation(centerOrientation);
  4460. + mount->SetHomePosition(me->GetHomePosition());
  4461. + return mount;
  4462. + }
  4463. + }
  4464. + if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  4465. + return ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1));
  4466. + else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  4467. + return ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2));
  4468. + else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  4469. + return ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3));
  4470. +
  4471. + // should not happen
  4472. + return nullptr;
  4473. +}
  4474. +
  4475. +// called on rider
  4476. +void SetGrandChampionToEvadeMode(Creature* me)
  4477. +{
  4478. + me->RemoveAllAuras();
  4479. + me->ApplySpellImmune(SPELL_TRAMPLE_AURA, IMMUNITY_ID, SPELL_TRAMPLE_AURA, false);
  4480. + me->GetThreatManager().ClearAllThreat();
  4481. + me->CombatStop(true);
  4482. + me->SetLootRecipient(nullptr);
  4483. + me->AI()->Reset();
  4484. + if (Creature* mount = FindMyMount(me))
  4485. + {
  4486. + mount->AI()->Reset();
  4487. + EnterAggressiveMode(mount);
  4488. + mount->GetMotionMaster()->Clear();
  4489. + mount->GetMotionMaster()->MoveTargetedHome();
  4490. + }
  4491. + DoCastPennant(me);
  4492. + // On reset Grand Champions' flags are restored to DB values and we don't want that
  4493. + EnterAggressiveMode(me);
  4494. +}
  4495. +
  4496. +/*
  4497. +* Generic AI for Grand Champions in ToC. *
  4498. +* Script Complete: 100% *
  4499. +*/
  4500. +
  4501. +struct boss_grand_championAI : BossAI
  4502. +{
  4503. + boss_grand_championAI(Creature* creature) : BossAI(creature, DATA_GRAND_CHAMPIONS)
  4504. + {
  4505. + LookingForMount = false;
  4506. + MountedPhaseDone = false;
  4507. + IsChampionDown = false;
  4508. + bDone = false;
  4509. + bHome = false;
  4510. +
  4511. + uiPhase = 0;
  4512. + }
  4513. + uint8 uiPhase;
  4514. +
  4515. + bool LookingForMount; // if is in looking for mount phase
  4516. + bool MountedPhaseDone; // if jousting phase is done
  4517. + bool IsChampionDown; // if champion is defeated
  4518. + bool bDone; // if all champions have been downed
  4519. + bool bHome; // if champion has reached home after jousing phase
  4520. +
  4521. + void Reset() override
  4522. + {
  4523. + if (MountedPhaseDone)
  4524. + DoCastPennant(me);
  4525. + if (IsChampionDown)
  4526. + IsChampionDown = false;
  4527. + _Reset();
  4528. + }
  4529. +
  4530. + bool GrandChampionsOutOfVehicles()
  4531. + {
  4532. + for (int i = 0; i < 3; i++)
  4533. + {
  4534. + if (Creature* pGrandChampion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1 + i)))
  4535. + {
  4536. + if (pGrandChampion->GetVehicleBase())
  4537. + return false;
  4538. + }
  4539. + }
  4540. + return true;
  4541. + }
  4542. +
  4543. + bool GrandChampionsDefeated()
  4544. + {
  4545. + for (int i = 0; i < 3; i++)
  4546. + {
  4547. + if (Creature* pGrandChampion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1 + i)))
  4548. + {
  4549. + if (!pGrandChampion->HasAura(SPELL_KNEEL))
  4550. + return false;
  4551. + }
  4552. + }
  4553. + return true;
  4554. + }
  4555. +
  4556. + void AttackRandomPlayer()
  4557. + {
  4558. + Map::PlayerList const& players = me->GetMap()->GetPlayers();
  4559. + if (players.isEmpty())
  4560. + return;
  4561. +
  4562. + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  4563. + {
  4564. + Player* plr = itr->GetSource();
  4565. + if (plr && !plr->IsGameMaster() && plr->IsAlive())
  4566. + {
  4567. + for (int i = 0; i < 3; i++)
  4568. + {
  4569. + if (Creature* pGrandChampion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1 + i)))
  4570. + {
  4571. + EnterAggressiveMode(pGrandChampion);
  4572. + if (!pGrandChampion->IsInCombat())
  4573. + pGrandChampion->AI()->AttackStart(plr);
  4574. + }
  4575. + }
  4576. + break;
  4577. + }
  4578. + }
  4579. + }
  4580. +
  4581. + bool CanUseNormalAI()
  4582. + {
  4583. + // must check for unattackable flag to prevent crash in certain situations
  4584. + return !UpdateVictim() || me->GetVehicleBase() || LookingForMount || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE) || !MountedPhaseDone;
  4585. + }
  4586. +
  4587. + void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override
  4588. + {
  4589. + if (LookingForMount || !MountedPhaseDone)
  4590. + return;
  4591. +
  4592. + // we must check if other champions have been downed and call evade for them
  4593. + // for example, if players wipe during killing the last champion
  4594. + for (int i = 0; i < 3; ++i)
  4595. + {
  4596. + if (Creature* pGrandChampion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1 + i)))
  4597. + {
  4598. + if (pGrandChampion->HasAura(SPELL_KNEEL))
  4599. + {
  4600. + pGrandChampion->RemoveAllAuras();
  4601. + pGrandChampion->GetThreatManager().ClearAllThreat();
  4602. + pGrandChampion->SetLootRecipient(nullptr);
  4603. + pGrandChampion->SetRegenerateHealth(true);
  4604. + pGrandChampion->GetMotionMaster()->MoveTargetedHome();
  4605. + pGrandChampion->AI()->Reset();
  4606. + }
  4607. + }
  4608. + }
  4609. + BossAI::EnterEvadeMode(why);
  4610. + }
  4611. +
  4612. + void JustReachedHome() override
  4613. + {
  4614. + if (bHome)
  4615. + {
  4616. + // Champions will be unattackable for 15 seconds when reached their homepositions for first time after jousting event
  4617. + // After that time, they will start attacking a random player
  4618. + // if group wipes during actual fight, grand champions will be attackable immediately when reached home position
  4619. + uiPhase = 4;
  4620. + events.ScheduleEvent(EVENT_START_ATTACK_REAL, 15s);
  4621. + bHome = false;
  4622. + }
  4623. + else if (MountedPhaseDone && !bHome)
  4624. + EnterAggressiveMode(me);
  4625. + _JustReachedHome();
  4626. + }
  4627. +
  4628. + void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
  4629. + {
  4630. + if (spellInfo->Id == SPELL_TRAMPLE_AURA && LookingForMount && uiPhase == 0 && !me->IsImmunedToSpell(spellInfo, caster))
  4631. + {
  4632. + uiPhase = 3;
  4633. + me->GetMotionMaster()->Clear();
  4634. + me->GetMotionMaster()->MoveIdle();
  4635. + Talk(EMOTE_TRAMPLE, me);
  4636. + events.ScheduleEvent(EVENT_TRAMPLE, Milliseconds(spellInfo->GetDuration()));
  4637. + }
  4638. + }
  4639. +
  4640. + void MovementInform(uint32 type, uint32 id) override
  4641. + {
  4642. + if (type != POINT_MOTION_TYPE)
  4643. + return;
  4644. +
  4645. + if (id == POINT_REMOUNT && LookingForMount)
  4646. + {
  4647. + // Reached point, mounting again
  4648. + if (Creature* mount = FindMyMount(me))
  4649. + {
  4650. + if (!me->IsWithinDist(mount, INTERACTION_DISTANCE))
  4651. + return;
  4652. +
  4653. + LookingForMount = false;
  4654. + uiPhase = 2;
  4655. + me->ApplySpellImmune(SPELL_TRAMPLE_AURA, IMMUNITY_ID, SPELL_TRAMPLE_AURA, true); // Champion should be immune to trample here
  4656. + me->GetMotionMaster()->Clear();
  4657. + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); // to prevent boss from bugging out
  4658. + me->SetHealth(me->GetMaxHealth());
  4659. + me->SetRegenerateHealth(true);
  4660. + me->SetWalk(false);
  4661. + mount->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE);
  4662. + // sometimes a player can trample champion right when he is about to enter in vehicle
  4663. + // it will bug the boss and you can kill him without the need to kill others as well
  4664. + // so we remove the stun aura just incase
  4665. + me->RemoveAura(SPELL_TRAMPLE_AURA);
  4666. + me->EnterVehicle(mount, SEAT_ID_0);
  4667. +
  4668. + // In rare scenario all players can die meanwhile one of the champions is going for new mount, and then the champion ends in a bugged state
  4669. + // so we must check do we have alive players in the map first, else we call evade
  4670. + bool foundPlr = false;
  4671. + Map::PlayerList const& players = me->GetMap()->GetPlayers();
  4672. + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  4673. + {
  4674. + Player* player = itr->GetSource();
  4675. + if (player && !player->IsGameMaster() && player->IsAlive())
  4676. + {
  4677. + foundPlr = true;
  4678. + break;
  4679. + }
  4680. + }
  4681. + if (foundPlr)
  4682. + events.ScheduleEvent(EVENT_START_ATTACK_JOUST, 2s); // slight delay before attacking
  4683. + else
  4684. + SetGrandChampionToEvadeMode(me);
  4685. + }
  4686. + }
  4687. + else if (id == POINT_DESPAWN)
  4688. + me->DisappearAndDie();
  4689. + }
  4690. +
  4691. + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
  4692. + {
  4693. + if (damage >= me->GetHealth() && me->GetVehicleBase())
  4694. + {
  4695. + damage = 0;
  4696. + LookingForMount = true;
  4697. + uiPhase = 1;
  4698. + me->ApplySpellImmune(SPELL_TRAMPLE_AURA, IMMUNITY_ID, SPELL_TRAMPLE_AURA, true); // Champion should be immune to trample here
  4699. + me->ExitVehicle();
  4700. + me->RemoveAllAuras();
  4701. + DoCastPennant(me);
  4702. + me->SetReactState(REACT_PASSIVE);
  4703. + me->SetHealth(1);
  4704. + me->CombatStop(true);
  4705. + me->SetRegenerateHealth(false); // we don't regen health yet
  4706. + me->GetMotionMaster()->MoveIdle();
  4707. + me->SetWalk(true);
  4708. + // Champion's current vehicle runs to the gates and despawns
  4709. + // Champion will search for new mount
  4710. + if (Creature* mount = FindMyMount(me))
  4711. + {
  4712. + mount->GetMotionMaster()->Clear();
  4713. + mount->SetWalk(false);
  4714. + mount->SetReactState(REACT_PASSIVE);
  4715. + mount->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  4716. +
  4717. + uint32 newMountEntry = instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE ? VEHICLE_ARGENT_BATTLEWORG_COSMETIC : VEHICLE_ARGENT_WARHORSE_COSMETIC;
  4718. + Creature* newMount = nullptr;
  4719. + float dist = 0.0f;
  4720. + std::list<Creature*> tempList;
  4721. +
  4722. + Trinity::AllCreaturesOfEntryInRange check(me, newMountEntry, 100);
  4723. + Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, tempList, check);
  4724. + Cell::VisitGridObjects(me, searcher, me->GetGridActivationRange());
  4725. +
  4726. + for (std::list<Creature*>::const_iterator itr = tempList.begin(); itr != tempList.end(); ++itr)
  4727. + {
  4728. + Creature* tmpMount = *itr;
  4729. +
  4730. + if (instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1) == tmpMount->GetGUID() ||
  4731. + instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2) == tmpMount->GetGUID() ||
  4732. + instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3) == tmpMount->GetGUID())
  4733. + continue;
  4734. +
  4735. + if (!tmpMount->IsAlive())
  4736. + continue;
  4737. +
  4738. + if (dist == 0)
  4739. + {
  4740. + dist = me->GetDistance(tmpMount);
  4741. + newMount = tmpMount;
  4742. + }
  4743. +
  4744. + if (me->GetDistance(tmpMount) < dist)
  4745. + {
  4746. + dist = me->GetDistance(tmpMount);
  4747. + newMount = tmpMount;
  4748. + }
  4749. + }
  4750. + if (newMount)
  4751. + {
  4752. + if (instance->GetGuidData(DATA_GRAND_CHAMPION_1) == me->GetGUID())
  4753. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1, newMount->GetGUID());
  4754. + else if (instance->GetGuidData(DATA_GRAND_CHAMPION_2) == me->GetGUID())
  4755. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2, newMount->GetGUID());
  4756. + else if (instance->GetGuidData(DATA_GRAND_CHAMPION_3) == me->GetGUID())
  4757. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3, newMount->GetGUID());
  4758. + newMount->SetHomePosition(mount->GetHomePosition());
  4759. + }
  4760. + else
  4761. + {
  4762. + // Summoning a new mount for Grand Champion if every other mount have been used
  4763. + (void)FindMyMount(me, true);
  4764. + }
  4765. +
  4766. + // Defeated mount runs towards the center of arena and disappears
  4767. + if (Creature* announcer = instance->GetCreature(DATA_ANNOUNCER))
  4768. + {
  4769. + mount->GetMotionMaster()->Clear();
  4770. + mount->GetMotionMaster()->MovePoint(1, announcer->GetHomePosition());
  4771. + }
  4772. + }
  4773. + events.ScheduleEvent(EVENT_WALK_TO_MOUNT, 3s); // slight delay before we go for new mount
  4774. + return;
  4775. + }
  4776. + else if (damage >= me->GetHealth() && LookingForMount)
  4777. + {
  4778. + damage = 0;
  4779. + return;
  4780. + }
  4781. + else if (damage >= me->GetHealth() && MountedPhaseDone)
  4782. + {
  4783. + damage = 0;
  4784. + if (!IsChampionDown)
  4785. + {
  4786. + IsChampionDown = true;
  4787. + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  4788. + me->SetReactState(REACT_PASSIVE);
  4789. + me->SetHealth(1);
  4790. + me->CombatStop(true);
  4791. + me->SetRegenerateHealth(false);
  4792. + me->GetMotionMaster()->MoveIdle();
  4793. + me->RemoveAura(SPELL_EARTH_SHIELD);
  4794. + me->RemoveAura(SPELL_HASTE);
  4795. + me->RemoveAura(SPELL_LIGHTNING_ARROWS_AURA);
  4796. + me->RemoveAura(SPELL_BLADESTORM);
  4797. + me->CastSpell(me, SPELL_KNEEL, true);
  4798. + }
  4799. + return;
  4800. + }
  4801. + else if (bDone)
  4802. + {
  4803. + damage = 0;
  4804. + return;
  4805. + }
  4806. + }
  4807. +
  4808. + void JustEngagedWith(Unit* who) override
  4809. + {
  4810. + //if (MountedPhaseDone)
  4811. + //{
  4812. + // All champions should attack together
  4813. + for (int i = 0; i < 3; i++)
  4814. + {
  4815. + Creature* pGrandChampion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1 + i));
  4816. + if (pGrandChampion && !pGrandChampion->HasAura(SPELL_KNEEL) && !pGrandChampion->IsInCombat())
  4817. + pGrandChampion->AI()->AttackStart(who);
  4818. + }
  4819. + _JustEngagedWith(who);
  4820. + //}
  4821. + }
  4822. +
  4823. + void AttackStart(Unit* who) override
  4824. + {
  4825. + if (LookingForMount || uiPhase != 0)
  4826. + return;
  4827. + if (Creature* mount = FindMyMount(me))
  4828. + mount->AI()->AttackStart(who);
  4829. + BossAI::AttackStart(who);
  4830. + }
  4831. +
  4832. + void UpdateAI(uint32 diff) override
  4833. + {
  4834. + events.Update(diff);
  4835. +
  4836. + while (uint32 eventId = events.ExecuteEvent())
  4837. + {
  4838. + switch (eventId)
  4839. + {
  4840. + case EVENT_WALK_TO_MOUNT:
  4841. + // Starts walking for mount
  4842. + if (!LookingForMount)
  4843. + break;
  4844. + me->ApplySpellImmune(SPELL_TRAMPLE_AURA, IMMUNITY_ID, SPELL_TRAMPLE_AURA, false);
  4845. + // Sometimes boss can bug out after being thrown down from mount and reset flags to DB values
  4846. + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  4847. + me->GetMotionMaster()->Clear();
  4848. + if (Creature* mount = FindMyMount(me))
  4849. + me->GetMotionMaster()->MovePoint(POINT_REMOUNT, mount->GetPosition());
  4850. + break;
  4851. + case EVENT_START_ATTACK_JOUST:
  4852. + {
  4853. + // We're mounted and preparing to attack
  4854. + if (Creature* mount = FindMyMount(me))
  4855. + {
  4856. + me->ApplySpellImmune(SPELL_TRAMPLE_AURA, IMMUNITY_ID, SPELL_TRAMPLE_AURA, false);
  4857. + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE);
  4858. + DoCastPennant(me);
  4859. + EnterAggressiveMode(me);
  4860. + EnterAggressiveMode(mount);
  4861. + bool foundPlr = false;
  4862. + Map::PlayerList const& players = me->GetMap()->GetPlayers();
  4863. + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  4864. + {
  4865. + Player* player = itr->GetSource();
  4866. + if (player && !player->IsGameMaster() && player->IsAlive())
  4867. + {
  4868. + if (player->GetVehicleBase())
  4869. + mount->AI()->AttackStart(player->GetVehicleBase());
  4870. + else
  4871. + mount->AI()->AttackStart(player);
  4872. + foundPlr = true;
  4873. + break;
  4874. + }
  4875. + }
  4876. + if (!foundPlr)
  4877. + SetGrandChampionToEvadeMode(me);
  4878. + }
  4879. + break;
  4880. + }
  4881. + case EVENT_TRAMPLE:
  4882. + // Got trampled and continuing walking
  4883. + me->GetMotionMaster()->Clear();
  4884. + if (Creature* mount = FindMyMount(me))
  4885. + me->GetMotionMaster()->MovePoint(0, mount->GetPosition());
  4886. + break;
  4887. + case EVENT_EVADE_MODE:
  4888. + // Entering to evade mode after jousting event is done
  4889. + bHome = true;
  4890. + EnterEvadeMode();
  4891. + break;
  4892. + case EVENT_START_ATTACK_REAL:
  4893. + // Searches an enemy to attack after waited a while after jousting event
  4894. + AttackRandomPlayer();
  4895. + break;
  4896. + case EVENT_DESPAWN:
  4897. + // Despawning
  4898. + _JustDied();
  4899. + me->RemoveAura(SPELL_KNEEL);
  4900. + instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_ACHIEVEMENT_CREDIT, 0, me);
  4901. + me->SetWalk(true);
  4902. + me->GetMotionMaster()->MovePoint(POINT_DESPAWN, bossExitPos);
  4903. + break;
  4904. + default:
  4905. + break;
  4906. + }
  4907. + uiPhase = 0;
  4908. + }
  4909. +
  4910. + if (!MountedPhaseDone && GrandChampionsOutOfVehicles())
  4911. + {
  4912. + // Champions have been defeated in jousting event
  4913. + MountedPhaseDone = true;
  4914. + if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_1))
  4915. + me->SetHomePosition(739.678f, 660.975f, 412.393f, 4.49f);
  4916. + else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_2))
  4917. + me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
  4918. + else if (me->GetGUID() == instance->GetGuidData(DATA_GRAND_CHAMPION_3))
  4919. + me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
  4920. +
  4921. + if (Creature* mount = FindMyMount(me))
  4922. + mount->DisappearAndDie();
  4923. +
  4924. + LookingForMount = false;
  4925. + me->ApplySpellImmune(SPELL_TRAMPLE_AURA, IMMUNITY_ID, SPELL_TRAMPLE_AURA, false);
  4926. + me->GetMotionMaster()->MoveIdle();
  4927. + me->GetMotionMaster()->Clear();
  4928. + me->SetRegenerateHealth(true);
  4929. + instance->SetData(DATA_REMOVE_VEHICLES, 0);
  4930. + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
  4931. + uiPhase = 5;
  4932. + events.ScheduleEvent(EVENT_EVADE_MODE, 2s); // minor delay before entering to evade mode to correct movement
  4933. + }
  4934. +
  4935. + if (!bDone && GrandChampionsDefeated())
  4936. + {
  4937. + // Grand Champions encounter is now over
  4938. + bDone = true;
  4939. + uiPhase = 6;
  4940. + events.ScheduleEvent(EVENT_DESPAWN, 2s); // minor delay before giving loot chest
  4941. + }
  4942. + }
  4943. +};
  4944. +
  4945. +/*
  4946. +* Generic AI for vehicles used by npcs in ToC. *
  4947. +* Code requires cleanup and vehicles some improvement *
  4948. +* Script Complete: 95%. *
  4949. +*/
  4950. +
  4951. +class generic_vehicleAI_toc5 : public CreatureScript
  4952. +{
  4953. +public:
  4954. + generic_vehicleAI_toc5() : CreatureScript("generic_vehicleAI_toc5") {}
  4955. +
  4956. + struct generic_vehicleAI_toc5AI : public EscortAI
  4957. + {
  4958. + generic_vehicleAI_toc5AI(Creature* creature) : EscortAI(creature)
  4959. + {
  4960. + Initialize();
  4961. + SetDespawnAtEnd(false);
  4962. + uiWaypointPath = 0;
  4963. +
  4964. + instance = creature->GetInstanceScript();
  4965. + }
  4966. +
  4967. + void Initialize()
  4968. + {
  4969. + castedPennant = false;
  4970. + events.ScheduleEvent(EVENT_BUFF_FLAG, 2s);
  4971. + events.ScheduleEvent(EVENT_BUFF_SHIELD, 5s);
  4972. + events.ScheduleEvent(EVENT_MOUNT_CHARGE, 5s);
  4973. + events.ScheduleEvent(EVENT_SHIELD_BREAKER, 8s);
  4974. + }
  4975. +
  4976. + InstanceScript* instance;
  4977. +
  4978. + EventMap events;
  4979. +
  4980. + bool castedPennant;
  4981. + uint32 uiWaypointPath;
  4982. +
  4983. + void Reset() override
  4984. + {
  4985. + events.Reset();
  4986. + Initialize();
  4987. + }
  4988. +
  4989. + bool IsGrandChampionVehicle()
  4990. + {
  4991. + if (instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1) == me->GetGUID() ||
  4992. + instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2) == me->GetGUID() ||
  4993. + instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3) == me->GetGUID())
  4994. + return true;
  4995. + return false;
  4996. + }
  4997. +
  4998. + bool IsLesserChampion()
  4999. + {
  5000. + switch (me->GetEntry())
  5001. + {
  5002. + case NPC_DARNASSUS_CHAMPION:
  5003. + case NPC_EXODAR_CHAMPION:
  5004. + case NPC_STORMWIND_CHAMPION:
  5005. + case NPC_GNOMEREGAN_CHAMPION:
  5006. + case NPC_IRONFORGE_CHAMPION:
  5007. + case NPC_UNDERCITY_CHAMPION:
  5008. + case NPC_THUNDER_BLUFF_CHAMPION:
  5009. + case NPC_ORGRIMMAR_CHAMPION:
  5010. + case NPC_SILVERMOON_CHAMPION:
  5011. + case NPC_SEN_JIN_CHAMPION:
  5012. + return true;
  5013. + }
  5014. + return false;
  5015. + }
  5016. +
  5017. + void SetData(uint32 uiType, uint32 uiData) override
  5018. + {
  5019. + switch (uiType)
  5020. + {
  5021. + case DATA_GENERATE_WAYPOINTS_FOR_BOSS_1:
  5022. + if (uiData == HORDE)
  5023. + {
  5024. + AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  5025. + AddWaypoint(1, 780.43f, 607.15f, 411.82f);
  5026. + AddWaypoint(2, 785.99f, 599.41f, 411.92f);
  5027. + AddWaypoint(3, GrandChampFinalLoc[3].GetPositionX(), GrandChampFinalLoc[3].GetPositionY(), GrandChampFinalLoc[3].GetPositionZ());
  5028. + }
  5029. + else if (uiData == ALLIANCE)
  5030. + {
  5031. + AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  5032. + AddWaypoint(1, 700.39f, 618.73f, 412.39f);
  5033. + AddWaypoint(2, 703.59f, 618.48f, 411.92f);
  5034. + AddWaypoint(3, GrandChampFinalLoc[0].GetPositionX(), GrandChampFinalLoc[0].GetPositionY(), GrandChampFinalLoc[0].GetPositionZ());
  5035. + }
  5036. + uiWaypointPath = WAYPOINT_MAP_BOSS_1;
  5037. + break;
  5038. + case DATA_GENERATE_WAYPOINTS_FOR_BOSS_2:
  5039. + if (uiData == HORDE)
  5040. + {
  5041. + AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  5042. + AddWaypoint(1, 792.36f, 614.47f, 412.39f);
  5043. + AddWaypoint(2, GrandChampFinalLoc[4].GetPositionX(), GrandChampFinalLoc[4].GetPositionY(), GrandChampFinalLoc[4].GetPositionZ());
  5044. + }
  5045. + else if (uiData == ALLIANCE)
  5046. + {
  5047. + AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  5048. + AddWaypoint(1, 708.31f, 635.07f, 411.93f);
  5049. + AddWaypoint(2, GrandChampFinalLoc[1].GetPositionX(), GrandChampFinalLoc[1].GetPositionY(), GrandChampFinalLoc[1].GetPositionZ());
  5050. + }
  5051. + uiWaypointPath = WAYPOINT_MAP_BOSS_2;
  5052. + break;
  5053. + case DATA_GENERATE_WAYPOINTS_FOR_BOSS_3:
  5054. + if (uiData == HORDE)
  5055. + {
  5056. + AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  5057. + AddWaypoint(1, 793.00f, 624.40f, 412.39f);
  5058. + AddWaypoint(2, GrandChampFinalLoc[5].GetPositionX(), GrandChampFinalLoc[5].GetPositionY(), GrandChampFinalLoc[5].GetPositionZ());
  5059. + }
  5060. + else if (uiData == ALLIANCE)
  5061. + {
  5062. + AddWaypoint(0, 747.35f, 634.07f, 411.57f);
  5063. + AddWaypoint(1, 716.67f, 651.1f, 411.93f);
  5064. + AddWaypoint(2, GrandChampFinalLoc[2].GetPositionX(), GrandChampFinalLoc[2].GetPositionY(), GrandChampFinalLoc[2].GetPositionZ());
  5065. + }
  5066. + uiWaypointPath = WAYPOINT_MAP_BOSS_3;
  5067. + break;
  5068. + case DATA_GENERATE_WAYPOINTS_FOR_ADDS:
  5069. + me->SetWalk(true);
  5070. + me->GetMotionMaster()->MovePoint(1, LesserChampLoc[uiData]);
  5071. + uiWaypointPath = WAYPOINT_MAP_ADDS;
  5072. + break;
  5073. + }
  5074. +
  5075. + if (uiType <= DATA_GENERATE_WAYPOINTS_FOR_BOSS_3)
  5076. + Start(false, true); // Grand Champions run to their positions
  5077. + }
  5078. +
  5079. + void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override
  5080. + {
  5081. + // Evade is handled in UpdateAI for Grand Champions' vehicles
  5082. + // "Cosmetic" vehicles are no longer grand champions' vehicles when champions are
  5083. + // already walking to new mount, therefore they enter into evade mode instead of despawning
  5084. + if (IsGrandChampionVehicle() ||
  5085. + me->GetEntry() == VEHICLE_ARGENT_BATTLEWORG_COSMETIC ||
  5086. + me->GetEntry() == VEHICLE_ARGENT_WARHORSE_COSMETIC)
  5087. + return;
  5088. +
  5089. + EscortAI::EnterEvadeMode(why);
  5090. + }
  5091. +
  5092. + void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
  5093. + {
  5094. + uint32 TeamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE);
  5095. + // Grand Champions reached their final positions in the jousting event
  5096. + // and Lesser Champions begin to correct their positions
  5097. + if ((uiWaypointPath == WAYPOINT_MAP_BOSS_1 && waypointId == 3) || ((uiWaypointPath == WAYPOINT_MAP_BOSS_2 || uiWaypointPath == WAYPOINT_MAP_BOSS_3) && waypointId == 2))
  5098. + {
  5099. + if (Creature* herald = instance->GetCreature(DATA_ANNOUNCER))
  5100. + {
  5101. + if (TeamInInstance == ALLIANCE)
  5102. + me->SetFacingTo(hordeOrientation);
  5103. + else
  5104. + me->SetFacingTo(allianceOrientation);
  5105. + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), TeamInInstance == ALLIANCE ? hordeOrientation : allianceOrientation);
  5106. + if (me->GetVehicleKit() && me->GetVehicleKit()->GetPassenger(SEAT_ID_0) && me->GetVehicleKit()->GetPassenger(SEAT_ID_0)->ToCreature())
  5107. + me->GetVehicleKit()->GetPassenger(SEAT_ID_0)->ToCreature()->SetHomePosition(me->GetPosition());
  5108. + herald->AI()->SetData(DATA_LESSER_CHAMPIONS_PREPARE, uiWaypointPath);
  5109. + }
  5110. + }
  5111. + // Grand Champions run from gates into the arena and then walk towards their waiting positions
  5112. + else if (uiWaypointPath < WAYPOINT_MAP_ADDS && waypointId == 0)
  5113. + me->SetWalk(true);
  5114. + }
  5115. +
  5116. + void MovementInform(uint32 type, uint32 pointId) override
  5117. + {
  5118. + EscortAI::MovementInform(type, pointId);
  5119. +
  5120. + if (type != POINT_MOTION_TYPE)
  5121. + return;
  5122. +
  5123. + // Lesser Champions correct their orientation
  5124. + if (pointId == 1 && uiWaypointPath == WAYPOINT_MAP_ADDS)
  5125. + {
  5126. + uint32 TeamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE);
  5127. + if (TeamInInstance == ALLIANCE)
  5128. + me->SetFacingTo(hordeOrientation);
  5129. + else
  5130. + me->SetFacingTo(allianceOrientation);
  5131. + me->SetWalk(false);
  5132. + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), TeamInInstance == ALLIANCE ? hordeOrientation : allianceOrientation);
  5133. + }
  5134. +
  5135. + // Grand Champions' old mount will despawn when it has run to the center of arena
  5136. + if (pointId == 1 && me->GetVehicleKit() && !me->GetVehicleKit()->GetPassenger(SEAT_ID_0))
  5137. + me->DisappearAndDie();
  5138. + }
  5139. +
  5140. + void JustDied(Unit* /*killer*/) override
  5141. + {
  5142. + if (IsLesserChampion())
  5143. + {
  5144. + me->Dismount();
  5145. + if (Creature* herald = instance->GetCreature(DATA_ANNOUNCER))
  5146. + herald->AI()->SetData(DATA_LESSER_CHAMPIONS_DEFEATED, 0);
  5147. + }
  5148. + }
  5149. +
  5150. + void DoCastShield()
  5151. + {
  5152. + if (IsGrandChampionVehicle())
  5153. + {
  5154. + if (me->GetVehicleKit())
  5155. + if (Unit* rider = me->GetVehicleKit()->GetPassenger(SEAT_ID_0))
  5156. + rider->CastSpell(rider, SPELL_SHIELD_GRAND_CHAMP, true);
  5157. + }
  5158. + else if (IsLesserChampion())
  5159. + DoCast(me, SPELL_SHIELD_LESSER_CHAMP, true);
  5160. + }
  5161. +
  5162. + void AttackStart(Unit* target) override
  5163. + {
  5164. + if (IsGrandChampionVehicle())
  5165. + {
  5166. + if (!(me->GetVehicleKit() && me->GetVehicleKit()->GetPassenger(SEAT_ID_0)))
  5167. + return;
  5168. +
  5169. + if (me->HasUnitState(UNIT_STATE_MELEE_ATTACKING))
  5170. + me->AttackStop();
  5171. +
  5172. + me->GetMotionMaster()->MoveFollow(target, 0, 0);
  5173. + }
  5174. + else if (IsLesserChampion())
  5175. + ScriptedAI::AttackStart(target);
  5176. + }
  5177. +
  5178. + // returns true if we are in combat and we have a victim
  5179. + // returns false if we have no victim, and enters grand champion to evade mode
  5180. + bool CheckCombat()
  5181. + {
  5182. + if (IsGrandChampionVehicle())
  5183. + {
  5184. + if (!me->GetVehicleKit())
  5185. + return false;
  5186. +
  5187. + Unit* rider = me->GetVehicleKit()->GetPassenger(SEAT_ID_0);
  5188. + if (!rider)
  5189. + return false;
  5190. +
  5191. + if (!rider->IsInCombat())
  5192. + return false;
  5193. +
  5194. + if ((rider->ToCreature() && !rider->ToCreature()->HasReactState(REACT_PASSIVE)) && !me->HasReactState(REACT_PASSIVE))
  5195. + {
  5196. + if (rider->GetVictim() == nullptr)
  5197. + {
  5198. + SetGrandChampionToEvadeMode(rider->ToCreature());
  5199. + return false;
  5200. + }
  5201. + }
  5202. + else if (rider->GetThreatManager().IsThreatListEmpty())
  5203. + {
  5204. + SetGrandChampionToEvadeMode(rider->ToCreature());
  5205. + return false;
  5206. + }
  5207. + }
  5208. + else if (!UpdateVictim())
  5209. + return false;
  5210. + return true;
  5211. + }
  5212. +
  5213. + void UpdateAI(uint32 uiDiff) override
  5214. + {
  5215. + EscortAI::UpdateAI(uiDiff);
  5216. + events.Update(uiDiff);
  5217. +
  5218. + while (uint32 eventId = events.ExecuteEvent())
  5219. + {
  5220. + switch (eventId)
  5221. + {
  5222. + case EVENT_BUFF_SHIELD:
  5223. + DoCastShield();
  5224. + events.ScheduleEvent(EVENT_BUFF_SHIELD, 7s);
  5225. + break;
  5226. + case EVENT_BUFF_FLAG:
  5227. + if (IsGrandChampionVehicle())
  5228. + {
  5229. + if (!castedPennant)
  5230. + {
  5231. + if (me->GetVehicleKit() && me->GetVehicleKit()->GetPassenger(SEAT_ID_0) && me->GetVehicleKit()->GetPassenger(SEAT_ID_0)->ToCreature())
  5232. + DoCastPennant(me->GetVehicleKit()->GetPassenger(SEAT_ID_0)->ToCreature());
  5233. + castedPennant = true;
  5234. + }
  5235. + }
  5236. + break;
  5237. + case EVENT_MOUNT_CHARGE:
  5238. + {
  5239. + if (CheckCombat())
  5240. + {
  5241. + // Charge is casted on random player
  5242. + // Champions' threatlist is reseted when using charge
  5243. + Map::PlayerList const& pList = me->GetMap()->GetPlayers();
  5244. + // Player list is always in the same order so we must "randomize" it
  5245. + if (!pList.isEmpty())
  5246. + {
  5247. + uint32 rand = urand(0, pList.getSize() - 1);
  5248. + for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
  5249. + {
  5250. + if (rand == 0)
  5251. + {
  5252. + Player* plr = itr->GetSource();
  5253. + if (plr && !plr->IsGameMaster() && plr->IsAlive() && me->IsInRange(plr, 8.0f, 25.0f, false))
  5254. + {
  5255. + uint32 spell_charge = IsGrandChampionVehicle() ? SPELL_CHARGE_GRAND_CHAMP : SPELL_CHARGE_LESSER_CHAMP;
  5256. + if (IsGrandChampionVehicle())
  5257. + {
  5258. + if (me->GetVehicleKit() && me->GetVehicleKit()->GetPassenger(SEAT_ID_0))
  5259. + {
  5260. + if (Creature* rider = me->GetVehicleKit()->GetPassenger(SEAT_ID_0)->ToCreature())
  5261. + {
  5262. + // Grand Champion
  5263. + // Resetting rider's threat (DoResetThreat() cannot be used on external unit)
  5264. + rider->GetThreatManager().ResetAllThreat();
  5265. + // Setting gaze on the new player
  5266. + if (plr->GetVehicleBase())
  5267. + AddThreat(plr->GetVehicleBase(), 100000.0f);
  5268. + else
  5269. + AddThreat(plr, 100000.0f);
  5270. + // Casting actual charge
  5271. + if (plr->GetVehicleBase())
  5272. + rider->CastSpell(plr->GetVehicleBase(), spell_charge);
  5273. + else
  5274. + rider->CastSpell(plr, spell_charge);
  5275. + me->GetMotionMaster()->MoveCharge(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ());
  5276. + }
  5277. + }
  5278. + }
  5279. + else
  5280. + {
  5281. + // Lesser Champion
  5282. + // Resetting threat
  5283. + ResetThreatList();
  5284. + // Setting gaze on the new player
  5285. + if (plr->GetVehicleBase())
  5286. + AddThreat(plr->GetVehicleBase(), 100000.0f);
  5287. + else
  5288. + AddThreat(plr, 100000.0f);
  5289. + // Casting actual charge
  5290. + if (plr->GetVehicleBase())
  5291. + DoCast(plr->GetVehicleBase(), spell_charge);
  5292. + else
  5293. + DoCast(plr, spell_charge);
  5294. + }
  5295. + break;
  5296. + }
  5297. + else
  5298. + continue;
  5299. + }
  5300. + else
  5301. + --rand;
  5302. + }
  5303. + }
  5304. + }
  5305. + events.ScheduleEvent(EVENT_MOUNT_CHARGE, 7s);
  5306. + break;
  5307. + }
  5308. + case EVENT_SHIELD_BREAKER:
  5309. + // Lesser Champions don't use Shield Breaker
  5310. + if (IsGrandChampionVehicle() && me->GetVehicleKit())
  5311. + {
  5312. + if (CheckCombat())
  5313. + {
  5314. + if (Unit* rider = me->GetVehicleKit()->GetPassenger(SEAT_ID_0))
  5315. + {
  5316. + if (Unit* victim = rider->GetVictim())
  5317. + {
  5318. + if (rider->IsInRange(victim, 5.0f, 30.0f, false))
  5319. + rider->CastSpell(victim, SPELL_SHIELD_BREAKER);
  5320. + }
  5321. + }
  5322. + }
  5323. + events.ScheduleEvent(EVENT_SHIELD_BREAKER, 4s);
  5324. + }
  5325. + break;
  5326. + default:
  5327. + break;
  5328. + }
  5329. + }
  5330. +
  5331. + if (!CheckCombat())
  5332. + return;
  5333. +
  5334. + DoMeleeAttackIfReady();
  5335. + }
  5336. + };
  5337. +
  5338. + CreatureAI* GetAI(Creature* creature) const override
  5339. + {
  5340. + return GetTrialOfChampionAI<generic_vehicleAI_toc5AI>(creature);
  5341. + }
  5342. +};
  5343. +
  5344. +class boss_warrior_toc5 : public CreatureScript
  5345. +{
  5346. +public:
  5347. + boss_warrior_toc5() : CreatureScript("boss_warrior_toc5") {}
  5348. +
  5349. + // Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
  5350. + struct boss_warrior_toc5AI : public boss_grand_championAI
  5351. + {
  5352. + boss_warrior_toc5AI(Creature* creature) : boss_grand_championAI(creature) {}
  5353. +
  5354. + void Reset() override
  5355. + {
  5356. + boss_grand_championAI::Reset();
  5357. + }
  5358. +
  5359. + void JustEngagedWith(Unit* who) override
  5360. + {
  5361. + events.ScheduleEvent(EVENT_BLADESTORM, randtime(15s, 20s));
  5362. + events.ScheduleEvent(EVENT_INTERCEPT, 7s);
  5363. + events.ScheduleEvent(EVENT_MORTAL_STRIKE, randtime(8s, 12s));
  5364. + events.ScheduleEvent(EVENT_ROLLING_THROW, 30s);
  5365. + boss_grand_championAI::JustEngagedWith(who);
  5366. + }
  5367. +
  5368. + void UpdateAI(uint32 uiDiff) override
  5369. + {
  5370. + boss_grand_championAI::UpdateAI(uiDiff);
  5371. +
  5372. + if (CanUseNormalAI())
  5373. + {
  5374. + if (UpdateVictim())
  5375. + DoMeleeAttackIfReady();
  5376. + return;
  5377. + }
  5378. +
  5379. + if (me->HasUnitState(UNIT_STATE_CASTING))
  5380. + return;
  5381. +
  5382. + while (uint32 eventId = events.ExecuteEvent())
  5383. + {
  5384. + switch (eventId)
  5385. + {
  5386. + case EVENT_INTERCEPT:
  5387. + {
  5388. + if (!me->HasAura(SPELL_BLADESTORM))
  5389. + {
  5390. + Map::PlayerList const& pList = me->GetMap()->GetPlayers();
  5391. + // Player list is always in the same order so we must "randomize" it
  5392. + if (!pList.isEmpty())
  5393. + {
  5394. + uint32 rand = urand(0, pList.getSize() - 1);
  5395. + for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
  5396. + {
  5397. + if (rand == 0)
  5398. + {
  5399. + Player* plr = itr->GetSource();
  5400. + if (plr && !plr->IsGameMaster() && plr->IsAlive() && me->IsInRange(plr, 8.0f, 25.0f, false))
  5401. + {
  5402. + ResetThreatList();
  5403. + DoCast(plr, SPELL_INTERCEPT);
  5404. + AddThreat(plr, 5.0f);
  5405. + break;
  5406. + }
  5407. + else
  5408. + continue;
  5409. + }
  5410. + else
  5411. + --rand;
  5412. + }
  5413. + }
  5414. + }
  5415. + events.ScheduleEvent(EVENT_INTERCEPT, 7s);
  5416. + break;
  5417. + }
  5418. + case EVENT_BLADESTORM:
  5419. + DoCastVictim(SPELL_BLADESTORM);
  5420. + events.ScheduleEvent(EVENT_BLADESTORM, randtime(15s, 20s));
  5421. + break;
  5422. + case EVENT_MORTAL_STRIKE:
  5423. + if (!me->HasAura(SPELL_BLADESTORM))
  5424. + DoCastVictim(SPELL_MORTAL_STRIKE);
  5425. + events.ScheduleEvent(EVENT_MORTAL_STRIKE, randtime(8s, 12s));
  5426. + break;
  5427. + case EVENT_ROLLING_THROW:
  5428. + // TODO: FIXME
  5429. + // currently hackfixed at Spell::EffectLeapBack in SpellEffects.cpp
  5430. + // without hackfix caster jumps forward, when caster should jump backwards and player jump forwards
  5431. + if (!me->HasAura(SPELL_BLADESTORM))
  5432. + DoCastVictim(SPELL_ROLLING_THROW);
  5433. + events.ScheduleEvent(EVENT_ROLLING_THROW, 30s);
  5434. + break;
  5435. + default:
  5436. + break;
  5437. + }
  5438. + }
  5439. + DoMeleeAttackIfReady();
  5440. + }
  5441. + };
  5442. +
  5443. + CreatureAI* GetAI(Creature* creature) const override
  5444. + {
  5445. + return GetTrialOfChampionAI<boss_warrior_toc5AI>(creature);
  5446. + }
  5447. +};
  5448. +
  5449. +class boss_mage_toc5 : public CreatureScript
  5450. +{
  5451. +public:
  5452. + boss_mage_toc5() : CreatureScript("boss_mage_toc5") {}
  5453. +
  5454. + // Ambrose Boltspark && Eressea Dawnsinger || Mage
  5455. + struct boss_mage_toc5AI : public boss_grand_championAI
  5456. + {
  5457. + boss_mage_toc5AI(Creature* creature) : boss_grand_championAI(creature) {}
  5458. +
  5459. + void Reset() override
  5460. + {
  5461. + boss_grand_championAI::Reset();
  5462. + }
  5463. +
  5464. + void JustEngagedWith(Unit* who) override
  5465. + {
  5466. + events.ScheduleEvent(EVENT_FIREBALL, 2s);
  5467. + events.ScheduleEvent(EVENT_POLYMORPH, 8s);
  5468. + events.ScheduleEvent(EVENT_BLASTWAVE, 12s);
  5469. + events.ScheduleEvent(EVENT_HASTE, 22s);
  5470. + boss_grand_championAI::JustEngagedWith(who);
  5471. + }
  5472. +
  5473. + void AttackStart(Unit* who) override
  5474. + {
  5475. + me->GetMotionMaster()->MoveChase(who, 20.0f);
  5476. + boss_grand_championAI::AttackStart(who);
  5477. + }
  5478. +
  5479. + void UpdateAI(uint32 uiDiff) override
  5480. + {
  5481. + boss_grand_championAI::UpdateAI(uiDiff);
  5482. +
  5483. + if (CanUseNormalAI())
  5484. + {
  5485. + if (UpdateVictim())
  5486. + DoMeleeAttackIfReady();
  5487. + return;
  5488. + }
  5489. +
  5490. + while (uint32 eventId = events.ExecuteEvent())
  5491. + {
  5492. + switch (eventId)
  5493. + {
  5494. + case EVENT_POLYMORPH:
  5495. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 30.0f, true))
  5496. + {
  5497. + DoCast(target, SPELL_POLYMORPH);
  5498. + if (me->HasAura(SPELL_HASTE))
  5499. + events.ScheduleEvent(EVENT_FIREBALL, 2s);
  5500. + else
  5501. + events.ScheduleEvent(EVENT_FIREBALL, 3s);
  5502. + }
  5503. + events.ScheduleEvent(EVENT_POLYMORPH, 8s);
  5504. + break;
  5505. + case EVENT_BLASTWAVE:
  5506. + if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0))
  5507. + {
  5508. + if (me->IsWithinDist(target, 5.0f, false))
  5509. + {
  5510. + me->InterruptNonMeleeSpells(true);
  5511. + DoCastAOE(SPELL_BLAST_WAVE);
  5512. + events.ScheduleEvent(EVENT_FIREBALL, 1500ms);
  5513. + }
  5514. + }
  5515. + events.ScheduleEvent(EVENT_BLASTWAVE, 13s);
  5516. + break;
  5517. + case EVENT_HASTE:
  5518. + me->InterruptNonMeleeSpells(true);
  5519. + DoCast(me, SPELL_HASTE);
  5520. + events.ScheduleEvent(EVENT_FIREBALL, 1500ms);
  5521. + events.ScheduleEvent(EVENT_HASTE, 22s);
  5522. + break;
  5523. + case EVENT_FIREBALL:
  5524. + DoCastVictim(SPELL_FIREBALL);
  5525. + if (me->HasAura(SPELL_HASTE))
  5526. + events.ScheduleEvent(EVENT_FIREBALL, 3s);
  5527. + else
  5528. + events.ScheduleEvent(EVENT_FIREBALL, 4s);
  5529. + break;
  5530. + default:
  5531. + break;
  5532. + }
  5533. + }
  5534. + if ((100.f * me->GetPower(POWER_MANA) / me->GetMaxPower(POWER_MANA)) <= 1)
  5535. + DoMeleeAttackIfReady();
  5536. + }
  5537. + };
  5538. +
  5539. + CreatureAI* GetAI(Creature* creature) const override
  5540. + {
  5541. + return GetTrialOfChampionAI<boss_mage_toc5AI>(creature);
  5542. + }
  5543. +};
  5544. +
  5545. +class boss_shaman_toc5 : public CreatureScript
  5546. +{
  5547. +public:
  5548. + boss_shaman_toc5() : CreatureScript("boss_shaman_toc5") {}
  5549. +
  5550. + // Colosos && Runok Wildmane || Shaman
  5551. + struct boss_shaman_toc5AI : public boss_grand_championAI
  5552. + {
  5553. + boss_shaman_toc5AI(Creature* creature) : boss_grand_championAI(creature)
  5554. + {
  5555. + Initialize();
  5556. + }
  5557. +
  5558. + void Initialize()
  5559. + {
  5560. + earthShieldTarget.Clear();
  5561. + isDefensive = false;
  5562. + }
  5563. + ObjectGuid earthShieldTarget;
  5564. + // If shaman's friend or himself goes below 25% HP, he will go into defensive mode,
  5565. + // casting healing spells only
  5566. + bool isDefensive;
  5567. +
  5568. + void Reset() override
  5569. + {
  5570. + Initialize();
  5571. + boss_grand_championAI::Reset();
  5572. + }
  5573. +
  5574. + void JustEngagedWith(Unit* who) override
  5575. + {
  5576. + events.ScheduleEvent(EVENT_DEF_CHECK, 5s);
  5577. + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 16s);
  5578. + events.ScheduleEvent(EVENT_HEALING_WAVE, 12s);
  5579. + events.ScheduleEvent(EVENT_EARTH_SHIELD, 5s);
  5580. + events.ScheduleEvent(EVENT_HEX_MENDING, 7s);
  5581. + boss_grand_championAI::JustEngagedWith(who);
  5582. + }
  5583. +
  5584. + void EnterCombatMode(bool interrupt)
  5585. + {
  5586. + if (interrupt)
  5587. + me->InterruptNonMeleeSpells(true);
  5588. + isDefensive = false;
  5589. + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 1s);
  5590. + }
  5591. +
  5592. + void EnterDefensiveMode()
  5593. + {
  5594. + me->InterruptNonMeleeSpells(true);
  5595. + isDefensive = true;
  5596. + events.ScheduleEvent(EVENT_EARTH_SHIELD, 1s);
  5597. + events.ScheduleEvent(EVENT_HEALING_WAVE, 1500ms);
  5598. + }
  5599. +
  5600. + Unit* FindChampionWithLowestHp(float range)
  5601. + {
  5602. + // DoSelectLowestHpFriendly does not work correctly in this fight
  5603. + // We look for champion with the lowest percentage health left
  5604. + // ignoring champions with full hp or with kneel state (= defeated)
  5605. + // and champions who are more than 40 yards away from me (max range of healing spells)
  5606. + Unit* lowChampion = nullptr;
  5607. + Creature* pGrandChampion1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1));
  5608. + Creature* pGrandChampion2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_2));
  5609. + Creature* pGrandChampion3 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_3));
  5610. + if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
  5611. + {
  5612. + if (!pGrandChampion1->HasAura(SPELL_KNEEL) && pGrandChampion1->GetHealthPct() < 100 && me->IsWithinDist(pGrandChampion1, range))
  5613. + lowChampion = pGrandChampion1;
  5614. + if (!pGrandChampion2->HasAura(SPELL_KNEEL) && pGrandChampion2->GetHealthPct() < 100 && me->IsWithinDist(pGrandChampion2, range))
  5615. + {
  5616. + if (lowChampion)
  5617. + {
  5618. + if (lowChampion->GetHealthPct() > pGrandChampion2->GetHealthPct())
  5619. + lowChampion = pGrandChampion2;
  5620. + }
  5621. + else
  5622. + lowChampion = pGrandChampion2;
  5623. + }
  5624. + if (!pGrandChampion3->HasAura(SPELL_KNEEL) && pGrandChampion3->GetHealthPct() < 100 && me->IsWithinDist(pGrandChampion3, range))
  5625. + {
  5626. + if (lowChampion)
  5627. + {
  5628. + if (lowChampion->GetHealthPct() > pGrandChampion3->GetHealthPct())
  5629. + lowChampion = pGrandChampion3;
  5630. + }
  5631. + else
  5632. + lowChampion = pGrandChampion3;
  5633. + }
  5634. + }
  5635. + // can return NULL if other champions are over 40 yards away and we're in full hp
  5636. + // or if one champion has been defeated and two are in full hp
  5637. + // or we are last man standing with full hp
  5638. + return lowChampion;
  5639. + }
  5640. +
  5641. + void UpdateAI(uint32 uiDiff) override
  5642. + {
  5643. + boss_grand_championAI::UpdateAI(uiDiff);
  5644. +
  5645. + if (CanUseNormalAI())
  5646. + {
  5647. + if (UpdateVictim())
  5648. + DoMeleeAttackIfReady();
  5649. + return;
  5650. + }
  5651. +
  5652. + while (uint32 eventId = events.ExecuteEvent())
  5653. + {
  5654. + switch (eventId)
  5655. + {
  5656. + case EVENT_DEF_CHECK:
  5657. + if (!isDefensive)
  5658. + {
  5659. + Unit* pFriend = FindChampionWithLowestHp(40.0f);
  5660. + if (pFriend && pFriend->GetHealthPct() <= 25)
  5661. + EnterDefensiveMode();
  5662. + }
  5663. + else
  5664. + {
  5665. + Unit* pFriend = FindChampionWithLowestHp(40.0f);
  5666. + if (pFriend && pFriend->GetHealthPct() > 25)
  5667. + EnterCombatMode(false);
  5668. + else
  5669. + EnterCombatMode(true);
  5670. + }
  5671. + events.ScheduleEvent(EVENT_DEF_CHECK, 5s);
  5672. + break;
  5673. + case EVENT_CHAIN_LIGHTNING:
  5674. + if (!isDefensive)
  5675. + {
  5676. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
  5677. + DoCast(target, SPELL_CHAIN_LIGHTNING);
  5678. + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 16s);
  5679. + }
  5680. + break;
  5681. + case EVENT_HEALING_WAVE:
  5682. + if (Unit* pFriend = FindChampionWithLowestHp(40.0f))
  5683. + {
  5684. + // double check to interrupt heal on defeated champion
  5685. + if (pFriend->HasAura(SPELL_KNEEL))
  5686. + EnterCombatMode(true);
  5687. + else
  5688. + DoCast(pFriend, SPELL_HEALING_WAVE);
  5689. + }
  5690. + if (isDefensive)
  5691. + events.ScheduleEvent(EVENT_HEALING_WAVE, 4s);
  5692. + else
  5693. + events.ScheduleEvent(EVENT_HEALING_WAVE, 12s);
  5694. + break;
  5695. + case EVENT_EARTH_SHIELD:
  5696. + if (Unit* pFriend = FindChampionWithLowestHp(40.0f))
  5697. + {
  5698. + // double check to interrupt shield on defeated champion
  5699. + if (pFriend->HasAura(SPELL_KNEEL))
  5700. + EnterCombatMode(true);
  5701. + else
  5702. + {
  5703. + // Earth Shield is single target spell, we must remove it from previous target
  5704. + if (Creature* target = ObjectAccessor::GetCreature(*me, earthShieldTarget))
  5705. + {
  5706. + if (target->HasAura(SPELL_EARTH_SHIELD))
  5707. + target->RemoveAura(SPELL_EARTH_SHIELD);
  5708. + }
  5709. + DoCast(pFriend, SPELL_EARTH_SHIELD);
  5710. + earthShieldTarget = pFriend->GetGUID();
  5711. + }
  5712. + }
  5713. + events.ScheduleEvent(EVENT_EARTH_SHIELD, randtime(30s, 35s));
  5714. + break;
  5715. + case EVENT_HEX_MENDING:
  5716. + DoCastVictim(SPELL_HEX_OF_MENDING);
  5717. + events.ScheduleEvent(EVENT_HEX_MENDING, randtime(20s, 25s));
  5718. + break;
  5719. + default:
  5720. + break;
  5721. + }
  5722. + }
  5723. + if (!isDefensive)
  5724. + DoMeleeAttackIfReady();
  5725. + }
  5726. + };
  5727. +
  5728. + CreatureAI* GetAI(Creature* creature) const override
  5729. + {
  5730. + return GetTrialOfChampionAI<boss_shaman_toc5AI>(creature);
  5731. + }
  5732. +};
  5733. +
  5734. +class boss_hunter_toc5 : public CreatureScript
  5735. +{
  5736. +public:
  5737. + boss_hunter_toc5() : CreatureScript("boss_hunter_toc5") {}
  5738. +
  5739. + // Jaelyne Evensong && Zul'tore || Hunter
  5740. + struct boss_hunter_toc5AI : public boss_grand_championAI
  5741. + {
  5742. + boss_hunter_toc5AI(Creature* creature) : boss_grand_championAI(creature) {}
  5743. +
  5744. + void Reset() override
  5745. + {
  5746. + boss_grand_championAI::Reset();
  5747. + }
  5748. +
  5749. + void JustEngagedWith(Unit* who) override
  5750. + {
  5751. + events.ScheduleEvent(EVENT_MULTI_SHOT, 7500ms);
  5752. + events.ScheduleEvent(EVENT_LIGHTNING_ARROWS, 15s);
  5753. + events.ScheduleEvent(EVENT_DISENGAGE, randtime(25s, 35s));
  5754. + boss_grand_championAI::JustEngagedWith(who);
  5755. + }
  5756. +
  5757. + void AttackStart(Unit* who) override
  5758. + {
  5759. + me->GetMotionMaster()->MoveChase(who, 25.0f);
  5760. + boss_grand_championAI::AttackStart(who);
  5761. + }
  5762. +
  5763. + void UpdateAI(uint32 uiDiff) override
  5764. + {
  5765. + boss_grand_championAI::UpdateAI(uiDiff);
  5766. +
  5767. + if (CanUseNormalAI())
  5768. + {
  5769. + if (UpdateVictim())
  5770. + DoMeleeAttackIfReady();
  5771. + return;
  5772. + }
  5773. +
  5774. + while (uint32 eventId = events.ExecuteEvent())
  5775. + {
  5776. + switch (eventId)
  5777. + {
  5778. + case EVENT_DISENGAGE:
  5779. + if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0))
  5780. + {
  5781. + if (me->IsWithinDist(target, 5.0f, false))
  5782. + {
  5783. + me->InterruptNonMeleeSpells(true);
  5784. + DoCast(me, SPELL_DISENGAGE);
  5785. + }
  5786. + }
  5787. + events.ScheduleEvent(EVENT_DISENGAGE, randtime(25s, 35s));
  5788. + break;
  5789. + case EVENT_LIGHTNING_ARROWS:
  5790. + if (!me->HasAura(SPELL_LIGHTNING_ARROWS_AURA) && !me->IsWithinDist(me->GetVictim(), 2.0f))
  5791. + {
  5792. + me->InterruptNonMeleeSpells(true);
  5793. + DoCastAOE(SPELL_LIGHTNING_ARROWS);
  5794. + }
  5795. + events.ScheduleEvent(EVENT_LIGHTNING_ARROWS, randtime(20s, 30s));
  5796. + break;
  5797. + case EVENT_MULTI_SHOT:
  5798. + if (me->IsInRange(me->GetVictim(), 5.0f, 30.0f, false) && !me->HasAura(SPELL_LIGHTNING_ARROWS))
  5799. + {
  5800. + me->InterruptNonMeleeSpells(true);
  5801. + DoCastVictim(SPELL_MULTI_SHOT);
  5802. + }
  5803. + events.ScheduleEvent(EVENT_MULTI_SHOT, 8s);
  5804. + break;
  5805. + default:
  5806. + break;
  5807. + }
  5808. + }
  5809. +
  5810. + if (me->IsWithinDist(me->GetVictim(), 2.0f))
  5811. + DoMeleeAttackIfReady();
  5812. + else
  5813. + DoSpellAttackIfReady(SPELL_SHOOT);
  5814. + }
  5815. + };
  5816. +
  5817. + CreatureAI* GetAI(Creature* creature) const override
  5818. + {
  5819. + return GetTrialOfChampionAI<boss_hunter_toc5AI>(creature);
  5820. + }
  5821. +};
  5822. +
  5823. +class boss_rogue_toc5 : public CreatureScript
  5824. +{
  5825. +public:
  5826. + boss_rogue_toc5() : CreatureScript("boss_rouge_toc5") {}
  5827. +
  5828. + // Lana Stouthammer Evensong && Deathstalker Visceri || Rogue
  5829. + struct boss_rogue_toc5AI : public boss_grand_championAI
  5830. + {
  5831. + boss_rogue_toc5AI(Creature* creature) : boss_grand_championAI(creature) {}
  5832. +
  5833. + void Reset() override
  5834. + {
  5835. + boss_grand_championAI::Reset();
  5836. + }
  5837. +
  5838. + void JustEngagedWith(Unit* who) override
  5839. + {
  5840. + events.ScheduleEvent(EVENT_DEADLY_POISON, 500ms);
  5841. + events.ScheduleEvent(EVENT_EVISCERATE, 8s);
  5842. + events.ScheduleEvent(EVENT_FAN_OF_KNIVES, 14s);
  5843. + events.ScheduleEvent(EVENT_POISON_BOTTLE, 19s);
  5844. + boss_grand_championAI::JustEngagedWith(who);
  5845. + }
  5846. +
  5847. + void UpdateAI(uint32 diff) override
  5848. + {
  5849. + boss_grand_championAI::UpdateAI(diff);
  5850. +
  5851. + if (CanUseNormalAI())
  5852. + {
  5853. + if (UpdateVictim())
  5854. + DoMeleeAttackIfReady();
  5855. + return;
  5856. + }
  5857. +
  5858. + if (me->HasUnitState(UNIT_STATE_CASTING))
  5859. + return;
  5860. +
  5861. + while (uint32 eventId = events.ExecuteEvent())
  5862. + {
  5863. + switch (eventId)
  5864. + {
  5865. + case EVENT_DEADLY_POISON:
  5866. + if (!me->HasAura(SPELL_DEADLY_POISON))
  5867. + DoCast(me, SPELL_DEADLY_POISON);
  5868. + events.ScheduleEvent(EVENT_DEADLY_POISON, 30s);
  5869. + case EVENT_EVISCERATE:
  5870. + DoCastVictim(SPELL_EVISCERATE);
  5871. + events.ScheduleEvent(EVENT_EVISCERATE, 8s);
  5872. + break;
  5873. + case EVENT_FAN_OF_KNIVES:
  5874. + if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0))
  5875. + {
  5876. + if (me->IsWithinDist(target, 8.0f, false)) // 8 yards is minimum range
  5877. + DoCastAOE(SPELL_FAN_OF_KNIVES);
  5878. + }
  5879. + events.ScheduleEvent(EVENT_FAN_OF_KNIVES, 14s);
  5880. + break;
  5881. + case EVENT_POISON_BOTTLE:
  5882. + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
  5883. + DoCast(target, SPELL_POISON_BOTTLE);
  5884. + events.ScheduleEvent(EVENT_POISON_BOTTLE, 19s);
  5885. + break;
  5886. + default:
  5887. + break;
  5888. + }
  5889. + }
  5890. + DoMeleeAttackIfReady();
  5891. + }
  5892. + };
  5893. +
  5894. + CreatureAI* GetAI(Creature* creature) const override
  5895. + {
  5896. + return GetTrialOfChampionAI<boss_rogue_toc5AI>(creature);
  5897. + }
  5898. +};
  5899. +
  5900. +class spell_toc5_trample_aura : public SpellScriptLoader
  5901. +{
  5902. +public:
  5903. + spell_toc5_trample_aura() : SpellScriptLoader("spell_toc5_trample_aura") {}
  5904. +
  5905. + class spell_toc5_trample_aura_SpellScript : public SpellScript
  5906. + {
  5907. + PrepareSpellScript(spell_toc5_trample_aura_SpellScript);
  5908. +
  5909. + void RemoveInvalidTargets(std::list<WorldObject*>& targets)
  5910. + {
  5911. + // The aura should not be applied if there is already a trample aura on target
  5912. + targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
  5913. + }
  5914. +
  5915. + void HandleStun()
  5916. + {
  5917. + if (Unit* target = GetHitUnit())
  5918. + {
  5919. + // If target is mounted, do not apply
  5920. + if (target->GetVehicleKit() // Grand Champions
  5921. + || target->GetVehicleBase() // Players
  5922. + || target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT)) // Lesser Champions
  5923. + {
  5924. + PreventHitEffect(EFFECT_0);
  5925. + _removed = true;
  5926. + }
  5927. + }
  5928. + }
  5929. +
  5930. + void RemoveAura()
  5931. + {
  5932. + if (_removed)
  5933. + PreventHitAura();
  5934. + }
  5935. +
  5936. + void Register() override
  5937. + {
  5938. + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_toc5_trample_aura_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  5939. + OnHit += SpellHitFn(spell_toc5_trample_aura_SpellScript::HandleStun);
  5940. + AfterHit += SpellHitFn(spell_toc5_trample_aura_SpellScript::RemoveAura);
  5941. + }
  5942. +
  5943. + bool _removed = false;
  5944. + };
  5945. +
  5946. + SpellScript* GetSpellScript() const override
  5947. + {
  5948. + return new spell_toc5_trample_aura_SpellScript();
  5949. + }
  5950. +};
  5951. +
  5952. +class spell_toc5_lightning_arrows : public SpellScriptLoader
  5953. +{
  5954. +public:
  5955. + spell_toc5_lightning_arrows() : SpellScriptLoader("spell_toc5_lightning_arrows") {}
  5956. +
  5957. + class spell_toc5_lightning_arrows_AuraScript : public AuraScript
  5958. + {
  5959. + PrepareAuraScript(spell_toc5_lightning_arrows_AuraScript);
  5960. +
  5961. + bool Validate(SpellInfo const* /*spellInfo*/) override
  5962. + {
  5963. + if (!sSpellMgr->GetSpellInfo(SPELL_LIGHTNING_ARROWS_AURA))
  5964. + return false;
  5965. + return true;
  5966. + }
  5967. +
  5968. + void HandleScript(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
  5969. + {
  5970. + GetCaster()->CastSpell(GetCaster(), SPELL_LIGHTNING_ARROWS_AURA, true);
  5971. + }
  5972. +
  5973. + void Register() override
  5974. + {
  5975. + AfterEffectRemove += AuraEffectRemoveFn(spell_toc5_lightning_arrows_AuraScript::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
  5976. + }
  5977. + };
  5978. +
  5979. + AuraScript* GetAuraScript() const override
  5980. + {
  5981. + return new spell_toc5_lightning_arrows_AuraScript();
  5982. + }
  5983. +};
  5984. +
  5985. +enum CriteriaIds
  5986. +{
  5987. + CRITERIA_WARRIOR = 12538,
  5988. + CRITERIA_HUNTER = 12540,
  5989. + CRITERIA_MAGE = 12542,
  5990. + CRITERIA_ROGUE = 12544,
  5991. + CRITERIA_SHAMAN = 12546,
  5992. + CRITERIA_WARRIOR_H = 12539,
  5993. + CRITERIA_HUNTER_H = 12541,
  5994. + CRITERIA_MAGE_H = 12543,
  5995. + CRITERIA_ROGUE_H = 12545,
  5996. + CRITERIA_SHAMAN_H = 12547
  5997. +};
  5998. +
  5999. +// Statistics achievements "Victories over X champion" both normal and heroic
  6000. +class achievement_victories_over_champion : public AchievementCriteriaScript
  6001. +{
  6002. +public:
  6003. + achievement_victories_over_champion(char const* name, uint32 criteriaId) : AchievementCriteriaScript(name),
  6004. + _criteriaId(criteriaId)
  6005. + {
  6006. + }
  6007. +
  6008. + bool OnCheck(Player* /*player*/, Unit* target) override
  6009. + {
  6010. + if (target)
  6011. + {
  6012. + switch (_criteriaId)
  6013. + {
  6014. + case CRITERIA_WARRIOR:
  6015. + case CRITERIA_WARRIOR_H:
  6016. + return target->GetEntry() == NPC_JACOB || target->GetEntry() == NPC_MOKRA;
  6017. + case CRITERIA_HUNTER:
  6018. + case CRITERIA_HUNTER_H:
  6019. + return target->GetEntry() == NPC_JAELYNE || target->GetEntry() == NPC_ZULTORE;
  6020. + case CRITERIA_MAGE:
  6021. + case CRITERIA_MAGE_H:
  6022. + return target->GetEntry() == NPC_AMBROSE || target->GetEntry() == NPC_ERESSEA;
  6023. + case CRITERIA_ROGUE:
  6024. + case CRITERIA_ROGUE_H:
  6025. + return target->GetEntry() == NPC_LANA || target->GetEntry() == NPC_VISCERI;
  6026. + case CRITERIA_SHAMAN:
  6027. + case CRITERIA_SHAMAN_H:
  6028. + return target->GetEntry() == NPC_COLOSOS || target->GetEntry() == NPC_RUNOK;
  6029. + default:
  6030. + break;
  6031. + }
  6032. + }
  6033. + return false;
  6034. + }
  6035. +
  6036. +private:
  6037. + uint32 const _criteriaId;
  6038. +};
  6039. +
  6040. +void AddSC_boss_grand_champions()
  6041. +{
  6042. + new generic_vehicleAI_toc5();
  6043. + new boss_warrior_toc5();
  6044. + new boss_mage_toc5();
  6045. + new boss_shaman_toc5();
  6046. + new boss_hunter_toc5();
  6047. + new boss_rogue_toc5();
  6048. + new spell_toc5_trample_aura();
  6049. + new spell_toc5_lightning_arrows();
  6050. + new achievement_victories_over_champion("achievement_victories_over_war_champion", CRITERIA_WARRIOR);
  6051. + new achievement_victories_over_champion("achievement_victories_over_hun_champion", CRITERIA_HUNTER);
  6052. + new achievement_victories_over_champion("achievement_victories_over_mag_champion", CRITERIA_MAGE);
  6053. + new achievement_victories_over_champion("achievement_victories_over_rog_champion", CRITERIA_ROGUE);
  6054. + new achievement_victories_over_champion("achievement_victories_over_sha_champion", CRITERIA_SHAMAN);
  6055. + new achievement_victories_over_champion("achievement_victories_over_war_champion_h", CRITERIA_WARRIOR_H);
  6056. + new achievement_victories_over_champion("achievement_victories_over_hun_champion_h", CRITERIA_HUNTER_H);
  6057. + new achievement_victories_over_champion("achievement_victories_over_mag_champion_h", CRITERIA_MAGE_H);
  6058. + new achievement_victories_over_champion("achievement_victories_over_rog_champion_h", CRITERIA_ROGUE_H);
  6059. + new achievement_victories_over_champion("achievement_victories_over_sha_champion_h", CRITERIA_SHAMAN_H);
  6060. +}
  6061. diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
  6062. dissimilarity index 75%
  6063. index 8a19f8d8d1..e0424e42ba 100644
  6064. --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
  6065. +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
  6066. @@ -1,293 +1,389 @@
  6067. -/*
  6068. - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
  6069. - *
  6070. - * This program is free software; you can redistribute it and/or modify it
  6071. - * under the terms of the GNU General Public License as published by the
  6072. - * Free Software Foundation; either version 2 of the License, or (at your
  6073. - * option) any later version.
  6074. - *
  6075. - * This program is distributed in the hope that it will be useful, but WITHOUT
  6076. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  6077. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  6078. - * more details.
  6079. - *
  6080. - * You should have received a copy of the GNU General Public License along
  6081. - * with this program. If not, see <http://www.gnu.org/licenses/>.
  6082. - */
  6083. -
  6084. -/* ScriptData
  6085. -SDName: Instance Trial of the Champion
  6086. -SDComment:
  6087. -SDCategory: Trial Of the Champion
  6088. -EndScriptData */
  6089. -
  6090. -#include "ScriptMgr.h"
  6091. -#include "Creature.h"
  6092. -#include "CreatureAI.h"
  6093. -#include "GameObject.h"
  6094. -#include "InstanceScript.h"
  6095. -#include "Log.h"
  6096. -#include "Map.h"
  6097. -#include "MotionMaster.h"
  6098. -#include "Player.h"
  6099. -#include "trial_of_the_champion.h"
  6100. -
  6101. -constexpr uint32 ToCEncounterCount = 4;
  6102. -
  6103. -class instance_trial_of_the_champion : public InstanceMapScript
  6104. -{
  6105. -public:
  6106. - instance_trial_of_the_champion() : InstanceMapScript(ToCScriptName, 650) { }
  6107. -
  6108. - InstanceScript* GetInstanceScript(InstanceMap* map) const override
  6109. - {
  6110. - return new instance_trial_of_the_champion_InstanceMapScript(map);
  6111. - }
  6112. -
  6113. - struct instance_trial_of_the_champion_InstanceMapScript : public InstanceScript
  6114. - {
  6115. - instance_trial_of_the_champion_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
  6116. - {
  6117. - SetHeaders(DataHeader);
  6118. - SetBossNumber(ToCEncounterCount);
  6119. - uiMovementDone = 0;
  6120. - uiGrandChampionsDeaths = 0;
  6121. - uiArgentSoldierDeaths = 0;
  6122. - teamInInstance = 0;
  6123. -
  6124. - bDone = false;
  6125. - }
  6126. -
  6127. - uint32 teamInInstance;
  6128. - uint16 uiMovementDone;
  6129. - uint16 uiGrandChampionsDeaths;
  6130. - uint8 uiArgentSoldierDeaths;
  6131. -
  6132. - ObjectGuid uiAnnouncerGUID;
  6133. - ObjectGuid uiMainGateGUID;
  6134. - ObjectGuid uiGrandChampionVehicle1GUID;
  6135. - ObjectGuid uiGrandChampionVehicle2GUID;
  6136. - ObjectGuid uiGrandChampionVehicle3GUID;
  6137. - ObjectGuid uiGrandChampion1GUID;
  6138. - ObjectGuid uiGrandChampion2GUID;
  6139. - ObjectGuid uiGrandChampion3GUID;
  6140. - ObjectGuid uiChampionLootGUID;
  6141. - ObjectGuid uiArgentChampionGUID;
  6142. -
  6143. - GuidList VehicleList;
  6144. -
  6145. - bool bDone;
  6146. -
  6147. - void OnPlayerEnter(Player* player) override
  6148. - {
  6149. - if (!teamInInstance)
  6150. - teamInInstance = player->GetTeam();
  6151. - }
  6152. -
  6153. - void OnCreatureCreate(Creature* creature) override
  6154. - {
  6155. - switch (creature->GetEntry())
  6156. - {
  6157. - case VEHICLE_ARGENT_WARHORSE:
  6158. - case VEHICLE_ARGENT_BATTLEWORG:
  6159. - VehicleList.push_back(creature->GetGUID());
  6160. - break;
  6161. - case NPC_EADRIC:
  6162. - case NPC_PALETRESS:
  6163. - uiArgentChampionGUID = creature->GetGUID();
  6164. - break;
  6165. - case NPC_JAEREN:
  6166. - case NPC_ARELAS:
  6167. - uiAnnouncerGUID = creature->GetGUID();
  6168. - break;
  6169. - default:
  6170. - break;
  6171. - }
  6172. - }
  6173. -
  6174. - uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) override
  6175. - {
  6176. - if (!teamInInstance)
  6177. - {
  6178. - Map::PlayerList const& players = instance->GetPlayers();
  6179. - if (!players.isEmpty())
  6180. - if (Player* player = players.begin()->GetSource())
  6181. - teamInInstance = player->GetTeam();
  6182. - }
  6183. -
  6184. - uint32 entry = data->id;
  6185. - switch (entry)
  6186. - {
  6187. - case VEHICLE_MOKRA_SKILLCRUSHER_MOUNT:
  6188. - return teamInInstance == HORDE ? VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT : VEHICLE_MOKRA_SKILLCRUSHER_MOUNT;
  6189. - case VEHICLE_ERESSEA_DAWNSINGER_MOUNT:
  6190. - return teamInInstance == HORDE ? VEHICLE_AMBROSE_BOLTSPARK_MOUNT : VEHICLE_ERESSEA_DAWNSINGER_MOUNT;
  6191. - case VEHICLE_RUNOK_WILDMANE_MOUNT:
  6192. - return teamInInstance == HORDE ? VEHICLE_COLOSOS_MOUNT : VEHICLE_RUNOK_WILDMANE_MOUNT;
  6193. - case VEHICLE_ZUL_TORE_MOUNT:
  6194. - return teamInInstance == HORDE ? VEHICLE_EVENSONG_MOUNT : VEHICLE_ZUL_TORE_MOUNT;
  6195. - case VEHICLE_DEATHSTALKER_VESCERI_MOUNT:
  6196. - return teamInInstance == HORDE ? VEHICLE_LANA_STOUTHAMMER_MOUNT : VEHICLE_DEATHSTALKER_VESCERI_MOUNT;
  6197. - case NPC_JAEREN:
  6198. - return teamInInstance == HORDE ? NPC_ARELAS : NPC_JAEREN;
  6199. - default:
  6200. - return entry;
  6201. - }
  6202. - }
  6203. -
  6204. - void OnGameObjectCreate(GameObject* go) override
  6205. - {
  6206. - switch (go->GetEntry())
  6207. - {
  6208. - case GO_MAIN_GATE:
  6209. - uiMainGateGUID = go->GetGUID();
  6210. - break;
  6211. - case GO_CHAMPIONS_LOOT:
  6212. - case GO_CHAMPIONS_LOOT_H:
  6213. - uiChampionLootGUID = go->GetGUID();
  6214. - break;
  6215. - }
  6216. - }
  6217. -
  6218. - bool SetBossState(uint32 id, EncounterState state) override
  6219. - {
  6220. - if (!InstanceScript::SetBossState(id, state))
  6221. - return false;
  6222. -
  6223. - switch (id)
  6224. - {
  6225. - case BOSS_GRAND_CHAMPIONS:
  6226. - if (state == IN_PROGRESS)
  6227. - {
  6228. - for (ObjectGuid guid : VehicleList)
  6229. - if (Creature* summon = instance->GetCreature(guid))
  6230. - summon->RemoveFromWorld();
  6231. - }
  6232. - else if (state == DONE)
  6233. - {
  6234. - ++uiGrandChampionsDeaths;
  6235. - if (uiGrandChampionsDeaths == 3)
  6236. - {
  6237. - if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
  6238. - {
  6239. - pAnnouncer->GetMotionMaster()->MovePoint(0, 748.309f, 619.487f, 411.171f);
  6240. - pAnnouncer->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  6241. - pAnnouncer->SummonGameObject(instance->IsHeroic() ? GO_CHAMPIONS_LOOT_H : GO_CHAMPIONS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, QuaternionData(), 25h);
  6242. - }
  6243. - }
  6244. - }
  6245. - break;
  6246. - case BOSS_ARGENT_CHALLENGE_E:
  6247. - if (state == DONE)
  6248. - {
  6249. - if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
  6250. - {
  6251. - pAnnouncer->GetMotionMaster()->MovePoint(0, 748.309f, 619.487f, 411.171f);
  6252. - pAnnouncer->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  6253. - pAnnouncer->SummonGameObject(instance->IsHeroic() ? GO_EADRIC_LOOT_H : GO_EADRIC_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, QuaternionData(), 25h);
  6254. - }
  6255. - }
  6256. - break;
  6257. - case BOSS_ARGENT_CHALLENGE_P:
  6258. - if (state == DONE)
  6259. - {
  6260. - if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
  6261. - {
  6262. - pAnnouncer->GetMotionMaster()->MovePoint(0, 748.309f, 619.487f, 411.171f);
  6263. - pAnnouncer->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  6264. - pAnnouncer->SummonGameObject(instance->IsHeroic() ? GO_PALETRESS_LOOT_H : GO_PALETRESS_LOOT, 746.59f, 618.49f, 411.09f, 1.42f, QuaternionData(), 25h);
  6265. - }
  6266. - }
  6267. - break;
  6268. - }
  6269. - return true;
  6270. - }
  6271. -
  6272. - void SetData(uint32 uiType, uint32 uiData) override
  6273. - {
  6274. - switch (uiType)
  6275. - {
  6276. - case DATA_MOVEMENT_DONE:
  6277. - uiMovementDone = uiData;
  6278. - if (uiMovementDone == 3)
  6279. - {
  6280. - if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
  6281. - pAnnouncer->AI()->SetData(DATA_IN_POSITION, 0);
  6282. - }
  6283. - break;
  6284. - case DATA_ARGENT_SOLDIER_DEFEATED:
  6285. - uiArgentSoldierDeaths = uiData;
  6286. - if (uiArgentSoldierDeaths == 9)
  6287. - {
  6288. - if (Creature* pBoss = instance->GetCreature(uiArgentChampionGUID))
  6289. - {
  6290. - pBoss->GetMotionMaster()->MovePoint(0, 746.88f, 618.74f, 411.06f);
  6291. - pBoss->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  6292. - pBoss->SetReactState(REACT_AGGRESSIVE);
  6293. - }
  6294. - }
  6295. - break;
  6296. - }
  6297. -
  6298. - if (uiData == DONE)
  6299. - SaveToDB();
  6300. - }
  6301. -
  6302. - uint32 GetData(uint32 uiData) const override
  6303. - {
  6304. - switch (uiData)
  6305. - {
  6306. - case DATA_MOVEMENT_DONE: return uiMovementDone;
  6307. - case DATA_ARGENT_SOLDIER_DEFEATED: return uiArgentSoldierDeaths;
  6308. - }
  6309. -
  6310. - return 0;
  6311. - }
  6312. -
  6313. - ObjectGuid GetGuidData(uint32 uiData) const override
  6314. - {
  6315. - switch (uiData)
  6316. - {
  6317. - case DATA_ANNOUNCER: return uiAnnouncerGUID;
  6318. - case DATA_MAIN_GATE: return uiMainGateGUID;
  6319. -
  6320. - case DATA_GRAND_CHAMPION_1: return uiGrandChampion1GUID;
  6321. - case DATA_GRAND_CHAMPION_2: return uiGrandChampion2GUID;
  6322. - case DATA_GRAND_CHAMPION_3: return uiGrandChampion3GUID;
  6323. - }
  6324. -
  6325. - return ObjectGuid::Empty;
  6326. - }
  6327. -
  6328. - void SetGuidData(uint32 uiType, ObjectGuid uiData) override
  6329. - {
  6330. - switch (uiType)
  6331. - {
  6332. - case DATA_GRAND_CHAMPION_1:
  6333. - uiGrandChampion1GUID = uiData;
  6334. - break;
  6335. - case DATA_GRAND_CHAMPION_2:
  6336. - uiGrandChampion2GUID = uiData;
  6337. - break;
  6338. - case DATA_GRAND_CHAMPION_3:
  6339. - uiGrandChampion3GUID = uiData;
  6340. - break;
  6341. - }
  6342. - }
  6343. -
  6344. - void WriteSaveDataMore(std::ostringstream& stream) override
  6345. - {
  6346. - stream << uiGrandChampionsDeaths << ' ' << uiMovementDone;
  6347. - }
  6348. -
  6349. - void ReadSaveDataMore(std::istringstream& stream) override
  6350. - {
  6351. - stream >> uiGrandChampionsDeaths >> uiMovementDone;
  6352. - }
  6353. - };
  6354. -};
  6355. -
  6356. -void AddSC_instance_trial_of_the_champion()
  6357. -{
  6358. - new instance_trial_of_the_champion();
  6359. -}
  6360. +/*
  6361. + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  6362. + *
  6363. + * This program is free software; you can redistribute it and/or modify it
  6364. + * under the terms of the GNU General Public License as published by the
  6365. + * Free Software Foundation; either version 2 of the License, or (at your
  6366. + * option) any later version.
  6367. + *
  6368. + * This program is distributed in the hope that it will be useful, but WITHOUT
  6369. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  6370. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  6371. + * more details.
  6372. + *
  6373. + * You should have received a copy of the GNU General Public License along
  6374. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  6375. + */
  6376. +
  6377. + /* ScriptData
  6378. + SDName: Instance Trial of the Champion
  6379. + SDComment: missing fireworks when boss encounter is set to done
  6380. + SDCategory: Trial Of the Champion
  6381. + EndScriptData */
  6382. +
  6383. +#include "GameObject.h"
  6384. +#include "InstanceScript.h"
  6385. +#include "Player.h"
  6386. +#include "ScriptedCreature.h"
  6387. +#include "ScriptMgr.h"
  6388. +#include "trial_of_the_champion.h"
  6389. +
  6390. +ObjectData const creatureData[] =
  6391. +{
  6392. + { NPC_ARELAS, DATA_ANNOUNCER },
  6393. + { NPC_JAEREN, DATA_ANNOUNCER },
  6394. + { NPC_TIRION, DATA_TIRION },
  6395. + { NPC_VARIAN, DATA_VARIAN },
  6396. + { NPC_JAINA, DATA_JAINA },
  6397. + { NPC_GARROSH, DATA_GARROSH },
  6398. + { NPC_THRALL, DATA_THRALL },
  6399. + { NPC_BLACK_KNIGHT, DATA_BLACK_KNIGHT },
  6400. + { 0, 0 } // END
  6401. +};
  6402. +
  6403. +ObjectData const gameObjectData[] =
  6404. +{
  6405. + { GO_MAIN_GATE, DATA_MAIN_GATE },
  6406. + { GO_CHAMPION_S_CACHE, DATA_CHAMPION_S_CACHE },
  6407. + { GO_CHAMPION_S_CACHE_H, DATA_CHAMPION_S_CACHE },
  6408. + { GO_EADRIC_S_CACHE, DATA_EADRIC_S_CACHE },
  6409. + { GO_EADRIC_S_CACHE_H, DATA_EADRIC_S_CACHE },
  6410. + { GO_CONFESSOR_S_CACHE, DATA_CONFESSOR_S_CACHE },
  6411. + { GO_CONFESSOR_S_CACHE_H, DATA_CONFESSOR_S_CACHE },
  6412. + { 0, 0 } // END
  6413. +};
  6414. +
  6415. +DoorData const doorData[] =
  6416. +{
  6417. + { GO_NORTH_PORTCULLIS, DATA_GRAND_CHAMPIONS, DOOR_TYPE_ROOM },
  6418. + { GO_NORTH_PORTCULLIS, DATA_ARGENT_CHALLENGE, DOOR_TYPE_ROOM },
  6419. + { GO_NORTH_PORTCULLIS, DATA_BLACK_KNIGHT, DOOR_TYPE_ROOM },
  6420. + { 0, 0, DOOR_TYPE_ROOM } // END
  6421. +};
  6422. +
  6423. +uint8 const GrandChampionsCount = 3;
  6424. +
  6425. +class instance_trial_of_the_champion : public InstanceMapScript
  6426. +{
  6427. +public:
  6428. + instance_trial_of_the_champion() : InstanceMapScript(ToCScriptName, 650) {}
  6429. +
  6430. + struct instance_trial_of_the_champion_InstanceMapScript : public InstanceScript
  6431. + {
  6432. + // CORRECCIÓN 1: Cambiar Map* por InstanceMap*
  6433. + instance_trial_of_the_champion_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
  6434. + {
  6435. + SetHeaders(DataHeader);
  6436. + SetBossNumber(MAX_ENCOUNTER);
  6437. + LoadObjectData(creatureData, gameObjectData);
  6438. + LoadDoorData(doorData);
  6439. +
  6440. + _teamInInstance = 0;
  6441. + _argentSoldierDeaths = 0;
  6442. + }
  6443. +
  6444. + uint32 GetCreatureEntry(uint32 /*guidLow*/, CreatureData const* data) override
  6445. + {
  6446. + uint32 entry = data->id;
  6447. + switch (entry)
  6448. + {
  6449. + case NPC_JAEREN:
  6450. + if (_teamInInstance == ALLIANCE)
  6451. + return NPC_ARELAS;
  6452. + break;
  6453. + case VEHICLE_ARGENT_WARHORSE_COSMETIC:
  6454. + if (_teamInInstance == ALLIANCE)
  6455. + return VEHICLE_ARGENT_WARHORSE_A;
  6456. + break;
  6457. + case VEHICLE_ARGENT_BATTLEWORG_H:
  6458. + if (_teamInInstance == ALLIANCE)
  6459. + return VEHICLE_ARGENT_BATTLEWORG_COSMETIC;
  6460. + break;
  6461. + default:
  6462. + break;
  6463. + }
  6464. +
  6465. + return entry;
  6466. + }
  6467. +
  6468. + void OnCreatureCreate(Creature* creature) override
  6469. + {
  6470. + if (!_teamInInstance)
  6471. + {
  6472. + Map::PlayerList const& players = instance->GetPlayers();
  6473. + if (!players.isEmpty())
  6474. + if (Player* player = players.begin()->GetSource())
  6475. + _teamInInstance = player->GetTeam();
  6476. + }
  6477. +
  6478. + switch (creature->GetEntry())
  6479. + {
  6480. + case NPC_MOKRA:
  6481. + case NPC_ERESSEA:
  6482. + case NPC_RUNOK:
  6483. + case NPC_ZULTORE:
  6484. + case NPC_VISCERI:
  6485. + case NPC_JACOB:
  6486. + case NPC_AMBROSE:
  6487. + case NPC_COLOSOS:
  6488. + case NPC_JAELYNE:
  6489. + case NPC_LANA:
  6490. + SetGrandChampionData(creature);
  6491. + break;
  6492. + case VEHICLE_ARGENT_WARHORSE_COSMETIC:
  6493. + case VEHICLE_ARGENT_WARHORSE_A:
  6494. + case VEHICLE_ARGENT_BATTLEWORG_COSMETIC:
  6495. + case VEHICLE_ARGENT_BATTLEWORG_H:
  6496. + _vehicles.push_back(creature->GetGUID());
  6497. + break;
  6498. +
  6499. + case NPC_EADRIC:
  6500. + case NPC_PALETRESS:
  6501. + _argentChampionGUID = creature->GetGUID();
  6502. + break;
  6503. + case VEHICLE_BLACK_KNIGHT:
  6504. + _blackKnightVehicleGUID = creature->GetGUID();
  6505. + break;
  6506. + // Setting passive and unattackable flags to Lesser Champions and Grand Champions' vehicles
  6507. + case NPC_DARNASSUS_CHAMPION:
  6508. + case NPC_EXODAR_CHAMPION:
  6509. + case NPC_STORMWIND_CHAMPION:
  6510. + case NPC_GNOMEREGAN_CHAMPION:
  6511. + case NPC_IRONFORGE_CHAMPION:
  6512. + case NPC_UNDERCITY_CHAMPION:
  6513. + case NPC_THUNDER_BLUFF_CHAMPION:
  6514. + case NPC_ORGRIMMAR_CHAMPION:
  6515. + case NPC_SILVERMOON_CHAMPION:
  6516. + case NPC_SEN_JIN_CHAMPION:
  6517. + case VEHICLE_AMBROSE_BOLTSPARK_MOUNT:
  6518. + case VEHICLE_COLOSOS_MOUNT:
  6519. + case VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT:
  6520. + case VEHICLE_MOKRA_SKULLCRUSHER_MOUNT:
  6521. + case VEHICLE_ERESSEA_DAWNSINGER_MOUNT:
  6522. + case VEHICLE_RUNOK_WILDMANE_MOUNT:
  6523. + case VEHICLE_ZUL_TORE_MOUNT:
  6524. + case VEHICLE_EVENSONG_MOUNT:
  6525. + case VEHICLE_DEATHSTALKER_VESCERI_MOUNT:
  6526. + case VEHICLE_LANA_STOUTHAMMER_MOUNT:
  6527. + creature->SetReactState(REACT_PASSIVE);
  6528. + creature->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // CORRECCIÓN: Usar SetUnitFlag en lugar de SetFlag
  6529. + break;
  6530. + default:
  6531. + break;
  6532. + }
  6533. +
  6534. + InstanceScript::OnCreatureCreate(creature);
  6535. + }
  6536. +
  6537. + void SetGrandChampionData(Creature* creature)
  6538. + {
  6539. + for (uint8 i = 0; i < GrandChampionsCount; ++i)
  6540. + {
  6541. + if (!_grandChampionGUIDs[i])
  6542. + {
  6543. + _grandChampionGUIDs[i] = creature->GetGUID();
  6544. + break;
  6545. + }
  6546. + }
  6547. + }
  6548. +
  6549. + bool SetBossState(uint32 id, EncounterState state) override
  6550. + {
  6551. + if (!InstanceScript::SetBossState(id, state))
  6552. + return false;
  6553. +
  6554. + switch (id)
  6555. + {
  6556. + case DATA_GRAND_CHAMPIONS:
  6557. + if (state == DONE)
  6558. + {
  6559. + if (Creature* announcer = GetCreature(DATA_ANNOUNCER))
  6560. + {
  6561. + // On heroic mode we must bind players to the instance
  6562. + if (instance->IsHeroic())
  6563. + instance->ToInstanceMap()->PermBindAllPlayers();
  6564. +
  6565. + announcer->GetMotionMaster()->MovePoint(1, announcerWaitPos);
  6566. + announcer->AI()->SetData(DATA_GRAND_CHAMPIONS_DONE, 0);
  6567. +
  6568. + // CORRECCIÓN 2: Usar Seconds con sufijo 's'
  6569. + DoRespawnGameObject(GetObjectGuid(DATA_CHAMPION_S_CACHE), Seconds(1 * DAY));
  6570. + if (GameObject* cache = GetGameObject(DATA_CHAMPION_S_CACHE))
  6571. + cache->RemoveFlag(GO_FLAG_NOT_SELECTABLE); // CORRECCIÓN 3: Solo el flag
  6572. + }
  6573. + }
  6574. + break;
  6575. + case DATA_ARGENT_CHALLENGE:
  6576. + if (state == SPECIAL)
  6577. + {
  6578. + if (Creature* champion = instance->GetCreature(_argentChampionGUID))
  6579. + {
  6580. + champion->InterruptNonMeleeSpells(true);
  6581. + champion->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); // CORRECCIÓN
  6582. + champion->SetReactState(REACT_PASSIVE);
  6583. + champion->SetHealth(1);
  6584. + champion->CombatStop(true);
  6585. + champion->SetRegenerateHealth(false);
  6586. + champion->SetEmoteState(EMOTE_ONESHOT_NONE); // CORRECCIÓN: Usar SetEmoteState
  6587. + champion->SetHomePosition(745.87f, 625.88f, 411.17f, champion->GetHomePosition().GetOrientation());
  6588. + champion->GetMotionMaster()->MoveTargetedHome();
  6589. + }
  6590. + }
  6591. + else if (state == DONE)
  6592. + {
  6593. + if (Creature* announcer = GetCreature(DATA_ANNOUNCER))
  6594. + {
  6595. + // On heroic mode we must bind players to the instance
  6596. + if (instance->IsHeroic())
  6597. + instance->ToInstanceMap()->PermBindAllPlayers();
  6598. +
  6599. + announcer->GetMotionMaster()->MovePoint(1, announcerWaitPos);
  6600. +
  6601. + uint32 dataType;
  6602. + switch (_argentChampionGUID.GetEntry())
  6603. + {
  6604. + case NPC_EADRIC:
  6605. + dataType = DATA_EADRIC_S_CACHE;
  6606. + break;
  6607. + case NPC_PALETRESS:
  6608. + dataType = DATA_CONFESSOR_S_CACHE;
  6609. + break;
  6610. + default:
  6611. + ABORT();
  6612. + break;
  6613. + }
  6614. +
  6615. + // CORRECCIÓN 4: Usar Seconds con sufijo 's'
  6616. + DoRespawnGameObject(GetObjectGuid(dataType), Seconds(1 * DAY));
  6617. + if (GameObject* cache = GetGameObject(dataType))
  6618. + cache->RemoveFlag(GO_FLAG_NOT_SELECTABLE); // CORRECCIÓN 5: Solo el flag
  6619. + }
  6620. + }
  6621. + break;
  6622. + case DATA_BLACK_KNIGHT:
  6623. + if (state == DONE)
  6624. + {
  6625. + if (Creature* announcer = GetCreature(DATA_ANNOUNCER))
  6626. + announcer->AI()->SetData(DATA_BLACK_KNIGHT_DONE, 0);
  6627. + }
  6628. + break;
  6629. + default:
  6630. + break;
  6631. + }
  6632. + return true;
  6633. + }
  6634. +
  6635. + void SetData(uint32 type, uint32 data) override
  6636. + {
  6637. + switch (type)
  6638. + {
  6639. + case DATA_REMOVE_VEHICLES:
  6640. + {
  6641. + for (ObjectGuid const& guid : _vehicles)
  6642. + if (Creature* vehicle = instance->GetCreature(guid))
  6643. + vehicle->DespawnOrUnsummon();
  6644. +
  6645. + // We must remove defense spells from players
  6646. + Map::PlayerList const& players = instance->GetPlayers();
  6647. + for (auto itr = players.begin(); itr != players.end(); ++itr)
  6648. + {
  6649. + Player* plr = itr->GetSource();
  6650. + plr->RemoveAurasDueToSpell(62552); // Actual defense spell
  6651. + plr->RemoveAurasDueToSpell(63130); // Shield Level 1 (visual only)
  6652. + plr->RemoveAurasDueToSpell(63131); // Shield Level 2 (visual only)
  6653. + plr->RemoveAurasDueToSpell(63132); // Shield Level 3 (visual only)
  6654. + }
  6655. + break;
  6656. + }
  6657. + case DATA_ARGENT_SOLDIER_DEFEATED:
  6658. + _argentSoldierDeaths = data;
  6659. + if (_argentSoldierDeaths == 9)
  6660. + {
  6661. + if (Creature* boss = instance->GetCreature(_argentChampionGUID))
  6662. + {
  6663. + boss->SetFaction(FACTION_MONSTER_2);
  6664. + boss->SetHomePosition(747.02f, 637.65f, 411.57f, centerOrientation);
  6665. + boss->GetMotionMaster()->MovePoint(1, boss->GetHomePosition());
  6666. + }
  6667. + }
  6668. + break;
  6669. + default:
  6670. + break;
  6671. + }
  6672. + }
  6673. +
  6674. + uint32 GetData(uint32 type) const override
  6675. + {
  6676. + switch (type)
  6677. + {
  6678. + case DATA_TEAM_IN_INSTANCE:
  6679. + return _teamInInstance;
  6680. + case DATA_ARGENT_SOLDIER_DEFEATED:
  6681. + return _argentSoldierDeaths;
  6682. + default:
  6683. + break;
  6684. + }
  6685. +
  6686. + return 0;
  6687. + }
  6688. +
  6689. + ObjectGuid GetGuidData(uint32 type) const override
  6690. + {
  6691. + switch (type)
  6692. + {
  6693. + case DATA_GRAND_CHAMPION_1:
  6694. + case DATA_GRAND_CHAMPION_2:
  6695. + case DATA_GRAND_CHAMPION_3:
  6696. + return _grandChampionGUIDs[type - DATA_GRAND_CHAMPION_1];
  6697. + case DATA_GRAND_CHAMPION_VEHICLE_1:
  6698. + case DATA_GRAND_CHAMPION_VEHICLE_2:
  6699. + case DATA_GRAND_CHAMPION_VEHICLE_3:
  6700. + return _grandChampionVehicleGUIDs[type - DATA_GRAND_CHAMPION_VEHICLE_1];
  6701. + case DATA_ARGENT_CHAMPION:
  6702. + return _argentChampionGUID;
  6703. + case DATA_BLACK_KNIGHT_VEHICLE:
  6704. + return _blackKnightVehicleGUID;
  6705. + default:
  6706. + break;
  6707. + }
  6708. +
  6709. + return InstanceScript::GetGuidData(type);
  6710. + }
  6711. +
  6712. + void SetGuidData(uint32 type, ObjectGuid data) override
  6713. + {
  6714. + switch (type)
  6715. + {
  6716. + case DATA_GRAND_CHAMPION_VEHICLE_1:
  6717. + case DATA_GRAND_CHAMPION_VEHICLE_2:
  6718. + case DATA_GRAND_CHAMPION_VEHICLE_3:
  6719. + _grandChampionVehicleGUIDs[type - DATA_GRAND_CHAMPION_VEHICLE_1] = data;
  6720. + break;
  6721. + default:
  6722. + break;
  6723. + }
  6724. + }
  6725. +
  6726. + private:
  6727. + ObjectGuid _grandChampionVehicleGUIDs[GrandChampionsCount];
  6728. + ObjectGuid _grandChampionGUIDs[GrandChampionsCount];
  6729. +
  6730. + ObjectGuid _argentChampionGUID;
  6731. + ObjectGuid _blackKnightVehicleGUID;
  6732. +
  6733. + GuidVector _vehicles;
  6734. +
  6735. + uint32 _teamInInstance;
  6736. + uint8 _argentSoldierDeaths;
  6737. + };
  6738. +
  6739. + InstanceScript* GetInstanceScript(InstanceMap* map) const override
  6740. + {
  6741. + return new instance_trial_of_the_champion_InstanceMapScript(map);
  6742. + }
  6743. +};
  6744. +
  6745. +void AddSC_instance_trial_of_the_champion()
  6746. +{
  6747. + new instance_trial_of_the_champion();
  6748. +}
  6749. diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
  6750. dissimilarity index 66%
  6751. index e3c4e1e6c6..f909cb9ef4 100644
  6752. --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
  6753. +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
  6754. @@ -1,507 +1,1374 @@
  6755. -/*
  6756. - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
  6757. - *
  6758. - * This program is free software; you can redistribute it and/or modify it
  6759. - * under the terms of the GNU General Public License as published by the
  6760. - * Free Software Foundation; either version 2 of the License, or (at your
  6761. - * option) any later version.
  6762. - *
  6763. - * This program is distributed in the hope that it will be useful, but WITHOUT
  6764. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  6765. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  6766. - * more details.
  6767. - *
  6768. - * You should have received a copy of the GNU General Public License along
  6769. - * with this program. If not, see <http://www.gnu.org/licenses/>.
  6770. - */
  6771. -
  6772. -/* ScriptData
  6773. -SDName: Trial Of the Champion
  6774. -SD%Complete:
  6775. -SDComment:
  6776. -SDCategory: trial_of_the_champion
  6777. -EndScriptData */
  6778. -
  6779. -/* ContentData
  6780. -npc_announcer_toc5
  6781. -EndContentData */
  6782. -
  6783. -#include "ScriptMgr.h"
  6784. -#include "GameObject.h"
  6785. -#include "InstanceScript.h"
  6786. -#include "Map.h"
  6787. -#include "MotionMaster.h"
  6788. -#include "ObjectAccessor.h"
  6789. -#include "Player.h"
  6790. -#include "ScriptedCreature.h"
  6791. -#include "ScriptedGossip.h"
  6792. -#include "TemporarySummon.h"
  6793. -#include "trial_of_the_champion.h"
  6794. -#include "Vehicle.h"
  6795. -
  6796. -enum Yells
  6797. -{
  6798. - SAY_INTRO_1 = 0,
  6799. - SAY_INTRO_2 = 1,
  6800. - SAY_INTRO_3 = 2,
  6801. - SAY_AGGRO = 3,
  6802. - SAY_PHASE_2 = 4,
  6803. - SAY_PHASE_3 = 5,
  6804. - SAY_KILL_PLAYER = 6,
  6805. - SAY_DEATH = 7
  6806. -};
  6807. -
  6808. -enum Gossip
  6809. -{
  6810. - GOSSIP_START_EVENT1_MID = 10614, // I'm ready to start challenge.
  6811. - GOSSIP_START_EVENT1_OID = 0,
  6812. - GOSSIP_START_EVENT2_MID = 10614, // I'm ready for the next challenge.
  6813. - GOSSIP_START_EVENT2_OID = 1
  6814. -};
  6815. -
  6816. -#define ORIENTATION 4.714f
  6817. -
  6818. -/*######
  6819. -## npc_announcer_toc5
  6820. -######*/
  6821. -
  6822. -const Position SpawnPosition = {746.261f, 657.401f, 411.681f, 4.65f};
  6823. -
  6824. -class npc_announcer_toc5 : public CreatureScript
  6825. -{
  6826. -public:
  6827. - npc_announcer_toc5() : CreatureScript("npc_announcer_toc5") { }
  6828. -
  6829. - struct npc_announcer_toc5AI : public ScriptedAI
  6830. - {
  6831. - npc_announcer_toc5AI(Creature* creature) : ScriptedAI(creature)
  6832. - {
  6833. - instance = creature->GetInstanceScript();
  6834. -
  6835. - uiSummonTimes = 0;
  6836. - uiPosition = 0;
  6837. - uiLesserChampions = 0;
  6838. -
  6839. - uiFirstBoss = 0;
  6840. - uiSecondBoss = 0;
  6841. - uiThirdBoss = 0;
  6842. -
  6843. - uiArgentChampion = 0;
  6844. -
  6845. - uiPhase = 0;
  6846. - uiTimer = 0;
  6847. -
  6848. - me->SetReactState(REACT_PASSIVE);
  6849. - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  6850. - me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  6851. -
  6852. - SetGrandChampionsForEncounter();
  6853. - SetArgentChampion();
  6854. - }
  6855. -
  6856. - InstanceScript* instance;
  6857. -
  6858. - uint8 uiSummonTimes;
  6859. - uint8 uiPosition;
  6860. - uint8 uiLesserChampions;
  6861. -
  6862. - uint32 uiArgentChampion;
  6863. -
  6864. - uint32 uiFirstBoss;
  6865. - uint32 uiSecondBoss;
  6866. - uint32 uiThirdBoss;
  6867. -
  6868. - uint32 uiPhase;
  6869. - uint32 uiTimer;
  6870. -
  6871. - ObjectGuid uiVehicle1GUID;
  6872. - ObjectGuid uiVehicle2GUID;
  6873. - ObjectGuid uiVehicle3GUID;
  6874. -
  6875. - GuidList Champion1List;
  6876. - GuidList Champion2List;
  6877. - GuidList Champion3List;
  6878. -
  6879. - void NextStep(uint32 uiTimerStep, bool bNextStep = true, uint8 uiPhaseStep = 0)
  6880. - {
  6881. - uiTimer = uiTimerStep;
  6882. - if (bNextStep)
  6883. - ++uiPhase;
  6884. - else
  6885. - uiPhase = uiPhaseStep;
  6886. - }
  6887. -
  6888. - void SetData(uint32 uiType, uint32 /*uiData*/) override
  6889. - {
  6890. - switch (uiType)
  6891. - {
  6892. - case DATA_START:
  6893. - DoSummonGrandChampion(uiFirstBoss);
  6894. - NextStep(10000, false, 1);
  6895. - break;
  6896. - case DATA_IN_POSITION: //movement done.
  6897. - me->GetMotionMaster()->MovePoint(1, 735.81f, 661.92f, 412.39f);
  6898. - if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_MAIN_GATE)))
  6899. - instance->HandleGameObject(go->GetGUID(), false);
  6900. - NextStep(10000, false, 3);
  6901. - break;
  6902. - case DATA_LESSER_CHAMPIONS_DEFEATED:
  6903. - {
  6904. - ++uiLesserChampions;
  6905. - GuidList TempList;
  6906. - if (uiLesserChampions == 3 || uiLesserChampions == 6)
  6907. - {
  6908. - switch (uiLesserChampions)
  6909. - {
  6910. - case 3:
  6911. - TempList = Champion2List;
  6912. - break;
  6913. - case 6:
  6914. - TempList = Champion3List;
  6915. - break;
  6916. - }
  6917. -
  6918. - for (GuidList::const_iterator itr = TempList.begin(); itr != TempList.end(); ++itr)
  6919. - if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
  6920. - AggroAllPlayers(summon);
  6921. - }else if (uiLesserChampions == 9)
  6922. - StartGrandChampionsAttack();
  6923. -
  6924. - break;
  6925. - }
  6926. - }
  6927. - }
  6928. -
  6929. - void StartGrandChampionsAttack()
  6930. - {
  6931. - Creature* pGrandChampion1 = ObjectAccessor::GetCreature(*me, uiVehicle1GUID);
  6932. - Creature* pGrandChampion2 = ObjectAccessor::GetCreature(*me, uiVehicle2GUID);
  6933. - Creature* pGrandChampion3 = ObjectAccessor::GetCreature(*me, uiVehicle3GUID);
  6934. -
  6935. - if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
  6936. - {
  6937. - AggroAllPlayers(pGrandChampion1);
  6938. - AggroAllPlayers(pGrandChampion2);
  6939. - AggroAllPlayers(pGrandChampion3);
  6940. - }
  6941. - }
  6942. -
  6943. - void MovementInform(uint32 uiType, uint32 uiPointId) override
  6944. - {
  6945. - if (uiType != POINT_MOTION_TYPE)
  6946. - return;
  6947. -
  6948. - if (uiPointId == 1)
  6949. - me->SetFacingTo(ORIENTATION);
  6950. - }
  6951. -
  6952. - void DoSummonGrandChampion(uint32 uiBoss)
  6953. - {
  6954. - ++uiSummonTimes;
  6955. - uint32 VEHICLE_TO_SUMMON1 = 0;
  6956. - uint32 VEHICLE_TO_SUMMON2 = 0;
  6957. - switch (uiBoss)
  6958. - {
  6959. - case 0:
  6960. - VEHICLE_TO_SUMMON1 = VEHICLE_MOKRA_SKILLCRUSHER_MOUNT;
  6961. - VEHICLE_TO_SUMMON2 = VEHICLE_ORGRIMMAR_WOLF;
  6962. - break;
  6963. - case 1:
  6964. - VEHICLE_TO_SUMMON1 = VEHICLE_ERESSEA_DAWNSINGER_MOUNT;
  6965. - VEHICLE_TO_SUMMON2 = VEHICLE_SILVERMOON_HAWKSTRIDER;
  6966. - break;
  6967. - case 2:
  6968. - VEHICLE_TO_SUMMON1 = VEHICLE_RUNOK_WILDMANE_MOUNT;
  6969. - VEHICLE_TO_SUMMON2 = VEHICLE_THUNDER_BLUFF_KODO;
  6970. - break;
  6971. - case 3:
  6972. - VEHICLE_TO_SUMMON1 = VEHICLE_ZUL_TORE_MOUNT;
  6973. - VEHICLE_TO_SUMMON2 = VEHICLE_DARKSPEAR_RAPTOR;
  6974. - break;
  6975. - case 4:
  6976. - VEHICLE_TO_SUMMON1 = VEHICLE_DEATHSTALKER_VESCERI_MOUNT;
  6977. - VEHICLE_TO_SUMMON2 = VEHICLE_FORSAKE_WARHORSE;
  6978. - break;
  6979. - default:
  6980. - return;
  6981. - }
  6982. -
  6983. - if (Creature* pBoss = me->SummonCreature(VEHICLE_TO_SUMMON1, SpawnPosition))
  6984. - {
  6985. - switch (uiSummonTimes)
  6986. - {
  6987. - case 1:
  6988. - {
  6989. - uiVehicle1GUID = pBoss->GetGUID();
  6990. - ObjectGuid uiGrandChampionBoss1;
  6991. - if (Vehicle* pVehicle = pBoss->GetVehicleKit())
  6992. - if (Unit* unit = pVehicle->GetPassenger(0))
  6993. - uiGrandChampionBoss1 = unit->GetGUID();
  6994. - instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1, uiVehicle1GUID);
  6995. - instance->SetGuidData(DATA_GRAND_CHAMPION_1, uiGrandChampionBoss1);
  6996. - pBoss->AI()->SetData(1, 0);
  6997. - break;
  6998. - }
  6999. - case 2:
  7000. - {
  7001. - uiVehicle2GUID = pBoss->GetGUID();
  7002. - ObjectGuid uiGrandChampionBoss2;
  7003. - if (Vehicle* pVehicle = pBoss->GetVehicleKit())
  7004. - if (Unit* unit = pVehicle->GetPassenger(0))
  7005. - uiGrandChampionBoss2 = unit->GetGUID();
  7006. - instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2, uiVehicle2GUID);
  7007. - instance->SetGuidData(DATA_GRAND_CHAMPION_2, uiGrandChampionBoss2);
  7008. - pBoss->AI()->SetData(2, 0);
  7009. - break;
  7010. - }
  7011. - case 3:
  7012. - {
  7013. - uiVehicle3GUID = pBoss->GetGUID();
  7014. - ObjectGuid uiGrandChampionBoss3;
  7015. - if (Vehicle* pVehicle = pBoss->GetVehicleKit())
  7016. - if (Unit* unit = pVehicle->GetPassenger(0))
  7017. - uiGrandChampionBoss3 = unit->GetGUID();
  7018. - instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3, uiVehicle3GUID);
  7019. - instance->SetGuidData(DATA_GRAND_CHAMPION_3, uiGrandChampionBoss3);
  7020. - pBoss->AI()->SetData(3, 0);
  7021. - break;
  7022. - }
  7023. - default:
  7024. - return;
  7025. - }
  7026. -
  7027. - for (uint8 i = 0; i < 3; ++i)
  7028. - {
  7029. - if (Creature* pAdd = me->SummonCreature(VEHICLE_TO_SUMMON2, SpawnPosition, TEMPSUMMON_CORPSE_DESPAWN))
  7030. - {
  7031. - switch (uiSummonTimes)
  7032. - {
  7033. - case 1:
  7034. - Champion1List.push_back(pAdd->GetGUID());
  7035. - break;
  7036. - case 2:
  7037. - Champion2List.push_back(pAdd->GetGUID());
  7038. - break;
  7039. - case 3:
  7040. - Champion3List.push_back(pAdd->GetGUID());
  7041. - break;
  7042. - }
  7043. -
  7044. - switch (i)
  7045. - {
  7046. - case 0:
  7047. - pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI));
  7048. - break;
  7049. - case 1:
  7050. - pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI) / 2);
  7051. - break;
  7052. - case 2:
  7053. - pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI) / 2 + float(M_PI));
  7054. - break;
  7055. - }
  7056. - }
  7057. -
  7058. - }
  7059. - }
  7060. - }
  7061. -
  7062. - void DoStartArgentChampionEncounter()
  7063. - {
  7064. - me->GetMotionMaster()->MovePoint(1, 735.81f, 661.92f, 412.39f);
  7065. -
  7066. - if (me->SummonCreature(uiArgentChampion, SpawnPosition))
  7067. - {
  7068. - for (uint8 i = 0; i < 3; ++i)
  7069. - {
  7070. - if (Creature* pTrash = me->SummonCreature(NPC_ARGENT_LIGHWIELDER, SpawnPosition))
  7071. - pTrash->AI()->SetData(i, 0);
  7072. - if (Creature* pTrash = me->SummonCreature(NPC_ARGENT_MONK, SpawnPosition))
  7073. - pTrash->AI()->SetData(i, 0);
  7074. - if (Creature* pTrash = me->SummonCreature(NPC_PRIESTESS, SpawnPosition))
  7075. - pTrash->AI()->SetData(i, 0);
  7076. - }
  7077. - }
  7078. - }
  7079. -
  7080. - void SetGrandChampionsForEncounter()
  7081. - {
  7082. - uiFirstBoss = urand(0, 4);
  7083. -
  7084. - while (uiSecondBoss == uiFirstBoss || uiThirdBoss == uiFirstBoss || uiThirdBoss == uiSecondBoss)
  7085. - {
  7086. - uiSecondBoss = urand(0, 4);
  7087. - uiThirdBoss = urand(0, 4);
  7088. - }
  7089. - }
  7090. -
  7091. - void SetArgentChampion()
  7092. - {
  7093. - uint8 uiTempBoss = urand(0, 1);
  7094. -
  7095. - switch (uiTempBoss)
  7096. - {
  7097. - case 0:
  7098. - uiArgentChampion = NPC_EADRIC;
  7099. - break;
  7100. - case 1:
  7101. - uiArgentChampion = NPC_PALETRESS;
  7102. - break;
  7103. - }
  7104. - }
  7105. -
  7106. - void StartEncounter()
  7107. - {
  7108. - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  7109. -
  7110. - if (instance->GetBossState(BOSS_BLACK_KNIGHT) == NOT_STARTED)
  7111. - {
  7112. - if (instance->GetBossState(BOSS_ARGENT_CHALLENGE_E) == NOT_STARTED && instance->GetBossState(BOSS_ARGENT_CHALLENGE_P) == NOT_STARTED)
  7113. - {
  7114. - if (instance->GetBossState(BOSS_GRAND_CHAMPIONS) == NOT_STARTED)
  7115. - SetData(DATA_START, 0);
  7116. -
  7117. - if (instance->GetBossState(BOSS_GRAND_CHAMPIONS) == DONE)
  7118. - DoStartArgentChampionEncounter();
  7119. - }
  7120. -
  7121. - if ((instance->GetBossState(BOSS_GRAND_CHAMPIONS) == DONE &&
  7122. - instance->GetBossState(BOSS_ARGENT_CHALLENGE_E) == DONE) ||
  7123. - instance->GetBossState(BOSS_ARGENT_CHALLENGE_P) == DONE)
  7124. - me->SummonCreature(VEHICLE_BLACK_KNIGHT, 769.834f, 651.915f, 447.035f, 0);
  7125. - }
  7126. - }
  7127. -
  7128. - void AggroAllPlayers(Creature* temp)
  7129. - {
  7130. - Map::PlayerList const& PlList = me->GetMap()->GetPlayers();
  7131. - if (PlList.isEmpty())
  7132. - return;
  7133. -
  7134. - for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
  7135. - {
  7136. - if (Player* player = i->GetSource())
  7137. - {
  7138. - if (player->IsGameMaster())
  7139. - continue;
  7140. -
  7141. - if (player->IsAlive())
  7142. - {
  7143. - temp->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
  7144. - temp->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  7145. - temp->SetReactState(REACT_AGGRESSIVE);
  7146. - AddThreat(player, 0.0f, temp);
  7147. - }
  7148. - }
  7149. - }
  7150. - }
  7151. -
  7152. - void UpdateAI(uint32 uiDiff) override
  7153. - {
  7154. - ScriptedAI::UpdateAI(uiDiff);
  7155. -
  7156. - if (uiTimer <= uiDiff)
  7157. - {
  7158. - switch (uiPhase)
  7159. - {
  7160. - case 1:
  7161. - DoSummonGrandChampion(uiSecondBoss);
  7162. - NextStep(10000, true);
  7163. - break;
  7164. - case 2:
  7165. - DoSummonGrandChampion(uiThirdBoss);
  7166. - NextStep(0, false);
  7167. - break;
  7168. - case 3:
  7169. - if (!Champion1List.empty())
  7170. - {
  7171. - for (GuidList::const_iterator itr = Champion1List.begin(); itr != Champion1List.end(); ++itr)
  7172. - if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
  7173. - AggroAllPlayers(summon);
  7174. - NextStep(0, false);
  7175. - }
  7176. - break;
  7177. - }
  7178. - } else uiTimer -= uiDiff;
  7179. -
  7180. - if (!UpdateVictim())
  7181. - return;
  7182. - }
  7183. -
  7184. - void JustSummoned(Creature* summon) override
  7185. - {
  7186. - if (instance->GetBossState(BOSS_GRAND_CHAMPIONS) == NOT_STARTED)
  7187. - {
  7188. - summon->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  7189. - summon->SetReactState(REACT_PASSIVE);
  7190. - }
  7191. - }
  7192. -
  7193. - void SummonedCreatureDespawn(Creature* summon) override
  7194. - {
  7195. - switch (summon->GetEntry())
  7196. - {
  7197. - case VEHICLE_DARNASSIA_NIGHTSABER:
  7198. - case VEHICLE_EXODAR_ELEKK:
  7199. - case VEHICLE_STORMWIND_STEED:
  7200. - case VEHICLE_GNOMEREGAN_MECHANOSTRIDER:
  7201. - case VEHICLE_IRONFORGE_RAM:
  7202. - case VEHICLE_FORSAKE_WARHORSE:
  7203. - case VEHICLE_THUNDER_BLUFF_KODO:
  7204. - case VEHICLE_ORGRIMMAR_WOLF:
  7205. - case VEHICLE_SILVERMOON_HAWKSTRIDER:
  7206. - case VEHICLE_DARKSPEAR_RAPTOR:
  7207. - SetData(DATA_LESSER_CHAMPIONS_DEFEATED, 0);
  7208. - break;
  7209. - }
  7210. - }
  7211. -
  7212. - bool OnGossipHello(Player* player) override
  7213. - {
  7214. - if (((instance->GetBossState(BOSS_GRAND_CHAMPIONS) == DONE &&
  7215. - instance->GetBossState(BOSS_BLACK_KNIGHT) == DONE &&
  7216. - instance->GetBossState(BOSS_ARGENT_CHALLENGE_E) == DONE) ||
  7217. - instance->GetBossState(BOSS_ARGENT_CHALLENGE_P) == DONE))
  7218. - return false;
  7219. -
  7220. - if (instance->GetBossState(BOSS_GRAND_CHAMPIONS) == NOT_STARTED &&
  7221. - instance->GetBossState(BOSS_ARGENT_CHALLENGE_E) == NOT_STARTED &&
  7222. - instance->GetBossState(BOSS_ARGENT_CHALLENGE_P) == NOT_STARTED &&
  7223. - instance->GetBossState(BOSS_BLACK_KNIGHT) == NOT_STARTED)
  7224. - {
  7225. - InitGossipMenuFor(player, GOSSIP_START_EVENT1_MID);
  7226. - AddGossipItemFor(player, GOSSIP_START_EVENT1_MID, GOSSIP_START_EVENT1_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  7227. - SendGossipMenuFor(player, player->GetGossipTextId(GOSSIP_START_EVENT1_MID, me), me->GetGUID());
  7228. - }
  7229. - else
  7230. - {
  7231. - InitGossipMenuFor(player, GOSSIP_START_EVENT2_MID);
  7232. - AddGossipItemFor(player, GOSSIP_START_EVENT2_MID, GOSSIP_START_EVENT2_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  7233. - SendGossipMenuFor(player, player->GetGossipTextId(GOSSIP_START_EVENT2_MID, me), me->GetGUID());
  7234. - }
  7235. -
  7236. - return true;
  7237. - }
  7238. -
  7239. - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
  7240. - {
  7241. - uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
  7242. - ClearGossipMenuFor(player);
  7243. - if (action == GOSSIP_ACTION_INFO_DEF + 1)
  7244. - {
  7245. - CloseGossipMenuFor(player);
  7246. - StartEncounter();
  7247. - }
  7248. - return true;
  7249. - }
  7250. - };
  7251. -
  7252. - CreatureAI* GetAI(Creature* creature) const override
  7253. - {
  7254. - return GetTrialOfTheChampionAI<npc_announcer_toc5AI>(creature);
  7255. - }
  7256. -};
  7257. -
  7258. -void AddSC_trial_of_the_champion()
  7259. -{
  7260. - new npc_announcer_toc5();
  7261. -}
  7262. +/*
  7263. + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  7264. + *
  7265. + * This program is free software; you can redistribute it and/or modify it
  7266. + * under the terms of the GNU General Public License as published by the
  7267. + * Free Software Foundation; either version 2 of the License, or (at your
  7268. + * option) any later version.
  7269. + *
  7270. + * This program is distributed in the hope that it will be useful, but WITHOUT
  7271. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  7272. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  7273. + * more details.
  7274. + *
  7275. + * You should have received a copy of the GNU General Public License along
  7276. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  7277. + */
  7278. +
  7279. +#include "GameObject.h"
  7280. +#include "ScriptMgr.h"
  7281. +#include "ScriptedCreature.h"
  7282. +#include "ScriptedGossip.h"
  7283. +#include "trial_of_the_champion.h"
  7284. +#include "Vehicle.h"
  7285. +#include "Player.h"
  7286. +
  7287. +#define GOSSIP_START_EVENT1 "I am ready."
  7288. +#define GOSSIP_START_EVENT2 "I am ready for the next challenge."
  7289. +#define GOSSIP_START_EVENT_SKIP "I am ready. However I'd like to skip the pageantry."
  7290. +
  7291. + // Agregar esta definición
  7292. +const Position SpawnPosition = { 746.261f, 687.0f, 412.374f, 4.65f };
  7293. +
  7294. +enum Texts
  7295. +{
  7296. + // Used by announcers
  7297. + SAY_INTRO_2_E = 0,
  7298. + SAY_INTRO_2_P = 1,
  7299. + SAY_INTRO_1 = 2,
  7300. + SAY_INTRO_SHAM_A = 3,
  7301. + SAY_INTRO_MAGE_H = 3,
  7302. + SAY_INTRO_HUN = 4,
  7303. + SAY_INTRO_MAGE_A = 5,
  7304. + SAY_INTRO_WARR_H = 5,
  7305. + SAY_INTRO_WARR_A = 6,
  7306. + SAY_INTRO_ROG_H = 6,
  7307. + SAY_INTRO_ROG_A = 7,
  7308. + SAY_INTRO_SHAM_H = 7,
  7309. + SAY_INTRO_3 = 8,
  7310. + SAY_INTRODUCE_PLR_0 = 9,
  7311. + SAY_INTRODUCE_PLR_1 = 10,
  7312. + SAY_INTRODUCE_PLR_2 = 11,
  7313. + SAY_INTRODUCE_PLR_3 = 12,
  7314. + SAY_INTRODUCE_PLR_4 = 13,
  7315. +
  7316. + // Used by Tirion
  7317. + SAY_TIRION_INTRO_1 = 50,
  7318. + SAY_TIRION_INTRO_2 = 51,
  7319. + SAY_TIRION_INTRO_3 = 52,
  7320. + SAY_TIRION_OUTRO_1 = 53,
  7321. + SAY_TIRION_INTRO_4 = 54,
  7322. + SAY_TIRION_INTRO_5 = 55,
  7323. + SAY_TIRION_INTRO_6 = 56,
  7324. + SAY_TIRION_OUTRO_2 = 57,
  7325. + SAY_TIRION_OUTRO_3 = 58,
  7326. +
  7327. + // Used by Varian
  7328. + SAY_VARIAN_INTRO_1 = 50,
  7329. + SAY_VARIAN_INTRO_2 = 52,
  7330. + SAY_VARIAN_INTRO_3 = 51,
  7331. + SAY_VARIAN_OUTRO_1 = 53,
  7332. +
  7333. + // Used by Garrosh
  7334. + SAY_GARROSH_INTRO_1 = 50,
  7335. + SAY_GARROSH_INTRO_2 = 52,
  7336. + SAY_GARROSH_INTRO_3 = 51,
  7337. +
  7338. + // Used by Jaina
  7339. + SAY_JAINA_INTRO_1 = 0,
  7340. + SAY_JAINA_INTRO_2 = 1,
  7341. +
  7342. + // Used by Thrall
  7343. + SAY_THRALL_INTRO_1 = 0,
  7344. + SAY_THRALL_INTRO_2 = 2,
  7345. + SAY_THRALL_OUTRO_1 = 1,
  7346. +
  7347. + // Used by Argent Confessor Paletress
  7348. + SAY_PALETRESS_INTRO_1 = 0,
  7349. + SAY_PALETRESS_INTRO_2 = 1,
  7350. +
  7351. + // Used by Eadric the Pure
  7352. + SAY_EADRIC_INTRO_1 = 0,
  7353. +
  7354. + // Used by The Black Knight
  7355. + SAY_KNIGHT_INTRO_1 = 0,
  7356. + SAY_KNIGHT_INTRO_2 = 1,
  7357. + SAY_KNIGHT_INTRO_3 = 2,
  7358. +
  7359. + // Used by spectators (same id for every spectator)
  7360. + EMOTE_SPECTATOR_CHEER = 0
  7361. +};
  7362. +
  7363. +enum BossData
  7364. +{
  7365. + BOSS_WARRIOR,
  7366. + BOSS_MAGE,
  7367. + BOSS_SHAMAN,
  7368. + BOSS_HUNTER,
  7369. + BOSS_ROGUE,
  7370. + BOSS_EADRIC,
  7371. + BOSS_PALETRESS
  7372. +};
  7373. +
  7374. +enum GossipTexts
  7375. +{
  7376. + GOSSIP_TEXT_UNMOUNTED_A = 14757,
  7377. + GOSSIP_TEXT_UNMOUNTED_H = 15043,
  7378. + GOSSIP_TEXT_FIRST_BOSS = 14688,
  7379. + GOSSIP_TEXT_SECOND_BOSS = 14737,
  7380. + GOSSIP_TEXT_THIRD_BOSS = 14738
  7381. +};
  7382. +
  7383. +enum Events
  7384. +{
  7385. + EVENT_CHEER_RND = 1,
  7386. + // Grand Champion - roleplaying intro
  7387. + EVENT_INTRODUCE,
  7388. + EVENT_CHAT_1,
  7389. + EVENT_CHAT_2,
  7390. + EVENT_CHAT_3,
  7391. + EVENT_CHAT_4,
  7392. + EVENT_CHAT_5,
  7393. + EVENT_CHAT_6,
  7394. + EVENT_SUMMON_1,
  7395. + EVENT_OPEN_DOOR_1,
  7396. + EVENT_INTRODUCE_BOSS_1,
  7397. + EVENT_CLOSE_DOOR_1,
  7398. + EVENT_SUMMON_2,
  7399. + EVENT_OPEN_DOOR_2,
  7400. + EVENT_INTRODUCE_BOSS_2,
  7401. + EVENT_CLOSE_DOOR_2,
  7402. + EVENT_SUMMON_3,
  7403. + EVENT_OPEN_DOOR_3,
  7404. + EVENT_INTRODUCE_BOSS_3,
  7405. + EVENT_CLOSE_DOOR_3,
  7406. + EVENT_WAIT_1,
  7407. + EVENT_FACING,
  7408. + EVENT_CHAT_7,
  7409. + EVENT_AGGRO_1,
  7410. + EVENT_CHAT_8,
  7411. + // Grand Champion - roleplaying skipped
  7412. + EVENT_CHAT_9 = 30,
  7413. + EVENT_SUMMON_1_SKIP,
  7414. + EVENT_SUMMON_2_SKIP,
  7415. + EVENT_SUMMON_3_SKIP,
  7416. + // Argent Champion
  7417. + EVENT_MOVE_MIDDLE = 40,
  7418. + EVENT_SPAWN_ALL,
  7419. + EVENT_OPEN_DOOR_4,
  7420. + EVENT_INTRODUCE_BOSS_4,
  7421. + EVENT_ARGENT_BOSS_WALK,
  7422. + EVENT_GO_TO_ARGENT_BOSS,
  7423. + EVENT_CHAT_10,
  7424. + EVENT_CHAT_11,
  7425. + EVENT_WAIT_2,
  7426. + EVENT_CHAT_12,
  7427. + // The Black Knight
  7428. + EVENT_STEP_FORWARD = 50,
  7429. + EVENT_CHAT_13,
  7430. + EVENT_FACING_1,
  7431. + EVENT_CHAT_14,
  7432. + EVENT_START_PATH,
  7433. + EVENT_CHAT_15,
  7434. + EVENT_FACING_2,
  7435. + EVENT_STUN_ANNOUNCER,
  7436. + EVENT_CHAT_16,
  7437. + EVENT_KNOCK_ANNOUNCER,
  7438. + EVENT_CHAT_17,
  7439. + EVENT_CHAT_18,
  7440. + EVENT_AGGRO_2,
  7441. + EVENT_CHAT_19,
  7442. + EVENT_CHAT_20,
  7443. + EVENT_CHAT_21,
  7444. + EVENT_CHAT_22
  7445. +};
  7446. +
  7447. +enum Spells
  7448. +{
  7449. + // Both casted by The Black Knight to announcer
  7450. + SPELL_DEATHS_RESPITE = 66798,
  7451. + SPELL_DEATHS_PUSH = 66797
  7452. +};
  7453. +
  7454. +enum PointMovement
  7455. +{
  7456. + POINT_ENCOUNTER_1_WAIT = 0,
  7457. + POINT_RETURN_TO_CENTER,
  7458. + POINT_START_ARGENT_CHAMP,
  7459. + POINT_ENCOUNTER_2_WAIT_1,
  7460. + POINT_ENCOUNTER_2_WAIT_2,
  7461. + POINT_ENCOUNTER_3_WAIT
  7462. +};
  7463. +
  7464. +/*######
  7465. +## npc_announcer_toc5
  7466. +######*/
  7467. +uint32 const IntroducePlrTxt[5] = { SAY_INTRODUCE_PLR_0, SAY_INTRODUCE_PLR_1, SAY_INTRODUCE_PLR_2, SAY_INTRODUCE_PLR_3, SAY_INTRODUCE_PLR_4 };
  7468. +uint32 const SpectatorData[12] =
  7469. +{
  7470. + 0,
  7471. + NPC_SPECTATOR_HUMAN,
  7472. + NPC_SPECTATOR_ORC,
  7473. + NPC_SPECTATOR_DWARF,
  7474. + NPC_SPECTATOR_NELF,
  7475. + NPC_SPECTATOR_UNDEAD,
  7476. + NPC_SPECTATOR_TAUREN,
  7477. + NPC_SPECTATOR_GNOME,
  7478. + NPC_SPECTATOR_TROLL,
  7479. + 0,
  7480. + NPC_SPECTATOR_BELF,
  7481. + NPC_SPECTATOR_DRAENEI
  7482. +};
  7483. +
  7484. +// Bases mostly on Joshiwald's work (big thanks)
  7485. +struct GrandChampionInfo
  7486. +{
  7487. + uint32 GrandChampionEntry[2];
  7488. + uint32 FactionChampionEntry[2];
  7489. + uint8 AnnounceText[2];
  7490. + uint32 GrandChampionRealEntry[2]; // used only for cheering at correct champion if event is skipped
  7491. + uint32 SpecatatorEntry[2];
  7492. +};
  7493. +
  7494. +GrandChampionInfo const GrandChampionData[5] =
  7495. +{
  7496. + {
  7497. + { VEHICLE_MOKRA_SKULLCRUSHER_MOUNT, VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT },
  7498. + { NPC_ORGRIMMAR_CHAMPION, NPC_STORMWIND_CHAMPION },
  7499. + { SAY_INTRO_WARR_H, SAY_INTRO_WARR_A },
  7500. + { NPC_MOKRA, NPC_JACOB },
  7501. + { SpectatorData[RACE_ORC], SpectatorData[RACE_HUMAN] },
  7502. + },
  7503. + {
  7504. + { VEHICLE_ERESSEA_DAWNSINGER_MOUNT, VEHICLE_AMBROSE_BOLTSPARK_MOUNT },
  7505. + { NPC_SILVERMOON_CHAMPION, NPC_GNOMEREGAN_CHAMPION },
  7506. + { SAY_INTRO_MAGE_H, SAY_INTRO_MAGE_A },
  7507. + { NPC_ERESSEA, NPC_AMBROSE },
  7508. + { SpectatorData[RACE_BLOODELF], SpectatorData[RACE_GNOME] },
  7509. + },
  7510. + {
  7511. + { VEHICLE_RUNOK_WILDMANE_MOUNT, VEHICLE_COLOSOS_MOUNT },
  7512. + { NPC_THUNDER_BLUFF_CHAMPION, NPC_EXODAR_CHAMPION },
  7513. + { SAY_INTRO_SHAM_H, SAY_INTRO_SHAM_A },
  7514. + { NPC_RUNOK, NPC_COLOSOS },
  7515. + { SpectatorData[RACE_TAUREN], SpectatorData[RACE_DRAENEI] },
  7516. + },
  7517. + {
  7518. + { VEHICLE_ZUL_TORE_MOUNT, VEHICLE_EVENSONG_MOUNT },
  7519. + { NPC_SEN_JIN_CHAMPION, NPC_DARNASSUS_CHAMPION },
  7520. + { SAY_INTRO_HUN, SAY_INTRO_HUN },
  7521. + { NPC_ZULTORE, NPC_JAELYNE },
  7522. + { SpectatorData[RACE_TROLL], SpectatorData[RACE_NIGHTELF] },
  7523. + },
  7524. + {
  7525. + { VEHICLE_DEATHSTALKER_VESCERI_MOUNT, VEHICLE_LANA_STOUTHAMMER_MOUNT },
  7526. + { NPC_UNDERCITY_CHAMPION, NPC_IRONFORGE_CHAMPION },
  7527. + { SAY_INTRO_ROG_H, SAY_INTRO_ROG_A },
  7528. + { NPC_VISCERI, NPC_LANA },
  7529. + { SpectatorData[RACE_UNDEAD_PLAYER], SpectatorData[RACE_DWARF] },
  7530. + }
  7531. +};
  7532. +
  7533. +class npc_announcer_toc5 : public CreatureScript
  7534. +{
  7535. +public:
  7536. + npc_announcer_toc5() : CreatureScript("npc_announcer_toc5") {}
  7537. +
  7538. + struct npc_announcer_toc5AI : public ScriptedAI
  7539. + {
  7540. + npc_announcer_toc5AI(Creature* creature) : ScriptedAI(creature)
  7541. + {
  7542. + instance = creature->GetInstanceScript();
  7543. +
  7544. + uiSummonTimes = 0;
  7545. + uiLesserChampions = 0;
  7546. +
  7547. + uiFirstBoss = 0;
  7548. + uiSecondBoss = 0;
  7549. + uiThirdBoss = 0;
  7550. + uiArgentChampion = 0;
  7551. +
  7552. + SetCombatMovement(false);
  7553. +
  7554. + me->SetReactState(REACT_PASSIVE);
  7555. + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  7556. + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  7557. + me->SetWalk(true);
  7558. +
  7559. + SetGrandChampionsForEncounter();
  7560. + SetArgentChampion();
  7561. + }
  7562. +
  7563. + InstanceScript* instance;
  7564. +
  7565. + uint8 uiSummonTimes;
  7566. + uint8 uiLesserChampions;
  7567. +
  7568. + uint32 uiFirstBoss;
  7569. + uint32 uiSecondBoss;
  7570. + uint32 uiThirdBoss;
  7571. + uint32 uiArgentChampion;
  7572. +
  7573. + EventMap events;
  7574. +
  7575. + GuidList Champion1List;
  7576. + GuidList Champion2List;
  7577. + GuidList Champion3List;
  7578. + GuidList PlayerEventList;
  7579. +
  7580. + void NextStep(uint32 uiTimerStep, bool bNextStep, uint32 currentEvent, uint8 uiPhaseStep = 0)
  7581. + {
  7582. + if (bNextStep)
  7583. + events.ScheduleEvent(currentEvent + 1, Milliseconds(uiTimerStep));
  7584. + else
  7585. + {
  7586. + if (uiPhaseStep > 0)
  7587. + events.ScheduleEvent(uiPhaseStep, Milliseconds(uiTimerStep));
  7588. + }
  7589. + }
  7590. +
  7591. + void Reset() override
  7592. + {
  7593. + events.Reset();
  7594. + events.ScheduleEvent(EVENT_CHEER_RND, 120s);
  7595. + }
  7596. +
  7597. + void SetData(uint32 uiType, uint32 uiData) override
  7598. + {
  7599. + switch (uiType)
  7600. + {
  7601. + case DATA_START:
  7602. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  7603. + tirion->AI()->Talk(SAY_TIRION_INTRO_1);
  7604. + me->GetMotionMaster()->MovePoint(POINT_ENCOUNTER_1_WAIT, announcerEncounterPos);
  7605. + NextStep(6000, false, 0, EVENT_CHAT_9);
  7606. + break;
  7607. + case DATA_LESSER_CHAMPIONS_PREPARE:
  7608. + {
  7609. + // Moving lesser champions to right position
  7610. + uint32 TeamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE);
  7611. + GuidList* TempList = nullptr;
  7612. + uint8 x = 0;
  7613. + switch (uiData)
  7614. + {
  7615. + case 1: // WAYPOINT_MAP_BOSS_1
  7616. + TempList = &Champion1List;
  7617. + if (TeamInInstance == HORDE)
  7618. + x = 9;
  7619. + else
  7620. + x = 0;
  7621. + break;
  7622. + case 2: // WAYPOINT_MAP_BOSS_2
  7623. + TempList = &Champion2List;
  7624. + if (TeamInInstance == HORDE)
  7625. + x = 12;
  7626. + else
  7627. + x = 3;
  7628. + break;
  7629. + case 3: // WAYPOINT_MAP_BOSS_3
  7630. + TempList = &Champion3List;
  7631. + if (TeamInInstance == HORDE)
  7632. + x = 15;
  7633. + else
  7634. + x = 6;
  7635. + break;
  7636. + default:
  7637. + break;
  7638. + }
  7639. +
  7640. + if (TempList)
  7641. + {
  7642. + for (ObjectGuid const& guid : *TempList)
  7643. + {
  7644. + if (Creature* add = ObjectAccessor::GetCreature(*me, guid))
  7645. + add->AI()->SetData(1, x); // DATA_GENERATE_WAYPOINTS_FOR_ADDS
  7646. + x++;
  7647. + }
  7648. + }
  7649. + break;
  7650. + }
  7651. + case DATA_LESSER_CHAMPIONS_DEFEATED:
  7652. + {
  7653. + ++uiLesserChampions;
  7654. + GuidList TempList;
  7655. + if (uiLesserChampions == 3 || uiLesserChampions == 6)
  7656. + {
  7657. + switch (uiLesserChampions)
  7658. + {
  7659. + case 3:
  7660. + TempList = Champion2List;
  7661. + break;
  7662. + case 6:
  7663. + TempList = Champion3List;
  7664. + break;
  7665. + }
  7666. +
  7667. + for (GuidList::const_iterator itr = TempList.begin(); itr != TempList.end(); ++itr)
  7668. + if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
  7669. + EnterAggressiveMode(summon);
  7670. + }
  7671. + else if (uiLesserChampions == 9)
  7672. + StartGrandChampionsAttack();
  7673. +
  7674. + break;
  7675. + }
  7676. + case DATA_GRAND_CHAMPIONS_DONE:
  7677. + NextStep(3000, false, 0, EVENT_CHAT_8);
  7678. + break;
  7679. + case DATA_ARGENT_CHAMPION_PREPARE:
  7680. + NextStep(500, false, 0, EVENT_GO_TO_ARGENT_BOSS);
  7681. + break;
  7682. + case DATA_BLACK_KNIGHT_PREPARE:
  7683. + NextStep(2000, false, 0, EVENT_CHAT_15);
  7684. + break;
  7685. + case DATA_BLACK_KNIGHT_PRECAST:
  7686. + NextStep(500, false, 0, EVENT_FACING_2);
  7687. + break;
  7688. + case DATA_BLACK_KNIGHT_DONE:
  7689. + NextStep(7000, false, 0, EVENT_CHAT_20);
  7690. + break;
  7691. + default:
  7692. + break;
  7693. + }
  7694. + }
  7695. +
  7696. + void StartGrandChampionsAttack()
  7697. + {
  7698. + Creature* pGrandChampion1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1));
  7699. + Creature* pGrandChampion2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_2));
  7700. + Creature* pGrandChampion3 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_VEHICLE_3));
  7701. + if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
  7702. + {
  7703. + EnterAggressiveMode(pGrandChampion1, true);
  7704. + EnterAggressiveMode(pGrandChampion2, true);
  7705. + EnterAggressiveMode(pGrandChampion3, true);
  7706. + }
  7707. + }
  7708. +
  7709. + void MovementInform(uint32 uiType, uint32 uiPointId) override
  7710. + {
  7711. + if (uiType != POINT_MOTION_TYPE)
  7712. + return;
  7713. +
  7714. + switch (uiPointId)
  7715. + {
  7716. + case POINT_ENCOUNTER_1_WAIT:
  7717. + NextStep(500, false, 0, EVENT_WAIT_1);
  7718. + break;
  7719. + case POINT_RETURN_TO_CENTER:
  7720. + me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  7721. + break;
  7722. + case POINT_START_ARGENT_CHAMP:
  7723. + me->SetFacingTo(me->GetHomePosition().GetOrientation());
  7724. + NextStep(500, false, 0, EVENT_SPAWN_ALL);
  7725. + break;
  7726. + case POINT_ENCOUNTER_2_WAIT_1:
  7727. + NextStep(500, false, 0, EVENT_WAIT_2);
  7728. + break;
  7729. + case POINT_ENCOUNTER_2_WAIT_2:
  7730. + me->SetFacingTo(centerOrientation);
  7731. + NextStep(1000, false, 0, EVENT_CHAT_12);
  7732. + break;
  7733. + case POINT_ENCOUNTER_3_WAIT:
  7734. + me->SetFacingTo(centerOrientation);
  7735. + NextStep(1000, false, 0, EVENT_CHAT_13);
  7736. + break;
  7737. + default:
  7738. + break;
  7739. + }
  7740. + }
  7741. +
  7742. + void DoSummonNextGrandChampion(bool skipEvent = false)
  7743. + {
  7744. + ++uiSummonTimes;
  7745. + uint32 bossId;
  7746. + switch (uiSummonTimes)
  7747. + {
  7748. + case 1:
  7749. + bossId = uiFirstBoss;
  7750. + break;
  7751. + case 2:
  7752. + bossId = uiSecondBoss;
  7753. + break;
  7754. + case 3:
  7755. + bossId = uiThirdBoss;
  7756. + break;
  7757. + default:
  7758. + return;
  7759. + }
  7760. +
  7761. + if (bossId >= 5)
  7762. + return;
  7763. +
  7764. + GrandChampionInfo const* info = &GrandChampionData[bossId];
  7765. + uint32 TeamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE);
  7766. + uint32 teamIndex = TeamInInstance == HORDE ? 1 : 0;
  7767. +
  7768. + // Calculating spawn position for grand champion if event is skipped
  7769. + int x = uiSummonTimes - 1;
  7770. + if (TeamInInstance == HORDE)
  7771. + x += 3;
  7772. +
  7773. + // Grand Champions
  7774. + Position const spawnPos = skipEvent ? GrandChampFinalLoc[x] : SpawnPosition;
  7775. + if (Creature* pBoss = me->SummonCreature(info->GrandChampionEntry[teamIndex], spawnPos))
  7776. + {
  7777. + instance->SetGuidData(DATA_GRAND_CHAMPION_VEHICLE_1 + uiSummonTimes - 1, pBoss->GetGUID());
  7778. +
  7779. + if (!skipEvent)
  7780. + pBoss->AI()->SetData(uiSummonTimes, TeamInInstance);
  7781. + else
  7782. + {
  7783. + if (TeamInInstance == ALLIANCE)
  7784. + pBoss->SetFacingTo(hordeOrientation);
  7785. + else
  7786. + pBoss->SetFacingTo(allianceOrientation);
  7787. + pBoss->SetHomePosition(pBoss->GetPositionX(), pBoss->GetPositionY(), pBoss->GetPositionZ(), TeamInInstance == ALLIANCE ? hordeOrientation : allianceOrientation);
  7788. +
  7789. + // Specatators cheer for champions even if event is skipped
  7790. + if (Creature* spectator = me->FindNearestCreature(info->SpecatatorEntry[teamIndex], 200.0f))
  7791. + {
  7792. + if (Creature* rider = me->FindNearestCreature(info->GrandChampionRealEntry[teamIndex], 200.0f))
  7793. + spectator->AI()->Talk(EMOTE_SPECTATOR_CHEER, rider);
  7794. + }
  7795. + }
  7796. +
  7797. + // Lesser Champions
  7798. + for (uint8 i = 0; i < 3; ++i)
  7799. + {
  7800. + // Calculating waiting positions for lesser champions if event is skipped
  7801. + int m = (uiSummonTimes - 1) * 3 + i;
  7802. + if (TeamInInstance == HORDE)
  7803. + m += 9;
  7804. +
  7805. + if (Creature* pAdd = me->SummonCreature(info->FactionChampionEntry[teamIndex], spawnPos, TEMPSUMMON_DEAD_DESPAWN))
  7806. + {
  7807. + switch (uiSummonTimes)
  7808. + {
  7809. + case 1:
  7810. + Champion1List.push_back(pAdd->GetGUID());
  7811. + break;
  7812. + case 2:
  7813. + Champion2List.push_back(pAdd->GetGUID());
  7814. + break;
  7815. + case 3:
  7816. + Champion3List.push_back(pAdd->GetGUID());
  7817. + break;
  7818. + default:
  7819. + break;
  7820. + }
  7821. +
  7822. + if (!skipEvent)
  7823. + {
  7824. + // Following grand champion
  7825. + switch (i)
  7826. + {
  7827. + case 0:
  7828. + pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI));
  7829. + break;
  7830. + case 1:
  7831. + pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI) / 2);
  7832. + break;
  7833. + case 2:
  7834. + pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI) / 2 + float(M_PI));
  7835. + break;
  7836. + default:
  7837. + break;
  7838. + }
  7839. + }
  7840. + else
  7841. + // Lesser Champions walk to their final positions
  7842. + pAdd->AI()->SetData(1, m); // DATA_GENERATE_WAYPOINTS_FOR_ADDS
  7843. + }
  7844. + }
  7845. + }
  7846. + }
  7847. +
  7848. + void DoStartArgentChampionEncounter()
  7849. + {
  7850. + // Removing vehicles (if not already been removed)
  7851. + instance->SetData(DATA_REMOVE_VEHICLES, 0);
  7852. + // Cleaning chest from arena
  7853. + if (GameObject* cache = instance->GetGameObject(DATA_CHAMPION_S_CACHE))
  7854. + cache->Delete();
  7855. + NextStep(1000, false, 0, EVENT_MOVE_MIDDLE);
  7856. + }
  7857. +
  7858. + void DoStartBlackKnight()
  7859. + {
  7860. + // Removing vehicles (if not already been removed)
  7861. + instance->SetData(DATA_REMOVE_VEHICLES, 0);
  7862. + // Cleaning chest from arena
  7863. + if (GameObject* cache = instance->GetGameObject(DATA_EADRIC_S_CACHE))
  7864. + cache->Delete();
  7865. + else if (GameObject* cache = instance->GetGameObject(DATA_CONFESSOR_S_CACHE))
  7866. + cache->Delete();
  7867. +
  7868. + NextStep(1000, false, 0, EVENT_STEP_FORWARD);
  7869. + }
  7870. +
  7871. + void SetGrandChampionsForEncounter()
  7872. + {
  7873. + uiFirstBoss = urand(BOSS_WARRIOR, BOSS_ROGUE);
  7874. + do
  7875. + {
  7876. + uiSecondBoss = urand(BOSS_WARRIOR, BOSS_ROGUE);
  7877. + uiThirdBoss = urand(BOSS_WARRIOR, BOSS_ROGUE);
  7878. + } while (uiSecondBoss == uiFirstBoss || uiThirdBoss == uiFirstBoss || uiThirdBoss == uiSecondBoss);
  7879. + }
  7880. +
  7881. + void SetArgentChampion()
  7882. + {
  7883. + switch (urand(BOSS_EADRIC, BOSS_PALETRESS))
  7884. + {
  7885. + case BOSS_EADRIC:
  7886. + uiArgentChampion = NPC_EADRIC;
  7887. + break;
  7888. + case BOSS_PALETRESS:
  7889. + uiArgentChampion = NPC_PALETRESS;
  7890. + break;
  7891. + default:
  7892. + break;
  7893. + }
  7894. + }
  7895. +
  7896. + void StartEncounter(bool startRp = false)
  7897. + {
  7898. + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  7899. +
  7900. + if (instance->GetBossState(DATA_BLACK_KNIGHT) == NOT_STARTED)
  7901. + {
  7902. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == NOT_STARTED)
  7903. + {
  7904. + // Starting Grand Champion event (with roleplaying)
  7905. + if (startRp && instance->GetBossState(DATA_GRAND_CHAMPIONS) == NOT_STARTED)
  7906. + {
  7907. + Talk(SAY_INTRO_1);
  7908. + NextStep(7000, false, 0, EVENT_INTRODUCE);
  7909. + }
  7910. +
  7911. + // Starting Grand Champion event (skipped roleplaying)
  7912. + if (!startRp && instance->GetBossState(DATA_GRAND_CHAMPIONS) == NOT_STARTED)
  7913. + SetData(DATA_START, 0);
  7914. +
  7915. + // Starting Argent Champion event
  7916. + if (instance->GetBossState(DATA_GRAND_CHAMPIONS) == DONE)
  7917. + DoStartArgentChampionEncounter();
  7918. + }
  7919. +
  7920. + // Starting Black Knight event
  7921. + if (instance->GetBossState(DATA_GRAND_CHAMPIONS) == DONE && instance->GetBossState(DATA_ARGENT_CHALLENGE) == DONE)
  7922. + DoStartBlackKnight();
  7923. + }
  7924. + }
  7925. +
  7926. + void IntroduceChampion()
  7927. + {
  7928. + uint32 bossId;
  7929. + switch (uiSummonTimes)
  7930. + {
  7931. + case 1:
  7932. + bossId = uiFirstBoss;
  7933. + break;
  7934. + case 2:
  7935. + bossId = uiSecondBoss;
  7936. + break;
  7937. + case 3:
  7938. + bossId = uiThirdBoss;
  7939. + break;
  7940. + default:
  7941. + return;
  7942. + }
  7943. +
  7944. + if (bossId >= 5)
  7945. + return;
  7946. +
  7947. + GrandChampionInfo const* info = &GrandChampionData[bossId];
  7948. + uint32 teamIndex = instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? 1 : 0;
  7949. +
  7950. + // Introduces champion
  7951. + Talk(info->AnnounceText[teamIndex]);
  7952. + // Spectators cheer for the champion
  7953. + if (Creature* spectator = me->FindNearestCreature(info->SpecatatorEntry[teamIndex], 200.0f))
  7954. + {
  7955. + if (Creature* boss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GRAND_CHAMPION_1 + uiSummonTimes - 1)))
  7956. + spectator->AI()->Talk(EMOTE_SPECTATOR_CHEER, boss);
  7957. + }
  7958. + }
  7959. +
  7960. + void EnterAggressiveMode(Creature* temp, bool riderAlso = false)
  7961. + {
  7962. + temp->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  7963. + temp->SetReactState(REACT_AGGRESSIVE);
  7964. + temp->SetWalk(false);
  7965. +
  7966. + Map::PlayerList const& players = me->GetMap()->GetPlayers();
  7967. + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  7968. + {
  7969. + Player* player = itr->GetSource();
  7970. + if (player && !player->IsGameMaster() && player->IsAlive())
  7971. + {
  7972. + if (player->GetVehicleBase())
  7973. + {
  7974. + // Reemplazar AddThreat por el sistema moderno de amenaza
  7975. + temp->EngageWithTarget(player->GetVehicleBase());
  7976. + temp->AI()->AttackStart(player->GetVehicleBase());
  7977. + }
  7978. + else
  7979. + {
  7980. + temp->EngageWithTarget(player);
  7981. + temp->AI()->AttackStart(player);
  7982. + }
  7983. + break;
  7984. + }
  7985. + }
  7986. +
  7987. + if (riderAlso)
  7988. + {
  7989. + if (temp->GetVehicleKit() && temp->GetVehicleKit()->GetPassenger(SEAT_ID_0))
  7990. + {
  7991. + if (Creature* rider = temp->GetVehicleKit()->GetPassenger(SEAT_ID_0)->ToCreature())
  7992. + {
  7993. + rider->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  7994. + rider->SetWalk(false);
  7995. + rider->SetReactState(REACT_AGGRESSIVE);
  7996. + }
  7997. + }
  7998. + }
  7999. + }
  8000. +
  8001. + void AttackStart(Unit* who) override
  8002. + {
  8003. + ScriptedAI::AttackStart(who);
  8004. + if (me->HasUnitState(UNIT_STATE_MELEE_ATTACKING))
  8005. + {
  8006. + me->ClearUnitState(UNIT_STATE_MELEE_ATTACKING);
  8007. + me->SendMeleeAttackStop(who);
  8008. + }
  8009. + }
  8010. +
  8011. + void UpdateAI(uint32 uiDiff) override
  8012. + {
  8013. + events.Update(uiDiff);
  8014. +
  8015. + while (uint32 eventId = events.ExecuteEvent())
  8016. + {
  8017. + switch (eventId)
  8018. + {
  8019. + case EVENT_CHEER_RND:
  8020. + if (!me->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP) && !me->HasUnitState(UNIT_STATE_MOVING) && !me->HasAura(66804))
  8021. + {
  8022. + // Every 2 minutes a random player is being cheered by his/her race's spectators
  8023. + // cheer should only occur during fights
  8024. + Map::PlayerList const& pList = me->GetMap()->GetPlayers();
  8025. + // Player list is always in the same order so we must "randomize" it
  8026. + if (!pList.isEmpty())
  8027. + {
  8028. + uint32 rand = urand(0, pList.getSize() - 1);
  8029. + for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
  8030. + {
  8031. + if (rand == 0)
  8032. + {
  8033. + Player* plr = itr->GetSource();
  8034. + if (plr && !plr->IsGameMaster() && plr->IsAlive())
  8035. + {
  8036. + // 50% chance for race cheering at you or faction cheering at you
  8037. + uint32 raceId = plr->GetRace();
  8038. + uint32 factionEntry = (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) ? NPC_SPECTATOR_ALLIANCE : NPC_SPECTATOR_HORDE;
  8039. + uint32 spectatorEntry = urand(0, 1) ? SpectatorData[raceId] : factionEntry;
  8040. +
  8041. + if (Creature* spectator = me->FindNearestCreature(spectatorEntry, 200.0f))
  8042. + spectator->AI()->Talk(EMOTE_SPECTATOR_CHEER, plr);
  8043. + break;
  8044. + }
  8045. + else
  8046. + continue;
  8047. + }
  8048. + else
  8049. + --rand;
  8050. + }
  8051. + }
  8052. + }
  8053. + events.ScheduleEvent(EVENT_CHEER_RND, 120s);
  8054. + break;
  8055. + // Phases below happen in Grand Champions encounter
  8056. + case EVENT_INTRODUCE:
  8057. + {
  8058. + // Introducing players to spectators
  8059. + bool foundPlr = false;
  8060. + Map::PlayerList const& players = me->GetMap()->GetPlayers();
  8061. + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  8062. + {
  8063. + Player* player = itr->GetSource();
  8064. +
  8065. + if (player->IsGameMaster() || !player->IsAlive())
  8066. + continue;
  8067. +
  8068. + GuidList::iterator i = std::find(PlayerEventList.begin(), PlayerEventList.end(), player->GetGUID());
  8069. + if (i != PlayerEventList.end())
  8070. + continue;
  8071. +
  8072. + // player has not been yet introduced
  8073. + uint32 x = PlayerEventList.size();
  8074. + if (x < 5 && IntroducePlrTxt[x])
  8075. + Talk(IntroducePlrTxt[x], player);
  8076. + else
  8077. + continue; // no text found, too many players?
  8078. +
  8079. + uint32 raceId = player->GetRace();
  8080. + if (Creature* spectator = me->FindNearestCreature(SpectatorData[raceId], 200.0f))
  8081. + spectator->AI()->Talk(EMOTE_SPECTATOR_CHEER, player);
  8082. +
  8083. + foundPlr = true;
  8084. + PlayerEventList.push_back(player->GetGUID());
  8085. + NextStep(7000, false, 0, EVENT_INTRODUCE);
  8086. + break;
  8087. + }
  8088. + // All players introduced, moving on
  8089. + if (!foundPlr)
  8090. + NextStep(16000, true, eventId);
  8091. + break;
  8092. + }
  8093. + case EVENT_CHAT_1:
  8094. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8095. + tirion->AI()->Talk(SAY_TIRION_INTRO_1);
  8096. + NextStep(8000, true, eventId);
  8097. + break;
  8098. + case EVENT_CHAT_2:
  8099. + // Tirion gets interrupted by Varian Wrynn or Garrosh Hellscream
  8100. + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
  8101. + {
  8102. + if (Creature* varian = instance->GetCreature(DATA_VARIAN))
  8103. + varian->AI()->Talk(SAY_VARIAN_INTRO_1);
  8104. + }
  8105. + else
  8106. + {
  8107. + if (Creature* garrosh = instance->GetCreature(DATA_GARROSH))
  8108. + garrosh->AI()->Talk(SAY_GARROSH_INTRO_1);
  8109. + }
  8110. + NextStep(6000, true, eventId);
  8111. + break;
  8112. + case EVENT_CHAT_3:
  8113. + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
  8114. + {
  8115. + if (Creature* jaina = instance->GetCreature(DATA_JAINA))
  8116. + jaina->AI()->Talk(SAY_JAINA_INTRO_1);
  8117. + }
  8118. + else
  8119. + {
  8120. + if (Creature* thrall = instance->GetCreature(DATA_THRALL))
  8121. + thrall->AI()->Talk(SAY_THRALL_INTRO_1);
  8122. + }
  8123. + NextStep(5000, true, eventId);
  8124. + break;
  8125. + case EVENT_CHAT_4:
  8126. + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
  8127. + {
  8128. + if (Creature* garrosh = instance->GetCreature(DATA_GARROSH))
  8129. + garrosh->AI()->Talk(SAY_GARROSH_INTRO_2);
  8130. + }
  8131. + else
  8132. + {
  8133. + if (Creature* varian = instance->GetCreature(DATA_VARIAN))
  8134. + varian->AI()->Talk(SAY_VARIAN_INTRO_2);
  8135. + }
  8136. + NextStep(8000, true, eventId);
  8137. + break;
  8138. + case EVENT_CHAT_5:
  8139. + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
  8140. + {
  8141. + if (Creature* thrall = instance->GetCreature(DATA_THRALL))
  8142. + thrall->AI()->Talk(SAY_THRALL_INTRO_2);
  8143. + }
  8144. + else
  8145. + {
  8146. + if (Creature* jaina = instance->GetCreature(DATA_JAINA))
  8147. + jaina->AI()->Talk(SAY_JAINA_INTRO_2);
  8148. + }
  8149. + NextStep(5000, true, eventId);
  8150. + break;
  8151. + case EVENT_CHAT_6:
  8152. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8153. + tirion->AI()->Talk(SAY_TIRION_INTRO_2);
  8154. + NextStep(6000, true, eventId);
  8155. + break;
  8156. + case EVENT_SUMMON_1:
  8157. + // Summoning first champion
  8158. + DoSummonNextGrandChampion();
  8159. + me->SetFacingTo(gateOrientation);
  8160. + NextStep(2000, true, eventId);
  8161. + break;
  8162. + case EVENT_OPEN_DOOR_1:
  8163. + // Opening doors
  8164. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), true);
  8165. + NextStep(500, true, eventId);
  8166. + break;
  8167. + case EVENT_INTRODUCE_BOSS_1:
  8168. + // Introducing first champion
  8169. + IntroduceChampion();
  8170. + NextStep(7500, true, eventId);
  8171. + break;
  8172. + case EVENT_CLOSE_DOOR_1:
  8173. + // Closing door
  8174. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), false);
  8175. + NextStep(8000, true, eventId);
  8176. + break;
  8177. + case EVENT_SUMMON_2:
  8178. + // Summoning second champion
  8179. + DoSummonNextGrandChampion();
  8180. + NextStep(2000, true, eventId);
  8181. + break;
  8182. + case EVENT_OPEN_DOOR_2:
  8183. + // Opening doors
  8184. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), true);
  8185. + NextStep(500, true, eventId);
  8186. + break;
  8187. + case EVENT_INTRODUCE_BOSS_2:
  8188. + // Introducing second champion
  8189. + IntroduceChampion();
  8190. + NextStep(7500, true, eventId);
  8191. + break;
  8192. + case EVENT_CLOSE_DOOR_2:
  8193. + // Closing door
  8194. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), false);
  8195. + NextStep(8000, true, eventId);
  8196. + break;
  8197. + case EVENT_SUMMON_3:
  8198. + // Summoning third and final champion
  8199. + DoSummonNextGrandChampion();
  8200. + NextStep(2000, true, eventId);
  8201. + break;
  8202. + case EVENT_OPEN_DOOR_3:
  8203. + // Opening doors
  8204. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), true);
  8205. + NextStep(500, true, eventId);
  8206. + break;
  8207. + case EVENT_INTRODUCE_BOSS_3:
  8208. + // Introducing third champion
  8209. + IntroduceChampion();
  8210. + NextStep(9500, true, eventId);
  8211. + break;
  8212. + case EVENT_CLOSE_DOOR_3:
  8213. + // Closing door and announcer walks to the gate
  8214. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), false);
  8215. + me->GetMotionMaster()->MovePoint(POINT_ENCOUNTER_1_WAIT, announcerEncounterPos);
  8216. + break;
  8217. + case EVENT_WAIT_1:
  8218. + // Lesser champions are moving to their respective positions
  8219. + NextStep(500, true, eventId);
  8220. + break;
  8221. + case EVENT_FACING:
  8222. + // Correcting facing
  8223. + me->SetFacingTo(centerOrientation);
  8224. + NextStep(5000, true, eventId);
  8225. + break;
  8226. + case EVENT_CHAT_7:
  8227. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8228. + tirion->AI()->Talk(SAY_TIRION_INTRO_3);
  8229. + NextStep(2000, true, eventId);
  8230. + break;
  8231. + case EVENT_AGGRO_1:
  8232. + // First wave of lesser champions aggroes
  8233. + for (GuidList::const_iterator itr = Champion1List.begin(); itr != Champion1List.end(); ++itr)
  8234. + {
  8235. + if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
  8236. + EnterAggressiveMode(summon);
  8237. + }
  8238. + break;
  8239. + case EVENT_CHAT_8:
  8240. + // Tirion congratulates players
  8241. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8242. + tirion->AI()->Talk(SAY_TIRION_OUTRO_1);
  8243. + break;
  8244. + // Phases below happen only if roleplaying event is skipped
  8245. + case EVENT_CHAT_9:
  8246. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8247. + tirion->AI()->Talk(SAY_TIRION_INTRO_2);
  8248. + NextStep(3000, true, eventId);
  8249. + break;
  8250. + case EVENT_SUMMON_1_SKIP:
  8251. + // Summoning first champion
  8252. + DoSummonNextGrandChampion(true);
  8253. + NextStep(2000, true, eventId);
  8254. + break;
  8255. + case EVENT_SUMMON_2_SKIP:
  8256. + // Summoning second champion
  8257. + DoSummonNextGrandChampion(true);
  8258. + NextStep(2000, true, eventId);
  8259. + break;
  8260. + case EVENT_SUMMON_3_SKIP:
  8261. + // Summoning third champion
  8262. + DoSummonNextGrandChampion(true);
  8263. + break;
  8264. + // Phases below happen in Argent Champion encounter
  8265. + case EVENT_MOVE_MIDDLE:
  8266. + // Moves into middle of arena
  8267. + me->GetMotionMaster()->MovePoint(POINT_START_ARGENT_CHAMP, me->GetHomePosition());
  8268. + break;
  8269. + case EVENT_SPAWN_ALL:
  8270. + // Spawns 9 adds and boss
  8271. + // Generating final positions for monks and other 2 adds follow the monk
  8272. + // when monk is in final position, then final positions are generated for other adds
  8273. + if (me->SummonCreature(uiArgentChampion, SpawnPosition))
  8274. + {
  8275. + for (uint8 i = 0; i < 3; ++i)
  8276. + {
  8277. + if (Creature* pMonk = me->SummonCreature(NPC_ARGENT_MONK, SpawnPosition))
  8278. + {
  8279. + pMonk->AI()->SetData(i, 0);
  8280. + if (Creature* pLightwielder = me->SummonCreature(NPC_ARGENT_LIGHWIELDER, SpawnPosition))
  8281. + {
  8282. + pLightwielder->AI()->SetData(i, 0);
  8283. + pLightwielder->GetMotionMaster()->MoveFollow(pMonk, 2.0f, float(M_PI));
  8284. + }
  8285. + if (Creature* pPriestess = me->SummonCreature(NPC_PRIESTESS, SpawnPosition))
  8286. + {
  8287. + pPriestess->AI()->SetData(i, 0);
  8288. + pPriestess->GetMotionMaster()->MoveFollow(pMonk, 2.0f, float(M_PI) / 2);
  8289. + }
  8290. + }
  8291. + }
  8292. + }
  8293. + NextStep(2000, true, eventId);
  8294. + break;
  8295. + case EVENT_OPEN_DOOR_4:
  8296. + // Opening doors
  8297. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), true);
  8298. + NextStep(2000, true, eventId);
  8299. + break;
  8300. + case EVENT_INTRODUCE_BOSS_4:
  8301. + // Introducing Argent Champion to spectators
  8302. + // Horde and alliance spectators cheer for Argent Champion
  8303. + if (Creature* pBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ARGENT_CHAMPION)))
  8304. + {
  8305. + if (pBoss->GetEntry() == NPC_EADRIC)
  8306. + Talk(SAY_INTRO_2_E, pBoss);
  8307. + else
  8308. + Talk(SAY_INTRO_2_P, pBoss);
  8309. + if (Creature* aSpectator = me->FindNearestCreature(NPC_SPECTATOR_ALLIANCE, 200.0f))
  8310. + aSpectator->AI()->Talk(EMOTE_SPECTATOR_CHEER, pBoss);
  8311. + if (Creature* hSpectator = me->FindNearestCreature(NPC_SPECTATOR_HORDE, 200.0f))
  8312. + hSpectator->AI()->Talk(EMOTE_SPECTATOR_CHEER, pBoss);
  8313. + }
  8314. + NextStep(10000, true, eventId);
  8315. + break;
  8316. + case EVENT_ARGENT_BOSS_WALK:
  8317. + // Argent Champion starts walking to arena
  8318. + if (Creature* pBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ARGENT_CHAMPION)))
  8319. + {
  8320. + pBoss->SetWalk(true);
  8321. + pBoss->GetMotionMaster()->MovePoint(0, 746.71f, 661.4f, 411.7f);
  8322. + }
  8323. + break;
  8324. + case EVENT_GO_TO_ARGENT_BOSS:
  8325. + // Announcer starts walking to Argent Champion
  8326. + instance->HandleGameObject(instance->GetGuidData(DATA_MAIN_GATE), false);
  8327. + me->GetMotionMaster()->MovePoint(POINT_ENCOUNTER_2_WAIT_1, 746.73f, 653.93f, 411.6f);
  8328. + NextStep(2000, true, eventId);
  8329. + break;
  8330. + case EVENT_CHAT_10:
  8331. + // Argent Champion talks
  8332. + if (Creature* pBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ARGENT_CHAMPION)))
  8333. + {
  8334. + if (pBoss->GetEntry() == NPC_EADRIC)
  8335. + {
  8336. + pBoss->AI()->Talk(SAY_EADRIC_INTRO_1, me);
  8337. + }
  8338. + else
  8339. + {
  8340. + pBoss->AI()->Talk(SAY_PALETRESS_INTRO_1, me);
  8341. + NextStep(6000, true, eventId);
  8342. + }
  8343. + }
  8344. + break;
  8345. + case EVENT_CHAT_11:
  8346. + // Paletress talks twice
  8347. + if (Creature* pBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ARGENT_CHAMPION)))
  8348. + {
  8349. + if (pBoss->GetEntry() == NPC_PALETRESS)
  8350. + pBoss->AI()->Talk(SAY_PALETRESS_INTRO_2, me);
  8351. + }
  8352. + break;
  8353. + case EVENT_WAIT_2:
  8354. + // After announcer reached position in front of Champion,
  8355. + // he goes to encounter position
  8356. + me->GetMotionMaster()->MovePoint(POINT_ENCOUNTER_2_WAIT_2, announcerEncounterPos);
  8357. + break;
  8358. + case EVENT_CHAT_12:
  8359. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8360. + tirion->AI()->Talk(SAY_TIRION_INTRO_4);
  8361. + break;
  8362. + // Phases below happen in The Black Knight encounter
  8363. + case EVENT_STEP_FORWARD:
  8364. + // Stepping forward
  8365. + me->GetMotionMaster()->MovePoint(POINT_ENCOUNTER_3_WAIT, 743.65f, 627.6f, 411.17f);
  8366. + break;
  8367. + case EVENT_CHAT_13:
  8368. + // Tirion congratulates champions and meanwhile Black Knight appears
  8369. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8370. + tirion->AI()->Talk(SAY_TIRION_INTRO_5);
  8371. + me->SummonCreature(VEHICLE_BLACK_KNIGHT, 780.69f, 669.61f, 463.66f, 3.77f);
  8372. + NextStep(6000, true, eventId);
  8373. + break;
  8374. + case EVENT_FACING_1:
  8375. + // Announcer turns towards Black Knight
  8376. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8377. + me->SetFacingToObject(knight);
  8378. + NextStep(2000, true, eventId);
  8379. + break;
  8380. + case EVENT_CHAT_14:
  8381. + // Announcer notifies everyone that something is near the rafters
  8382. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8383. + Talk(SAY_INTRO_3, knight);
  8384. + NextStep(1000, true, eventId);
  8385. + break;
  8386. + case EVENT_START_PATH:
  8387. + // Black Knight starts to fly down
  8388. + if (Creature* knightVehicle = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLACK_KNIGHT_VEHICLE)))
  8389. + {
  8390. + knightVehicle->AI()->SetData(1, 0);
  8391. + // We start attacking Black Knight without combat movement
  8392. + // so we keep facing him all the time
  8393. + if (knightVehicle->GetVehicleKit() && knightVehicle->GetVehicleKit()->GetPassenger(SEAT_ID_0))
  8394. + AttackStart(knightVehicle->GetVehicleKit()->GetPassenger(SEAT_ID_0));
  8395. + }
  8396. + break;
  8397. + case EVENT_CHAT_15:
  8398. + // Black Knight exits his vehicle and talks
  8399. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8400. + {
  8401. + knight->AI()->Talk(SAY_KNIGHT_INTRO_1, me);
  8402. + knight->ExitVehicle();
  8403. + knight->SetWalk(true);
  8404. + knight->GetMotionMaster()->MovePoint(0, 747.79f, 632.49f, 411.41f);
  8405. + }
  8406. + break;
  8407. + case EVENT_FACING_2:
  8408. + // Black Knight corrects facing and we're stopping attacking
  8409. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8410. + knight->SetFacingToObject(me);
  8411. + me->AttackStop();
  8412. + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  8413. + NextStep(1500, true, eventId);
  8414. + break;
  8415. + case EVENT_STUN_ANNOUNCER:
  8416. + // Announcer gets strangulated
  8417. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8418. + knight->CastSpell(me, SPELL_DEATHS_RESPITE);
  8419. + NextStep(3000, true, eventId);
  8420. + break;
  8421. + case EVENT_CHAT_16:
  8422. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8423. + tirion->AI()->Talk(SAY_TIRION_INTRO_6, me);
  8424. + NextStep(1000, true, eventId);
  8425. + break;
  8426. + case EVENT_KNOCK_ANNOUNCER:
  8427. + // Announcer gets pushed to death and Black Knight's vehicle flies away
  8428. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8429. + knight->CastSpell(me, SPELL_DEATHS_PUSH);
  8430. + if (Creature* knightVehicle = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLACK_KNIGHT_VEHICLE)))
  8431. + knightVehicle->AI()->SetData(2, 0);
  8432. + NextStep(3000, true, eventId);
  8433. + break;
  8434. + case EVENT_CHAT_17:
  8435. + // Black Knight moves to center
  8436. + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
  8437. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8438. + {
  8439. + knight->AI()->Talk(SAY_KNIGHT_INTRO_2, me);
  8440. + knight->GetMotionMaster()->MovePoint(1, 747.21f, 622.75f, 411.42f);
  8441. + }
  8442. + NextStep(14000, true, eventId);
  8443. + break;
  8444. + case EVENT_CHAT_18:
  8445. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8446. + knight->AI()->Talk(SAY_KNIGHT_INTRO_3, me);
  8447. + NextStep(3000, true, eventId);
  8448. + break;
  8449. + case EVENT_AGGRO_2:
  8450. + // Entering aggressive
  8451. + if (Creature* knight = instance->GetCreature(DATA_BLACK_KNIGHT))
  8452. + {
  8453. + knight->SetWalk(false);
  8454. + knight->SetHomePosition(knight->GetPosition());
  8455. + knight->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
  8456. + knight->SetReactState(REACT_AGGRESSIVE);
  8457. + }
  8458. + NextStep(1000, true, eventId);
  8459. + break;
  8460. + case EVENT_CHAT_19:
  8461. + // Varian or Garrosh tells players to kill him
  8462. + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
  8463. + {
  8464. + if (Creature* varian = instance->GetCreature(DATA_VARIAN))
  8465. + varian->AI()->Talk(SAY_VARIAN_INTRO_3, me);
  8466. + }
  8467. + else
  8468. + {
  8469. + if (Creature* garrosh = instance->GetCreature(DATA_GARROSH))
  8470. + garrosh->AI()->Talk(SAY_GARROSH_INTRO_3, me);
  8471. + }
  8472. + break;
  8473. + case EVENT_CHAT_20:
  8474. + // After Black Knight is dead, a small outro event happens
  8475. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8476. + tirion->AI()->Talk(SAY_TIRION_OUTRO_2, me);
  8477. + NextStep(6000, true, eventId);
  8478. + break;
  8479. + case EVENT_CHAT_21:
  8480. + if (Creature* tirion = instance->GetCreature(DATA_TIRION))
  8481. + tirion->AI()->Talk(SAY_TIRION_OUTRO_3, me);
  8482. + NextStep(7000, true, eventId);
  8483. + break;
  8484. + case EVENT_CHAT_22:
  8485. + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
  8486. + {
  8487. + if (Creature* varian = instance->GetCreature(DATA_VARIAN))
  8488. + varian->AI()->Talk(SAY_VARIAN_OUTRO_1, me);
  8489. + }
  8490. + else
  8491. + {
  8492. + if (Creature* thrall = instance->GetCreature(DATA_THRALL))
  8493. + thrall->AI()->Talk(SAY_THRALL_OUTRO_1, me);
  8494. + }
  8495. + break;
  8496. + default:
  8497. + break;
  8498. + }
  8499. + }
  8500. +
  8501. + if (!UpdateVictim())
  8502. + return;
  8503. +
  8504. + // No combat for announcer
  8505. + }
  8506. +
  8507. + bool OnGossipHello(Player* player) override
  8508. + {
  8509. + InstanceScript* instance = me->GetInstanceScript();
  8510. + if (instance)
  8511. + {
  8512. + if (player->IsGameMaster())
  8513. + {
  8514. + // Gamemaster mode on you can choose which encounter you start
  8515. + // you can't though do Grand Champions encounter more than once per instance ID
  8516. + // other encounters you can do as many times as you like
  8517. + if ((instance->GetBossState(DATA_GRAND_CHAMPIONS) == NOT_STARTED) &&
  8518. + (instance->GetBossState(DATA_ARGENT_CHALLENGE) == NOT_STARTED) &&
  8519. + (instance->GetBossState(DATA_BLACK_KNIGHT) == NOT_STARTED))
  8520. + {
  8521. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "[GM] Start Grand Champions encounter, unskipped roleplaying", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
  8522. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "[GM] Start Grand Champions encounter, skipped roleplaying", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  8523. + }
  8524. + if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == NOT_STARTED)
  8525. + {
  8526. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "[GM] Start Eadric the Pure encounter", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
  8527. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "[GM] Start Argent Confessor Paletress encounter", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
  8528. + }
  8529. + if (instance->GetBossState(DATA_BLACK_KNIGHT) == NOT_STARTED)
  8530. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "[GM] Start The Black Knight encounter", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
  8531. + SendGossipMenuFor(player, 1, me->GetGUID());
  8532. + }
  8533. + else if ((instance->GetBossState(DATA_GRAND_CHAMPIONS) == NOT_STARTED) && player->GetVehicleBase())
  8534. + {
  8535. + // If Grand Champions encounter hasn't been started and the player is mounted
  8536. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
  8537. + // Patch 3.2.2: "There is now an option in the herald's dialogue to skip the introductory scripted scene if everyone in the party has already seen it."
  8538. + if (HasAllSeenEvent(player))
  8539. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT_SKIP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  8540. + SendGossipMenuFor(player, GOSSIP_TEXT_FIRST_BOSS, me->GetGUID());
  8541. + }
  8542. + else if ((instance->GetBossState(DATA_GRAND_CHAMPIONS) == NOT_STARTED) && !player->GetVehicleBase())
  8543. + {
  8544. + // If Grand Champions encounter hasn't been started and the player is not mounted
  8545. + if (player->GetTeam() == HORDE)
  8546. + SendGossipMenuFor(player, GOSSIP_TEXT_UNMOUNTED_H, me->GetGUID());
  8547. + else
  8548. + SendGossipMenuFor(player, GOSSIP_TEXT_UNMOUNTED_A, me->GetGUID());
  8549. + }
  8550. + else if (instance->GetBossState(DATA_GRAND_CHAMPIONS) == DONE && (instance->GetBossState(DATA_ARGENT_CHALLENGE) == NOT_STARTED))
  8551. + {
  8552. + // If Grand Champions encounter is done and Eadric the Pure nor Argent Confessor Paletress encounters have been started
  8553. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  8554. + SendGossipMenuFor(player, GOSSIP_TEXT_SECOND_BOSS, me->GetGUID());
  8555. + }
  8556. + else if (instance->GetBossState(DATA_ARGENT_CHALLENGE) == DONE && (instance->GetBossState(DATA_BLACK_KNIGHT) == NOT_STARTED))
  8557. + {
  8558. + // If Grand Champions, Eadric the Pure and Argent Confessor Paletress encounters are all done but Black Knight encounter has not been started
  8559. + AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
  8560. + SendGossipMenuFor(player, GOSSIP_TEXT_THIRD_BOSS, me->GetGUID());
  8561. + }
  8562. + }
  8563. + return true;
  8564. + }
  8565. +
  8566. + bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
  8567. + {
  8568. + uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
  8569. + ClearGossipMenuFor(player);
  8570. + CloseGossipMenuFor(player);
  8571. + switch (action)
  8572. + {
  8573. + case GOSSIP_ACTION_INFO_DEF + 1:
  8574. + StartEncounter();
  8575. + break;
  8576. + case GOSSIP_ACTION_INFO_DEF + 2:
  8577. + StartEncounter(true);
  8578. + break;
  8579. + case GOSSIP_ACTION_INFO_DEF + 3:
  8580. + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  8581. + uiArgentChampion = NPC_EADRIC;
  8582. + DoStartArgentChampionEncounter();
  8583. + break;
  8584. + case GOSSIP_ACTION_INFO_DEF + 4:
  8585. + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  8586. + uiArgentChampion = NPC_PALETRESS;
  8587. + DoStartArgentChampionEncounter();
  8588. + break;
  8589. + case GOSSIP_ACTION_INFO_DEF + 5:
  8590. + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
  8591. + DoStartBlackKnight();
  8592. + break;
  8593. + default:
  8594. + break;
  8595. + }
  8596. + return true;
  8597. + }
  8598. +
  8599. + bool HasAllSeenEvent(Player* player)
  8600. + {
  8601. + if (!player)
  8602. + return false;
  8603. +
  8604. + if (player->IsGameMaster())
  8605. + return true;
  8606. +
  8607. + bool seen = true;
  8608. + Map::PlayerList const& players = player->GetMap()->GetPlayers();
  8609. + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
  8610. + {
  8611. + if (Player const* plr = itr->GetSource())
  8612. + {
  8613. + // if everyone from your group have completed one of the Trial of the Champion achievements, you have option to skip the event
  8614. + // maybe not the correct way to do it but I couldn't figure out better
  8615. + if (!plr->HasAchieved(4298) /* Heroic ToC (alliance) */ && !plr->HasAchieved(3778) /* Normal ToC (horde) */ && !plr->HasAchieved(4297) /* Heroic ToC (horde) */ && !plr->HasAchieved(4296) /* Normal ToC (alliance) */)
  8616. + {
  8617. + seen = false;
  8618. + break;
  8619. + }
  8620. + }
  8621. + }
  8622. + return seen;
  8623. + }
  8624. + };
  8625. +
  8626. + CreatureAI* GetAI(Creature* creature) const override
  8627. + {
  8628. + return new npc_announcer_toc5AI(creature);
  8629. + }
  8630. +};
  8631. +
  8632. +void AddSC_trial_of_the_champion()
  8633. +{
  8634. + new npc_announcer_toc5();
  8635. +}
  8636. diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h
  8637. dissimilarity index 74%
  8638. index 2da7435e32..0b50d18fac 100644
  8639. --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h
  8640. +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h
  8641. @@ -1,139 +1,297 @@
  8642. -/*
  8643. - * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
  8644. - *
  8645. - * This program is free software; you can redistribute it and/or modify it
  8646. - * under the terms of the GNU General Public License as published by the
  8647. - * Free Software Foundation; either version 2 of the License, or (at your
  8648. - * option) any later version.
  8649. - *
  8650. - * This program is distributed in the hope that it will be useful, but WITHOUT
  8651. - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  8652. - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  8653. - * more details.
  8654. - *
  8655. - * You should have received a copy of the GNU General Public License along
  8656. - * with this program. If not, see <http://www.gnu.org/licenses/>.
  8657. - */
  8658. -
  8659. -#ifndef DEF_TOC_H
  8660. -#define DEF_TOC_H
  8661. -
  8662. -#include "CreatureAIImpl.h"
  8663. -
  8664. -#define ToCScriptName "instance_trial_of_the_champion"
  8665. -#define DataHeader "TC"
  8666. -
  8667. -enum TCData
  8668. -{
  8669. - BOSS_GRAND_CHAMPIONS = 0,
  8670. - BOSS_ARGENT_CHALLENGE_E = 1,
  8671. - BOSS_ARGENT_CHALLENGE_P = 2,
  8672. - BOSS_BLACK_KNIGHT = 3,
  8673. -
  8674. - DATA_MOVEMENT_DONE,
  8675. - DATA_LESSER_CHAMPIONS_DEFEATED,
  8676. - DATA_START,
  8677. - DATA_IN_POSITION,
  8678. - DATA_ARGENT_SOLDIER_DEFEATED
  8679. -};
  8680. -
  8681. -enum TCData64
  8682. -{
  8683. - DATA_ANNOUNCER,
  8684. - DATA_MAIN_GATE,
  8685. -
  8686. - DATA_GRAND_CHAMPION_VEHICLE_1,
  8687. - DATA_GRAND_CHAMPION_VEHICLE_2,
  8688. - DATA_GRAND_CHAMPION_VEHICLE_3,
  8689. -
  8690. - DATA_GRAND_CHAMPION_1,
  8691. - DATA_GRAND_CHAMPION_2,
  8692. - DATA_GRAND_CHAMPION_3
  8693. -};
  8694. -
  8695. -enum TCCreatureIds
  8696. -{
  8697. - // Horde Champions
  8698. - NPC_MOKRA = 35572,
  8699. - NPC_ERESSEA = 35569,
  8700. - NPC_RUNOK = 35571,
  8701. - NPC_ZULTORE = 35570,
  8702. - NPC_VISCERI = 35617,
  8703. -
  8704. - // Alliance Champions
  8705. - NPC_JACOB = 34705,
  8706. - NPC_AMBROSE = 34702,
  8707. - NPC_COLOSOS = 34701,
  8708. - NPC_JAELYNE = 34657,
  8709. - NPC_LANA = 34703,
  8710. -
  8711. - NPC_EADRIC = 35119,
  8712. - NPC_PALETRESS = 34928,
  8713. -
  8714. - NPC_ARGENT_LIGHWIELDER = 35309,
  8715. - NPC_ARGENT_MONK = 35305,
  8716. - NPC_PRIESTESS = 35307,
  8717. -
  8718. - NPC_BLACK_KNIGHT = 35451,
  8719. -
  8720. - NPC_RISEN_JAEREN = 35545,
  8721. - NPC_RISEN_ARELAS = 35564,
  8722. -
  8723. - NPC_JAEREN = 35004,
  8724. - NPC_ARELAS = 35005
  8725. -};
  8726. -
  8727. -enum TCGameObjects
  8728. -{
  8729. - GO_MAIN_GATE = 195647,
  8730. -
  8731. - GO_CHAMPIONS_LOOT = 195709,
  8732. - GO_CHAMPIONS_LOOT_H = 195710,
  8733. -
  8734. - GO_EADRIC_LOOT = 195374,
  8735. - GO_EADRIC_LOOT_H = 195375,
  8736. -
  8737. - GO_PALETRESS_LOOT = 195323,
  8738. - GO_PALETRESS_LOOT_H = 195324
  8739. -};
  8740. -
  8741. -enum TCVehicles
  8742. -{
  8743. - //Grand Champions Alliance Vehicles
  8744. - VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT = 35637,
  8745. - VEHICLE_AMBROSE_BOLTSPARK_MOUNT = 35633,
  8746. - VEHICLE_COLOSOS_MOUNT = 35768,
  8747. - VEHICLE_EVENSONG_MOUNT = 34658,
  8748. - VEHICLE_LANA_STOUTHAMMER_MOUNT = 35636,
  8749. - //Faction Champions (ALLIANCE)
  8750. - VEHICLE_DARNASSIA_NIGHTSABER = 33319,
  8751. - VEHICLE_EXODAR_ELEKK = 33318,
  8752. - VEHICLE_STORMWIND_STEED = 33217,
  8753. - VEHICLE_GNOMEREGAN_MECHANOSTRIDER = 33317,
  8754. - VEHICLE_IRONFORGE_RAM = 33316,
  8755. - //Grand Champions Horde Vehicles
  8756. - VEHICLE_MOKRA_SKILLCRUSHER_MOUNT = 35638,
  8757. - VEHICLE_ERESSEA_DAWNSINGER_MOUNT = 35635,
  8758. - VEHICLE_RUNOK_WILDMANE_MOUNT = 35640,
  8759. - VEHICLE_ZUL_TORE_MOUNT = 35641,
  8760. - VEHICLE_DEATHSTALKER_VESCERI_MOUNT = 35634,
  8761. - //Faction Champions (HORDE)
  8762. - VEHICLE_FORSAKE_WARHORSE = 33324,
  8763. - VEHICLE_THUNDER_BLUFF_KODO = 33322,
  8764. - VEHICLE_ORGRIMMAR_WOLF = 33320,
  8765. - VEHICLE_SILVERMOON_HAWKSTRIDER = 33323,
  8766. - VEHICLE_DARKSPEAR_RAPTOR = 33321,
  8767. -
  8768. - VEHICLE_ARGENT_WARHORSE = 35644,
  8769. - VEHICLE_ARGENT_BATTLEWORG = 36558,
  8770. -
  8771. - VEHICLE_BLACK_KNIGHT = 35491
  8772. -};
  8773. -
  8774. -template <class AI, class T>
  8775. -inline AI* GetTrialOfTheChampionAI(T* obj)
  8776. -{
  8777. - return GetInstanceAI<AI>(obj, ToCScriptName);
  8778. -}
  8779. -
  8780. -#endif
  8781. +/*
  8782. + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  8783. + * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  8784. + *
  8785. + * This program is free software; you can redistribute it and/or modify it
  8786. + * under the terms of the GNU General Public License as published by the
  8787. + * Free Software Foundation; either version 2 of the License, or (at your
  8788. + * option) any later version.
  8789. + *
  8790. + * This program is distributed in the hope that it will be useful, but WITHOUT
  8791. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  8792. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  8793. + * more details.
  8794. + *
  8795. + * You should have received a copy of the GNU General Public License along
  8796. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  8797. + */
  8798. +
  8799. +#ifndef TRIAL_OF_CHAMPION_H_
  8800. +#define TRIAL_OF_CHAMPION_H_
  8801. +
  8802. +#define ToCScriptName "instance_trial_of_the_champion"
  8803. +#define DataHeader "TC"
  8804. +
  8805. +Position const LesserChampLoc[18] =
  8806. +{
  8807. + // Horde Lesser Champions
  8808. + { 715.12f, 612.69f, 411.77f },
  8809. + { 715.97f, 618.20f, 411.56f },
  8810. + { 716.55f, 623.53f, 411.79f },
  8811. + { 717.10f, 627.32f, 411.83f },
  8812. + { 717.91f, 632.39f, 411.87f },
  8813. + { 718.54f, 636.32f, 411.89f },
  8814. + { 718.82f, 641.95f, 411.90f },
  8815. + { 719.28f, 645.82f, 411.91f },
  8816. + { 719.86f, 650.74f, 411.92f },
  8817. + // Alliance Lesser Champions
  8818. + { 774.66f, 600.71f, 411.71f },
  8819. + { 775.31f, 604.16f, 411.75f },
  8820. + { 775.96f, 607.60f, 411.76f },
  8821. + { 776.95f, 612.87f, 411.76f },
  8822. + { 777.60f, 616.31f, 411.76f },
  8823. + { 778.22f, 619.64f, 411.71f },
  8824. + { 779.11f, 624.34f, 411.83f },
  8825. + { 779.69f, 627.44f, 411.87f },
  8826. + { 780.34f, 630.89f, 411.89f }
  8827. +};
  8828. +
  8829. +Position const GrandChampFinalLoc[6] =
  8830. +{
  8831. + // Horde Grand Champions
  8832. + { 706.49f, 618.48f, 411.88f },
  8833. + { 709.00f, 633.73f, 411.92f },
  8834. + { 709.17f, 646.25f, 412.39f },
  8835. + // Alliance Grand Champions
  8836. + { 780.96f, 603.13f, 411.84f },
  8837. + { 783.76f, 615.98f, 411.84f },
  8838. + { 785.75f, 625.89f, 411.89f }
  8839. +};
  8840. +
  8841. +Position const announcerEncounterPos = { 732.5243f, 663.007f, 412.3932f };
  8842. +Position const announcerWaitPos = { 742.7739f, 629.849f, 411.1722f };
  8843. +Position const bossExitPos = { 746.776f, 665.221f, 411.743f, 4.82f };
  8844. +
  8845. +float const hordeOrientation = 6.175f; // Facing towards alliance spectators
  8846. +float const allianceOrientation = 3.114f; // Facing towards horde spectators
  8847. +float const gateOrientation = 1.582f; // Facing towards main gate
  8848. +float const centerOrientation = 4.714f; // Facing towards the center of arena
  8849. +
  8850. +enum DataTypes
  8851. +{
  8852. + // Encounter States/Boss GUIDs
  8853. + DATA_GRAND_CHAMPIONS,
  8854. + DATA_ARGENT_CHALLENGE,
  8855. + DATA_BLACK_KNIGHT,
  8856. +
  8857. + MAX_ENCOUNTER,
  8858. +
  8859. + // Additional Data
  8860. + DATA_ANNOUNCER,
  8861. + DATA_MAIN_GATE,
  8862. + DATA_TIRION,
  8863. + DATA_VARIAN,
  8864. + DATA_JAINA,
  8865. + DATA_GARROSH,
  8866. + DATA_THRALL,
  8867. +
  8868. + DATA_CHAMPION_S_CACHE,
  8869. + DATA_EADRIC_S_CACHE,
  8870. + DATA_CONFESSOR_S_CACHE,
  8871. +
  8872. + DATA_TEAM_IN_INSTANCE,
  8873. +
  8874. + DATA_LESSER_CHAMPIONS_PREPARE,
  8875. + DATA_LESSER_CHAMPIONS_DEFEATED,
  8876. + DATA_START,
  8877. + DATA_REMOVE_VEHICLES,
  8878. + DATA_GRAND_CHAMPIONS_DONE,
  8879. + DATA_ARGENT_CHAMPION_PREPARE,
  8880. + DATA_ARGENT_SOLDIER_DEFEATED,
  8881. + DATA_BLACK_KNIGHT_PREPARE,
  8882. + DATA_BLACK_KNIGHT_PRECAST,
  8883. + DATA_BLACK_KNIGHT_DONE,
  8884. +
  8885. + DATA_GRAND_CHAMPION_VEHICLE_1,
  8886. + DATA_GRAND_CHAMPION_VEHICLE_2,
  8887. + DATA_GRAND_CHAMPION_VEHICLE_3,
  8888. +
  8889. + DATA_GRAND_CHAMPION_1,
  8890. + DATA_GRAND_CHAMPION_2,
  8891. + DATA_GRAND_CHAMPION_3,
  8892. +
  8893. + DATA_ARGENT_CHAMPION,
  8894. +
  8895. + DATA_BLACK_KNIGHT_VEHICLE
  8896. +};
  8897. +
  8898. +enum Creatures
  8899. +{
  8900. + // Horde Champions
  8901. + NPC_MOKRA = 35572,
  8902. + NPC_ERESSEA = 35569,
  8903. + NPC_RUNOK = 35571,
  8904. + NPC_ZULTORE = 35570,
  8905. + NPC_VISCERI = 35617,
  8906. +
  8907. + // Alliance Champions
  8908. + NPC_JACOB = 34705,
  8909. + NPC_AMBROSE = 34702,
  8910. + NPC_COLOSOS = 34701,
  8911. + NPC_JAELYNE = 34657,
  8912. + NPC_LANA = 34703,
  8913. +
  8914. + // Horde Lesser Champions
  8915. + NPC_ORGRIMMAR_CHAMPION = 35314,
  8916. + NPC_SILVERMOON_CHAMPION = 35326,
  8917. + NPC_THUNDER_BLUFF_CHAMPION = 35325,
  8918. + NPC_SEN_JIN_CHAMPION = 35323,
  8919. + NPC_UNDERCITY_CHAMPION = 35327,
  8920. +
  8921. + // Alliance Lesser Champions
  8922. + NPC_STORMWIND_CHAMPION = 35328,
  8923. + NPC_GNOMEREGAN_CHAMPION = 35331,
  8924. + NPC_EXODAR_CHAMPION = 35330,
  8925. + NPC_DARNASSUS_CHAMPION = 35332,
  8926. + NPC_IRONFORGE_CHAMPION = 35329,
  8927. +
  8928. + // Argent Champions
  8929. + NPC_EADRIC = 35119,
  8930. + NPC_PALETRESS = 34928,
  8931. +
  8932. + NPC_ARGENT_LIGHWIELDER = 35309,
  8933. + NPC_ARGENT_MONK = 35305,
  8934. + NPC_PRIESTESS = 35307,
  8935. +
  8936. + // Memories
  8937. + NPC_MEMORY_HOGGER = 34942,
  8938. + NPC_MEMORY_VANCLEEF = 35028,
  8939. + NPC_MEMORY_MUTANUS = 35029,
  8940. + NPC_MEMORY_HEROD = 35030,
  8941. + NPC_MEMORY_LUCIFRON = 35031,
  8942. + NPC_MEMORY_THUNDERAAN = 35032,
  8943. + NPC_MEMORY_CHROMAGGUS = 35033,
  8944. + NPC_MEMORY_HAKKAR = 35034,
  8945. + NPC_MEMORY_VEKNILASH = 35036,
  8946. + NPC_MEMORY_KALITHRESH = 35037,
  8947. + NPC_MEMORY_MALCHEZAAR = 35038,
  8948. + NPC_MEMORY_GRUUL = 35039,
  8949. + NPC_MEMORY_VASHJ = 35040,
  8950. + NPC_MEMORY_ARCHIMONDE = 35041,
  8951. + NPC_MEMORY_ILLIDAN = 35042,
  8952. + NPC_MEMORY_DELRISSA = 35043,
  8953. + NPC_MEMORY_MURU = 35044,
  8954. + NPC_MEMORY_INGVAR = 35045,
  8955. + NPC_MEMORY_CYANIGOSA = 35046,
  8956. + NPC_MEMORY_ECK = 35047,
  8957. + NPC_MEMORY_ONYXIA = 35048,
  8958. + NPC_MEMORY_HEIGAN = 35049,
  8959. + NPC_MEMORY_IGNIS = 35050,
  8960. + NPC_MEMORY_VEZAX = 35051,
  8961. + NPC_MEMORY_ALGALON = 35052,
  8962. +
  8963. + // The Black Knight
  8964. + NPC_BLACK_KNIGHT = 35451,
  8965. +
  8966. + NPC_RISEN_GHOUL = 35590,
  8967. + NPC_RISEN_JAEREN = 35545,
  8968. + NPC_RISEN_ARELAS = 35564,
  8969. + NPC_DESECRATION_STALKER = 35614,
  8970. +
  8971. + // Announcers
  8972. + NPC_JAEREN = 35004,
  8973. + NPC_ARELAS = 35005,
  8974. +
  8975. + // Spectators
  8976. + NPC_TIRION = 34996,
  8977. + NPC_JAINA = 34992,
  8978. + NPC_VARIAN = 34990,
  8979. + NPC_THRALL = 34994,
  8980. + NPC_GARROSH = 34995,
  8981. + NPC_SPECTATOR_HORDE = 34883,
  8982. + NPC_SPECTATOR_ALLIANCE = 34887,
  8983. + NPC_SPECTATOR_HUMAN = 34900,
  8984. + NPC_SPECTATOR_ORC = 34901,
  8985. + NPC_SPECTATOR_TROLL = 34902,
  8986. + NPC_SPECTATOR_TAUREN = 34903,
  8987. + NPC_SPECTATOR_BELF = 34904,
  8988. + NPC_SPECTATOR_UNDEAD = 34905,
  8989. + NPC_SPECTATOR_DWARF = 34906,
  8990. + NPC_SPECTATOR_DRAENEI = 34908,
  8991. + NPC_SPECTATOR_NELF = 34909,
  8992. + NPC_SPECTATOR_GNOME = 34910
  8993. +};
  8994. +
  8995. +enum GameObjects
  8996. +{
  8997. + GO_MAIN_GATE = 195647,
  8998. + GO_NORTH_PORTCULLIS = 195650,
  8999. +
  9000. + GO_CHAMPION_S_CACHE = 195709,
  9001. + GO_CHAMPION_S_CACHE_H = 195710,
  9002. +
  9003. + GO_EADRIC_S_CACHE = 195374,
  9004. + GO_EADRIC_S_CACHE_H = 195375,
  9005. +
  9006. + GO_CONFESSOR_S_CACHE = 195323,
  9007. + GO_CONFESSOR_S_CACHE_H = 195324
  9008. +};
  9009. +
  9010. +enum Vehicles
  9011. +{
  9012. + // Grand Champions Alliance Vehicles
  9013. + VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT = 35637,
  9014. + VEHICLE_AMBROSE_BOLTSPARK_MOUNT = 35633,
  9015. + VEHICLE_COLOSOS_MOUNT = 35768,
  9016. + VEHICLE_EVENSONG_MOUNT = 34658,
  9017. + VEHICLE_LANA_STOUTHAMMER_MOUNT = 35636,
  9018. +
  9019. + // Grand Champions Horde Vehicles
  9020. + VEHICLE_MOKRA_SKULLCRUSHER_MOUNT = 35638,
  9021. + VEHICLE_ERESSEA_DAWNSINGER_MOUNT = 35635,
  9022. + VEHICLE_RUNOK_WILDMANE_MOUNT = 35640,
  9023. + VEHICLE_ZUL_TORE_MOUNT = 35641,
  9024. + VEHICLE_DEATHSTALKER_VESCERI_MOUNT = 35634,
  9025. +
  9026. + // Player vehicles
  9027. + VEHICLE_ARGENT_WARHORSE_COSMETIC = 35644,
  9028. + VEHICLE_ARGENT_WARHORSE_A = 36557,
  9029. + VEHICLE_ARGENT_BATTLEWORG_H = 36558,
  9030. + VEHICLE_ARGENT_BATTLEWORG_COSMETIC = 36559,
  9031. +
  9032. + // The Black Knight's vehicle
  9033. + VEHICLE_BLACK_KNIGHT = 35491
  9034. +};
  9035. +
  9036. +enum WaypointData
  9037. +{
  9038. + DATA_GENERATE_WAYPOINTS_FOR_BOSS_1 = 1,
  9039. + DATA_GENERATE_WAYPOINTS_FOR_BOSS_2,
  9040. + DATA_GENERATE_WAYPOINTS_FOR_BOSS_3,
  9041. + DATA_GENERATE_WAYPOINTS_FOR_ADDS
  9042. +};
  9043. +
  9044. +enum WaypointPaths
  9045. +{
  9046. + WAYPOINT_MAP_BOSS_1 = 1,
  9047. + WAYPOINT_MAP_BOSS_2,
  9048. + WAYPOINT_MAP_BOSS_3,
  9049. + WAYPOINT_MAP_ADDS
  9050. +};
  9051. +
  9052. +enum Seats
  9053. +{
  9054. + SEAT_ID_0 = 0
  9055. +};
  9056. +
  9057. +enum PennantSpells
  9058. +{
  9059. + SPELL_PENNANT_DARNASSUS = 63406,
  9060. + SPELL_PENNANT_EXODAR = 63423,
  9061. + SPELL_PENNANT_GNOMEREGAN = 63396,
  9062. + SPELL_PENNANT_IRONFORGE = 63427,
  9063. + SPELL_PENNANT_ORGRIMMAR = 63433,
  9064. + SPELL_PENNANT_SEN_JIN = 63399,
  9065. + SPELL_PENNANT_SILVERMOON = 63403,
  9066. + SPELL_PENNANT_STORMWIND = 62594,
  9067. + SPELL_PENNANT_THUNDER_BLUFF = 63436,
  9068. + SPELL_PENNANT_UNDERCITY = 63430
  9069. +};
  9070. +
  9071. +template<class AI>
  9072. +AI* GetTrialOfChampionAI(Creature* creature)
  9073. +{
  9074. + return GetInstanceAI<AI>(creature, ToCScriptName);
  9075. +}
  9076. +
  9077. +#endif // TRIAL_OF_CHAMPION_H_
  9078. --
  9079. 2.30.0.windows.2
  9080.  
  9081.  
Add Comment
Please, Sign In to add comment