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 }
347
348private:
351};
352
353// 25166 - Grand Warlock Alythess
354struct boss_alythess : public BossAI
355{
356 boss_alythess(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS), _sisterIsDead(false), _isAboutToDie(false) { }
357
358 void InitializeAI() override
359 {
361 SetCombatMovement(false);
362 }
363
364 void Reset() override
365 {
366 _Reset();
367
369
370 _sisterIsDead = false;
371 _isAboutToDie = false;
372
374 }
375
376 void JustEngagedWith(Unit* who) override
377 {
379
380 // Prevents sending Badge of Justice from each boss
381 me->SetLootMode(0);
382
385
391 }
392
393 void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
394 {
395 if (_sisterIsDead)
396 return;
397
398 if (damage >= me->GetHealth() && who != me)
399 {
400 damage = me->GetHealth() -1;
401
402 if (!_isAboutToDie)
403 {
404 _isAboutToDie = true;
405
406 if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
407 if (sacrolash->IsAlive())
408 sacrolash->AI()->DoAction(ACTION_SISTER_DEAD);
409
410 events.Reset();
413 }
414 }
415 }
416
417 void EnterEvadeMode(EvadeReason /*why*/) override
418 {
421 if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
422 sacrolash->RemoveCorpse(false);
423 }
424
425 void OnSpellCast(SpellInfo const* spell) override
426 {
427 switch (spell->Id)
428 {
429 case SPELL_BERSERK:
431 break;
432 case SPELL_EMPOWER:
434 break;
435 default:
436 break;
437 }
438 }
439
440 void DoAction(int32 action) override
441 {
442 switch (action)
443 {
446 break;
448 me->ResetLootMode();
449 _sisterIsDead = true;
453 break;
454 default:
455 break;
456 }
457 }
458
459 void KilledUnit(Unit* victim) override
460 {
461 // Do not say if killed self by spell
462 if (victim != me)
464 }
465
466 void JustDied(Unit* /*killer*/) override
467 {
468 if (_sisterIsDead)
469 {
470 // It is important to make encounter complete only if both sisters are defeated
471 // Otherwise if only one sister will be defeated and wipe occured, second sister will despawn on evade and never respawn
472 _JustDied();
474 }
475 else
477 }
478
479 void UpdateAI(uint32 diff) override
480 {
481 if (!UpdateVictim())
482 {
483 events.Update(diff);
484
485 while (uint32 eventId = events.ExecuteEvent())
486 {
487 switch (eventId)
488 {
492 break;
495 break;
496 default:
497 break;
498 }
499 }
500 return;
501 }
502
503 events.Update(diff);
504
506 return;
507
508 while (uint32 eventId = events.ExecuteEvent())
509 {
510 switch (eventId)
511 {
512 case EVENT_PYROGENICS:
514 events.Repeat(20s, 40s);
515 break;
516 case EVENT_BLAZE:
518 events.Repeat(3s, 4s);
519 break;
520 case EVENT_FLAME_SEAR:
522 events.Repeat(8s, 13s);
523 break;
525 {
526 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
527
528 if (target)
529 {
533 }
534 events.Repeat(30s, 35s);
535 break;
536 }
538 {
539 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
540
541 if (target)
542 {
543 DoCast(target, SPELL_SHADOW_NOVA);
545 }
546 events.Repeat(30s, 35s);
547 break;
548 }
549 case EVENT_BERSERK:
551 break;
554 break;
555 case EVENT_DEATH_1:
558 break;
559 case EVENT_DEATH_2:
560 me->SetCorpseDelay(60, true);
562 break;
563 default:
564 break;
565 }
566
568 return;
569 }
570 }
571
572private:
575};
576
577// 25214 - Shadow Image
579{
580 npc_shadow_image(Creature* creature) : ScriptedAI(creature) { }
581
582 void InitializeAI() override
583 {
585 me->SetCorpseDelay(0);
586 }
587
588 void JustAppeared() override
589 {
591
593
594 _scheduler.Schedule(1s, [this](TaskContext const& /*task*/)
595 {
597 });
598
599 _scheduler.Schedule(10s, [this](TaskContext const& /*task*/)
600 {
601 me->KillSelf();
602 });
603 }
604
605 void Reset() override
606 {
608 }
609
611 {
614
615 if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
616 {
617 AddThreat(target, 1000000.0f);
618 AttackStart(target);
619 }
620 }
621
622 void JustEngagedWith(Unit* /*who*/) override
623 {
624 switch (urand(0, 2))
625 {
626 case 0:
627 {
628 _scheduler.Schedule(2s, [this](TaskContext& task)
629 {
632 else
633 task.Repeat(100ms);
634 });
635 break;
636 }
637 case 1:
638 {
639 _scheduler.Schedule(2s, [this](TaskContext& task)
640 {
642 task.Repeat(1s);
643 });
644 break;
645 }
646 case 2:
647 {
648 _scheduler.Schedule(2s, [this](TaskContext& task)
649 {
651 task.Repeat(1s);
652 });
653
654 _scheduler.Schedule(3s, [this](TaskContext& task)
655 {
657 task.Repeat(1s);
658 });
659 break;
660 }
661 default:
662 break;
663 }
664 }
665
666 void OnSpellCast(SpellInfo const* spell) override
667 {
668 switch (spell->Id)
669 {
672 break;
674 // Not sure where exactly this should be called. What is known is it is called not always,
675 // before Dark Strike, in both scenarios with Dark Strike. What should be checked is the exact place where it should be called.
676 // Also looks like it is called every time before first Dark Strike, but that should be re-checked
677 if (roll_chance(50))
679 break;
680 default:
681 break;
682 }
683 }
684
685 void UpdateAI(uint32 diff) override
686 {
687 _scheduler.Update(diff);
688
689 UpdateVictim();
690 }
691
692private:
694};
695
696// 45235 - Blaze
698{
699 bool Validate(SpellInfo const* /*spellInfo*/) override
700 {
702 }
703
704 void HandleScript(SpellEffIndex /*effIndex*/)
705 {
707 }
708
713};
714
715// 45343 - Dark Flame Aura
717{
718 bool Validate(SpellInfo const* /*spellInfo*/) override
719 {
720 return ValidateSpellInfo(
721 {
730 });
731 }
732
733 bool CheckProc(ProcEventInfo& eventInfo)
734 {
735 // Don't allow to proc if target has Dark Flame
736 if (eventInfo.GetActionTarget()->HasAura(SPELL_DARK_FLAME))
737 return false;
738
739 // Allow proc from melee damage (Shadow Image deals no melee damage (see on-spawn aura), only Sacrolash does)
740 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
741 if (!spellInfo)
742 return true;
743
744 // Allow proc from shadow spells
745 switch (spellInfo->Id)
746 {
752 return true;
753 default:
754 return false;
755 }
756
757 return false;
758 }
759
760 void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
761 {
762 Unit* target = eventInfo.GetActionTarget();
763
764 if (target->HasAura(SPELL_FLAME_TOUCHED))
765 {
767 target->CastSpell(target, SPELL_DARK_FLAME, true);
768 }
769 else
770 target->CastSpell(target, SPELL_DARK_TOUCHED, true);
771 }
772
778};
779
780// 47300 - Dark Flame Aura
782{
783 bool Validate(SpellInfo const* /*spellInfo*/) override
784 {
785 return ValidateSpellInfo(
786 {
795 });
796 }
797
798 bool CheckProc(ProcEventInfo& eventInfo)
799 {
800 // Don't allow to proc if target has Dark Flame
801 if (eventInfo.GetActionTarget()->HasAura(SPELL_DARK_FLAME))
802 return false;
803
804 // Don't allow to proc from melee damage, Alythess any way doesn't do melee damage
805 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
806 if (!spellInfo)
807 return false;
808
809 // Allow proc from fire spells
810 switch (spellInfo->Id)
811 {
812 case SPELL_BLAZE:
813 case SPELL_FLAME_SEAR:
815 case SPELL_BURN:
817 return true;
818 default:
819 return false;
820 }
821
822 return false;
823 }
824
825 void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
826 {
827 Unit* target = eventInfo.GetActionTarget();
828
829 if (target->HasAura(SPELL_DARK_TOUCHED))
830 {
832 target->CastSpell(target, SPELL_DARK_FLAME, true);
833 }
834 else
835 target->CastSpell(target, SPELL_FLAME_TOUCHED, true);
836 }
837
843};
844
845// 4937
847{
848public:
849 at_witchs_sanctum() : OnlyOnceAreaTriggerScript("at_witchs_sanctum") { }
850
851 bool TryHandleOnce(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
852 {
853 if (InstanceScript* instance = player->GetInstanceScript())
854 {
855 if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
856 sacrolash->AI()->DoAction(ACTION_START_INTRO);
857
858 if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
859 alythess->AI()->DoAction(ACTION_START_INTRO);
860 }
861
862 return true;
863 }
864};
865
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
bool roll_chance(float chance, PseudoRandomDistributionState &state)
Definition Random.cpp:131
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:43
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
SpellEffIndex
@ EFFECT_1
@ EFFECT_0
@ SPELL_EFFECT_SCRIPT_EFFECT
@ UNIT_DYNFLAG_LOOTABLE
@ SPAWN_TYPE_CREATURE
Definition SpawnData.h:36
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELLVALUE_MAX_TARGETS
#define AuraEffectProcFn(F, I, N)
#define SpellEffectFn(F, I, N)
#define AuraCheckProcFn(F)
EvadeReason
@ REACT_PASSIVE
DamageEffectType
@ UNIT_STATE_CASTING
Definition Unit.h:290
@ 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()
Definition CreatureAI.h:169
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
void ResetLootMode()
Definition Creature.h:330
void SetReactState(ReactStates st)
Definition Creature.h:180
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition Creature.h:118
void SetLootMode(uint16 lootMode)
Definition Creature.h:327
void Update(uint32 time)
Definition EventMap.h:77
void Repeat(Milliseconds time)
Definition EventMap.cpp:67
EventId ExecuteEvent()
Definition EventMap.cpp:77
void CancelEvent(EventId eventId)
Definition EventMap.cpp:156
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition EventMap.cpp:40
void Reset()
Definition EventMap.cpp:25
Creature * GetCreature(uint32 type)
void Respawn(RespawnInfo *info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:2070
void RemoveDynamicFlag(uint32 flag)
Definition Object.h:98
Unit * GetActionTarget() const
Definition Unit.h:514
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:281
uint32 const Id
Definition SpellInfo.h:328
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & CancelAll()
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.h:160
virtual void InitializeAI()
Definition UnitAI.cpp:35
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition UnitAI.cpp:172
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:71
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:81
Definition Unit.h:647
bool IsWithinMeleeRange(Unit const *obj) const
Definition Unit.h:722
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:3253
uint64 GetHealth() const
Definition Unit.h:800
Unit * GetVictim() const
Definition Unit.h:738
bool HasUnitState(const uint32 f) const
Definition Unit.h:755
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition Unit.h:951
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
Map * GetMap() const
Definition Object.h:411
InstanceScript * GetInstanceScript() const
Definition Object.cpp:394
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
virtual uint64 GetData64(uint32) const
Definition ZoneScript.h:95
bool TryHandleOnce(Player *player, AreaTriggerEntry const *) override
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *, ProcEventInfo &eventInfo)
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
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