mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Scripts/ZG: Update scripts to new register model (5/5) (#26695)
This commit is contained in:
@@ -94,272 +94,261 @@ enum Data
|
||||
float const DamageIncrease = 40.0f;
|
||||
float const DamageDecrease = 100.f / (1.f + DamageIncrease / 100.f) - 100.f;
|
||||
|
||||
class boss_thekal : public CreatureScript
|
||||
struct boss_thekal : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_thekal() : CreatureScript("boss_thekal") { }
|
||||
boss_thekal(Creature* creature) : BossAI(creature, DATA_THEKAL)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
struct boss_thekalAI : public BossAI
|
||||
void Initialize()
|
||||
{
|
||||
_enraged = false;
|
||||
_isThekalDead = false;
|
||||
_isLorkhanDead = false;
|
||||
_isZathDead = false;
|
||||
_isResurrectTimerActive = false;
|
||||
_isChangingPhase = false;
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (!_EnterEvadeMode(why))
|
||||
return;
|
||||
me->AddUnitState(UNIT_STATE_EVADE);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (events.IsInPhase(PHASE_TWO))
|
||||
me->ApplyStatPctModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, DamageDecrease);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
events.Reset();
|
||||
_Reset();
|
||||
Initialize();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TALK_DEATH);
|
||||
|
||||
// Adds are still feign-deathing, so kill them when the encounter is over
|
||||
if (Creature* creature = instance->GetCreature(DATA_LORKHAN))
|
||||
creature->KillSelf();
|
||||
if (Creature* creature = instance->GetCreature(DATA_ZATH))
|
||||
creature->KillSelf();
|
||||
instance->SetBossState(DATA_LORKHAN, DONE);
|
||||
instance->SetBossState(DATA_ZATH, DONE);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
events.SetPhase(PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, 4s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SILENCE, 9s, 0, PHASE_ONE);
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
if (type == DATA_FAKE_DEATH)
|
||||
{
|
||||
boss_thekalAI(Creature* creature) : BossAI(creature, DATA_THEKAL)
|
||||
// A mob died
|
||||
switch (data)
|
||||
{
|
||||
Initialize();
|
||||
case NPC_HIGH_PRIEST_THEKAL:
|
||||
_isThekalDead = true;
|
||||
break;
|
||||
case NPC_ZEALOT_LORKHAN:
|
||||
_isLorkhanDead = true;
|
||||
break;
|
||||
case NPC_ZEALOT_ZATH:
|
||||
_isZathDead = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
if (_isThekalDead && _isLorkhanDead && _isZathDead)
|
||||
{
|
||||
_enraged = false;
|
||||
_isThekalDead = false;
|
||||
_isLorkhanDead = false;
|
||||
_isZathDead = false;
|
||||
_isResurrectTimerActive = false;
|
||||
_isChangingPhase = false;
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (!_EnterEvadeMode(why))
|
||||
return;
|
||||
me->AddUnitState(UNIT_STATE_EVADE);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (events.IsInPhase(PHASE_TWO))
|
||||
me->ApplyStatPctModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, DamageDecrease);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
events.Reset();
|
||||
_Reset();
|
||||
Initialize();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
events.ScheduleEvent(EVENT_CHANGE_PHASE_1, 3s);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
else
|
||||
{
|
||||
_JustDied();
|
||||
Talk(TALK_DEATH);
|
||||
|
||||
// Adds are still feign-deathing, so kill them when the encounter is over
|
||||
if (Creature* creature = instance->GetCreature(DATA_LORKHAN))
|
||||
creature->KillSelf();
|
||||
if (Creature* creature = instance->GetCreature(DATA_ZATH))
|
||||
creature->KillSelf();
|
||||
instance->SetBossState(DATA_LORKHAN, DONE);
|
||||
instance->SetBossState(DATA_ZATH, DONE);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
events.SetPhase(PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, 4s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SILENCE, 9s, 0, PHASE_ONE);
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
if (type == DATA_FAKE_DEATH)
|
||||
// Start resurrection timer if not already started, otherwise ignore
|
||||
if (!_isResurrectTimerActive)
|
||||
{
|
||||
// A mob died
|
||||
switch (data)
|
||||
{
|
||||
case NPC_HIGH_PRIEST_THEKAL:
|
||||
_isThekalDead = true;
|
||||
break;
|
||||
case NPC_ZEALOT_LORKHAN:
|
||||
_isLorkhanDead = true;
|
||||
break;
|
||||
case NPC_ZEALOT_ZATH:
|
||||
_isZathDead = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isThekalDead && _isLorkhanDead && _isZathDead)
|
||||
{
|
||||
_isResurrectTimerActive = false;
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_CHANGE_PHASE_1, 3s);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start resurrection timer if not already started, otherwise ignore
|
||||
if (!_isResurrectTimerActive)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10s);
|
||||
_isResurrectTimerActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == DATA_RESURRECTED)
|
||||
{
|
||||
Creature* creature = nullptr;
|
||||
if (data == NPC_HIGH_PRIEST_THEKAL)
|
||||
creature = me;
|
||||
else if (data == NPC_ZEALOT_LORKHAN)
|
||||
creature = instance->GetCreature(DATA_LORKHAN);
|
||||
else if (data == NPC_ZEALOT_ZATH)
|
||||
creature = instance->GetCreature(DATA_ZATH);
|
||||
|
||||
// Resurrect
|
||||
if (creature)
|
||||
{
|
||||
creature->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
creature->SetFullHealth();
|
||||
creature->SetImmuneToPC(false, true);
|
||||
creature->SetImmuneToNPC(false, true);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10s);
|
||||
_isResurrectTimerActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && events.IsInPhase(PHASE_ONE))
|
||||
{
|
||||
Talk(TALK_FAKE_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
me->SetImmuneToPC(true, true);
|
||||
me->SetImmuneToNPC(true, true);
|
||||
DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true);
|
||||
events.DelayEvents(10s);
|
||||
SetData(DATA_FAKE_DEATH, me->GetEntry());
|
||||
damage = 0;
|
||||
}
|
||||
else if (events.IsInPhase(PHASE_TWO) && !_enraged && me->HealthBelowPct(10))
|
||||
{
|
||||
DoCastSelf(SPELL_FRENZY);
|
||||
Talk(TALK_FRENZY);
|
||||
_enraged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MORTALCLEAVE:
|
||||
DoCastVictim(SPELL_MORTALCLEAVE);
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, 15s, 20s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SILENCE:
|
||||
DoCastVictim(SPELL_SILENCE);
|
||||
events.ScheduleEvent(EVENT_SILENCE, 20s, 25s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RESURRECT_TIMER:
|
||||
{
|
||||
// If only one or two of the three mobs were killed, resurrect them
|
||||
_isResurrectTimerActive = false;
|
||||
|
||||
if (_isThekalDead)
|
||||
{
|
||||
DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
SetData(DATA_RESURRECTED, me->GetEntry());
|
||||
_isThekalDead = false;
|
||||
}
|
||||
|
||||
if (_isLorkhanDead)
|
||||
{
|
||||
if (Creature* lorkhan = instance->GetCreature(DATA_LORKHAN))
|
||||
{
|
||||
lorkhan->AI()->DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
SetData(DATA_RESURRECTED, lorkhan->GetEntry());
|
||||
}
|
||||
_isLorkhanDead = false;
|
||||
}
|
||||
|
||||
if (_isZathDead)
|
||||
{
|
||||
if (Creature* zath = instance->GetCreature(DATA_ZATH))
|
||||
{
|
||||
zath->AI()->DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
SetData(DATA_RESURRECTED, zath->GetEntry());
|
||||
}
|
||||
_isZathDead = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_CHANGE_PHASE_1:
|
||||
_isChangingPhase = true;
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->SetFullHealth();
|
||||
DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
events.ScheduleEvent(EVENT_CHANGE_PHASE_2, 1s);
|
||||
break;
|
||||
case EVENT_CHANGE_PHASE_2:
|
||||
Talk(TALK_TIGER_PHASE);
|
||||
events.ScheduleEvent(EVENT_CHANGE_PHASE_3, 1s);
|
||||
break;
|
||||
case EVENT_CHANGE_PHASE_3:
|
||||
{
|
||||
// Trigger phase change
|
||||
_isChangingPhase = false;
|
||||
DoCastSelf(SPELL_TIGER_FORM);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->ApplyStatPctModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, DamageIncrease);
|
||||
ResetThreatList();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, 4s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_SPELL_CHARGE, 12s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, 25s, 0, PHASE_TWO);
|
||||
events.SetPhase(PHASE_TWO);
|
||||
break;
|
||||
}
|
||||
case EVENT_FORCEPUNCH:
|
||||
DoCastVictim(SPELL_FORCEPUNCH, true);
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, 16s, 21s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_CHARGE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true))
|
||||
{
|
||||
ResetThreatList();
|
||||
AttackStart(target);
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHARGE, 15s, 22s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_SUMMONTIGERS:
|
||||
DoCastVictim(SPELL_SUMMONTIGERS, true);
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, 10s, 14s, 0, PHASE_TWO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isChangingPhase)
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _enraged;
|
||||
bool _isThekalDead;
|
||||
bool _isLorkhanDead;
|
||||
bool _isZathDead;
|
||||
bool _isResurrectTimerActive;
|
||||
bool _isChangingPhase;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<boss_thekalAI>(creature);
|
||||
}
|
||||
else if (type == DATA_RESURRECTED)
|
||||
{
|
||||
Creature* creature = nullptr;
|
||||
if (data == NPC_HIGH_PRIEST_THEKAL)
|
||||
creature = me;
|
||||
else if (data == NPC_ZEALOT_LORKHAN)
|
||||
creature = instance->GetCreature(DATA_LORKHAN);
|
||||
else if (data == NPC_ZEALOT_ZATH)
|
||||
creature = instance->GetCreature(DATA_ZATH);
|
||||
|
||||
// Resurrect
|
||||
if (creature)
|
||||
{
|
||||
creature->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
creature->SetFullHealth();
|
||||
creature->SetImmuneToPC(false, true);
|
||||
creature->SetImmuneToNPC(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && events.IsInPhase(PHASE_ONE))
|
||||
{
|
||||
Talk(TALK_FAKE_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
me->SetImmuneToPC(true, true);
|
||||
me->SetImmuneToNPC(true, true);
|
||||
DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true);
|
||||
events.DelayEvents(10s);
|
||||
SetData(DATA_FAKE_DEATH, me->GetEntry());
|
||||
damage = 0;
|
||||
}
|
||||
else if (events.IsInPhase(PHASE_TWO) && !_enraged && me->HealthBelowPct(10))
|
||||
{
|
||||
DoCastSelf(SPELL_FRENZY);
|
||||
Talk(TALK_FRENZY);
|
||||
_enraged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MORTALCLEAVE:
|
||||
DoCastVictim(SPELL_MORTALCLEAVE);
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, 15s, 20s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SILENCE:
|
||||
DoCastVictim(SPELL_SILENCE);
|
||||
events.ScheduleEvent(EVENT_SILENCE, 20s, 25s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RESURRECT_TIMER:
|
||||
{
|
||||
// If only one or two of the three mobs were killed, resurrect them
|
||||
_isResurrectTimerActive = false;
|
||||
|
||||
if (_isThekalDead)
|
||||
{
|
||||
DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
SetData(DATA_RESURRECTED, me->GetEntry());
|
||||
_isThekalDead = false;
|
||||
}
|
||||
|
||||
if (_isLorkhanDead)
|
||||
{
|
||||
if (Creature* lorkhan = instance->GetCreature(DATA_LORKHAN))
|
||||
{
|
||||
lorkhan->AI()->DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
SetData(DATA_RESURRECTED, lorkhan->GetEntry());
|
||||
}
|
||||
_isLorkhanDead = false;
|
||||
}
|
||||
|
||||
if (_isZathDead)
|
||||
{
|
||||
if (Creature* zath = instance->GetCreature(DATA_ZATH))
|
||||
{
|
||||
zath->AI()->DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
SetData(DATA_RESURRECTED, zath->GetEntry());
|
||||
}
|
||||
_isZathDead = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_CHANGE_PHASE_1:
|
||||
_isChangingPhase = true;
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->SetFullHealth();
|
||||
DoCastSelf(SPELL_RESURRECT_VISUAL);
|
||||
events.ScheduleEvent(EVENT_CHANGE_PHASE_2, 1s);
|
||||
break;
|
||||
case EVENT_CHANGE_PHASE_2:
|
||||
Talk(TALK_TIGER_PHASE);
|
||||
events.ScheduleEvent(EVENT_CHANGE_PHASE_3, 1s);
|
||||
break;
|
||||
case EVENT_CHANGE_PHASE_3:
|
||||
{
|
||||
// Trigger phase change
|
||||
_isChangingPhase = false;
|
||||
DoCastSelf(SPELL_TIGER_FORM);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->ApplyStatPctModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, DamageIncrease);
|
||||
ResetThreatList();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, 4s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_SPELL_CHARGE, 12s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, 25s, 0, PHASE_TWO);
|
||||
events.SetPhase(PHASE_TWO);
|
||||
break;
|
||||
}
|
||||
case EVENT_FORCEPUNCH:
|
||||
DoCastVictim(SPELL_FORCEPUNCH, true);
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, 16s, 21s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_CHARGE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.f, true))
|
||||
{
|
||||
ResetThreatList();
|
||||
AttackStart(target);
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHARGE, 15s, 22s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_SUMMONTIGERS:
|
||||
DoCastVictim(SPELL_SUMMONTIGERS, true);
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, 10s, 14s, 0, PHASE_TWO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isChangingPhase)
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _enraged;
|
||||
bool _isThekalDead;
|
||||
bool _isLorkhanDead;
|
||||
bool _isZathDead;
|
||||
bool _isResurrectTimerActive;
|
||||
bool _isChangingPhase;
|
||||
};
|
||||
|
||||
enum LorkhanEvents
|
||||
@@ -404,103 +393,92 @@ class LorKhanSelectTargetToHeal
|
||||
};
|
||||
|
||||
// Zealot Lor'Khan
|
||||
class npc_zealot_lorkhan : public CreatureScript
|
||||
struct npc_zealot_lorkhan : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_zealot_lorkhan() : CreatureScript("npc_zealot_lorkhan") { }
|
||||
npc_zealot_lorkhan(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
struct npc_zealot_lorkhanAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
_events.Reset();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
npc_zealot_lorkhanAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_events.Reset();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_IMMUNE_TO_PC);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
Talk(TALK_FAKE_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
me->SetImmuneToPC(true, true);
|
||||
me->SetImmuneToNPC(true, true);
|
||||
DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true);
|
||||
me->AttackStop();
|
||||
if (Creature* thekal = _instance->GetCreature(DATA_THEKAL))
|
||||
thekal->AI()->SetData(DATA_FAKE_DEATH, me->GetEntry());
|
||||
_events.DelayEvents(10s);
|
||||
damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_SHIELD, 1s);
|
||||
_events.ScheduleEvent(EVENT_BLOODLUST, 16s);
|
||||
_events.ScheduleEvent(EVENT_GREATER_HEAL, 32s);
|
||||
_events.ScheduleEvent(EVENT_DISARM, 6s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SHIELD:
|
||||
DoCastSelf(SPELL_SHIELD);
|
||||
_events.ScheduleEvent(EVENT_SHIELD, 61s);
|
||||
break;
|
||||
case EVENT_BLOODLUST:
|
||||
DoCastSelf(SPELL_BLOODLUST);
|
||||
_events.ScheduleEvent(EVENT_BLOODLUST, 20s, 28s);
|
||||
break;
|
||||
case EVENT_GREATER_HEAL:
|
||||
{
|
||||
Unit* target = nullptr;
|
||||
LorKhanSelectTargetToHeal check(me, 100.0f);
|
||||
Trinity::UnitLastSearcher<LorKhanSelectTargetToHeal> searcher(me, target, check);
|
||||
Cell::VisitAllObjects(me, searcher, 100.0f);
|
||||
|
||||
if (target)
|
||||
DoCast(target, SPELL_GREATERHEAL);
|
||||
|
||||
_events.ScheduleEvent(EVENT_GREATER_HEAL, 15s, 20s);
|
||||
break;
|
||||
}
|
||||
case EVENT_DISARM:
|
||||
DoCastVictim(SPELL_DISARM);
|
||||
_events.ScheduleEvent(EVENT_DISARM, 15s, 25s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<npc_zealot_lorkhanAI>(creature);
|
||||
Talk(TALK_FAKE_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
me->SetImmuneToPC(true, true);
|
||||
me->SetImmuneToNPC(true, true);
|
||||
DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true);
|
||||
me->AttackStop();
|
||||
if (Creature* thekal = _instance->GetCreature(DATA_THEKAL))
|
||||
thekal->AI()->SetData(DATA_FAKE_DEATH, me->GetEntry());
|
||||
_events.DelayEvents(10s);
|
||||
damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_SHIELD, 1s);
|
||||
_events.ScheduleEvent(EVENT_BLOODLUST, 16s);
|
||||
_events.ScheduleEvent(EVENT_GREATER_HEAL, 32s);
|
||||
_events.ScheduleEvent(EVENT_DISARM, 6s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SHIELD:
|
||||
DoCastSelf(SPELL_SHIELD);
|
||||
_events.ScheduleEvent(EVENT_SHIELD, 61s);
|
||||
break;
|
||||
case EVENT_BLOODLUST:
|
||||
DoCastSelf(SPELL_BLOODLUST);
|
||||
_events.ScheduleEvent(EVENT_BLOODLUST, 20s, 28s);
|
||||
break;
|
||||
case EVENT_GREATER_HEAL:
|
||||
{
|
||||
Unit* target = nullptr;
|
||||
LorKhanSelectTargetToHeal check(me, 100.0f);
|
||||
Trinity::UnitLastSearcher<LorKhanSelectTargetToHeal> searcher(me, target, check);
|
||||
Cell::VisitAllObjects(me, searcher, 100.0f);
|
||||
|
||||
if (target)
|
||||
DoCast(target, SPELL_GREATERHEAL);
|
||||
|
||||
_events.ScheduleEvent(EVENT_GREATER_HEAL, 15s, 20s);
|
||||
break;
|
||||
}
|
||||
case EVENT_DISARM:
|
||||
DoCastVictim(SPELL_DISARM);
|
||||
_events.ScheduleEvent(EVENT_DISARM, 15s, 25s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
enum ZathEvents
|
||||
@@ -513,103 +491,92 @@ enum ZathEvents
|
||||
};
|
||||
|
||||
// Zealot Zath
|
||||
class npc_zealot_zath : public CreatureScript
|
||||
struct npc_zealot_zath : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_zealot_zath() : CreatureScript("npc_zealot_zath") { }
|
||||
npc_zealot_zath(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
struct npc_zealot_zathAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
_events.Reset();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
npc_zealot_zathAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_events.Reset();
|
||||
me->RemoveAurasDueToSpell(SPELL_PERMANENT_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
Talk(TALK_FAKE_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
me->SetImmuneToPC(true, true);
|
||||
me->SetImmuneToNPC(true, true);
|
||||
DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true);
|
||||
me->AttackStop();
|
||||
if (Creature* thekal = _instance->GetCreature(DATA_THEKAL))
|
||||
thekal->AI()->SetData(DATA_FAKE_DEATH, me->GetEntry());
|
||||
_events.DelayEvents(10s);
|
||||
damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_SWEEPING_STRIKES, 13s);
|
||||
_events.ScheduleEvent(EVENT_SINISTER_STRIKE, 8s);
|
||||
_events.ScheduleEvent(EVENT_GOUGE, 25s);
|
||||
_events.ScheduleEvent(EVENT_KICK, 18s);
|
||||
_events.ScheduleEvent(EVENT_BLIND, 5s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SWEEPING_STRIKES:
|
||||
DoCastVictim(SPELL_SWEEPINGSTRIKES);
|
||||
_events.ScheduleEvent(EVENT_SWEEPING_STRIKES, 22s, 26s);
|
||||
break;
|
||||
case EVENT_SINISTER_STRIKE:
|
||||
DoCastVictim(SPELL_SINISTERSTRIKE);
|
||||
_events.ScheduleEvent(EVENT_SINISTER_STRIKE, 8s, 16s);
|
||||
break;
|
||||
case EVENT_GOUGE:
|
||||
DoCastVictim(SPELL_GOUGE);
|
||||
if (GetThreat(me->GetVictim()))
|
||||
ModifyThreatByPercent(me->GetVictim(), -100);
|
||||
_events.ScheduleEvent(EVENT_GOUGE, 17s, 27s);
|
||||
break;
|
||||
case EVENT_KICK:
|
||||
DoCastVictim(SPELL_KICK);
|
||||
_events.ScheduleEvent(EVENT_KICK, 15s, 25s);
|
||||
break;
|
||||
case EVENT_BLIND:
|
||||
DoCastVictim(SPELL_BLIND);
|
||||
_events.ScheduleEvent(EVENT_BLIND, 10s, 20s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<npc_zealot_zathAI>(creature);
|
||||
Talk(TALK_FAKE_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
me->SetImmuneToPC(true, true);
|
||||
me->SetImmuneToNPC(true, true);
|
||||
DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH, true);
|
||||
me->AttackStop();
|
||||
if (Creature* thekal = _instance->GetCreature(DATA_THEKAL))
|
||||
thekal->AI()->SetData(DATA_FAKE_DEATH, me->GetEntry());
|
||||
_events.DelayEvents(10s);
|
||||
damage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_SWEEPING_STRIKES, 13s);
|
||||
_events.ScheduleEvent(EVENT_SINISTER_STRIKE, 8s);
|
||||
_events.ScheduleEvent(EVENT_GOUGE, 25s);
|
||||
_events.ScheduleEvent(EVENT_KICK, 18s);
|
||||
_events.ScheduleEvent(EVENT_BLIND, 5s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SWEEPING_STRIKES:
|
||||
DoCastVictim(SPELL_SWEEPINGSTRIKES);
|
||||
_events.ScheduleEvent(EVENT_SWEEPING_STRIKES, 22s, 26s);
|
||||
break;
|
||||
case EVENT_SINISTER_STRIKE:
|
||||
DoCastVictim(SPELL_SINISTERSTRIKE);
|
||||
_events.ScheduleEvent(EVENT_SINISTER_STRIKE, 8s, 16s);
|
||||
break;
|
||||
case EVENT_GOUGE:
|
||||
DoCastVictim(SPELL_GOUGE);
|
||||
if (GetThreat(me->GetVictim()))
|
||||
ModifyThreatByPercent(me->GetVictim(), -100);
|
||||
_events.ScheduleEvent(EVENT_GOUGE, 17s, 27s);
|
||||
break;
|
||||
case EVENT_KICK:
|
||||
DoCastVictim(SPELL_KICK);
|
||||
_events.ScheduleEvent(EVENT_KICK, 15s, 25s);
|
||||
break;
|
||||
case EVENT_BLIND:
|
||||
DoCastVictim(SPELL_BLIND);
|
||||
_events.ScheduleEvent(EVENT_BLIND, 10s, 20s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
void AddSC_boss_thekal()
|
||||
{
|
||||
new boss_thekal();
|
||||
new npc_zealot_lorkhan();
|
||||
new npc_zealot_zath();
|
||||
RegisterZulGurubCreatureAI(boss_thekal);
|
||||
RegisterZulGurubCreatureAI(npc_zealot_lorkhan);
|
||||
RegisterZulGurubCreatureAI(npc_zealot_zath);
|
||||
}
|
||||
|
||||
@@ -85,203 +85,192 @@ enum NPCs
|
||||
NPC_PARASITIC_SERPENT = 14884
|
||||
};
|
||||
|
||||
class boss_venoxis : public CreatureScript
|
||||
struct boss_venoxis : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_venoxis() : CreatureScript("boss_venoxis") { }
|
||||
boss_venoxis(Creature* creature) : BossAI(creature, DATA_VENOXIS)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
struct boss_venoxisAI : public BossAI
|
||||
void Initialize()
|
||||
{
|
||||
_inMeleeRange = 0;
|
||||
_transformed = false;
|
||||
_frenzied = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
// remove all spells and auras from previous attempts
|
||||
me->RemoveAllAuras();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
// set some internally used variables to their defaults
|
||||
Initialize();
|
||||
events.SetPhase(PHASE_ONE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_VENOXIS_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
// Always running events
|
||||
events.ScheduleEvent(EVENT_THRASH, 5s);
|
||||
// Phase one events (regular form)
|
||||
events.ScheduleEvent(EVENT_HOLY_NOVA, 5s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_DISPEL_MAGIC, 35s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_HOLY_FIRE, 10s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_RENEW, 30s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_HOLY_WRATH, 1min, 0, PHASE_ONE);
|
||||
|
||||
events.SetPhase(PHASE_ONE);
|
||||
|
||||
// Set zone in combat
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
|
||||
{
|
||||
// check if venoxis is ready to transform
|
||||
if (!_transformed && !HealthAbovePct(50))
|
||||
{
|
||||
boss_venoxisAI(Creature* creature) : BossAI(creature, DATA_VENOXIS)
|
||||
_transformed = true;
|
||||
// schedule the event that changes our phase
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 100ms);
|
||||
}
|
||||
// we're losing health, bad, go frenzy
|
||||
else if (!_frenzied && !HealthAbovePct(20))
|
||||
{
|
||||
_frenzied = true;
|
||||
events.ScheduleEvent(EVENT_FRENZY, 100ms);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
// return back to main code if we're still casting
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
// thrash is available in all phases
|
||||
case EVENT_THRASH:
|
||||
DoCast(me, SPELL_THRASH, true);
|
||||
events.ScheduleEvent(EVENT_THRASH, 10s, 20s);
|
||||
break;
|
||||
// troll form spells and Actions (first part)
|
||||
case EVENT_DISPEL_MAGIC:
|
||||
DoCast(me, SPELL_DISPEL_MAGIC);
|
||||
events.ScheduleEvent(EVENT_DISPEL_MAGIC, 15s, 20s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RENEW:
|
||||
DoCast(me, SPELL_RENEW);
|
||||
events.ScheduleEvent(EVENT_RENEW, 25s, 30s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_NOVA:
|
||||
_inMeleeRange = 0;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_inMeleeRange = 0;
|
||||
_transformed = false;
|
||||
_frenzied = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
// remove all spells and auras from previous attempts
|
||||
me->RemoveAllAuras();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
// set some internally used variables to their defaults
|
||||
Initialize();
|
||||
events.SetPhase(PHASE_ONE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_VENOXIS_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
// Always running events
|
||||
events.ScheduleEvent(EVENT_THRASH, 5s);
|
||||
// Phase one events (regular form)
|
||||
events.ScheduleEvent(EVENT_HOLY_NOVA, 5s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_DISPEL_MAGIC, 35s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_HOLY_FIRE, 10s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_RENEW, 30s, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_HOLY_WRATH, 1min, 0, PHASE_ONE);
|
||||
|
||||
events.SetPhase(PHASE_ONE);
|
||||
|
||||
// Set zone in combat
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
|
||||
{
|
||||
// check if venoxis is ready to transform
|
||||
if (!_transformed && !HealthAbovePct(50))
|
||||
{
|
||||
_transformed = true;
|
||||
// schedule the event that changes our phase
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 100ms);
|
||||
}
|
||||
// we're losing health, bad, go frenzy
|
||||
else if (!_frenzied && !HealthAbovePct(20))
|
||||
{
|
||||
_frenzied = true;
|
||||
events.ScheduleEvent(EVENT_FRENZY, 100ms);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
// return back to main code if we're still casting
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
// thrash is available in all phases
|
||||
case EVENT_THRASH:
|
||||
DoCast(me, SPELL_THRASH, true);
|
||||
events.ScheduleEvent(EVENT_THRASH, 10s, 20s);
|
||||
break;
|
||||
// troll form spells and Actions (first part)
|
||||
case EVENT_DISPEL_MAGIC:
|
||||
DoCast(me, SPELL_DISPEL_MAGIC);
|
||||
events.ScheduleEvent(EVENT_DISPEL_MAGIC, 15s, 20s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RENEW:
|
||||
DoCast(me, SPELL_RENEW);
|
||||
events.ScheduleEvent(EVENT_RENEW, 25s, 30s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_NOVA:
|
||||
_inMeleeRange = 0;
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, i))
|
||||
// check if target is within melee-distance
|
||||
if (me->IsWithinMeleeRange(target))
|
||||
++_inMeleeRange;
|
||||
}
|
||||
|
||||
// trigger spellcast only if we have 3 or more targets to affect
|
||||
if (_inMeleeRange >= 3)
|
||||
DoCastVictim(SPELL_HOLY_NOVA);
|
||||
|
||||
events.ScheduleEvent(EVENT_HOLY_NOVA, 45s, 75s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_FIRE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_HOLY_FIRE);
|
||||
events.ScheduleEvent(EVENT_HOLY_FIRE, 45s, 60s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_WRATH:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_HOLY_WRATH);
|
||||
events.ScheduleEvent(EVENT_HOLY_WRATH, 45s, 60s, 0, PHASE_ONE);
|
||||
break;
|
||||
|
||||
//
|
||||
// snake form spells and Actions
|
||||
//
|
||||
|
||||
case EVENT_VENOM_SPIT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_VENOM_SPIT);
|
||||
events.ScheduleEvent(EVENT_VENOM_SPIT, 5s, 15s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_POISON_CLOUD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_POISON_CLOUD);
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, 15s, 20s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_PARASITIC_SERPENT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_SUMMON_PARASITIC_SERPENT);
|
||||
events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 15s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
// frenzy at 20% health
|
||||
DoCast(me, SPELL_FRENZY, true);
|
||||
break;
|
||||
|
||||
//
|
||||
// shape and phase-changing
|
||||
//
|
||||
|
||||
case EVENT_TRANSFORM:
|
||||
// shapeshift at 50% health
|
||||
DoCast(me, SPELL_VENOXIS_TRANSFORM);
|
||||
Talk(SAY_VENOXIS_TRANSFORM);
|
||||
ResetThreatList();
|
||||
|
||||
// phase two events (snakeform)
|
||||
events.ScheduleEvent(EVENT_VENOM_SPIT, 5s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, 10s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 30s, 0, PHASE_TWO);
|
||||
|
||||
// transformed, start phase two
|
||||
events.SetPhase(PHASE_TWO);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, i))
|
||||
// check if target is within melee-distance
|
||||
if (me->IsWithinMeleeRange(target))
|
||||
++_inMeleeRange;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
// trigger spellcast only if we have 3 or more targets to affect
|
||||
if (_inMeleeRange >= 3)
|
||||
DoCastVictim(SPELL_HOLY_NOVA);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
events.ScheduleEvent(EVENT_HOLY_NOVA, 45s, 75s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_FIRE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_HOLY_FIRE);
|
||||
events.ScheduleEvent(EVENT_HOLY_FIRE, 45s, 60s, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_WRATH:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_HOLY_WRATH);
|
||||
events.ScheduleEvent(EVENT_HOLY_WRATH, 45s, 60s, 0, PHASE_ONE);
|
||||
break;
|
||||
|
||||
//
|
||||
// snake form spells and Actions
|
||||
//
|
||||
|
||||
case EVENT_VENOM_SPIT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_VENOM_SPIT);
|
||||
events.ScheduleEvent(EVENT_VENOM_SPIT, 5s, 15s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_POISON_CLOUD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_POISON_CLOUD);
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, 15s, 20s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_PARASITIC_SERPENT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
DoCast(target, SPELL_SUMMON_PARASITIC_SERPENT);
|
||||
events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 15s, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
// frenzy at 20% health
|
||||
DoCast(me, SPELL_FRENZY, true);
|
||||
break;
|
||||
|
||||
//
|
||||
// shape and phase-changing
|
||||
//
|
||||
|
||||
case EVENT_TRANSFORM:
|
||||
// shapeshift at 50% health
|
||||
DoCast(me, SPELL_VENOXIS_TRANSFORM);
|
||||
Talk(SAY_VENOXIS_TRANSFORM);
|
||||
ResetThreatList();
|
||||
|
||||
// phase two events (snakeform)
|
||||
events.ScheduleEvent(EVENT_VENOM_SPIT, 5s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, 10s, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 30s, 0, PHASE_TWO);
|
||||
|
||||
// transformed, start phase two
|
||||
events.SetPhase(PHASE_TWO);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _inMeleeRange;
|
||||
bool _transformed;
|
||||
bool _frenzied;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<boss_venoxisAI>(creature);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _inMeleeRange;
|
||||
bool _transformed;
|
||||
bool _frenzied;
|
||||
};
|
||||
|
||||
void AddSC_boss_venoxis()
|
||||
{
|
||||
new boss_venoxis();
|
||||
RegisterZulGurubCreatureAI(boss_venoxis);
|
||||
}
|
||||
|
||||
@@ -31,63 +31,52 @@ enum Events
|
||||
EVENT_LIGHTNINGWAVE = 2
|
||||
};
|
||||
|
||||
class boss_wushoolay : public CreatureScript
|
||||
struct boss_wushoolay : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_wushoolay() : CreatureScript("boss_wushoolay") { }
|
||||
boss_wushoolay(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
struct boss_wushoolayAI : public BossAI
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, 5s, 10s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGWAVE, 8s, 16s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
switch (eventId)
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, 5s, 10s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGWAVE, 8s, 16s);
|
||||
case EVENT_LIGHTNINGCLOUD:
|
||||
DoCastVictim(SPELL_LIGHTNINGCLOUD, true);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, 15s, 20s);
|
||||
break;
|
||||
case EVENT_LIGHTNINGWAVE:
|
||||
DoCast(SelectTarget(SelectTargetMethod::Random, 0, 100, true), SPELL_LIGHTNINGWAVE);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGWAVE, 12s, 16s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_LIGHTNINGCLOUD:
|
||||
DoCastVictim(SPELL_LIGHTNINGCLOUD, true);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, 15s, 20s);
|
||||
break;
|
||||
case EVENT_LIGHTNINGWAVE:
|
||||
DoCast(SelectTarget(SelectTargetMethod::Random, 0, 100, true), SPELL_LIGHTNINGWAVE);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGWAVE, 12s, 16s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetZulGurubAI<boss_wushoolayAI>(creature);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_wushoolay()
|
||||
{
|
||||
new boss_wushoolay();
|
||||
RegisterZulGurubCreatureAI(boss_wushoolay);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user