TrinityCore
Loading...
Searching...
No Matches
boss_eredar_twins.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/*
19 * Timers requires to be revisited
20 * The way Shadow Nova \ Conflagration is handled requires re-checks,
21 there are spells with unknown purpose. Also maybe it should be handled in one event instead of two
22 */
23
24#include "ScriptMgr.h"
25#include "InstanceScript.h"
26#include "Map.h"
27#include "Player.h"
28#include "ScriptedCreature.h"
29#include "SpellInfo.h"
30#include "SpellScript.h"
31#include "sunwell_plateau.h"
32
55
57{
58 // Sacrolash - Passive
61
62 // Sacrolash - Combat
67 SPELL_SHADOW_NOVA_DUMMY = 45332, // NYI, related to how Shadow Nova \ Conflagration is handled
68
69 // Alythess - Passive
71
72 // Alythess - Combat
74 SPELL_BLAZE = 45235,
77 SPELL_CONFLAGRATION_DUMMY = 45333, // NYI, related to how Shadow Nova \ Conflagration is handled
78
79 // Shared
85
86 // Shadow Image
91
92 // Scripts
97 SPELL_BURN = 45246,
99};
100
128
135
136// 25165 - Lady Sacrolash
137struct boss_sacrolash : public BossAI
138{
139 boss_sacrolash(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS), _sisterIsDead(false), _isAboutToDie(false) { }
140
141 void Reset() override
142 {
143 _Reset();
144
147
148 _sisterIsDead = false;
149 _isAboutToDie = false;
150
152 }
153
154 void JustEngagedWith(Unit* who) override
155 {
157
158 // Prevents sending Badge of Justice from each boss
159 me->SetLootMode(0);
160
163
169 }
170
171 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
172 {
173 if (_sisterIsDead)
174 return;
175
176 if (damage >= me->GetHealth() && who != me)
177 {
178 damage = me->GetHealth() -1;
179
180 if (!_isAboutToDie)
181 {
182 _isAboutToDie = true;
183
184 if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
185 if (alythess->IsAlive())
186 alythess->AI()->DoAction(ACTION_SISTER_DEAD);
187
188 events.Reset();
191 }
192 }
193 }
194
195 void EnterEvadeMode(EvadeReason /*why*/) override
196 {
199 if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
200 alythess->RemoveCorpse(false);
201 }
202
203 void OnSpellCast(SpellInfo const* spell) override
204 {
205 switch (spell->Id)
206 {
207 case SPELL_BERSERK:
209 break;
210 case SPELL_EMPOWER:
212 break;
213 default:
214 break;
215 }
216 }
217
218 void DoAction(int32 action) override
219 {
220 switch (action)
221 {
224 break;
226 me->ResetLootMode();
227 _sisterIsDead = true;
231 break;
232 default:
233 break;
234 }
235 }
236
237 void KilledUnit(Unit* victim) override
238 {
239 // Do not say if killed self by spell
240 if (victim != me)
242 }
243
244 void JustDied(Unit* /*killer*/) override
245 {
246 if (_sisterIsDead)
247 {
248 // It is important to make encounter complete only if both sisters are defeated
249 // Otherwise if only one sister will be defeated and wipe occured, second sister will despawn on evade and never respawn
250 _JustDied();
252 }
253 else
255 }
256
257 void UpdateAI(uint32 diff) override
258 {
259 if (!UpdateVictim())
260 {
261 events.Update(diff);
262
263 while (uint32 eventId = events.ExecuteEvent())
264 {
265 switch (eventId)
266 {
267 case EVENT_SAC_INTRO:
270 break;
271 default:
272 break;
273 }
274 }
275 return;
276 }
277
278 events.Update(diff);
279
281 return;
282
283 while (uint32 eventId = events.ExecuteEvent())
284 {
285 switch (eventId)
286 {
289 events.Repeat(10s, 15s);
290 break;
294 events.Repeat(20s, 30s);
295 break;
298 events.Repeat(8s, 20s);
299 break;
301 {
302 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
303
304 if (target)
305 {
306 DoCast(target, SPELL_SHADOW_NOVA);
309 }
310 events.Repeat(30s, 35s);
311 break;
312 }
314 {
315 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
316
317 if (target)
318 {
321 }
322 events.Repeat(30s, 35s);
323 break;
324 }
325 case EVENT_BERSERK:
327 break;
330 break;
331 case EVENT_DEATH_1:
334 break;
335 case EVENT_DEATH_2:
336 me->SetCorpseDelay(60, true);
338 break;
339 default:
340 break;
341 }
342
344 return;
345 }
346
348 }
349
350private:
353};
354
355// 25166 - Grand Warlock Alythess
356struct boss_alythess : public BossAI
357{
358 boss_alythess(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS), _sisterIsDead(false), _isAboutToDie(false) { }
359
360 void InitializeAI() override
361 {
363 SetCombatMovement(false);
364 }
365
366 void Reset() override
367 {
368 _Reset();
369
371
372 _sisterIsDead = false;
373 _isAboutToDie = false;
374
376 }
377
378 void JustEngagedWith(Unit* who) override
379 {
381
382 // Prevents sending Badge of Justice from each boss
383 me->SetLootMode(0);
384
387
393 }
394
395 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
396 {
397 if (_sisterIsDead)
398 return;
399
400 if (damage >= me->GetHealth() && who != me)
401 {
402 damage = me->GetHealth() -1;
403
404 if (!_isAboutToDie)
405 {
406 _isAboutToDie = true;
407
408 if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
409 if (sacrolash->IsAlive())
410 sacrolash->AI()->DoAction(ACTION_SISTER_DEAD);
411
412 events.Reset();
415 }
416 }
417 }
418
419 void EnterEvadeMode(EvadeReason /*why*/) override
420 {
423 if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
424 sacrolash->RemoveCorpse(false);
425 }
426
427 void OnSpellCast(SpellInfo const* spell) override
428 {
429 switch (spell->Id)
430 {
431 case SPELL_BERSERK:
433 break;
434 case SPELL_EMPOWER:
436 break;
437 default:
438 break;
439 }
440 }
441
442 void DoAction(int32 action) override
443 {
444 switch (action)
445 {
448 break;
450 me->ResetLootMode();
451 _sisterIsDead = true;
455 break;
456 default:
457 break;
458 }
459 }
460
461 void KilledUnit(Unit* victim) override
462 {
463 // Do not say if killed self by spell
464 if (victim != me)
466 }
467
468 void JustDied(Unit* /*killer*/) override
469 {
470 if (_sisterIsDead)
471 {
472 // It is important to make encounter complete only if both sisters are defeated
473 // Otherwise if only one sister will be defeated and wipe occured, second sister will despawn on evade and never respawn
474 _JustDied();
476 }
477 else
479 }
480
481 void UpdateAI(uint32 diff) override
482 {
483 if (!UpdateVictim())
484 {
485 events.Update(diff);
486
487 while (uint32 eventId = events.ExecuteEvent())
488 {
489 switch (eventId)
490 {
494 break;
497 break;
498 default:
499 break;
500 }
501 }
502 return;
503 }
504
505 events.Update(diff);
506
508 return;
509
510 while (uint32 eventId = events.ExecuteEvent())
511 {
512 switch (eventId)
513 {
514 case EVENT_PYROGENICS:
516 events.Repeat(20s, 40s);
517 break;
518 case EVENT_BLAZE:
520 events.Repeat(3s, 4s);
521 break;
522 case EVENT_FLAME_SEAR:
524 events.Repeat(8s, 13s);
525 break;
527 {
528 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
529
530 if (target)
531 {
535 }
536 events.Repeat(30s, 35s);
537 break;
538 }
540 {
541 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
542
543 if (target)
544 {
545 DoCast(target, SPELL_SHADOW_NOVA);
547 }
548 events.Repeat(30s, 35s);
549 break;
550 }
551 case EVENT_BERSERK:
553 break;
556 break;
557 case EVENT_DEATH_1:
560 break;
561 case EVENT_DEATH_2:
562 me->SetCorpseDelay(60, true);
564 break;
565 default:
566 break;
567 }
568
570 return;
571 }
572 }
573
574private:
577};
578
579// 25214 - Shadow Image
581{
582 npc_shadow_image(Creature* creature) : ScriptedAI(creature) { }
583
584 void InitializeAI() override
585 {
587 me->SetCorpseDelay(0);
588 }
589
590 void JustAppeared() override
591 {
593
595
596 _scheduler.Schedule(1s, [this](TaskContext /*task*/)
597 {
599 });
600
601 _scheduler.Schedule(10s, [this](TaskContext /*task*/)
602 {
603 me->KillSelf();
604 });
605 }
606
607 void Reset() override
608 {
610 }
611
613 {
616
617 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
618 {
619 AddThreat(target, 1000000.0f);
620 AttackStart(target);
621 }
622 }
623
624 void JustEngagedWith(Unit* /*who*/) override
625 {
626 switch (urand(0, 2))
627 {
628 case 0:
629 {
630 _scheduler.Schedule(2s, [this](TaskContext task)
631 {
634 else
635 task.Repeat(100ms);
636 });
637 break;
638 }
639 case 1:
640 {
641 _scheduler.Schedule(2s, [this](TaskContext task)
642 {
644 task.Repeat(1s);
645 });
646 break;
647 }
648 case 2:
649 {
650 _scheduler.Schedule(2s, [this](TaskContext task)
651 {
653 task.Repeat(1s);
654 });
655
656 _scheduler.Schedule(3s, [this](TaskContext task)
657 {
659 task.Repeat(1s);
660 });
661 break;
662 }
663 default:
664 break;
665 }
666 }
667
668 void OnSpellCast(SpellInfo const* spell) override
669 {
670 switch (spell->Id)
671 {
674 break;
676 // Not sure where exactly this should be called. What is known is it is called not always,
677 // before Dark Strike, in both scenarios with Dark Strike. What should be checked is the exact place where it should be called.
678 // Also looks like it is called every time before first Dark Strike, but that should be re-checked
679 if (roll_chance_i(50))
681 break;
682 default:
683 break;
684 }
685 }
686
687 void UpdateAI(uint32 diff) override
688 {
689 _scheduler.Update(diff);
690
691 if (UpdateVictim())
693 }
694
695private:
697};
698
699// 45235 - Blaze
719
720// 45343 - Dark Flame Aura
722{
724
725 bool Validate(SpellInfo const* /*spellInfo*/) override
726 {
727 return ValidateSpellInfo(
728 {
737 });
738 }
739
740 bool CheckProc(ProcEventInfo& eventInfo)
741 {
742 // Don't allow to proc if target has Dark Flame
743 if (eventInfo.GetActionTarget()->HasAura(SPELL_DARK_FLAME))
744 return false;
745
746 // Allow proc from melee damage (Shadow Image deals no melee damage (see on-spawn aura), only Sacrolash does)
747 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
748 if (!spellInfo)
749 return true;
750
751 // Allow proc from shadow spells
752 switch (spellInfo->Id)
753 {
759 return true;
760 default:
761 return false;
762 }
763
764 return false;
765 }
766
767 void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
768 {
769 Unit* target = eventInfo.GetActionTarget();
770
771 if (target->HasAura(SPELL_FLAME_TOUCHED))
772 {
774 target->CastSpell(target, SPELL_DARK_FLAME, true);
775 }
776 else
777 target->CastSpell(target, SPELL_DARK_TOUCHED, true);
778 }
779
785};
786
787// 47300 - Dark Flame Aura
789{
791
792 bool Validate(SpellInfo const* /*spellInfo*/) override
793 {
794 return ValidateSpellInfo(
795 {
804 });
805 }
806
807 bool CheckProc(ProcEventInfo& eventInfo)
808 {
809 // Don't allow to proc if target has Dark Flame
810 if (eventInfo.GetActionTarget()->HasAura(SPELL_DARK_FLAME))
811 return false;
812
813 // Don't allow to proc from melee damage, Alythess any way doesn't do melee damage
814 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
815 if (!spellInfo)
816 return false;
817
818 // Allow proc from fire spells
819 switch (spellInfo->Id)
820 {
821 case SPELL_BLAZE:
822 case SPELL_FLAME_SEAR:
824 case SPELL_BURN:
826 return true;
827 default:
828 return false;
829 }
830
831 return false;
832 }
833
834 void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
835 {
836 Unit* target = eventInfo.GetActionTarget();
837
838 if (target->HasAura(SPELL_DARK_TOUCHED))
839 {
841 target->CastSpell(target, SPELL_DARK_FLAME, true);
842 }
843 else
844 target->CastSpell(target, SPELL_FLAME_TOUCHED, true);
845 }
846
852};
853
854// 4937
856{
857public:
858 at_witchs_sanctum() : OnlyOnceAreaTriggerScript("at_witchs_sanctum") { }
859
860 bool TryHandleOnce(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
861 {
862 if (InstanceScript* instance = player->GetInstanceScript())
863 {
864 if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
865 sacrolash->AI()->DoAction(ACTION_START_INTRO);
866
867 if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
868 alythess->AI()->DoAction(ACTION_START_INTRO);
869 }
870
871 return true;
872 }
873};
874
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
bool roll_chance_i(int chance)
Definition Random.h:59
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1128
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ UNIT_DYNFLAG_LOOTABLE
@ SPAWN_TYPE_CREATURE
Definition SpawnData.h:31
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELLVALUE_MAX_TARGETS
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define AuraCheckProcFn(F)
@ REACT_PASSIVE
@ UNIT_STATE_CASTING
Definition Unit.h:235
DamageEffectType
Definition Unit.h:352
@ ACTION_SISTER_DEAD
@ SOUND_INTRO
@ ACTION_START_INTRO
@ SAY_SACROLASH_DEAD
@ EMOTE_CONFLAGRATION_SAC
@ SAY_INTRO_ALY
@ SAY_BERSERK_ALY
@ EMOTE_CONFLAGRATION_ALY
@ SAY_ALYTHESS_DEAD
@ SAY_DEATH_SAC
@ EMOTE_SHADOW_NOVA_SAC
@ SAY_BERSERK_SAC
@ SAY_SHADOW_NOVA
@ SAY_CONFLAGRATION
@ SAY_SLAY_SAC
@ SAY_DEATH_ALY
@ SAY_SLAY_ALY
@ EMOTE_SHADOW_NOVA_ALY
@ SAY_INTRO_SAC
void AddSC_boss_eredar_twins()
SacrolashSpells
@ SPELL_EMPOWER
@ SPELL_SHADOWSTEP
@ SPELL_SHADOWFORM
@ SPELL_CONFOUNDING_BLOW
@ SPELL_FLAME_TOUCHED
@ SPELL_SHADOW_BLADES
@ SPELL_FIREFORM
@ SPELL_SHADOW_IMAGE_VISUAL
@ SPELL_CONFLAGRATION
@ SPELL_INSTAKILL_SELF
@ SPELL_CONFLAGRATION_DUMMY
@ SPELL_PYROGENICS
@ SPELL_BLAZE_SUMMON
@ SPELL_SUMMON_SHADOW_IMAGES
@ SPELL_DARK_FLAME_AURA_ALY
@ SPELL_SHADOW_FURY
@ SPELL_BURN
@ SPELL_DUAL_WIELD_PASSIVE
@ SPELL_CONFLAGRATION_TRIGGER
@ SPELL_BERSERK
@ SPELL_SHADOW_NOVA
@ SPELL_DARK_FLAME_AURA_SAC
@ SPELL_DARK_FLAME
@ SPELL_BLAZE
@ SPELL_SHADOW_NOVA_DUMMY
@ SPELL_DARK_STRIKE
@ SPELL_DARK_TOUCHED
@ SPELL_FLAME_SEAR
@ EVENT_CONFOUNDING_BLOW
@ EVENT_SUMMON_SHADOW_IMAGES
@ EVENT_BLAZE
@ EVENT_FLAME_SEAR
@ EVENT_SHADOW_BLADES
@ EVENT_PYROGENICS
@ EVENT_ALY_INTRO_2
@ EVENT_ALY_INTRO_1
@ EVENT_SHADOW_NOVA
@ EVENT_CONFLAGRATION
@ EVENT_BERSERK
@ EVENT_DEATH_2
@ EVENT_SISTER_DEAD
@ EVENT_DEATH_1
@ EVENT_SAC_INTRO
HookList< CheckProcHandler > DoCheckProc
HookList< EffectProcHandler > OnEffectProc
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
SummonList summons
EventMap events
void DoZoneInCombat(Creature *creature=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:82
void ResetLootMode()
Definition Creature.h:227
void SetReactState(ReactStates st)
Definition Creature.h:119
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition Creature.h:89
void SetLootMode(uint16 lootMode)
Definition Creature.h:224
void Update(uint32 time)
Definition EventMap.h:67
void Repeat(Milliseconds time)
Definition EventMap.cpp:63
EventId ExecuteEvent()
Definition EventMap.cpp:73
void CancelEvent(EventId eventId)
Definition EventMap.cpp:151
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:36
void Reset()
Definition EventMap.cpp:21
Creature * GetCreature(uint32 type)
void Respawn(RespawnInfo *info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:3105
virtual void RemoveDynamicFlag(uint32 flag)
Definition Object.h:90
Unit * GetActionTarget() const
Definition Unit.h:509
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:268
uint32 Id
Definition SpellInfo.h:289
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
TaskContext & Repeat(std::chrono::duration< _Rep, _Period > const &duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler & Update(success_t const &callback=EmptyCallback)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:241
virtual void InitializeAI()
Definition UnitAI.cpp:36
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:166
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:106
Definition Unit.h:769
bool IsWithinMeleeRange(Unit const *obj) const
Definition Unit.h:844
void KillSelf(bool durabilityLoss=true)
Definition Unit.h:1023
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3093
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4535
uint32 GetHealth() const
Definition Unit.h:913
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
Map * GetMap() const
Definition Object.h:449
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1087
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
virtual uint64 GetData64(uint32) const
Definition ZoneScript.h:51
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
bool TryHandleOnce(Player *player, AreaTriggerEntry const *) override
void HandleScript(SpellEffIndex)
PrepareSpellScript(spell_eredar_twins_blaze)
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *, ProcEventInfo &eventInfo)
PrepareAuraScript(spell_eredar_twins_dark_flame_aura_fire)
bool Validate(SpellInfo const *) override
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_eredar_twins_dark_flame_aura_shadow)
void HandleProc(AuraEffect const *, ProcEventInfo &eventInfo)
void AttackStart(Unit *) override
void SetCombatMovement(bool allowMovement)
void ResetThreatList(Unit *who=nullptr)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void OnSpellCast(SpellInfo const *spell) override
void UpdateAI(uint32 diff) override
void JustDied(Unit *) override
void KilledUnit(Unit *victim) override
boss_alythess(Creature *creature)
void DoAction(int32 action) override
void Reset() override
void DamageTaken(Unit *who, uint32 &damage, DamageEffectType, SpellInfo const *) override
void JustEngagedWith(Unit *who) override
void EnterEvadeMode(EvadeReason) override
void InitializeAI() override
void OnSpellCast(SpellInfo const *spell) override
void JustDied(Unit *) override
void UpdateAI(uint32 diff) override
void KilledUnit(Unit *victim) override
void DamageTaken(Unit *who, uint32 &damage, DamageEffectType, SpellInfo const *) override
boss_sacrolash(Creature *creature)
void JustEngagedWith(Unit *who) override
void Reset() override
void EnterEvadeMode(EvadeReason) override
void DoAction(int32 action) override
void OnSpellCast(SpellInfo const *spell) override
void Reset() override
void JustEngagedWith(Unit *) override
void InitializeAI() override
void UpdateAI(uint32 diff) override
void JustAppeared() override
npc_shadow_image(Creature *creature)
#define RegisterSunwellPlateauCreatureAI(ai_name)
@ DATA_EREDAR_TWINS
@ DATA_ALYTHESS
@ DATA_SACROLASH