TrinityCore
boss_emerald_dragons.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "MotionMaster.h"
20#include "PassiveAI.h"
21#include "ScriptedCreature.h"
22#include "SpellInfo.h"
23#include "SpellScript.h"
24
25//
26// Emerald Dragon NPCs and IDs (kept here for reference)
27//
28
30{
36};
37
38//
39// Emerald Dragon Spells (used for the dragons)
40//
41
43{
44 SPELL_TAIL_SWEEP = 15847, // tail sweep - slap everything behind dragon (2 seconds interval)
45 SPELL_SUMMON_PLAYER = 24776, // teleport highest threat player in front of dragon if wandering off
46 SPELL_DREAM_FOG = 24777, // auraspell for Dream Fog NPC (15224)
47 SPELL_SLEEP = 24778, // sleep triggerspell (used for Dream Fog)
48 SPELL_SEEPING_FOG_LEFT = 24813, // dream fog - summon left
49 SPELL_SEEPING_FOG_RIGHT = 24814, // dream fog - summon right
51 SPELL_MARK_OF_NATURE = 25040, // Mark of Nature trigger (applied on target death - 15 minutes of being suspectible to Aura Of Nature)
52 SPELL_MARK_OF_NATURE_AURA = 25041, // Mark of Nature (passive marker-test, ticks every 10 seconds from boss, triggers spellID 25042 (scripted)
53 SPELL_AURA_OF_NATURE = 25043, // Stun for 2 minutes (used when SPELL_MARK_OF_NATURE exists on the target)
54};
55
56//
57// Emerald Dragon Eventlists (shared and specials)
58//
59
61{
62 // General events for all dragons
66
67 // Ysondre
70
71 // Lethon
73
74 // Emeriss
77
78 // Taerar
81};
82
83/*
84 * ---
85 * --- Emerald Dragons : Base AI-structure used for all the Emerald dragons
86 * ---
87 */
88
90{
91 emerald_dragonAI(Creature* creature) : WorldBossAI(creature)
92 {
93 }
94
95 void Reset() override
96 {
99 me->SetUninteractible(false);
105 }
106
107 // Target killed during encounter, mark them as suspectible for Aura Of Nature
108 void KilledUnit(Unit* who) override
109 {
110 if (who->GetTypeId() == TYPEID_PLAYER)
111 who->CastSpell(who, SPELL_MARK_OF_NATURE, true);
112 }
113
114 // Execute and reschedule base events shared between all Emerald Dragons
115 void ExecuteEvent(uint32 eventId) override
116 {
117 switch (eventId)
118 {
120 // Seeping Fog appears only as "pairs", and only ONE pair at any given time!
121 // Despawntime is 2 minutes, so reschedule it for new cast after 2 minutes + a minor "random time" (30 seconds at max)
125 break;
127 // Noxious Breath is cast on random intervals, no less than 7.5 seconds between
130 break;
131 case EVENT_TAIL_SWEEP:
132 // Tail Sweep is cast every two seconds, no matter what goes on in front of the dragon
135 break;
136 }
137 }
138
139 void UpdateAI(uint32 diff) override
140 {
141 if (!UpdateVictim())
142 return;
143
144 events.Update(diff);
145
147 return;
148
149 while (uint32 eventId = events.ExecuteEvent())
150 {
151 ExecuteEvent(eventId);
152
154 return;
155 }
156
157 if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, -50.0f, true))
159 }
160};
161
162/*
163 * --- NPC: Dream Fog
164 */
165
167{
168 public:
169 npc_dream_fog() : CreatureScript("npc_dream_fog") { }
170
172 {
173 npc_dream_fogAI(Creature* creature) : ScriptedAI(creature)
174 {
175 Initialize();
176 }
177
179 {
180 _roamTimer = 0;
181 }
182
183 void Reset() override
184 {
185 Initialize();
186 }
187
188 void UpdateAI(uint32 diff) override
189 {
190 if (!UpdateVictim())
191 return;
192
193 if (!_roamTimer)
194 {
195 // Chase target, but don't attack - otherwise just roam around
196 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
197 {
198 _roamTimer = urand(15000, 30000);
200 me->GetMotionMaster()->MoveChase(target, 0.2f);
201 }
202 else
203 {
204 _roamTimer = 2500;
206 me->GetMotionMaster()->MoveRandom(25.0f);
207 }
208 // Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
209 me->SetWalk(true);
210 me->SetSpeedRate(MOVE_WALK, 0.75f);
211 }
212 else
213 _roamTimer -= diff;
214 }
215
216 private:
218 };
219
220 CreatureAI* GetAI(Creature* creature) const override
221 {
222 return new npc_dream_fogAI(creature);
223 }
224};
225
226/*
227 * ---
228 * --- Dragonspecific scripts and handling: YSONDRE
229 * ---
230 */
231
233{
235};
236
238{
241};
242
244{
247};
248
250{
251 public:
252 boss_ysondre() : CreatureScript("boss_ysondre") { }
253
255 {
257 {
258 Initialize();
259 }
260
262 {
263 _stage = 1;
264 }
265
266 void Reset() override
267 {
268 Initialize();
271 }
272
273 void JustEngagedWith(Unit* who) override
274 {
277 }
278
279 // Summon druid spirits on 75%, 50% and 25% health
280 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
281 {
282 if (!HealthAbovePct(100 - 25 * _stage))
283 {
285
286 for (uint8 i = 0; i < 10; ++i)
288 ++_stage;
289 }
290 }
291
292 void ExecuteEvent(uint32 eventId) override
293 {
294 switch (eventId)
295 {
299 break;
300 default:
302 break;
303 }
304 }
305
306 private:
308 };
309
310 CreatureAI* GetAI(Creature* creature) const override
311 {
312 return new boss_ysondreAI(creature);
313 }
314};
315
316/*
317 * ---
318 * --- Dragonspecific scripts and handling: LETHON
319 * ---
320 *
321 * @todo
322 * - Spell: Shadow bolt whirl casts needs custom handling (spellscript)
323 */
324
326{
329};
330
332{
336};
337
339{
341};
342
344{
345 public:
346 boss_lethon() : CreatureScript("boss_lethon") { }
347
349 {
351 {
352 Initialize();
353 }
354
356 {
357 _stage = 1;
358 }
359
360 void Reset() override
361 {
362 Initialize();
365 }
366
367 void JustEngagedWith(Unit* who) override
368 {
371 }
372
373 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
374 {
375 if (!HealthAbovePct(100 - 25 * _stage))
376 {
379 ++_stage;
380 }
381 }
382
383 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
384 {
385 if (spellInfo->Id == SPELL_DRAW_SPIRIT && target->GetTypeId() == TYPEID_PLAYER)
386 {
387 Position targetPos = target->GetPosition();
389 }
390 }
391
392 void ExecuteEvent(uint32 eventId) override
393 {
394 switch (eventId)
395 {
397 me->CastSpell(nullptr, SPELL_SHADOW_BOLT_WHIRL, false);
399 break;
400 default:
402 break;
403 }
404 }
405
406 private:
408 };
409
410 CreatureAI* GetAI(Creature* creature) const override
411 {
412 return new boss_lethonAI(creature);
413 }
414};
415
417{
418 public:
419 npc_spirit_shade() : CreatureScript("npc_spirit_shade") { }
420
422 {
424 {
425 }
426
427 void IsSummonedBy(WorldObject* summonerWO) override
428 {
429 Unit* summoner = summonerWO->ToUnit();
430 if (!summoner)
431 return;
432
433 _summonerGuid = summoner->GetGUID();
434 me->GetMotionMaster()->MoveFollow(summoner, 0.0f, 0.0f);
435 }
436
437 void MovementInform(uint32 moveType, uint32 data) override
438 {
439 if (moveType == FOLLOW_MOTION_TYPE && data == _summonerGuid.GetCounter())
440 {
441 me->CastSpell(nullptr, SPELL_DARK_OFFERING, false);
443 }
444 }
445
446 private:
448 };
449
450 CreatureAI* GetAI(Creature* creature) const override
451 {
452 return new npc_spirit_shadeAI(creature);
453 }
454};
455
456/*
457 * ---
458 * --- Dragonspecific scripts and handling: EMERISS
459 * ---
460 */
461
463{
466};
467
469{
473};
474
476{
477 public:
478 boss_emeriss() : CreatureScript("boss_emeriss") { }
479
481 {
483 {
484 Initialize();
485 }
486
488 {
489 _stage = 1;
490 }
491
492 void Reset() override
493 {
494 Initialize();
497 }
498
499 void KilledUnit(Unit* who) override
500 {
501 if (who->GetTypeId() == TYPEID_PLAYER)
502 DoCast(who, SPELL_PUTRID_MUSHROOM, true);
504 }
505
506 void JustEngagedWith(Unit* who) override
507 {
510 }
511
512 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
513 {
514 if (!HealthAbovePct(100 - 25 * _stage))
515 {
518 ++_stage;
519 }
520 }
521
522 void ExecuteEvent(uint32 eventId) override
523 {
524 switch (eventId)
525 {
529 break;
530 default:
532 break;
533 }
534 }
535
536 private:
538 };
539
540 CreatureAI* GetAI(Creature* creature) const override
541 {
542 return new boss_emerissAI(creature);
543 }
544};
545
546/*
547 * ---
548 * --- Dragonspecific scripts and handling: TAERAR
549 * ---
550 */
551
553{
556};
557
559{
561 SPELL_SHADE = 24313,
566};
567
569{
571};
572
574{
575 public:
576 boss_taerar() : CreatureScript("boss_taerar") { }
577
579 {
581 {
582 Initialize();
583 }
584
586 {
587 _stage = 1;
588 _shades = 0;
589 _banished = false;
590 _banishedTimer = 0;
591 }
592
593 void Reset() override
594 {
596
597 Initialize();
598
602 }
603
604 void JustEngagedWith(Unit* who) override
605 {
608 }
609
610 void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override
611 {
612 --_shades;
613 }
614
615 void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
616 {
617 // At 75, 50 or 25 percent health, we need to activate the shades and go "banished"
618 // Note: _stage holds the amount of times they have been summoned
619 if (!_banished && !HealthAbovePct(100 - 25 * _stage))
620 {
621 _banished = true;
622 _banishedTimer = 60000;
623
625 DoStopAttack();
626
628
629 uint32 count = sizeof(TaerarShadeSpells) / sizeof(uint32);
630 for (uint32 i = 0; i < count; ++i)
632 _shades += count;
633
636 me->SetUninteractible(true);
638
639 ++_stage;
640 }
641 }
642
643 void ExecuteEvent(uint32 eventId) override
644 {
645 switch (eventId)
646 {
650 break;
654 break;
655 default:
657 break;
658 }
659 }
660
661 void UpdateAI(uint32 diff) override
662 {
663 if (!me->IsInCombat())
664 return;
665
666 if (_banished)
667 {
668 // If all three shades are dead, OR it has taken too long, end the current event and get Taerar back into business
669 if (_banishedTimer <= diff || !_shades)
670 {
671 _banished = false;
672
674 me->SetUninteractible(false);
677 }
678 // _banishtimer has not expired, and we still have active shades:
679 else
680 _banishedTimer -= diff;
681
682 // Update the events before we return (handled under emerald_dragonAI::UpdateAI(diff); if we're not inside this check)
683 events.Update(diff);
684
685 return;
686 }
687
689 }
690
691 private:
692 bool _banished; // used for shades activation testing
693 uint32 _banishedTimer; // counter for banishment timeout
694 uint8 _shades; // keep track of how many shades are dead
695 uint8 _stage; // check which "shade phase" we're at (75-50-25 percentage counters)
696 };
697
698 CreatureAI* GetAI(Creature* creature) const override
699 {
700 return new boss_taerarAI(creature);
701 }
702};
703
704/*
705 * --- Spell: Dream Fog
706 */
707
709{
710 public:
712
714 {
715 if (Unit* unit = object->ToUnit())
716 return unit->HasAura(SPELL_SLEEP);
717 return true;
718 }
719};
720
721// 24778 - Sleep
723{
724 public:
725 spell_dream_fog_sleep() : SpellScriptLoader("spell_dream_fog_sleep") { }
726
728 {
729 void FilterTargets(std::list<WorldObject*>& targets)
730 {
731 targets.remove_if(DreamFogTargetSelector());
732 }
733
734 void Register() override
735 {
737 }
738 };
739
740 SpellScript* GetSpellScript() const override
741 {
743 }
744};
745
746/*
747 * --- Spell: Mark of Nature
748 */
749
751{
752 public:
754
756 {
757 // return those not tagged or already under the influence of Aura of Nature
758 if (Unit* unit = object->ToUnit())
759 return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
760 return true;
761 }
762};
763
764// 25042 - Triggerspell - Mark of Nature
766{
767 public:
768 spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { }
769
771 {
772 bool Validate(SpellInfo const* /*spellInfo*/) override
773 {
774 return ValidateSpellInfo(
775 {
778 });
779 }
780
781 void FilterTargets(std::list<WorldObject*>& targets)
782 {
783 targets.remove_if(MarkOfNatureTargetSelector());
784 }
785
787 {
788 PreventHitDefaultEffect(effIndex);
790 }
791
792 void Register() override
793 {
796 }
797 };
798
799 SpellScript* GetSpellScript() const override
800 {
802 }
803};
804
806{
807 // helper NPC scripts
808 new npc_dream_fog();
809 new npc_spirit_shade();
810
811 // dragons
812 new boss_ysondre();
813 new boss_taerar();
814 new boss_emeriss();
815 new boss_lethon();
816
817 // dragon spellscripts
820}
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
@ FOLLOW_MOTION_TYPE
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition: ObjectDefines.h:66
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ TARGET_UNIT_DEST_AREA_ENEMY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_EFFECT_APPLY_AURA
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellObjectAreaTargetSelectFn(F, I, N)
Definition: SpellScript.h:864
@ MOVE_WALK
Definition: UnitDefines.h:117
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
DamageEffectType
Definition: UnitDefines.h:131
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:145
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ SAY_TAERAR_SUMMON_SHADES
@ SAY_TAERAR_AGGRO
EmeraldDragonSpells
@ SPELL_MARK_OF_NATURE
@ SPELL_SUMMON_PLAYER
@ SPELL_MARK_OF_NATURE_AURA
@ SPELL_AURA_OF_NATURE
@ SPELL_SEEPING_FOG_RIGHT
@ SPELL_TAIL_SWEEP
@ SPELL_DREAM_FOG
@ SPELL_SEEPING_FOG_LEFT
@ SPELL_NOXIOUS_BREATH
@ SPELL_CORRUPTION_OF_EARTH
@ SPELL_VOLATILE_INFECTION
@ SPELL_PUTRID_MUSHROOM
@ DRAGON_TAERAR
@ DRAGON_EMERISS
@ DRAGON_YSONDRE
@ DRAGON_LETHON
@ NPC_DREAM_FOG
uint32 const TaerarShadeSpells[]
@ SPELL_LIGHTNING_WAVE
@ SPELL_SUMMON_DRUID_SPIRITS
@ SPELL_SUMMON_SHADE_3
@ SPELL_SUMMON_SHADE_1
@ SPELL_BELLOWING_ROAR
@ SPELL_SUMMON_SHADE_2
@ SPELL_ARCANE_BLAST
@ SAY_LETHON_DRAW_SPIRIT
@ SAY_LETHON_AGGRO
@ SAY_YSONDRE_SUMMON_DRUIDS
@ SAY_YSONDRE_AGGRO
@ NPC_DEMENTED_DRUID
@ NPC_SPIRIT_SHADE
@ SAY_EMERISS_CAST_CORRUPTION
@ SAY_EMERISS_AGGRO
void AddSC_emerald_dragons()
@ SPELL_DARK_OFFERING
@ SPELL_SHADOW_BOLT_WHIRL
@ SPELL_DRAW_SPIRIT
@ EVENT_CORRUPTION_OF_EARTH
@ EVENT_TAIL_SWEEP
@ EVENT_ARCANE_BLAST
@ EVENT_SUMMON_DRUID_SPIRITS
@ EVENT_LIGHTNING_WAVE
@ EVENT_BELLOWING_ROAR
@ EVENT_VOLATILE_INFECTION
@ EVENT_NOXIOUS_BREATH
@ EVENT_SEEPING_FOG
@ EVENT_SHADOW_BOLT_WHIRL
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetReactState(ReactStates st)
Definition: Creature.h:160
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
bool operator()(WorldObject *object)
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool operator()(WorldObject *object)
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MoveRandom(float wanderDistance=0.0f, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_DEFAULT)
void MoveFollow(Unit *target, float dist, ChaseAngle angle, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_ACTIVE)
LowType GetCounter() const
Definition: ObjectGuid.h:293
static Unit * ToUnit(Object *o)
Definition: Object.h:225
TypeID GetTypeId() const
Definition: Object.h:173
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
uint32 const Id
Definition: SpellInfo.h:325
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Definition: SpellScript.h:863
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.cpp:8525
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
bool IsInCombat() const
Definition: Unit.h:1043
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
void JustEngagedWith(Unit *) override
void Reset() override
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
void FilterTargets(std::list< WorldObject * > &targets)
SpellScript * GetSpellScript() const override
void FilterTargets(std::list< WorldObject * > &targets)
SpellScript * GetSpellScript() const override
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
bool HealthAbovePct(uint32 pct) const
void JustEngagedWith(Unit *who) override
void ExecuteEvent(uint32 eventId) override
void KilledUnit(Unit *who) override
void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellInfo const *) override
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void JustEngagedWith(Unit *who) override
void ExecuteEvent(uint32 eventId) override
void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellInfo const *) override
void SummonedCreatureDies(Creature *, Unit *) override
void UpdateAI(uint32 diff) override
void ExecuteEvent(uint32 eventId) override
void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellInfo const *) override
void JustEngagedWith(Unit *who) override
void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellInfo const *) override
void ExecuteEvent(uint32 eventId) override
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
void KilledUnit(Unit *who) override
void ExecuteEvent(uint32 eventId) override
emerald_dragonAI(Creature *creature)
void UpdateAI(uint32 diff) override
void IsSummonedBy(WorldObject *summonerWO) override
void MovementInform(uint32 moveType, uint32 data) override