mirror of
https://github.com/ZhengPeiRu21/mod-individual-progression
synced 2025-11-29 23:44:51 +08:00
765 lines
27 KiB
C++
765 lines
27 KiB
C++
/*
|
|
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Affero General Public License as published by the
|
|
* Free Software Foundation; either version 3 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "Player.h"
|
|
#include "ScriptMgr.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "SpellScript.h"
|
|
#include "naxxramas.h"
|
|
|
|
enum Says
|
|
{
|
|
// Stalagg
|
|
SAY_STAL_AGGRO = 0,
|
|
SAY_STAL_SLAY = 1,
|
|
SAY_STAL_DEATH = 2,
|
|
EMOTE_STAL_DEATH = 3,
|
|
EMOTE_STAL_REVIVE = 4,
|
|
|
|
// Feugen
|
|
SAY_FEUG_AGGRO = 0,
|
|
SAY_FEUG_SLAY = 1,
|
|
SAY_FEUG_DEATH = 2,
|
|
EMOTE_FEUG_DEATH = 3,
|
|
EMOTE_FEUG_REVIVE = 4,
|
|
|
|
// Thaddius
|
|
SAY_GREET = 0,
|
|
SAY_AGGRO = 1,
|
|
SAY_SLAY = 2,
|
|
SAY_ELECT = 3,
|
|
SAY_DEATH = 4,
|
|
EMOTE_POLARITY_SHIFTED = 6,
|
|
|
|
// Tesla Coil
|
|
EMOTE_TESLA_LINK_BREAKS = 0,
|
|
EMOTE_TESLA_OVERLOAD = 1
|
|
};
|
|
|
|
enum Spells
|
|
{
|
|
SPELL_MAGNETIC_PULL = 28337,
|
|
SPELL_TESLA_SHOCK = 28099,
|
|
SPELL_SHOCK_VISUAL = 28159,
|
|
|
|
// Stalagg
|
|
SPELL_POWER_SURGE = 28134,
|
|
SPELL_STALAGG_CHAIN = 28096,
|
|
|
|
// Feugen
|
|
SPELL_STATIC_FIELD = 28135,
|
|
SPELL_FEUGEN_CHAIN = 28111,
|
|
|
|
// Thaddius
|
|
SPELL_POLARITY_SHIFT = 28089,
|
|
SPELL_BALL_LIGHTNING = 28299,
|
|
SPELL_CHAIN_LIGHTNING = 28167,
|
|
SPELL_BERSERK = 27680,
|
|
SPELL_THADDIUS_VISUAL_LIGHTNING = 28136,
|
|
SPELL_THADDIUS_SPAWN_STUN = 28160,
|
|
|
|
SPELL_POSITIVE_CHARGE = 28062,
|
|
SPELL_POSITIVE_CHARGE_STACK = 29659,
|
|
SPELL_NEGATIVE_CHARGE = 28085,
|
|
SPELL_NEGATIVE_CHARGE_STACK = 29660,
|
|
SPELL_POSITIVE_POLARITY = 28059,
|
|
SPELL_NEGATIVE_POLARITY = 28084
|
|
};
|
|
|
|
enum Events
|
|
{
|
|
EVENT_MINION_POWER_SURGE = 1,
|
|
EVENT_MINION_MAGNETIC_PULL = 2,
|
|
EVENT_MINION_CHECK_DISTANCE = 3,
|
|
EVENT_MINION_STATIC_FIELD = 4,
|
|
|
|
EVENT_THADDIUS_INIT = 5,
|
|
EVENT_THADDIUS_ENTER_COMBAT = 6,
|
|
EVENT_THADDIUS_CHAIN_LIGHTNING = 7,
|
|
EVENT_THADDIUS_BERSERK = 8,
|
|
EVENT_THADDIUS_POLARITY_SHIFT = 9,
|
|
EVENT_ALLOW_BALL_LIGHTNING = 10
|
|
};
|
|
|
|
enum Misc
|
|
{
|
|
ACTION_MAGNETIC_PULL = 1,
|
|
ACTION_SUMMON_DIED = 2,
|
|
ACTION_RESTORE = 3,
|
|
GO_TESLA_COIL_LEFT = 181478,
|
|
GO_TESLA_COIL_RIGHT = 181477,
|
|
NPC_TESLA_COIL = 16218
|
|
};
|
|
|
|
class boss_thaddius_40 : public CreatureScript
|
|
{
|
|
public:
|
|
boss_thaddius_40() : CreatureScript("boss_thaddius_40") { }
|
|
|
|
CreatureAI* GetAI(Creature* pCreature) const override
|
|
{
|
|
return GetNaxxramasAI<boss_thaddius_40AI>(pCreature);
|
|
}
|
|
|
|
struct boss_thaddius_40AI : public BossAI
|
|
{
|
|
explicit boss_thaddius_40AI(Creature* c) : BossAI(c, BOSS_THADDIUS), summons(me), ballLightningEnabled(false)
|
|
{
|
|
pInstance = me->GetInstanceScript();
|
|
}
|
|
|
|
InstanceScript* pInstance;
|
|
EventMap events;
|
|
SummonList summons;
|
|
uint32 summonTimer{};
|
|
uint32 reviveTimer{};
|
|
uint32 resetTimer{};
|
|
bool ballLightningEnabled;
|
|
|
|
void DoAction(int32 param) override
|
|
{
|
|
if (param == ACTION_SUMMON_DIED)
|
|
{
|
|
if (summonTimer)
|
|
{
|
|
summonTimer = 0;
|
|
reviveTimer = 1;
|
|
return;
|
|
}
|
|
summonTimer = 1;
|
|
}
|
|
}
|
|
|
|
void Reset() override
|
|
{
|
|
BossAI::Reset();
|
|
events.Reset();
|
|
summons.DespawnAll();
|
|
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
me->SetControlled(true, UNIT_STATE_ROOT);
|
|
summonTimer = 0;
|
|
reviveTimer = 0;
|
|
resetTimer = 1;
|
|
me->SetPosition(me->GetHomePosition());
|
|
ballLightningEnabled = false;
|
|
|
|
me->SummonCreature(NPC_STALAGG_40, 3450.45f, -2931.42f, 312.091f, 5.49779f);
|
|
me->SummonCreature(NPC_FEUGEN_40, 3508.14f, -2988.65f, 312.092f, 2.37365f);
|
|
if (Creature* cr = me->SummonCreature(NPC_TESLA_COIL, 3527.34f, -2951.56f, 318.75f, 0.0f))
|
|
{
|
|
cr->RemoveAllAuras();
|
|
cr->InterruptNonMeleeSpells(true);
|
|
cr->CastSpell(cr, SPELL_FEUGEN_CHAIN, false);
|
|
cr->SetDisableGravity(true);
|
|
cr->SetImmuneToPC(false);
|
|
cr->SetControlled(true, UNIT_STATE_ROOT);
|
|
}
|
|
if (Creature* cr = me->SummonCreature(NPC_TESLA_COIL, 3487.04f, -2911.68f, 318.75f, 0.0f))
|
|
{
|
|
cr->RemoveAllAuras();
|
|
cr->InterruptNonMeleeSpells(true);
|
|
cr->CastSpell(cr, SPELL_STALAGG_CHAIN, false);
|
|
cr->SetDisableGravity(true);
|
|
cr->SetImmuneToPC(false);
|
|
cr->SetControlled(true, UNIT_STATE_ROOT);
|
|
}
|
|
|
|
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_LEFT, 100.0f))
|
|
{
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
}
|
|
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f))
|
|
{
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
}
|
|
if (pInstance)
|
|
{
|
|
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_THADDIUS_GATE)))
|
|
{
|
|
if (pInstance->GetBossState(BOSS_GLUTH) == DONE)
|
|
{
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
}
|
|
}
|
|
}
|
|
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY);
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_STACK);
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_POLARITY);
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_STACK);
|
|
}
|
|
|
|
void KilledUnit(Unit* who) override
|
|
{
|
|
if (who->GetTypeId() != TYPEID_PLAYER)
|
|
return;
|
|
|
|
Talk(SAY_SLAY);
|
|
if (pInstance)
|
|
{
|
|
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
|
}
|
|
}
|
|
|
|
void JustDied(Unit* killer) override
|
|
{
|
|
BossAI::JustDied(killer);
|
|
Talk(SAY_DEATH);
|
|
if (pInstance)
|
|
{
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_POLARITY);
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POSITIVE_CHARGE_STACK);
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_POLARITY);
|
|
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NEGATIVE_CHARGE_STACK);
|
|
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_THADDIUS_GATE)))
|
|
{
|
|
go->SetGoState(GO_STATE_ACTIVE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void JustSummoned(Creature* cr) override
|
|
{
|
|
summons.Summon(cr);
|
|
}
|
|
|
|
void JustEngagedWith(Unit* who) override
|
|
{
|
|
BossAI::JustEngagedWith(who);
|
|
me->SetInCombatWithZone();
|
|
summons.DoZoneInCombat(NPC_FEUGEN_40);
|
|
summons.DoZoneInCombat(NPC_STALAGG_40);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (resetTimer)
|
|
{
|
|
resetTimer += diff;
|
|
if (resetTimer > 1000)
|
|
{
|
|
resetTimer = 0;
|
|
me->CastSpell(me, SPELL_THADDIUS_SPAWN_STUN, true);
|
|
}
|
|
return;
|
|
}
|
|
if (reviveTimer)
|
|
{
|
|
reviveTimer += diff;
|
|
if (reviveTimer >= 12000)
|
|
{
|
|
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
|
{
|
|
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
|
{
|
|
if (cr->GetEntry() == NPC_TESLA_COIL)
|
|
{
|
|
cr->AI()->Talk(EMOTE_TESLA_OVERLOAD);
|
|
cr->CastSpell(me, SPELL_SHOCK_VISUAL, true);
|
|
}
|
|
}
|
|
}
|
|
reviveTimer = 0;
|
|
events.ScheduleEvent(EVENT_THADDIUS_INIT, 750);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
if (summonTimer) // Revive
|
|
{
|
|
summonTimer += diff;
|
|
if (summonTimer >= 5000)
|
|
{
|
|
summons.DoAction(ACTION_RESTORE);
|
|
summonTimer = 0;
|
|
}
|
|
}
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_THADDIUS_INIT:
|
|
{
|
|
me->RemoveAllAuras();
|
|
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
|
{
|
|
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
|
{
|
|
if (cr->GetEntry() == NPC_TESLA_COIL)
|
|
{
|
|
Unit::Kill(cr, cr);
|
|
}
|
|
}
|
|
}
|
|
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_LEFT, 100.0f))
|
|
{
|
|
go->SetGoState(GO_STATE_READY);
|
|
}
|
|
if (GameObject* go = me->FindNearestGameObject(GO_TESLA_COIL_RIGHT, 100.0f))
|
|
{
|
|
go->SetGoState(GO_STATE_READY);
|
|
}
|
|
me->CastSpell(me, SPELL_THADDIUS_VISUAL_LIGHTNING, true);
|
|
events.ScheduleEvent(EVENT_THADDIUS_ENTER_COMBAT, 1000);
|
|
break;
|
|
}
|
|
case EVENT_THADDIUS_ENTER_COMBAT:
|
|
Talk(SAY_AGGRO);
|
|
me->SetReactState(REACT_AGGRESSIVE);
|
|
me->SetControlled(false, UNIT_STATE_STUNNED);
|
|
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
events.ScheduleEvent(EVENT_THADDIUS_CHAIN_LIGHTNING, 14000);
|
|
events.ScheduleEvent(EVENT_THADDIUS_BERSERK, 360000);
|
|
events.ScheduleEvent(EVENT_THADDIUS_POLARITY_SHIFT, 30000);
|
|
events.ScheduleEvent(EVENT_ALLOW_BALL_LIGHTNING, 5000);
|
|
return;
|
|
case EVENT_THADDIUS_BERSERK:
|
|
me->CastSpell(me, SPELL_BERSERK, true);
|
|
break;
|
|
case EVENT_THADDIUS_CHAIN_LIGHTNING:
|
|
{
|
|
CustomSpellValues values;
|
|
int32 customChainLightningDamage = 1850; // (1850, 2150), die 675
|
|
values.AddSpellMod(SPELLVALUE_BASE_POINT0, customChainLightningDamage);
|
|
values.AddSpellMod(SPELLVALUE_MAX_TARGETS, 15);
|
|
me->CastCustomSpell(SPELL_CHAIN_LIGHTNING, values, me->GetVictim(), TRIGGERED_NONE, nullptr, nullptr, ObjectGuid::Empty);
|
|
events.RepeatEvent(15000);
|
|
break;
|
|
}
|
|
case EVENT_THADDIUS_POLARITY_SHIFT:
|
|
me->CastSpell(me, SPELL_POLARITY_SHIFT, false);
|
|
events.RepeatEvent(30000);
|
|
break;
|
|
case EVENT_ALLOW_BALL_LIGHTNING:
|
|
ballLightningEnabled = true;
|
|
break;
|
|
}
|
|
|
|
if (me->IsWithinMeleeRange(me->GetVictim()))
|
|
{
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
else if (ballLightningEnabled)
|
|
{
|
|
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat))
|
|
{
|
|
int32 customBallLightningDamage = 6000;
|
|
me->CastCustomSpell(target, SPELL_BALL_LIGHTNING, &customBallLightningDamage, 0, 0, false);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
class boss_thaddius_summon_40 : public CreatureScript
|
|
{
|
|
public:
|
|
boss_thaddius_summon_40() : CreatureScript("boss_thaddius_summon_40") { }
|
|
|
|
CreatureAI* GetAI(Creature* pCreature) const override
|
|
{
|
|
return GetNaxxramasAI<boss_thaddius_summon_40AI>(pCreature);
|
|
}
|
|
|
|
struct boss_thaddius_summon_40AI : public ScriptedAI
|
|
{
|
|
explicit boss_thaddius_summon_40AI(Creature* c) : ScriptedAI(c)
|
|
{
|
|
pInstance = me->GetInstanceScript();
|
|
overload = false;
|
|
}
|
|
|
|
InstanceScript* pInstance;
|
|
EventMap events;
|
|
uint32 pullTimer{};
|
|
uint32 visualTimer{};
|
|
bool overload;
|
|
ObjectGuid myCoil;
|
|
|
|
void Reset() override
|
|
{
|
|
pullTimer = 0;
|
|
visualTimer = 1;
|
|
overload = false;
|
|
events.Reset();
|
|
me->SetControlled(false, UNIT_STATE_STUNNED);
|
|
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
|
{
|
|
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG_40 ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
|
cr->SetImmuneToPC(false);
|
|
myCoil = cr->GetGUID();
|
|
}
|
|
}
|
|
|
|
void EnterEvadeMode(EvadeReason why) override
|
|
{
|
|
me->SetControlled(false, UNIT_STATE_STUNNED);
|
|
ScriptedAI::EnterEvadeMode(why);
|
|
}
|
|
|
|
void JustEngagedWith(Unit* pWho) override
|
|
{
|
|
me->SetInCombatWithZone();
|
|
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.f, true))
|
|
{
|
|
myCoil = cr->GetGUID();
|
|
}
|
|
if (me->GetEntry() == NPC_STALAGG_40)
|
|
{
|
|
events.ScheduleEvent(EVENT_MINION_POWER_SURGE, 10000);
|
|
Talk(SAY_STAL_AGGRO);
|
|
}
|
|
else
|
|
{
|
|
events.ScheduleEvent(EVENT_MINION_STATIC_FIELD, 5000);
|
|
Talk(SAY_FEUG_AGGRO);
|
|
}
|
|
events.ScheduleEvent(EVENT_MINION_CHECK_DISTANCE, 5000);
|
|
|
|
if (me->GetEntry() == NPC_STALAGG_40) // This event needs synchronisation, called for stalagg only
|
|
{
|
|
events.ScheduleEvent(EVENT_MINION_MAGNETIC_PULL, 20000);
|
|
}
|
|
if (pInstance)
|
|
{
|
|
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_THADDIUS_GATE)))
|
|
{
|
|
go->SetGoState(GO_STATE_READY);
|
|
}
|
|
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_THADDIUS_BOSS)))
|
|
{
|
|
cr->AI()->AttackStart(pWho);
|
|
cr->AddThreat(pWho, 10.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DoAction(int32 param) override
|
|
{
|
|
if (param == ACTION_MAGNETIC_PULL)
|
|
{
|
|
pullTimer = 1;
|
|
me->SetControlled(true, UNIT_STATE_STUNNED);
|
|
}
|
|
else if (param == ACTION_RESTORE)
|
|
{
|
|
if (!me->IsAlive())
|
|
{
|
|
me->Respawn();
|
|
me->SetInCombatWithZone();
|
|
Talk(me->GetEntry() == NPC_STALAGG_40 ? EMOTE_STAL_REVIVE : EMOTE_FEUG_REVIVE);
|
|
}
|
|
else
|
|
{
|
|
me->SetHealth(me->GetMaxHealth());
|
|
}
|
|
}
|
|
}
|
|
|
|
void JustDied(Unit* /*killer*/) override
|
|
{
|
|
Talk(me->GetEntry() == NPC_STALAGG_40 ? SAY_STAL_DEATH : SAY_FEUG_DEATH);
|
|
Talk(me->GetEntry() == NPC_STALAGG_40 ? EMOTE_STAL_DEATH : EMOTE_FEUG_DEATH);
|
|
if (pInstance)
|
|
{
|
|
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_THADDIUS_BOSS)))
|
|
{
|
|
cr->AI()->DoAction(ACTION_SUMMON_DIED);
|
|
}
|
|
}
|
|
}
|
|
|
|
void KilledUnit(Unit* who) override
|
|
{
|
|
if (who->GetTypeId() != TYPEID_PLAYER)
|
|
return;
|
|
|
|
if (pInstance)
|
|
{
|
|
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
|
}
|
|
if (!urand(0, 2))
|
|
{
|
|
Talk(me->GetEntry() == NPC_STALAGG_40 ? SAY_STAL_SLAY : SAY_FEUG_SLAY);
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (visualTimer)
|
|
{
|
|
visualTimer += diff;
|
|
if (visualTimer >= 3000)
|
|
{
|
|
visualTimer = 0;
|
|
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
|
{
|
|
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG_40 ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
if (pullTimer) // Disable AI during pull
|
|
{
|
|
pullTimer += diff;
|
|
if (pullTimer >= 3000)
|
|
{
|
|
me->SetControlled(false, UNIT_STATE_STUNNED);
|
|
pullTimer = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_MINION_POWER_SURGE:
|
|
me->CastSpell(me, SPELL_POWER_SURGE, false);
|
|
events.RepeatEvent(19000);
|
|
break;
|
|
case EVENT_MINION_STATIC_FIELD:
|
|
me->CastSpell(me, SPELL_STATIC_FIELD, false);
|
|
events.RepeatEvent(3000);
|
|
break;
|
|
case EVENT_MINION_MAGNETIC_PULL:
|
|
events.RepeatEvent(20000);
|
|
if (pInstance)
|
|
{
|
|
if (Creature* feugen = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_FEUGEN_BOSS)))
|
|
{
|
|
if (!feugen->IsAlive() || !feugen->GetVictim() || !me->GetVictim())
|
|
return;
|
|
|
|
float threatFeugen = feugen->GetThreatMgr().GetThreat(feugen->GetVictim());
|
|
float threatStalagg = me->GetThreatMgr().GetThreat(me->GetVictim());
|
|
Unit* tankFeugen = feugen->GetVictim();
|
|
Unit* tankStalagg = me->GetVictim();
|
|
|
|
feugen->GetThreatMgr().ModifyThreatByPercent(tankFeugen, -100);
|
|
feugen->AddThreat(tankStalagg, threatFeugen);
|
|
feugen->CastSpell(tankStalagg, SPELL_MAGNETIC_PULL, true);
|
|
feugen->AI()->DoAction(ACTION_MAGNETIC_PULL);
|
|
|
|
me->GetThreatMgr().ModifyThreatByPercent(tankStalagg, -100);
|
|
me->AddThreat(tankFeugen, threatStalagg);
|
|
me->CastSpell(tankFeugen, SPELL_MAGNETIC_PULL, true);
|
|
DoAction(ACTION_MAGNETIC_PULL);
|
|
}
|
|
}
|
|
break;
|
|
case EVENT_MINION_CHECK_DISTANCE:
|
|
if (Creature* cr = ObjectAccessor::GetCreature(*me, myCoil))
|
|
{
|
|
if (!me->GetHomePosition().IsInDist(me, 28) && me->IsInCombat())
|
|
{
|
|
if (!overload)
|
|
{
|
|
overload = true;
|
|
cr->AI()->Talk(EMOTE_TESLA_LINK_BREAKS);
|
|
me->RemoveAurasDueToSpell(me->GetEntry() == NPC_STALAGG_40 ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN);
|
|
cr->InterruptNonMeleeSpells(true);
|
|
}
|
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 1000.f, true))
|
|
{
|
|
cr->CastStop(SPELL_TESLA_SHOCK);
|
|
int32 customTeslaShockDamage = 4374;
|
|
cr->CastCustomSpell(target, SPELL_TESLA_SHOCK, &customTeslaShockDamage, 0, 0, true);
|
|
}
|
|
events.RepeatEvent(1500);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
overload = false;
|
|
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG_40 ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
|
}
|
|
}
|
|
events.RepeatEvent(5000);
|
|
break;
|
|
}
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
};
|
|
|
|
// This will overwrite the declared 10 and 25 man pos_neg_charge to handle all versions of the spell script
|
|
class spell_thaddius_pos_neg_charge : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_thaddius_pos_neg_charge);
|
|
|
|
void HandleTargets(std::list<WorldObject*>& targets)
|
|
{
|
|
uint8 count = 0;
|
|
for (auto& ihit : targets)
|
|
{
|
|
if (ihit->GetGUID() != GetCaster()->GetGUID())
|
|
{
|
|
if (Player* target = ihit->ToPlayer())
|
|
{
|
|
if (target->HasAura(GetTriggeringSpell()->Id))
|
|
{
|
|
++count;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count)
|
|
{
|
|
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
|
|
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
|
|
}
|
|
}
|
|
|
|
void HandleDamage(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (!GetTriggeringSpell())
|
|
return;
|
|
|
|
Unit* target = GetHitUnit();
|
|
if (!target)
|
|
return;
|
|
|
|
if (target->HasAura(GetTriggeringSpell()->Id) || target->GetTypeId() != TYPEID_PLAYER)
|
|
{
|
|
SetHitDamage(0);
|
|
}
|
|
else if (target->GetInstanceScript())
|
|
{
|
|
target->GetInstanceScript()->SetData(DATA_CHARGES_CROSSED, 0);
|
|
}
|
|
// Adjust damage to 2000 from 4500 for naxx40
|
|
if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_HEROIC)
|
|
{
|
|
SetHitDamage(2000);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
|
|
}
|
|
};
|
|
|
|
class spell_thaddius_polarity_shift : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_thaddius_polarity_shift);
|
|
|
|
bool Validate(SpellInfo const* /*spell*/) override
|
|
{
|
|
return ValidateSpellInfo({ SPELL_POSITIVE_POLARITY, SPELL_NEGATIVE_POLARITY });
|
|
}
|
|
|
|
void HandleDummy(SpellEffIndex /* effIndex */)
|
|
{
|
|
Unit* caster = GetCaster();
|
|
if (Unit* target = GetHitUnit())
|
|
{
|
|
target->RemoveAurasDueToSpell(SPELL_POSITIVE_CHARGE_STACK);
|
|
target->RemoveAurasDueToSpell(SPELL_NEGATIVE_CHARGE_STACK);
|
|
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, nullptr, nullptr, caster->GetGUID());
|
|
}
|
|
}
|
|
|
|
void HandleAfterCast()
|
|
{
|
|
if (GetCaster())
|
|
{
|
|
if (Creature* caster = GetCaster()->ToCreature())
|
|
{
|
|
if (caster->GetEntry() == NPC_THADDIUS_40)
|
|
{
|
|
caster->AI()->Talk(SAY_ELECT);
|
|
caster->AI()->Talk(EMOTE_POLARITY_SHIFTED);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_thaddius_polarity_shift::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
AfterCast += SpellCastFn(spell_thaddius_polarity_shift::HandleAfterCast);
|
|
}
|
|
};
|
|
|
|
class npc_tesla : public CreatureScript
|
|
{
|
|
public:
|
|
npc_tesla() : CreatureScript("npc_tesla") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetNaxxramasAI<npc_teslaAI>(creature);
|
|
}
|
|
|
|
struct npc_teslaAI : public ScriptedAI
|
|
{
|
|
public:
|
|
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, DamageEffectType, SpellSchoolMask) override { damage = 0; } // no, you can't kill it
|
|
};
|
|
};
|
|
|
|
class at_thaddius_entrance : public AreaTriggerScript
|
|
{
|
|
public:
|
|
at_thaddius_entrance() : AreaTriggerScript("at_thaddius_entrance") { }
|
|
|
|
bool OnTrigger(Player* player, AreaTrigger const* /*areaTrigger*/) override
|
|
{
|
|
InstanceScript* instance = player->GetInstanceScript();
|
|
if (!instance || instance->GetData(DATA_HAD_THADDIUS_GREET) || instance->GetBossState(BOSS_THADDIUS) == DONE)
|
|
return true;
|
|
|
|
if (Creature* thaddius = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THADDIUS_BOSS)))
|
|
{
|
|
thaddius->AI()->Talk(SAY_GREET);
|
|
}
|
|
instance->SetData(DATA_HAD_THADDIUS_GREET, 1);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void AddSC_boss_thaddius_40()
|
|
{
|
|
new boss_thaddius_40();
|
|
new boss_thaddius_summon_40();
|
|
// new npc_tesla();
|
|
RegisterSpellScript(spell_thaddius_pos_neg_charge);
|
|
// RegisterSpellScript(spell_thaddius_polarity_shift);
|
|
// new at_thaddius_entrance();
|
|
}
|