aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroffl <11556157+offl@users.noreply.github.com>2021-04-13 10:33:36 +0300
committerGitHub <noreply@github.com>2021-04-13 09:33:36 +0200
commit07fe74b2333567d0c51b22e587396ddc70da1ffb (patch)
tree029a74004d58138a5be55e493fd47432257facf1
parent2cbfb784e047f5711bb543de38c9760ff84b9dd7 (diff)
Scripts/Naxxramas: Update Thaddius to new model (#26391)
Co-authored-by: offl <offl@users.noreply.github.com>
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp1693
1 files changed, 813 insertions, 880 deletions
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
index 516a3b6aa92..4fc258739a7 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
@@ -159,1057 +159,990 @@ enum ThaddiusSpells
struct boss_thaddius : public BossAI
{
- public:
- boss_thaddius(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningUnlocked(false), ballLightningEnabled(false), shockingEligibility(true) {}
+public:
+ boss_thaddius(Creature* creature) : BossAI(creature, BOSS_THADDIUS), stalaggAlive(true), feugenAlive(true), ballLightningUnlocked(false), ballLightningEnabled(false), shockingEligibility(true) {}
- void InitializeAI() override
+ void InitializeAI() override
+ {
+ if (instance->GetBossState(BOSS_THADDIUS) != DONE)
{
- if (instance->GetBossState(BOSS_THADDIUS) != DONE)
- {
- events.SetPhase(PHASE_NOT_ENGAGED);
- SetCombatMovement(false);
- }
+ events.SetPhase(PHASE_NOT_ENGAGED);
+ SetCombatMovement(false);
}
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- void Reset() override { }
+ void Reset() override { }
- void EnterEvadeMode(EvadeReason why) override
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (!ballLightningEnabled && why == EVADE_REASON_NO_HOSTILES)
{
- if (!ballLightningEnabled && why == EVADE_REASON_NO_HOSTILES)
- {
- ballLightningEnabled = true;
- return; // try again
- }
- if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive()))
- BeginResetEncounter();
+ ballLightningEnabled = true;
+ return; // try again
}
+ if (events.IsInPhase(PHASE_TRANSITION) || (events.IsInPhase(PHASE_THADDIUS) && me->IsAlive()))
+ BeginResetEncounter();
+ }
- bool CanAIAttack(Unit const* who) const override
- {
- if (ballLightningEnabled || me->IsWithinMeleeRange(who))
- return BossAI::CanAIAttack(who);
- else
- return false;
- }
+ bool CanAIAttack(Unit const* who) const override
+ {
+ if (ballLightningEnabled || me->IsWithinMeleeRange(who))
+ return BossAI::CanAIAttack(who);
+ else
+ return false;
+ }
- void JustAppeared() override
+ void JustAppeared() override
+ {
+ if (instance->GetBossState(BOSS_THADDIUS) != DONE)
+ ResetEncounter();
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ me->setActive(false);
+ me->SetFarVisible(false);
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
{
- if (instance->GetBossState(BOSS_THADDIUS) != DONE)
- ResetEncounter();
+ stalagg->setActive(false);
+ stalagg->SetFarVisible(false);
}
-
- void JustDied(Unit* /*killer*/) override
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
{
- _JustDied();
- me->setActive(false);
- me->SetFarVisible(false);
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- {
- stalagg->setActive(false);
- stalagg->SetFarVisible(false);
- }
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- {
- feugen->setActive(false);
- feugen->SetFarVisible(false);
- }
- Talk(SAY_DEATH);
+ feugen->setActive(false);
+ feugen->SetFarVisible(false);
}
+ Talk(SAY_DEATH);
+ }
- void DoAction(int32 action) override
+ void DoAction(int32 action) override
+ {
+ switch (action)
{
- switch (action)
- {
- case ACTION_FEUGEN_RESET:
- case ACTION_STALAGG_RESET:
- if (!events.IsInPhase(PHASE_NOT_ENGAGED))
- BeginResetEncounter();
- break;
- case ACTION_FEUGEN_AGGRO:
- case ACTION_STALAGG_AGGRO:
- if (!events.IsInPhase(PHASE_NOT_ENGAGED))
- return;
- events.SetPhase(PHASE_PETS);
+ case ACTION_FEUGEN_RESET:
+ case ACTION_STALAGG_RESET:
+ if (!events.IsInPhase(PHASE_NOT_ENGAGED))
+ BeginResetEncounter();
+ break;
+ case ACTION_FEUGEN_AGGRO:
+ case ACTION_STALAGG_AGGRO:
+ if (!events.IsInPhase(PHASE_NOT_ENGAGED))
+ return;
+ events.SetPhase(PHASE_PETS);
- shockingEligibility = true;
+ shockingEligibility = true;
- if (!instance->CheckRequiredBosses(BOSS_THADDIUS))
- {
- BeginResetEncounter();
- return;
- }
- instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS);
+ if (!instance->CheckRequiredBosses(BOSS_THADDIUS))
+ {
+ BeginResetEncounter();
+ return;
+ }
+ instance->SetBossState(BOSS_THADDIUS, IN_PROGRESS);
- me->setActive(true);
- me->SetFarVisible(true);
- DoZoneInCombat();
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- {
- stalagg->setActive(true);
- stalagg->SetFarVisible(true);
- }
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- {
- feugen->setActive(true);
- feugen->SetFarVisible(true);
- }
- break;
- case ACTION_FEUGEN_DIED:
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX);
- feugenAlive = false;
- if (stalaggAlive)
- events.ScheduleEvent(EVENT_REVIVE_FEUGEN, 5s, 0, PHASE_PETS);
- else
- Transition();
+ me->setActive(true);
+ me->SetFarVisible(true);
+ DoZoneInCombat();
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ {
+ stalagg->setActive(true);
+ stalagg->SetFarVisible(true);
+ }
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ {
+ feugen->setActive(true);
+ feugen->SetFarVisible(true);
+ }
+ break;
+ case ACTION_FEUGEN_DIED:
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ feugen->AI()->DoAction(ACTION_FEUGEN_REVIVING_FX);
+ feugenAlive = false;
+ if (stalaggAlive)
+ events.ScheduleEvent(EVENT_REVIVE_FEUGEN, 5s, 0, PHASE_PETS);
+ else
+ Transition();
- break;
- case ACTION_STALAGG_DIED:
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX);
- stalaggAlive = false;
- if (feugenAlive)
- events.ScheduleEvent(EVENT_REVIVE_STALAGG, 5s, 0, PHASE_PETS);
- else
- Transition();
+ break;
+ case ACTION_STALAGG_DIED:
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ stalagg->AI()->DoAction(ACTION_STALAGG_REVIVING_FX);
+ stalaggAlive = false;
+ if (feugenAlive)
+ events.ScheduleEvent(EVENT_REVIVE_STALAGG, 5s, 0, PHASE_PETS);
+ else
+ Transition();
- break;
+ break;
- case ACTION_POLARITY_CROSSED:
- shockingEligibility = false;
- break;
- default:
- break;
- }
+ case ACTION_POLARITY_CROSSED:
+ shockingEligibility = false;
+ break;
+ default:
+ break;
}
+ }
- uint32 GetData(uint32 id) const override
- {
- return (id == DATA_POLARITY_CROSSED && shockingEligibility) ? 1u : 0u;
- }
+ uint32 GetData(uint32 id) const override
+ {
+ return (id == DATA_POLARITY_CROSSED && shockingEligibility) ? 1u : 0u;
+ }
- void Transition() // initiate transition between pet phase and thaddius phase
- {
- events.SetPhase(PHASE_TRANSITION);
+ void Transition() // initiate transition between pet phase and thaddius phase
+ {
+ events.SetPhase(PHASE_TRANSITION);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- events.ScheduleEvent(EVENT_TRANSITION_1, 10s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_TRANSITION_2, 12s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_TRANSITION_3, 14s, 0, PHASE_TRANSITION);
- }
+ events.ScheduleEvent(EVENT_TRANSITION_1, 10s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_TRANSITION_2, 12s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_TRANSITION_3, 14s, 0, PHASE_TRANSITION);
+ }
- void BeginResetEncounter()
- {
- if (instance->GetBossState(BOSS_THADDIUS) == DONE)
- return;
+ void BeginResetEncounter()
+ {
+ if (instance->GetBossState(BOSS_THADDIUS) == DONE)
+ return;
+
+ // remove polarity shift debuffs on reset
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY);
+
+ me->DespawnOrUnsummon(0s, 30s);
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
+ me->SetImmuneToPC(true);
+ me->setActive(false);
+ me->SetFarVisible(false);
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ feugen->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER);
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ stalagg->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER);
+ }
- // remove polarity shift debuffs on reset
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_APPLY);
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_APPLY);
+ void ResetEncounter()
+ {
+ feugenAlive = true;
+ stalaggAlive = true;
- me->DespawnOrUnsummon(0s, 30s);
+ _Reset();
+ events.SetPhase(PHASE_NOT_ENGAGED);
+ me->SetReactState(REACT_PASSIVE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
- me->SetImmuneToPC(true);
- me->setActive(false);
- me->SetFarVisible(false);
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- feugen->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER);
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- stalagg->AI()->DoAction(ACTION_BEGIN_RESET_ENCOUNTER);
- }
+ // @todo these guys should really be moved to a summon group - this is merely a hack to make them work in dynamic_spawning
+ instance->instance->Respawn(SPAWN_TYPE_CREATURE, 130958); // Stalagg
+ instance->instance->Respawn(SPAWN_TYPE_CREATURE, 130959); // Feugen
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (events.IsInPhase(PHASE_NOT_ENGAGED))
+ return;
+ if (events.IsInPhase(PHASE_THADDIUS) && !UpdateVictim())
+ return;
- void ResetEncounter()
+ events.Update(diff);
+ while (uint32 eventId = events.ExecuteEvent())
{
- feugenAlive = true;
- stalaggAlive = true;
+ switch (eventId)
+ {
+ case EVENT_REVIVE_FEUGEN:
+ feugenAlive = true;
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ feugen->AI()->DoAction(ACTION_FEUGEN_REVIVED);
+ break;
+ case EVENT_REVIVE_STALAGG:
+ stalaggAlive = true;
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ stalagg->AI()->DoAction(ACTION_STALAGG_REVIVED);
+ break;
+ case EVENT_TRANSITION_1: // tesla coils overload
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ feugen->AI()->DoAction(ACTION_TRANSITION);
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ stalagg->AI()->DoAction(ACTION_TRANSITION);
+ break;
+ case EVENT_TRANSITION_2: // tesla coils shock thaddius
+ me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true);
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ feugen->AI()->DoAction(ACTION_TRANSITION_2);
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ stalagg->AI()->DoAction(ACTION_TRANSITION_2);
+ break;
+ case EVENT_TRANSITION_3: // thaddius becomes active
+ me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true);
+ ballLightningUnlocked = false;
+ me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL);
+ me->SetImmuneToPC(false);
+ DoZoneInCombat();
- _Reset();
- events.SetPhase(PHASE_NOT_ENGAGED);
- me->SetReactState(REACT_PASSIVE);
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ feugen->AI()->DoAction(ACTION_TRANSITION_3);
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ stalagg->AI()->DoAction(ACTION_TRANSITION_3);
- // @todo these guys should really be moved to a summon group - this is merely a hack to make them work in dynamic_spawning
- instance->instance->Respawn(SPAWN_TYPE_CREATURE, 130958); // Stalagg
- instance->instance->Respawn(SPAWN_TYPE_CREATURE, 130959); // Feugen
- }
+ events.SetPhase(PHASE_THADDIUS);
- void UpdateAI(uint32 diff) override
- {
- if (events.IsInPhase(PHASE_NOT_ENGAGED))
- return;
- if (events.IsInPhase(PHASE_THADDIUS) && !UpdateVictim())
- return;
+ Talk(SAY_AGGRO);
- events.Update(diff);
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_REVIVE_FEUGEN:
- feugenAlive = true;
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- feugen->AI()->DoAction(ACTION_FEUGEN_REVIVED);
- break;
- case EVENT_REVIVE_STALAGG:
- stalaggAlive = true;
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- stalagg->AI()->DoAction(ACTION_STALAGG_REVIVED);
- break;
- case EVENT_TRANSITION_1: // tesla coils overload
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- feugen->AI()->DoAction(ACTION_TRANSITION);
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- stalagg->AI()->DoAction(ACTION_TRANSITION);
- break;
- case EVENT_TRANSITION_2: // tesla coils shock thaddius
- me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true);
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- feugen->AI()->DoAction(ACTION_TRANSITION_2);
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- stalagg->AI()->DoAction(ACTION_TRANSITION_2);
- break;
- case EVENT_TRANSITION_3: // thaddius becomes active
- me->CastSpell(me, SPELL_THADDIUS_SPARK_VISUAL, true);
- ballLightningUnlocked = false;
- me->RemoveAura(SPELL_THADDIUS_INACTIVE_VISUAL);
- me->SetImmuneToPC(false);
- DoZoneInCombat();
-
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- feugen->AI()->DoAction(ACTION_TRANSITION_3);
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- stalagg->AI()->DoAction(ACTION_TRANSITION_3);
-
- events.SetPhase(PHASE_THADDIUS);
-
- Talk(SAY_AGGRO);
-
- events.ScheduleEvent(EVENT_ENGAGE, 2s, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, 5s, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_SHIFT, 10s, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_CHAIN, 10s, 20s, 0, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_BERSERK, 6min, 0, PHASE_THADDIUS);
-
- break;
- case EVENT_ENABLE_BALL_LIGHTNING:
- ballLightningUnlocked = true;
- break;
- case EVENT_ENGAGE:
- me->SetReactState(REACT_AGGRESSIVE);
- break;
- case EVENT_SHIFT:
- me->CastStop(); // shift overrides all other spells
- DoCastAOE(SPELL_POLARITY_SHIFT);
- events.ScheduleEvent(EVENT_SHIFT_TALK, 3s, PHASE_THADDIUS);
- events.ScheduleEvent(EVENT_SHIFT, 30s, PHASE_THADDIUS);
- break;
- case EVENT_SHIFT_TALK:
- Talk(SAY_ELECT);
- Talk(EMOTE_POLARITY_SHIFTED);
- break;
- case EVENT_CHAIN:
- if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over
- events.Repeat(Seconds(3));
- else
- {
- me->CastStop();
- DoCastVictim(SPELL_CHAIN_LIGHTNING);
- events.Repeat(randtime(Seconds(10), Seconds(20)));
- }
- break;
- case EVENT_BERSERK:
+ events.ScheduleEvent(EVENT_ENGAGE, 2s, 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_ENABLE_BALL_LIGHTNING, 5s, 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_SHIFT, 10s, 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_CHAIN, 10s, 20s, 0, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_BERSERK, 6min, 0, PHASE_THADDIUS);
+
+ break;
+ case EVENT_ENABLE_BALL_LIGHTNING:
+ ballLightningUnlocked = true;
+ break;
+ case EVENT_ENGAGE:
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ case EVENT_SHIFT:
+ me->CastStop(); // shift overrides all other spells
+ DoCastAOE(SPELL_POLARITY_SHIFT);
+ events.ScheduleEvent(EVENT_SHIFT_TALK, 3s, PHASE_THADDIUS);
+ events.ScheduleEvent(EVENT_SHIFT, 30s, PHASE_THADDIUS);
+ break;
+ case EVENT_SHIFT_TALK:
+ Talk(SAY_ELECT);
+ Talk(EMOTE_POLARITY_SHIFTED);
+ break;
+ case EVENT_CHAIN:
+ if (me->FindCurrentSpellBySpellId(SPELL_POLARITY_SHIFT)) // delay until shift is over
+ events.Repeat(Seconds(3));
+ else
+ {
me->CastStop();
- DoCast(me, SPELL_BERSERK);
- break;
- default:
- break;
- }
+ DoCastVictim(SPELL_CHAIN_LIGHTNING);
+ events.Repeat(randtime(Seconds(10), Seconds(20)));
+ }
+ break;
+ case EVENT_BERSERK:
+ me->CastStop();
+ DoCast(me, SPELL_BERSERK);
+ break;
+ default:
+ break;
}
+ }
- if (events.IsInPhase(PHASE_THADDIUS) && !me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady())
+ if (events.IsInPhase(PHASE_THADDIUS) && !me->HasUnitState(UNIT_STATE_CASTING) && me->isAttackReady())
+ {
+ if (me->IsWithinMeleeRange(me->GetVictim()))
{
- if (me->IsWithinMeleeRange(me->GetVictim()))
- {
- ballLightningEnabled = false;
- DoMeleeAttackIfReady();
- }
- else if (ballLightningUnlocked)
- if (Unit* target = SelectTarget(SelectTargetMethod::Random))
- DoCast(target, SPELL_BALL_LIGHTNING);
+ ballLightningEnabled = false;
+ DoMeleeAttackIfReady();
}
+ else if (ballLightningUnlocked)
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random))
+ DoCast(target, SPELL_BALL_LIGHTNING);
}
+ }
- private:
- bool stalaggAlive;
- bool feugenAlive;
- bool ballLightningUnlocked; // whether the initial ball lightning grace period has expired and we should proceed to exterminate with extreme prejudice
- bool ballLightningEnabled; // switch that is flipped to true if we try to evade due to no eligible targets in melee range
- bool shockingEligibility;
+private:
+ bool stalaggAlive;
+ bool feugenAlive;
+ bool ballLightningUnlocked; // whether the initial ball lightning grace period has expired and we should proceed to exterminate with extreme prejudice
+ bool ballLightningEnabled; // switch that is flipped to true if we try to evade due to no eligible targets in melee range
+ bool shockingEligibility;
};
-class npc_stalagg : public CreatureScript
+struct npc_stalagg : public ScriptedAI
{
public:
- npc_stalagg() : CreatureScript("npc_stalagg") { }
+ npc_stalagg(Creature* creature) : ScriptedAI(creature),
+ instance(creature->GetInstanceScript()), powerSurgeTimer(), _myCoil(ObjectGuid::Empty), _myCoilGO(ObjectGuid::Empty), isOverloading(false), refreshBeam(false), isFeignDeath(false)
+ {
+ instance = creature->GetInstanceScript();
+ SetBoundary(instance->GetBossBoundary(BOSS_THADDIUS));
+ }
- CreatureAI* GetAI(Creature* creature) const override
+ void InitializeAI() override
{
- return GetNaxxramasAI<npc_stalaggAI>(creature);
+ if (GameObject* coil = myCoilGO())
+ coil->SetGoState(GO_STATE_ACTIVE);
+
+ powerSurgeTimer = 10 * IN_MILLISECONDS;
+
+ // force tesla coil state refresh
+ refreshBeam = true;
}
- struct npc_stalaggAI : public ScriptedAI
+ void EnterEvadeMode(EvadeReason /*reason*/) override
{
- public:
- npc_stalaggAI(Creature* creature) : ScriptedAI(creature),
- instance(creature->GetInstanceScript()), powerSurgeTimer(), _myCoil(ObjectGuid::Empty), _myCoilGO(ObjectGuid::Empty), isOverloading(false), refreshBeam(false), isFeignDeath(false)
- {
- instance = creature->GetInstanceScript();
- SetBoundary(instance->GetBossBoundary(BOSS_THADDIUS));
- }
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ thaddius->AI()->DoAction(ACTION_STALAGG_RESET);
+ }
- void InitializeAI() override
- {
- if (GameObject* coil = myCoilGO())
- coil->SetGoState(GO_STATE_ACTIVE);
+ void BeginResetEncounter()
+ {
+ if (GameObject* coil = myCoilGO())
+ coil->SetGoState(GO_STATE_READY);
+ me->DespawnOrUnsummon(0s, 7_days); // will be force respawned by thaddius
+ }
- powerSurgeTimer = 10 * IN_MILLISECONDS;
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_BEGIN_RESET_ENCOUNTER:
+ BeginResetEncounter();
+ break;
+ case ACTION_STALAGG_REVIVING_FX:
+ break;
+ case ACTION_STALAGG_REVIVED:
+ if (!isFeignDeath)
+ break;
- // force tesla coil state refresh
- refreshBeam = true;
- }
+ me->SetFullHealth();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetControlled(false, UNIT_STATE_ROOT);
+ Talk(EMOTE_FEIGN_REVIVE);
+ isFeignDeath = false;
- void EnterEvadeMode(EvadeReason /*reason*/) override
- {
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_STALAGG_RESET);
- }
+ refreshBeam = true; // force beam refresh
- void BeginResetEncounter()
- {
- if (GameObject* coil = myCoilGO())
- coil->SetGoState(GO_STATE_READY);
- me->DespawnOrUnsummon(0s, 7_days); // will be force respawned by thaddius
- }
+ DoZoneInCombat();
+ if (!me->IsEngaged())
+ BeginResetEncounter();
+ break;
+ case ACTION_TRANSITION:
+ me->KillSelf(); // true death
- void DoAction(int32 action) override
- {
- switch (action)
+ if (Creature* coil = myCoil())
{
- case ACTION_BEGIN_RESET_ENCOUNTER:
- BeginResetEncounter();
- break;
- case ACTION_STALAGG_REVIVING_FX:
- break;
- case ACTION_STALAGG_REVIVED:
- if (!isFeignDeath)
- break;
-
- me->SetFullHealth();
- me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetControlled(false, UNIT_STATE_ROOT);
- Talk(EMOTE_FEIGN_REVIVE);
- isFeignDeath = false;
-
- refreshBeam = true; // force beam refresh
-
- DoZoneInCombat();
- if (!me->IsEngaged())
- BeginResetEncounter();
- break;
- case ACTION_TRANSITION:
- me->KillSelf(); // true death
-
- if (Creature* coil = myCoil())
- {
- coil->CastStop();
- coil->AI()->Talk(EMOTE_TESLA_OVERLOAD);
- }
- break;
- case ACTION_TRANSITION_2:
- if (Creature* coil = myCoil())
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- coil->CastSpell(thaddius, SPELL_SHOCK_VISUAL);
- break;
- case ACTION_TRANSITION_3:
- if (GameObject* coil = myCoilGO())
- coil->SetGoState(GO_STATE_READY);
- me->DespawnOrUnsummon(0s, 7_days);
- break;
- default:
- break;
+ coil->CastStop();
+ coil->AI()->Talk(EMOTE_TESLA_OVERLOAD);
}
- }
+ break;
+ case ACTION_TRANSITION_2:
+ if (Creature* coil = myCoil())
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ coil->CastSpell(thaddius, SPELL_SHOCK_VISUAL);
+ break;
+ case ACTION_TRANSITION_3:
+ if (GameObject* coil = myCoilGO())
+ coil->SetGoState(GO_STATE_READY);
+ me->DespawnOrUnsummon(0s, 7_days);
+ break;
+ default:
+ break;
+ }
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_STALAGG_SLAY);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_STALAGG_SLAY);
+ }
- void JustEngagedWith(Unit* who) override
- {
- Talk(SAY_STALAGG_AGGRO);
+ void JustEngagedWith(Unit* who) override
+ {
+ Talk(SAY_STALAGG_AGGRO);
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_STALAGG_AGGRO);
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ thaddius->AI()->DoAction(ACTION_STALAGG_AGGRO);
- if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
- if (!feugen->IsEngaged())
- AddThreat(who, 0.0f, feugen);
- }
+ if (Creature* feugen = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FEUGEN)))
+ if (!feugen->IsEngaged())
+ AddThreat(who, 0.0f, feugen);
+ }
- void DamageTaken(Unit* /*who*/, uint32& damage) override
- {
- if (damage < me->GetHealth())
- return;
+ void DamageTaken(Unit* /*who*/, uint32& damage) override
+ {
+ if (damage < me->GetHealth())
+ return;
- if (isFeignDeath) // don't take damage while feigning death
- {
- damage = 0;
- return;
- }
+ if (isFeignDeath) // don't take damage while feigning death
+ {
+ damage = 0;
+ return;
+ }
- isFeignDeath = true;
- isOverloading = false;
+ isFeignDeath = true;
+ isOverloading = false;
- Talk(EMOTE_FEIGN_DEATH);
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_STALAGG_DIED);
+ Talk(EMOTE_FEIGN_DEATH);
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ thaddius->AI()->DoAction(ACTION_STALAGG_DIED);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveAllAuras();
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- me->SetControlled(true, UNIT_STATE_ROOT);
- me->SetStandState(UNIT_STAND_STATE_DEAD);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveAllAuras();
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->SetControlled(true, UNIT_STATE_ROOT);
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
- damage = me->GetHealth()-1;
+ damage = me->GetHealth()-1;
- // force beam refresh as we just removed auras
- refreshBeam = true;
- }
+ // force beam refresh as we just removed auras
+ refreshBeam = true;
+ }
- void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
- {
- Creature* creatureCaster = caster->ToCreature();
- if (!creatureCaster)
- return;
+ void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
+ {
+ Creature* creatureCaster = caster->ToCreature();
+ if (!creatureCaster)
+ return;
- if (spellInfo->Id != SPELL_STALAGG_TESLA_PERIODIC)
- return;
- if (!isFeignDeath && me->IsInCombat() && !me->GetHomePosition().IsInDist(me, OVERLOAD_DISTANCE))
- {
- if (!isOverloading)
- {
- isOverloading = true;
- creatureCaster->SetImmuneToPC(false);
- creatureCaster->AI()->Talk(EMOTE_TESLA_LINK_BREAKS);
- me->RemoveAura(SPELL_STALAGG_CHAIN_VISUAL);
- }
- if (Unit* target = SelectTarget(SelectTargetMethod::Random))
- {
- creatureCaster->CastStop(SPELL_TESLA_SHOCK);
- creatureCaster->CastSpell(target, SPELL_TESLA_SHOCK,true);
- }
- }
- else if (isOverloading || refreshBeam)
- {
- isOverloading = false;
- refreshBeam = false;
- creatureCaster->CastStop();
- creatureCaster->CastSpell(me, SPELL_STALAGG_CHAIN_VISUAL, true);
- creatureCaster->SetImmuneToPC(true);
- }
+ if (spellInfo->Id != SPELL_STALAGG_TESLA_PERIODIC)
+ return;
+ if (!isFeignDeath && me->IsInCombat() && !me->GetHomePosition().IsInDist(me, OVERLOAD_DISTANCE))
+ {
+ if (!isOverloading)
+ {
+ isOverloading = true;
+ creatureCaster->SetImmuneToPC(false);
+ creatureCaster->AI()->Talk(EMOTE_TESLA_LINK_BREAKS);
+ me->RemoveAura(SPELL_STALAGG_CHAIN_VISUAL);
}
-
- void UpdateAI(uint32 uiDiff) override
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random))
{
- if (!isFeignDeath)
- if (!UpdateVictim())
- return;
-
- if (powerSurgeTimer <= uiDiff)
- {
- if (isFeignDeath) // delay until potential revive
- powerSurgeTimer = 0u;
- else
- {
- DoCast(me, SPELL_STALAGG_POWERSURGE);
- powerSurgeTimer = urandms(25, 30);
- }
- }
- else
- powerSurgeTimer -= uiDiff;
-
- if (!isFeignDeath)
- DoMeleeAttackIfReady();
+ creatureCaster->CastStop(SPELL_TESLA_SHOCK);
+ creatureCaster->CastSpell(target, SPELL_TESLA_SHOCK,true);
}
+ }
+ else if (isOverloading || refreshBeam)
+ {
+ isOverloading = false;
+ refreshBeam = false;
+ creatureCaster->CastStop();
+ creatureCaster->CastSpell(me, SPELL_STALAGG_CHAIN_VISUAL, true);
+ creatureCaster->SetImmuneToPC(true);
+ }
+ }
+
+ void UpdateAI(uint32 uiDiff) override
+ {
+ if (!isFeignDeath)
+ if (!UpdateVictim())
+ return;
- private:
- Creature* myCoil()
+ if (powerSurgeTimer <= uiDiff)
+ {
+ if (isFeignDeath) // delay until potential revive
+ powerSurgeTimer = 0u;
+ else
{
- Creature* coil = nullptr;
- if (_myCoil)
- coil = ObjectAccessor::GetCreature(*me, _myCoil);
- if (!coil)
- {
- coil = me->FindNearestCreature(NPC_TESLA, 1000.0f, true);
- if (coil)
- {
- _myCoil = coil->GetGUID();
- coil->SetReactState(REACT_PASSIVE);
- }
- }
- return coil;
+ DoCast(me, SPELL_STALAGG_POWERSURGE);
+ powerSurgeTimer = urandms(25, 30);
}
+ }
+ else
+ powerSurgeTimer -= uiDiff;
+
+ if (!isFeignDeath)
+ DoMeleeAttackIfReady();
+ }
- GameObject* myCoilGO()
+private:
+ Creature* myCoil()
+ {
+ Creature* coil = nullptr;
+ if (_myCoil)
+ coil = ObjectAccessor::GetCreature(*me, _myCoil);
+ if (!coil)
+ {
+ coil = me->FindNearestCreature(NPC_TESLA, 1000.0f, true);
+ if (coil)
{
- GameObject* coil = nullptr;
- if (_myCoilGO)
- coil = ObjectAccessor::GetGameObject(*me, _myCoilGO);
- if (!coil)
- {
- coil = me->FindNearestGameObject(GO_CONS_NOX_TESLA_STALAGG, 1000.0f);
- if (coil)
- _myCoilGO = coil->GetGUID();
- }
- return coil;
+ _myCoil = coil->GetGUID();
+ coil->SetReactState(REACT_PASSIVE);
}
+ }
+ return coil;
+ }
- InstanceScript* instance;
+ GameObject* myCoilGO()
+ {
+ GameObject* coil = nullptr;
+ if (_myCoilGO)
+ coil = ObjectAccessor::GetGameObject(*me, _myCoilGO);
+ if (!coil)
+ {
+ coil = me->FindNearestGameObject(GO_CONS_NOX_TESLA_STALAGG, 1000.0f);
+ if (coil)
+ _myCoilGO = coil->GetGUID();
+ }
+ return coil;
+ }
- uint32 powerSurgeTimer;
+ InstanceScript* instance;
- ObjectGuid _myCoil;
- ObjectGuid _myCoilGO;
- bool isOverloading;
- bool refreshBeam;
- bool isFeignDeath;
- };
+ uint32 powerSurgeTimer;
+ ObjectGuid _myCoil;
+ ObjectGuid _myCoilGO;
+ bool isOverloading;
+ bool refreshBeam;
+ bool isFeignDeath;
};
-class npc_feugen : public CreatureScript
+struct npc_feugen : public ScriptedAI
{
public:
- npc_feugen() : CreatureScript("npc_feugen") { }
-
- CreatureAI* GetAI(Creature* creature) const override
+ npc_feugen(Creature* creature) : ScriptedAI(creature),
+ instance(creature->GetInstanceScript()), magneticPullTimer(), staticFieldTimer(), _myCoil(ObjectGuid::Empty), _myCoilGO(ObjectGuid::Empty), isOverloading(false), refreshBeam(false), isFeignDeath(false)
{
- return GetNaxxramasAI<npc_feugenAI>(creature);
+ instance = creature->GetInstanceScript();
+ SetBoundary(instance->GetBossBoundary(BOSS_THADDIUS));
}
- struct npc_feugenAI : public ScriptedAI
+ void InitializeAI() override
{
- public:
- npc_feugenAI(Creature* creature) : ScriptedAI(creature),
- instance(creature->GetInstanceScript()), magneticPullTimer(), staticFieldTimer(), _myCoil(ObjectGuid::Empty), _myCoilGO(ObjectGuid::Empty), isOverloading(false), refreshBeam(false), isFeignDeath(false)
- {
- instance = creature->GetInstanceScript();
- SetBoundary(instance->GetBossBoundary(BOSS_THADDIUS));
- }
+ if (GameObject* coil = myCoilGO())
+ coil->SetGoState(GO_STATE_ACTIVE);
- void InitializeAI() override
- {
- if (GameObject* coil = myCoilGO())
- coil->SetGoState(GO_STATE_ACTIVE);
-
- staticFieldTimer = 6 * IN_MILLISECONDS;
- magneticPullTimer = 20 * IN_MILLISECONDS;
+ staticFieldTimer = 6 * IN_MILLISECONDS;
+ magneticPullTimer = 20 * IN_MILLISECONDS;
- // force coil state to refresh
- refreshBeam = true;
- }
-
- void EnterEvadeMode(EvadeReason /*why*/) override
- {
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_FEUGEN_RESET);
- }
+ // force coil state to refresh
+ refreshBeam = true;
+ }
- void BeginResetEncounter()
- {
- if (GameObject* coil = myCoilGO())
- coil->SetGoState(GO_STATE_READY);
- me->DespawnOrUnsummon(0s, 7_days); // will be force respawned by thaddius
- }
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ thaddius->AI()->DoAction(ACTION_FEUGEN_RESET);
+ }
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_BEGIN_RESET_ENCOUNTER:
- BeginResetEncounter();
- break;
- case ACTION_FEUGEN_REVIVING_FX:
- break;
- case ACTION_FEUGEN_REVIVED:
- if (!isFeignDeath)
- break;
-
- me->SetFullHealth();
- me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetControlled(false, UNIT_STATE_ROOT);
- Talk(EMOTE_FEIGN_REVIVE);
- isFeignDeath = false;
-
- refreshBeam = true; // force beam refresh
-
- if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- if (stalagg->GetVictim())
- {
- AddThreat(stalagg->EnsureVictim(), 0.0f);
- me->SetInCombatWith(stalagg->EnsureVictim());
- }
- staticFieldTimer = 6 * IN_MILLISECONDS;
- magneticPullTimer = 30 * IN_MILLISECONDS;
- break;
- case ACTION_TRANSITION:
- me->KillSelf(); // true death this time around
-
- if (Creature* coil = myCoil())
- {
- coil->CastStop();
- coil->AI()->Talk(EMOTE_TESLA_OVERLOAD);
- }
- break;
- case ACTION_TRANSITION_2:
- if (Creature* coil = myCoil())
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- coil->CastSpell(thaddius, SPELL_SHOCK_VISUAL);
- break;
- case ACTION_TRANSITION_3:
- if (GameObject* coil = myCoilGO())
- coil->SetGoState(GO_STATE_READY);
- me->DespawnOrUnsummon(0s, 7_days);
- break;
- default:
- break;
- }
- }
+ void BeginResetEncounter()
+ {
+ if (GameObject* coil = myCoilGO())
+ coil->SetGoState(GO_STATE_READY);
+ me->DespawnOrUnsummon(0s, 7_days); // will be force respawned by thaddius
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_FEUGEN_SLAY);
- }
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_BEGIN_RESET_ENCOUNTER:
+ BeginResetEncounter();
+ break;
+ case ACTION_FEUGEN_REVIVING_FX:
+ break;
+ case ACTION_FEUGEN_REVIVED:
+ if (!isFeignDeath)
+ break;
- void JustEngagedWith(Unit* who) override
- {
- Talk(SAY_FEUGEN_AGGRO);
+ me->SetFullHealth();
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetControlled(false, UNIT_STATE_ROOT);
+ Talk(EMOTE_FEIGN_REVIVE);
+ isFeignDeath = false;
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_FEUGEN_AGGRO);
+ refreshBeam = true; // force beam refresh
if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
- if (!stalagg->IsInCombat())
- AddThreat(who, 0.0f, stalagg);
- }
-
- void DamageTaken(Unit* /*who*/, uint32& damage) override
- {
- if (damage < me->GetHealth())
- return;
+ if (stalagg->GetVictim())
+ {
+ AddThreat(stalagg->EnsureVictim(), 0.0f);
+ me->SetInCombatWith(stalagg->EnsureVictim());
+ }
+ staticFieldTimer = 6 * IN_MILLISECONDS;
+ magneticPullTimer = 30 * IN_MILLISECONDS;
+ break;
+ case ACTION_TRANSITION:
+ me->KillSelf(); // true death this time around
- if (isFeignDeath) // don't take damage while feigning death
+ if (Creature* coil = myCoil())
{
- damage = 0;
- return;
+ coil->CastStop();
+ coil->AI()->Talk(EMOTE_TESLA_OVERLOAD);
}
+ break;
+ case ACTION_TRANSITION_2:
+ if (Creature* coil = myCoil())
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ coil->CastSpell(thaddius, SPELL_SHOCK_VISUAL);
+ break;
+ case ACTION_TRANSITION_3:
+ if (GameObject* coil = myCoilGO())
+ coil->SetGoState(GO_STATE_READY);
+ me->DespawnOrUnsummon(0s, 7_days);
+ break;
+ default:
+ break;
+ }
+ }
- isFeignDeath = true;
- isOverloading = false;
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_FEUGEN_SLAY);
+ }
- Talk(EMOTE_FEIGN_DEATH);
- if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
- thaddius->AI()->DoAction(ACTION_FEUGEN_DIED);
+ void JustEngagedWith(Unit* who) override
+ {
+ Talk(SAY_FEUGEN_AGGRO);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveAllAuras();
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- me->SetControlled(true, UNIT_STATE_ROOT);
- me->SetStandState(UNIT_STAND_STATE_DEAD);
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ thaddius->AI()->DoAction(ACTION_FEUGEN_AGGRO);
- damage = me->GetHealth()-1;
+ if (Creature* stalagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_STALAGG)))
+ if (!stalagg->IsInCombat())
+ AddThreat(who, 0.0f, stalagg);
+ }
- // force beam refresh as we just removed auras
- refreshBeam = true;
- }
+ void DamageTaken(Unit* /*who*/, uint32& damage) override
+ {
+ if (damage < me->GetHealth())
+ return;
- void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
- {
- Creature* creatureCaster = caster->ToCreature();
- if (!creatureCaster)
- return;
+ if (isFeignDeath) // don't take damage while feigning death
+ {
+ damage = 0;
+ return;
+ }
- if (spellInfo->Id != SPELL_FEUGEN_TESLA_PERIODIC)
- return;
+ isFeignDeath = true;
+ isOverloading = false;
- if (!isFeignDeath && me->IsInCombat() && !me->GetHomePosition().IsInDist(me, OVERLOAD_DISTANCE))
- {
- if (!isOverloading)
- {
- isOverloading = true;
- creatureCaster->SetImmuneToPC(false);
- creatureCaster->AI()->Talk(EMOTE_TESLA_LINK_BREAKS);
- me->RemoveAura(SPELL_STALAGG_CHAIN_VISUAL);
- }
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
- {
- creatureCaster->CastStop(SPELL_TESLA_SHOCK);
- creatureCaster->CastSpell(target, SPELL_TESLA_SHOCK,true);
- }
- }
- else if (isOverloading || refreshBeam)
- {
- isOverloading = false;
- refreshBeam = false;
- creatureCaster->CastStop();
- creatureCaster->CastSpell(me, SPELL_FEUGEN_CHAIN_VISUAL, true);
- creatureCaster->SetImmuneToPC(true);
- }
- }
+ Talk(EMOTE_FEIGN_DEATH);
+ if (Creature* thaddius = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THADDIUS)))
+ thaddius->AI()->DoAction(ACTION_FEUGEN_DIED);
- void UpdateAI(uint32 uiDiff) override
- {
- if (isFeignDeath)
- return;
- if (!UpdateVictim())
- return;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveAllAuras();
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->SetControlled(true, UNIT_STATE_ROOT);
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
- if (magneticPullTimer <= uiDiff)
- {
- DoCast(me, SPELL_MAGNETIC_PULL);
- magneticPullTimer = 20 * IN_MILLISECONDS;
- }
- else magneticPullTimer -= uiDiff;
+ damage = me->GetHealth()-1;
- if (staticFieldTimer <= uiDiff)
- {
- DoCast(me, SPELL_FEUGEN_STATICFIELD);
- staticFieldTimer = 6 * IN_MILLISECONDS;
- }
- else staticFieldTimer -= uiDiff;
+ // force beam refresh as we just removed auras
+ refreshBeam = true;
+ }
- DoMeleeAttackIfReady();
- }
+ void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override
+ {
+ Creature* creatureCaster = caster->ToCreature();
+ if (!creatureCaster)
+ return;
- private:
- Creature* myCoil()
+ if (spellInfo->Id != SPELL_FEUGEN_TESLA_PERIODIC)
+ return;
+
+ if (!isFeignDeath && me->IsInCombat() && !me->GetHomePosition().IsInDist(me, OVERLOAD_DISTANCE))
+ {
+ if (!isOverloading)
{
- Creature* coil = nullptr;
- if (_myCoil)
- coil = ObjectAccessor::GetCreature(*me, _myCoil);
- if (!coil)
- {
- coil = me->FindNearestCreature(NPC_TESLA, 1000.0f, true);
- if (coil)
- {
- _myCoil = coil->GetGUID();
- coil->SetReactState(REACT_PASSIVE);
- }
- }
- return coil;
+ isOverloading = true;
+ creatureCaster->SetImmuneToPC(false);
+ creatureCaster->AI()->Talk(EMOTE_TESLA_LINK_BREAKS);
+ me->RemoveAura(SPELL_STALAGG_CHAIN_VISUAL);
}
-
- GameObject* myCoilGO()
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
- GameObject* coil = nullptr;
- if (_myCoilGO)
- coil = ObjectAccessor::GetGameObject(*me, _myCoilGO);
- if (!coil)
- {
- coil = me->FindNearestGameObject(GO_CONS_NOX_TESLA_FEUGEN, 1000.0f);
- if (coil)
- _myCoilGO = coil->GetGUID();
- }
- return coil;
+ creatureCaster->CastStop(SPELL_TESLA_SHOCK);
+ creatureCaster->CastSpell(target, SPELL_TESLA_SHOCK,true);
}
- InstanceScript* instance;
-
- uint32 magneticPullTimer;
- uint32 staticFieldTimer;
+ }
+ else if (isOverloading || refreshBeam)
+ {
+ isOverloading = false;
+ refreshBeam = false;
+ creatureCaster->CastStop();
+ creatureCaster->CastSpell(me, SPELL_FEUGEN_CHAIN_VISUAL, true);
+ creatureCaster->SetImmuneToPC(true);
+ }
+ }
- ObjectGuid _myCoil;
- ObjectGuid _myCoilGO;
+ void UpdateAI(uint32 uiDiff) override
+ {
+ if (isFeignDeath)
+ return;
+ if (!UpdateVictim())
+ return;
- bool isOverloading;
- bool refreshBeam;
- bool isFeignDeath;
- };
-};
+ if (magneticPullTimer <= uiDiff)
+ {
+ DoCast(me, SPELL_MAGNETIC_PULL);
+ magneticPullTimer = 20 * IN_MILLISECONDS;
+ }
+ else magneticPullTimer -= uiDiff;
-class npc_tesla : public CreatureScript
-{
-public:
- npc_tesla() : CreatureScript("npc_tesla") { }
+ if (staticFieldTimer <= uiDiff)
+ {
+ DoCast(me, SPELL_FEUGEN_STATICFIELD);
+ staticFieldTimer = 6 * IN_MILLISECONDS;
+ }
+ else staticFieldTimer -= uiDiff;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetNaxxramasAI<npc_teslaAI>(creature);
+ DoMeleeAttackIfReady();
}
- struct npc_teslaAI : public ScriptedAI
+private:
+ Creature* myCoil()
{
- npc_teslaAI(Creature* creature) : ScriptedAI(creature) { }
-
- void EnterEvadeMode(EvadeReason /*why*/) override { } // never stop casting due to evade
- void UpdateAI(uint32 /*diff*/) override { } // never do anything unless told
- void JustEngagedWith(Unit* /*who*/) override { }
- void DamageTaken(Unit* /*who*/, uint32& damage) override { damage = 0; } // no, you can't kill it
- };
-};
-
-class spell_thaddius_polarity_charge : public SpellScriptLoader
-{
- public:
- spell_thaddius_polarity_charge() : SpellScriptLoader("spell_thaddius_polarity_charge") { }
-
- class spell_thaddius_polarity_charge_SpellScript : public SpellScript
+ Creature* coil = nullptr;
+ if (_myCoil)
+ coil = ObjectAccessor::GetCreature(*me, _myCoil);
+ if (!coil)
{
- PrepareSpellScript(spell_thaddius_polarity_charge_SpellScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
+ coil = me->FindNearestCreature(NPC_TESLA, 1000.0f, true);
+ if (coil)
{
- return ValidateSpellInfo(
- {
- SPELL_POLARITY_SHIFT,
- SPELL_POSITIVE_CHARGE_APPLY,
- SPELL_POSITIVE_CHARGE_TICK,
- SPELL_POSITIVE_CHARGE_AMP,
- SPELL_NEGATIVE_CHARGE_APPLY,
- SPELL_NEGATIVE_CHARGE_TICK,
- SPELL_NEGATIVE_CHARGE_AMP
- });
+ _myCoil = coil->GetGUID();
+ coil->SetReactState(REACT_PASSIVE);
}
+ }
+ return coil;
+ }
- void HandleTargets(std::list<WorldObject*>& targetList)
- {
- if (!GetTriggeringSpell())
- return;
-
- uint32 triggeringId = GetTriggeringSpell()->Id;
- uint32 ampId;
- switch (triggeringId)
- {
- case SPELL_POSITIVE_CHARGE_APPLY:
- ampId = SPELL_POSITIVE_CHARGE_AMP;
- break;
- case SPELL_NEGATIVE_CHARGE_APPLY:
- ampId = SPELL_NEGATIVE_CHARGE_AMP;
- break;
- default:
- return;
- }
+ GameObject* myCoilGO()
+ {
+ GameObject* coil = nullptr;
+ if (_myCoilGO)
+ coil = ObjectAccessor::GetGameObject(*me, _myCoilGO);
+ if (!coil)
+ {
+ coil = me->FindNearestGameObject(GO_CONS_NOX_TESLA_FEUGEN, 1000.0f);
+ if (coil)
+ _myCoilGO = coil->GetGUID();
+ }
+ return coil;
+ }
+ InstanceScript* instance;
- uint8 maxStacks = 0;
- if (GetCaster())
- switch (GetCaster()->GetMap()->GetDifficulty())
- {
- case RAID_DIFFICULTY_10MAN_NORMAL:
- maxStacks = MAX_POLARITY_10M;
- break;
- case RAID_DIFFICULTY_25MAN_NORMAL:
- maxStacks = MAX_POLARITY_25M;
- break;
- default:
- break;
- }
+ uint32 magneticPullTimer;
+ uint32 staticFieldTimer;
- uint8 stacksCount = 1; // do we get a stack for our own debuff?
- std::list<WorldObject*>::iterator it = targetList.begin();
- while(it != targetList.end())
- {
- if ((*it)->GetTypeId() != TYPEID_PLAYER)
- {
- it = targetList.erase(it);
- continue;
- }
- if ((*it)->ToPlayer()->HasAura(triggeringId))
- {
- it = targetList.erase(it);
- if (stacksCount < maxStacks)
- stacksCount++;
- continue;
- }
+ ObjectGuid _myCoil;
+ ObjectGuid _myCoilGO;
- // this guy will get hit - achievement failure trigger
- if (Creature* thaddius = (*it)->FindNearestCreature(NPC_THADDIUS, 200.0f))
- thaddius->AI()->DoAction(ACTION_POLARITY_CROSSED);
+ bool isOverloading;
+ bool refreshBeam;
+ bool isFeignDeath;
+};
- ++it;
- }
+struct npc_tesla : public ScriptedAI
+{
+ npc_tesla(Creature* creature) : ScriptedAI(creature) { }
- if (GetCaster() && GetCaster()->ToPlayer())
- {
- if (!GetCaster()->ToPlayer()->HasAura(ampId))
- GetCaster()->ToPlayer()->AddAura(ampId, GetCaster());
- GetCaster()->ToPlayer()->SetAuraStack(ampId, GetCaster(), stacksCount);
- }
- }
+ void EnterEvadeMode(EvadeReason /*why*/) override { } // never stop casting due to evade
+ void UpdateAI(uint32 /*diff*/) override { } // never do anything unless told
+ void JustEngagedWith(Unit* /*who*/) override { }
+ void DamageTaken(Unit* /*who*/, uint32& damage) override { damage = 0; } // no, you can't kill it
+};
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
- }
- };
+class spell_thaddius_polarity_charge : public SpellScript
+{
+ PrepareSpellScript(spell_thaddius_polarity_charge);
- SpellScript* GetSpellScript() const override
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo(
{
- return new spell_thaddius_polarity_charge_SpellScript();
- }
-};
+ SPELL_POLARITY_SHIFT,
+ SPELL_POSITIVE_CHARGE_APPLY,
+ SPELL_POSITIVE_CHARGE_TICK,
+ SPELL_POSITIVE_CHARGE_AMP,
+ SPELL_NEGATIVE_CHARGE_APPLY,
+ SPELL_NEGATIVE_CHARGE_TICK,
+ SPELL_NEGATIVE_CHARGE_AMP
+ });
+ }
-class spell_thaddius_polarity_shift : public SpellScriptLoader
-{
- public:
- spell_thaddius_polarity_shift() : SpellScriptLoader("spell_thaddius_polarity_shift") { }
+ void HandleTargets(std::list<WorldObject*>& targetList)
+ {
+ if (!GetTriggeringSpell())
+ return;
- class spell_thaddius_polarity_shift_SpellScript : public SpellScript
+ uint32 triggeringId = GetTriggeringSpell()->Id;
+ uint32 ampId;
+ switch (triggeringId)
{
- PrepareSpellScript(spell_thaddius_polarity_shift_SpellScript);
+ case SPELL_POSITIVE_CHARGE_APPLY:
+ ampId = SPELL_POSITIVE_CHARGE_AMP;
+ break;
+ case SPELL_NEGATIVE_CHARGE_APPLY:
+ ampId = SPELL_NEGATIVE_CHARGE_AMP;
+ break;
+ default:
+ return;
+ }
- bool Validate(SpellInfo const* /*spell*/) override
+ uint8 maxStacks = 0;
+ if (GetCaster())
+ switch (GetCaster()->GetMap()->GetDifficulty())
{
- return ValidateSpellInfo(
- {
- SPELL_POLARITY_SHIFT,
- SPELL_POSITIVE_CHARGE_APPLY,
- SPELL_POSITIVE_CHARGE_TICK,
- SPELL_POSITIVE_CHARGE_AMP,
- SPELL_NEGATIVE_CHARGE_APPLY,
- SPELL_NEGATIVE_CHARGE_TICK,
- SPELL_NEGATIVE_CHARGE_AMP
- });
+ case RAID_DIFFICULTY_10MAN_NORMAL:
+ maxStacks = MAX_POLARITY_10M;
+ break;
+ case RAID_DIFFICULTY_25MAN_NORMAL:
+ maxStacks = MAX_POLARITY_25M;
+ break;
+ default:
+ break;
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ uint8 stacksCount = 1; // do we get a stack for our own debuff?
+ std::list<WorldObject*>::iterator it = targetList.begin();
+ while(it != targetList.end())
+ {
+ if ((*it)->GetTypeId() != TYPEID_PLAYER)
{
- if (Unit* target = GetHitUnit())
- if (target->GetTypeId() == TYPEID_PLAYER)
- {
- if (roll_chance_i(50))
- { // positive
- target->CastSpell(target, SPELL_POSITIVE_CHARGE_APPLY, true);
- target->RemoveAura(SPELL_POSITIVE_CHARGE_AMP);
- }
- else
- { // negative
- target->CastSpell(target, SPELL_NEGATIVE_CHARGE_APPLY, true);
- target->RemoveAura(SPELL_NEGATIVE_CHARGE_AMP);
- }
- }
+ it = targetList.erase(it);
+ continue;
}
-
- void Register() override
+ if ((*it)->ToPlayer()->HasAura(triggeringId))
{
- OnEffectHitTarget += SpellEffectFn(spell_thaddius_polarity_shift_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ it = targetList.erase(it);
+ if (stacksCount < maxStacks)
+ stacksCount++;
+ continue;
}
- };
- SpellScript* GetSpellScript() const override
+ // this guy will get hit - achievement failure trigger
+ if (Creature* thaddius = (*it)->FindNearestCreature(NPC_THADDIUS, 200.0f))
+ thaddius->AI()->DoAction(ACTION_POLARITY_CROSSED);
+
+ ++it;
+ }
+
+ if (GetCaster() && GetCaster()->ToPlayer())
{
- return new spell_thaddius_polarity_shift_SpellScript();
+ if (!GetCaster()->ToPlayer()->HasAura(ampId))
+ GetCaster()->ToPlayer()->AddAura(ampId, GetCaster());
+ GetCaster()->ToPlayer()->SetAuraStack(ampId, GetCaster(), stacksCount);
}
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_polarity_charge::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ }
};
-class spell_thaddius_magnetic_pull : public SpellScriptLoader
+class spell_thaddius_polarity_shift : public SpellScript
{
- public:
- spell_thaddius_magnetic_pull() : SpellScriptLoader("spell_thaddius_magnetic_pull") { };
+ PrepareSpellScript(spell_thaddius_polarity_shift);
- class spell_thaddius_magnetic_pull_SpellScript : public SpellScript
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo(
{
- PrepareSpellScript(spell_thaddius_magnetic_pull_SpellScript);
+ SPELL_POLARITY_SHIFT,
+ SPELL_POSITIVE_CHARGE_APPLY,
+ SPELL_POSITIVE_CHARGE_TICK,
+ SPELL_POSITIVE_CHARGE_AMP,
+ SPELL_NEGATIVE_CHARGE_APPLY,
+ SPELL_NEGATIVE_CHARGE_TICK,
+ SPELL_NEGATIVE_CHARGE_AMP
+ });
+ }
- bool Validate(SpellInfo const* /*spell*/) override
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ if (target->GetTypeId() == TYPEID_PLAYER)
{
- return ValidateSpellInfo({ SPELL_MAGNETIC_PULL });
+ if (roll_chance_i(50))
+ { // positive
+ target->CastSpell(target, SPELL_POSITIVE_CHARGE_APPLY, true);
+ target->RemoveAura(SPELL_POSITIVE_CHARGE_AMP);
+ }
+ else
+ { // negative
+ target->CastSpell(target, SPELL_NEGATIVE_CHARGE_APPLY, true);
+ target->RemoveAura(SPELL_NEGATIVE_CHARGE_AMP);
+ }
}
+ }
- void HandleCast() // only feugen ever casts this according to wowhead data
- {
- Unit* feugen = GetCaster();
- if (!feugen || feugen->GetEntry() != NPC_FEUGEN)
- return;
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_thaddius_polarity_shift::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+};
- Unit* stalagg = ObjectAccessor::GetCreature(*feugen, feugen->GetInstanceScript()->GetGuidData(DATA_STALAGG));
- if (!stalagg)
- return;
+class spell_thaddius_magnetic_pull : public SpellScript
+{
+ PrepareSpellScript(spell_thaddius_magnetic_pull);
- ThreatManager& feugenThreat = feugen->GetThreatManager();
- ThreatManager& stalaggThreat = stalagg->GetThreatManager();
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_MAGNETIC_PULL });
+ }
- Unit* feugenTank = feugenThreat.GetCurrentVictim();
- Unit* stalaggTank = stalaggThreat.GetCurrentVictim();
+ void HandleCast() // only feugen ever casts this according to wowhead data
+ {
+ Unit* feugen = GetCaster();
+ if (!feugen || feugen->GetEntry() != NPC_FEUGEN)
+ return;
- if (!feugenTank || !stalaggTank)
- return;
+ Unit* stalagg = ObjectAccessor::GetCreature(*feugen, feugen->GetInstanceScript()->GetGuidData(DATA_STALAGG));
+ if (!stalagg)
+ return;
- if (feugenTank == stalaggTank) // special behavior if the tanks are the same (taken from retail)
- {
- float feugenTankThreat = feugenThreat.GetThreat(feugenTank);
- float stalaggTankThreat = stalaggThreat.GetThreat(stalaggTank);
+ ThreatManager& feugenThreat = feugen->GetThreatManager();
+ ThreatManager& stalaggThreat = stalagg->GetThreatManager();
- feugen->GetThreatManager().AddThreat(feugenTank, stalaggTankThreat - feugenTankThreat, nullptr, true, true);
- stalagg->GetThreatManager().AddThreat(stalaggTank, feugenTankThreat - stalaggTankThreat, nullptr, true, true);
+ Unit* feugenTank = feugenThreat.GetCurrentVictim();
+ Unit* stalaggTank = stalaggThreat.GetCurrentVictim();
- feugen->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true);
- }
- else // normal case, two tanks
- {
- float feugenTankThreat = feugenThreat.GetThreat(feugenTank);
- float feugenOtherThreat = feugenThreat.GetThreat(stalaggTank);
- float stalaggTankThreat = stalaggThreat.GetThreat(stalaggTank);
- float stalaggOtherThreat = stalaggThreat.GetThreat(feugenTank);
-
- // set the two entries in feugen's threat table to be equal to the ones in stalagg's
- feugen->GetThreatManager().AddThreat(stalaggTank, stalaggTankThreat - feugenOtherThreat, nullptr, true, true);
- feugen->GetThreatManager().AddThreat(feugenTank, stalaggOtherThreat - feugenTankThreat, nullptr, true, true);
-
- // set the two entries in stalagg's threat table to be equal to the ones in feugen's
- stalagg->GetThreatManager().AddThreat(feugenTank, feugenTankThreat - stalaggOtherThreat, nullptr, true, true);
- stalagg->GetThreatManager().AddThreat(stalaggTank, feugenOtherThreat - stalaggTankThreat, nullptr, true, true);
-
- // pull the two tanks across
- feugenTank->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true);
- stalaggTank->CastSpell(feugenTank, SPELL_MAGNETIC_PULL_EFFECT, true);
-
- // @hack prevent mmaps clusterfucks from breaking tesla while tanks are midair
- feugen->AddAura(SPELL_ROOT_SELF, feugen);
- stalagg->AddAura(SPELL_ROOT_SELF, stalagg);
-
- // and make both attack their respective new tanks
- if (feugen->GetAI())
- feugen->GetAI()->AttackStart(stalaggTank);
- if (stalagg->GetAI())
- stalagg->GetAI()->AttackStart(feugenTank);
- }
- }
+ if (!feugenTank || !stalaggTank)
+ return;
- void Register() override
- {
- OnCast += SpellCastFn(spell_thaddius_magnetic_pull_SpellScript::HandleCast);
- }
- };
+ if (feugenTank == stalaggTank) // special behavior if the tanks are the same (taken from retail)
+ {
+ float feugenTankThreat = feugenThreat.GetThreat(feugenTank);
+ float stalaggTankThreat = stalaggThreat.GetThreat(stalaggTank);
- SpellScript* GetSpellScript() const override
+ feugen->GetThreatManager().AddThreat(feugenTank, stalaggTankThreat - feugenTankThreat, nullptr, true, true);
+ stalagg->GetThreatManager().AddThreat(stalaggTank, feugenTankThreat - stalaggTankThreat, nullptr, true, true);
+
+ feugen->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true);
+ }
+ else // normal case, two tanks
{
- return new spell_thaddius_magnetic_pull_SpellScript();
+ float feugenTankThreat = feugenThreat.GetThreat(feugenTank);
+ float feugenOtherThreat = feugenThreat.GetThreat(stalaggTank);
+ float stalaggTankThreat = stalaggThreat.GetThreat(stalaggTank);
+ float stalaggOtherThreat = stalaggThreat.GetThreat(feugenTank);
+
+ // set the two entries in feugen's threat table to be equal to the ones in stalagg's
+ feugen->GetThreatManager().AddThreat(stalaggTank, stalaggTankThreat - feugenOtherThreat, nullptr, true, true);
+ feugen->GetThreatManager().AddThreat(feugenTank, stalaggOtherThreat - feugenTankThreat, nullptr, true, true);
+
+ // set the two entries in stalagg's threat table to be equal to the ones in feugen's
+ stalagg->GetThreatManager().AddThreat(feugenTank, feugenTankThreat - stalaggOtherThreat, nullptr, true, true);
+ stalagg->GetThreatManager().AddThreat(stalaggTank, feugenOtherThreat - stalaggTankThreat, nullptr, true, true);
+
+ // pull the two tanks across
+ feugenTank->CastSpell(stalaggTank, SPELL_MAGNETIC_PULL_EFFECT, true);
+ stalaggTank->CastSpell(feugenTank, SPELL_MAGNETIC_PULL_EFFECT, true);
+
+ // @hack prevent mmaps clusterfucks from breaking tesla while tanks are midair
+ feugen->AddAura(SPELL_ROOT_SELF, feugen);
+ stalagg->AddAura(SPELL_ROOT_SELF, stalagg);
+
+ // and make both attack their respective new tanks
+ if (feugen->GetAI())
+ feugen->GetAI()->AttackStart(stalaggTank);
+ if (stalagg->GetAI())
+ stalagg->GetAI()->AttackStart(feugenTank);
}
+ }
+
+ void Register() override
+ {
+ OnCast += SpellCastFn(spell_thaddius_magnetic_pull::HandleCast);
+ }
};
class at_thaddius_entrance : public OnlyOnceAreaTriggerScript
@@ -1244,13 +1177,13 @@ class achievement_thaddius_shocking : public AchievementCriteriaScript
void AddSC_boss_thaddius()
{
RegisterNaxxramasCreatureAI(boss_thaddius);
- new npc_stalagg();
- new npc_feugen();
- new npc_tesla();
+ RegisterNaxxramasCreatureAI(npc_stalagg);
+ RegisterNaxxramasCreatureAI(npc_feugen);
+ RegisterNaxxramasCreatureAI(npc_tesla);
- new spell_thaddius_polarity_charge();
- new spell_thaddius_polarity_shift();
- new spell_thaddius_magnetic_pull();
+ RegisterSpellScript(spell_thaddius_polarity_charge);
+ RegisterSpellScript(spell_thaddius_polarity_shift);
+ RegisterSpellScript(spell_thaddius_magnetic_pull);
new at_thaddius_entrance();