Guest User

Untitled

a guest
Apr 21st, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.72 KB | None | 0 0
  1. */
  2.  
  3. #include "ScriptPCH.h"
  4. #include "ObjectMgr.h"
  5. #include "ScriptMgr.h"
  6. #include "ScriptedCreature.h"
  7. #include "SpellScript.h"
  8. #include "Spell.h"
  9. #include "SpellAuraEffects.h"
  10.  
  11. //
  12. // Emerald Dragon NPCs and IDs (kept here for reference)
  13. //
  14.  
  15. enum EmeraldDragonNPC
  16. {
  17. NPC_DREAM_FOG = 15224,
  18. DRAGON_YSONDRE = 14887,
  19. DRAGON_LETHON = 14888,
  20. DRAGON_EMERISS = 14889,
  21. DRAGON_TAERAR = 14890,
  22. };
  23.  
  24. //
  25. // Emerald Dragon Spells (used for the dragons)
  26. //
  27.  
  28. enum EmeraldDragonSpells
  29. {
  30. SPELL_TAIL_SWEEP = 15847, // tail sweep - slap everything behind dragon (2 seconds interval)
  31. SPELL_SUMMON_PLAYER = 24776, // teleport highest threat player in front of dragon if wandering off
  32. SPELL_DREAM_FOG = 24777, // auraspell for Dream Fog NPC (15224)
  33. SPELL_SLEEP = 24778, // sleep triggerspell (used for Dream Fog)
  34. SPELL_SEEPING_FOG_LEFT = 24813, // dream fog - summon left
  35. SPELL_SEEPING_FOG_RIGHT = 24814, // dream fog - summon right
  36. SPELL_NOXIOUS_BREATH = 24818,
  37. SPELL_MARK_OF_NATURE = 25040, // Mark of Nature trigger (applied on target death - 15 minutes of being suspectible to Aura Of Nature)
  38. SPELL_MARK_OF_NATURE_AURA = 25041, // Mark of Nature (passive marker-test, ticks every 10 seconds from boss, triggers spellID 25042 (scripted)
  39. SPELL_AURA_OF_NATURE = 25043, // Stun for 2 minutes (used when SPELL_MARK_OF_NATURE exists on the target)
  40. };
  41.  
  42. //
  43. // Emerald Dragon Eventlists (shared and specials)
  44. //
  45.  
  46. enum Events
  47. {
  48. // General events for all dragons
  49. EVENT_SEEPING_FOG = 1,
  50. EVENT_NOXIOUS_BREATH,
  51. EVENT_TAIL_SWEEP,
  52.  
  53. // Ysondre
  54. EVENT_LIGHTNING_WAVE,
  55. EVENT_SUMMON_DRUID_SPIRITS,
  56.  
  57. // Lethon
  58. EVENT_SHADOW_BOLT_WHIRL,
  59.  
  60. // Emeriss
  61. EVENT_VOLATILE_INFECTION,
  62. EVENT_CORRUPTION_OF_EARTH,
  63.  
  64. // Taerar
  65. EVENT_ARCANE_BLAST,
  66. EVENT_BELLOWING_ROAR,
  67. };
  68.  
  69. /*
  70. * ---
  71. * --- Emerald Dragons : Base AI-structure used for all the Emerald dragons
  72. * ---
  73. */
  74.  
  75. struct emerald_dragonAI : public WorldBossAI
  76. {
  77. emerald_dragonAI(Creature* creature) : WorldBossAI(creature)
  78. {
  79. // me->m_CombatDistance = 12.0f;
  80. // me->m_SightDistance = 60.0f;
  81. }
  82.  
  83. void Reset()
  84. {
  85. _Reset();
  86. me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
  87. me->SetReactState(REACT_AGGRESSIVE);
  88. DoCast(me, SPELL_MARK_OF_NATURE_AURA, true);
  89. events.ScheduleEvent(EVENT_TAIL_SWEEP, 4000);
  90. events.ScheduleEvent(EVENT_NOXIOUS_BREATH, urand(7500, 15000));
  91. events.ScheduleEvent(EVENT_SEEPING_FOG, urand(12500, 20000));
  92. }
  93.  
  94. // Target killed during encounter, mark them as suspectible for Aura Of Nature
  95. void KilledUnit(Unit* who)
  96. {
  97. who->CastSpell(who, SPELL_MARK_OF_NATURE, true);
  98. }
  99.  
  100. // Execute and reschedule base events shared between all Emerald Dragons
  101. void ExecuteEvent(uint32 const eventId)
  102. {
  103. switch (eventId)
  104. {
  105. case EVENT_SEEPING_FOG:
  106. // Seeping Fog appears only as "pairs", and only ONE pair at any given time!
  107. // Despawntime is 2 minutes, so reschedule it for new cast after 2 minutes + a minor "random time" (30 seconds at max)
  108. DoCast(me, SPELL_SEEPING_FOG_LEFT, true);
  109. DoCast(me, SPELL_SEEPING_FOG_RIGHT, true);
  110. events.ScheduleEvent(EVENT_SEEPING_FOG, urand(120000, 150000));
  111. break;
  112. case EVENT_NOXIOUS_BREATH:
  113. // Noxious Breath is cast on random intervals, no less than 7.5 seconds between
  114. DoCast(me, SPELL_NOXIOUS_BREATH);
  115. events.ScheduleEvent(EVENT_NOXIOUS_BREATH, urand(7500, 15000));
  116. break;
  117. case EVENT_TAIL_SWEEP:
  118. // Tail Sweep is cast every two seconds, no matter what goes on in front of the dragon
  119. DoCast(me, SPELL_TAIL_SWEEP);
  120. events.ScheduleEvent(EVENT_TAIL_SWEEP, 2000);
  121. break;
  122. }
  123. }
  124.  
  125. void UpdateAI(uint32 const diff)
  126. {
  127. if (!UpdateVictim())
  128. return;
  129.  
  130. events.Update(diff);
  131.  
  132. if (me->HasUnitState(UNIT_STAT_CASTING))
  133. return;
  134.  
  135. while (uint32 eventId = events.ExecuteEvent())
  136. ExecuteEvent(eventId);
  137.  
  138. if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, -50.0f, true))
  139. DoCast(target, SPELL_SUMMON_PLAYER);
  140.  
  141. DoMeleeAttackIfReady();
  142. }
  143. };
  144.  
  145. /*
  146. * --- NPC: Dream Fog
  147. */
  148.  
  149. class npc_dream_fog : public CreatureScript
  150. {
  151. public:
  152. npc_dream_fog() : CreatureScript("npc_dream_fog") { }
  153.  
  154. struct npc_dream_fogAI : public ScriptedAI
  155. {
  156. npc_dream_fogAI(Creature* creature) : ScriptedAI(creature)
  157. {
  158. }
  159.  
  160. void Reset()
  161. {
  162. _roamTimer = 0;
  163. }
  164.  
  165. void UpdateAI(uint32 const diff)
  166. {
  167. if (!UpdateVictim())
  168. return;
  169.  
  170. if (!_roamTimer)
  171. {
  172. // Chase target, but don't attack - otherwise just roam around
  173. if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
  174. {
  175. _roamTimer = urand(15000, 30000);
  176. me->GetMotionMaster()->Clear(false);
  177. me->GetMotionMaster()->MoveChase(target, 0.2f);
  178. }
  179. else
  180. {
  181. _roamTimer = 2500;
  182. me->GetMotionMaster()->Clear(false);
  183. me->GetMotionMaster()->MoveRandom(25.0f);
  184. }
  185. // Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
  186. me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
  187. me->SetSpeed(MOVE_WALK, 0.75f);
  188. }
  189. else
  190. _roamTimer -= diff;
  191. }
  192.  
  193. private:
  194. uint32 _roamTimer;
  195. };
  196.  
  197. CreatureAI* GetAI(Creature* creature) const
  198. {
  199. return new npc_dream_fogAI(creature);
  200. }
  201. };
  202.  
  203. /*
  204. * --- Spell: Dream Fog
  205. */
  206.  
  207. class DreamFogTargetSelector
  208. {
  209. public:
  210. DreamFogTargetSelector() { }
  211.  
  212. bool operator()(Unit* unit)
  213. {
  214. return unit->HasAura(SPELL_SLEEP);
  215. }
  216. };
  217.  
  218. class spell_dream_fog_sleep : public SpellScriptLoader
  219. {
  220. public:
  221. spell_dream_fog_sleep() : SpellScriptLoader("spell_dream_fog_sleep") { }
  222.  
  223. class spell_dream_fog_sleep_SpellScript : public SpellScript
  224. {
  225. PrepareSpellScript(spell_dream_fog_sleep_SpellScript);
  226.  
  227. void FilterTargets(std::list<Unit*>& unitList)
  228. {
  229. unitList.remove_if (DreamFogTargetSelector());
  230. }
  231.  
  232. void Register()
  233. {
  234. OnUnitTargetSelect += SpellUnitTargetFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
  235. }
  236. };
  237.  
  238. SpellScript* GetSpellScript() const
  239. {
  240. return new spell_dream_fog_sleep_SpellScript();
  241. }
  242. };
  243.  
  244. /*
  245. * --- Spell: Mark of Nature
  246. */
  247.  
  248. class MarkOfNatureTargetSelector
  249. {
  250. public:
  251. MarkOfNatureTargetSelector() { }
  252.  
  253. bool operator()(Unit* unit)
  254. {
  255. // return anyone that isn't tagged or already under the influence of Aura of Nature
  256. return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
  257. }
  258. };
  259.  
  260. class spell_mark_of_nature : public SpellScriptLoader
  261. {
  262. public:
  263. spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { }
  264.  
  265. class spell_mark_of_nature_SpellScript : public SpellScript
  266. {
  267. PrepareSpellScript(spell_mark_of_nature_SpellScript);
  268.  
  269. bool Validate(SpellInfo const* /*spellInfo*/)
  270. {
  271. if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_NATURE))
  272. return false;
  273. if (!sSpellMgr->GetSpellInfo(SPELL_AURA_OF_NATURE))
  274. return false;
  275. return true;
  276. }
  277.  
  278. void FilterTargets(std::list<Unit*>& unitList)
  279. {
  280. unitList.remove_if (MarkOfNatureTargetSelector());
  281. }
  282.  
  283. void HandleEffect(SpellEffIndex effIndex)
  284. {
  285. PreventHitDefaultEffect(effIndex);
  286.  
  287. if (GetHitUnit())
  288. GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_NATURE, true);
  289. }
  290.  
  291. void Register()
  292. {
  293. OnUnitTargetSelect += SpellUnitTargetFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
  294. OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
  295. }
  296. };
  297.  
  298. SpellScript* GetSpellScript() const
  299. {
  300. return new spell_mark_of_nature_SpellScript();
  301. }
  302. };
  303.  
  304. /*
  305. * ---
  306. * --- Dragonspecific scripts and handling: YSONDRE
  307. * ---
  308. */
  309.  
  310. enum YsondreNPC
  311. {
  312. NPC_DEMENTED_DRUID = 15260,
  313. };
  314.  
  315. enum YsondreTexts
  316. {
  317. SAY_YSONDRE_AGGRO = 0,
  318. SAY_YSONDRE_SUMMON_DRUIDS = 1,
  319. };
  320.  
  321. enum YsondreSpells
  322. {
  323. SPELL_LIGHTNING_WAVE = 24819,
  324. SPELL_SUMMON_DRUID_SPIRITS = 24795,
  325. };
  326.  
  327. class boss_ysondre : public CreatureScript
  328. {
  329. public:
  330. boss_ysondre() : CreatureScript("boss_ysondre") { }
  331.  
  332. struct boss_ysondreAI : public emerald_dragonAI
  333. {
  334. boss_ysondreAI(Creature* creature) : emerald_dragonAI(creature)
  335. {
  336. }
  337.  
  338. void Reset()
  339. {
  340. _stage = 1;
  341. _Reset();
  342. emerald_dragonAI::Reset();
  343. events.ScheduleEvent(EVENT_LIGHTNING_WAVE, 12000);
  344. }
  345.  
  346. void EnterCombat(Unit* who)
  347. {
  348. Talk(SAY_YSONDRE_AGGRO);
  349. WorldBossAI::EnterCombat(who);
  350. }
  351.  
  352. // Summon druid spirits on 75%, 50% and 25% health
  353. void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
  354. {
  355. if (!HealthAbovePct(100 - 25 * _stage))
  356. {
  357. Talk(SAY_YSONDRE_SUMMON_DRUIDS);
  358.  
  359. for (uint8 i = 0 ; i < 10 ; ++i)
  360. DoCast(me, SPELL_SUMMON_DRUID_SPIRITS, true);
  361. ++_stage;
  362. }
  363. }
  364.  
  365. void ExecuteEvent(uint32 const eventId)
  366. {
  367. switch (eventId)
  368. {
  369. case EVENT_LIGHTNING_WAVE:
  370. DoCastVictim(SPELL_LIGHTNING_WAVE);
  371. events.ScheduleEvent(EVENT_LIGHTNING_WAVE, urand(10000, 20000));
  372. break;
  373. default:
  374. emerald_dragonAI::ExecuteEvent(eventId);
  375. break;
  376. }
  377. }
  378.  
  379. private:
  380. uint8 _stage;
  381. };
  382.  
  383. CreatureAI* GetAI(Creature* creature) const
  384. {
  385. return new boss_ysondreAI(creature);
  386. }
  387. };
  388.  
  389. /*
  390. * ---
  391. * --- Dragonspecific scripts and handling: LETHON
  392. * ---
  393. *
  394. * TODO:
  395. * - NPC helper for spirit shades(?)
  396. * - Spirit shade NPC moves towards Lethon and heals him if close enough (each shade heals for 15000 HP)
  397. * - Spell: Shadow bolt whirl casts needs custom handling (spellscript)
  398. */
  399.  
  400. enum LethonTexts
  401. {
  402. SAY_LETHON_AGGRO = 0,
  403. SAY_LETHON_DRAW_SPIRIT = 1,
  404. };
  405.  
  406. enum LethonSpells
  407. {
  408. SPELL_DRAW_SPIRIT = 24811,
  409. SPELL_SHADOW_BOLT_WHIRL = 24834,
  410. SPELL_SPIRIT_SHADE_VISUAL = 24908,
  411. };
  412.  
  413. class boss_lethon : public CreatureScript
  414. {
  415. public:
  416. boss_lethon() : CreatureScript("boss_lethon") { }
  417.  
  418. struct boss_lethonAI : public emerald_dragonAI
  419. {
  420. boss_lethonAI(Creature* creature) : emerald_dragonAI(creature)
  421. {
  422. }
  423.  
  424. void Reset()
  425. {
  426. _stage = 1;
  427. _Reset();
  428. emerald_dragonAI::Reset();
  429. events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, 10000);
  430. }
  431.  
  432. void EnterCombat(Unit* who)
  433. {
  434. Talk(SAY_LETHON_AGGRO);
  435. WorldBossAI::EnterCombat(who);
  436. }
  437.  
  438. void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
  439. {
  440. if (!HealthAbovePct(100 - 25 * _stage))
  441. {
  442. Talk(SAY_LETHON_DRAW_SPIRIT);
  443. DoCast(me, SPELL_DRAW_SPIRIT);
  444. ++_stage;
  445. }
  446. }
  447.  
  448. void ExecuteEvent(uint32 const eventId)
  449. {
  450. switch (eventId)
  451. {
  452. case EVENT_SHADOW_BOLT_WHIRL:
  453. DoCast(me, SPELL_SHADOW_BOLT_WHIRL, true);
  454. events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, urand(15000, 30000));
  455. break;
  456. default:
  457. emerald_dragonAI::ExecuteEvent(eventId);
  458. break;
  459. }
  460. }
  461.  
  462. private:
  463. uint8 _stage;
  464. };
  465.  
  466. CreatureAI* GetAI(Creature* creature) const
  467. {
  468. return new boss_lethonAI(creature);
  469. }
  470. };
  471.  
  472. /*
  473. * ---
  474. * --- Dragonspecific scripts and handling: EMERISS
  475. * ---
  476. */
  477.  
  478. enum EmerissTexts
  479. {
  480. SAY_EMERISS_AGGRO = 0,
  481. SAY_EMERISS_CAST_CORRUPTION = 1,
  482. };
  483.  
  484. enum EmerissSpells
  485. {
  486. SPELL_PUTRID_MUSHROOM = 24904,
  487. SPELL_CORRUPTION_OF_EARTH = 24910,
  488. SPELL_VOLATILE_INFECTION = 24928,
  489. };
  490.  
  491. class boss_emeriss : public CreatureScript
  492. {
  493. public:
  494. boss_emeriss() : CreatureScript("boss_emeriss") { }
  495.  
  496. struct boss_emerissAI : public emerald_dragonAI
  497. {
  498. boss_emerissAI(Creature* creature) : emerald_dragonAI(creature)
  499. {
  500. }
  501.  
  502. void Reset()
  503. {
  504. _stage = 1;
  505. _Reset();
  506. emerald_dragonAI::Reset();
  507. events.ScheduleEvent(EVENT_VOLATILE_INFECTION, 12000);
  508. }
  509.  
  510. void KilledUnit(Unit* who)
  511. {
  512. if (who->GetTypeId() == TYPEID_PLAYER)
  513. DoCast(who, SPELL_PUTRID_MUSHROOM, true);
  514. emerald_dragonAI::KilledUnit(who);
  515. }
  516.  
  517. void EnterCombat(Unit* who)
  518. {
  519. Talk(SAY_EMERISS_AGGRO);
  520. WorldBossAI::EnterCombat(who);
  521. }
  522.  
  523. void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
  524. {
  525. if (!HealthAbovePct(100 - 25 * _stage))
  526. {
  527. Talk(SAY_EMERISS_CAST_CORRUPTION);
  528. DoCast(me, SPELL_CORRUPTION_OF_EARTH, true);
  529. ++_stage;
  530. }
  531. }
  532.  
  533. void ExecuteEvent(uint32 const eventId)
  534. {
  535. switch (eventId)
  536. {
  537. case EVENT_VOLATILE_INFECTION:
  538. DoCastVictim(SPELL_VOLATILE_INFECTION);
  539. events.ScheduleEvent(EVENT_VOLATILE_INFECTION, 120000);
  540. break;
  541. default:
  542. emerald_dragonAI::ExecuteEvent(eventId);
  543. break;
  544. }
  545. }
  546.  
  547. private:
  548. uint8 _stage;
  549. };
  550.  
  551. CreatureAI* GetAI(Creature* creature) const
  552. {
  553. return new boss_emerissAI(creature);
  554. }
  555. };
  556.  
  557. /*
  558. * ---
  559. * --- Dragonspecific scripts and handling: TAERAR
  560. * ---
  561. */
  562.  
  563. enum TaerarTexts
  564. {
  565. SAY_TAERAR_AGGRO = 0,
  566. SAY_TAERAR_SUMMON_SHADES = 1,
  567. };
  568.  
  569. enum TaerarSpells
  570. {
  571. SPELL_BELLOWING_ROAR = 22686,
  572. SPELL_SHADE = 24313,
  573. SPELL_SUMMON_SHADE_1 = 24841,
  574. SPELL_SUMMON_SHADE_2 = 24842,
  575. SPELL_SUMMON_SHADE_3 = 24843,
  576. SPELL_ARCANE_BLAST = 24857,
  577. };
  578.  
  579. uint32 const TaerarShadeSpells[] =
  580. {
  581. SPELL_SUMMON_SHADE_1, SPELL_SUMMON_SHADE_2, SPELL_SUMMON_SHADE_3
  582. };
  583.  
  584. class boss_taerar : public CreatureScript
  585. {
  586. public:
  587. boss_taerar() : CreatureScript("boss_taerar") { }
  588.  
  589. struct boss_taerarAI : public emerald_dragonAI
  590. {
  591. boss_taerarAI(Creature* creature) : emerald_dragonAI(creature)
  592. {
  593. _stage = 1;
  594. _shades = 0;
  595. _banished = false;
  596. _banishedTimer = 0;
  597. }
  598.  
  599. void Reset()
  600. {
  601. me->RemoveAurasDueToSpell(SPELL_SHADE);
  602. _stage = 1;
  603.  
  604. _shades = 0;
  605. _banished = false;
  606. _banishedTimer = 0;
  607.  
  608. _Reset();
  609. emerald_dragonAI::Reset();
  610. events.ScheduleEvent(EVENT_ARCANE_BLAST, 12000);
  611. events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000);
  612. }
  613.  
  614. void EnterCombat(Unit* who)
  615. {
  616. Talk(SAY_TAERAR_AGGRO);
  617. emerald_dragonAI::EnterCombat(who);
  618. }
  619.  
  620. void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/)
  621. {
  622. --_shades;
  623. }
  624.  
  625. void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
  626. {
  627. // At 75, 50 or 25 percent health, we need to activate the shades and go "banished"
  628. // Note: _stage holds the amount of times they have been summoned
  629. if (!_banished && !HealthAbovePct(100 - 25 * _stage))
  630. {
  631. _banished = true;
  632. _banishedTimer = 60000;
  633.  
  634. me->InterruptNonMeleeSpells(false);
  635. DoStopAttack();
  636.  
  637. Talk(SAY_TAERAR_SUMMON_SHADES);
  638.  
  639. uint32 count = sizeof(TaerarShadeSpells) / sizeof(uint32);
  640. for (uint32 i = 0; i < count; ++i)
  641. DoCastVictim(TaerarShadeSpells[i], true);
  642. _shades += count;
  643.  
  644. DoCast(SPELL_SHADE);
  645. me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
  646. me->SetReactState(REACT_PASSIVE);
  647.  
  648. ++_stage;
  649. }
  650. }
  651.  
  652. void ExecuteEvent(uint32 const eventId)
  653. {
  654. switch (eventId)
  655. {
  656. case EVENT_ARCANE_BLAST:
  657. DoCast(SPELL_ARCANE_BLAST);
  658. events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(7000, 12000));
  659. break;
  660. case EVENT_BELLOWING_ROAR:
  661. DoCast(SPELL_BELLOWING_ROAR);
  662. events.ScheduleEvent(EVENT_BELLOWING_ROAR, urand(20000, 30000));
  663. break;
  664. default:
  665. emerald_dragonAI::ExecuteEvent(eventId);
  666. break;
  667. }
  668. }
  669.  
  670. void UpdateAI(uint32 const diff)
  671. {
  672. if (!me->isInCombat())
  673. return;
  674.  
  675. if (_banished)
  676. {
  677. // If all three shades are dead, OR it has taken too long, end the current event and get Taerar back into business
  678. if (_banishedTimer <= diff || !_shades)
  679. {
  680. _banished = false;
  681.  
  682. me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
  683. me->RemoveAurasDueToSpell(SPELL_SHADE);
  684. me->SetReactState(REACT_AGGRESSIVE);
  685. }
  686. // _banishtimer has not expired, and we still have active shades:
  687. else
  688. _banishedTimer -= diff;
  689.  
  690. // Update the events before we return (handled under emerald_dragonAI::UpdateAI(diff); if we're not inside this check)
  691. events.Update(diff);
  692.  
  693. return;
  694. }
  695.  
  696. emerald_dragonAI::UpdateAI(diff);
  697. }
  698.  
  699. private:
  700. bool _banished; // used for shades activation testing
  701. uint32 _banishedTimer; // counter for banishment timeout
  702. uint8 _shades; // keep track of how many shades are dead
  703. uint8 _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
  704. };
  705.  
  706. CreatureAI* GetAI(Creature* creature) const
  707. {
  708. return new boss_taerarAI(creature);
  709. }
  710. };
  711.  
  712. void AddSC_emerald_dragons()
  713. {
  714. // helper NPC scripts
  715. new npc_dream_fog();
  716.  
  717. // dragon spellscripts
  718. new spell_dream_fog_sleep();
  719. new spell_mark_of_nature();
  720.  
  721. // dragons
  722. new boss_ysondre();
  723. new boss_taerar();
  724. new boss_emeriss();
  725. new boss_lethon();
  726. };
Add Comment
Please, Sign In to add comment