[Scripts] Naxxramas scripts refactor with namespace

This commit is contained in:
Yunfan Li
2024-05-26 23:41:04 +08:00
parent 1e22c4dc94
commit 12ea82a57f
28 changed files with 247 additions and 74 deletions

View File

@@ -20,6 +20,7 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
using namespace Anubrekhan;
void AddSC_boss_anubrekhan()
{

View File

@@ -5,6 +5,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
namespace Anubrekhan {
enum AnubrekhanSays
{
ANUBREKHAN_SAY_AGGRO = 0,
@@ -229,4 +231,6 @@ public:
};
};
}
#endif

View File

@@ -21,6 +21,7 @@
#include "SpellInfo.h"
#include "naxxramas.h"
using namespace Faerlina;
void AddSC_boss_faerlina()
{

View File

@@ -6,6 +6,8 @@
#include "SpellInfo.h"
#include "naxxramas.h"
namespace Faerlina {
enum FaerlinaYells
{
FAERLINA_SAY_GREET = 0,
@@ -232,4 +234,6 @@ public:
};
};
}
#endif

View File

@@ -9,9 +9,11 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
enum FourHorsemenSpells
namespace FourHorsemen {
enum Spells
{
FOURHORSEMEN_SPELL_BERSERK = 26662,
SPELL_BERSERK = 26662,
// Marks
SPELL_MARK_OF_KORTHAZZ = 28832,
SPELL_MARK_OF_BLAUMEUX = 28833,
@@ -38,15 +40,15 @@ enum FourHorsemenSpells
SPELL_RIVENDARE_UNHOLY_SHADOW_25 = 57369
};
enum FourHorsemenEvents
enum Events
{
EVENT_MARK_CAST = 1,
EVENT_PRIMARY_SPELL = 2,
EVENT_SECONDARY_SPELL = 3,
FOURHORSEMEN_EVENT_BERSERK = 4
EVENT_BERSERK = 4
};
enum FourHorsemenMisc
enum Misc
{
// Movement
MOVE_PHASE_NONE = 0,
@@ -61,12 +63,12 @@ enum FourHorsemenMisc
enum FourHorsemen
{
FOURHORSEMEN_SAY_AGGRO = 0,
FOURHORSEMEN_SAY_TAUNT = 1,
FOURHORSEMEN_SAY_SPECIAL = 2,
FOURHORSEMEN_SAY_SLAY = 3,
FOURHORSEMEN_SAY_DEATH = 4,
FOURHORSEMEN_EMOTE_RAGECAST = 7
SAY_AGGRO = 0,
SAY_TAUNT = 1,
SAY_SPECIAL = 2,
SAY_SLAY = 3,
SAY_DEATH = 4,
EMOTE_RAGECAST = 7
};
// MARKS
@@ -180,7 +182,7 @@ public:
me->SetReactState(REACT_AGGRESSIVE);
events.Reset();
events.RescheduleEvent(EVENT_MARK_CAST, 24s);
events.RescheduleEvent(FOURHORSEMEN_EVENT_BERSERK, 10min);
events.RescheduleEvent(EVENT_BERSERK, 10min);
if ((me->GetEntry() != NPC_LADY_BLAUMEUX && me->GetEntry() != NPC_SIR_ZELIEK))
{
events.RescheduleEvent(EVENT_PRIMARY_SPELL, 10s, 15s);
@@ -247,7 +249,7 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER)
return;
Talk(FOURHORSEMEN_SAY_SLAY);
Talk(SAY_SLAY);
if (pInstance)
{
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
@@ -277,7 +279,7 @@ public:
}
}
}
Talk(FOURHORSEMEN_SAY_DEATH);
Talk(SAY_DEATH);
}
void JustEngagedWith(Unit* who) override
@@ -285,7 +287,7 @@ public:
BossAI::JustEngagedWith(who);
if (movementPhase == MOVE_PHASE_NONE)
{
Talk(FOURHORSEMEN_SAY_AGGRO);
Talk(SAY_AGGRO);
me->SetReactState(REACT_PASSIVE);
movementPhase = MOVE_PHASE_STARTED;
me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true);
@@ -324,12 +326,12 @@ public:
me->CastSpell(me, TABLE_SPELL_MARK[horsemanId], false);
events.Repeat((me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK) ? 15s : 12s);
return;
case FOURHORSEMEN_EVENT_BERSERK:
Talk(FOURHORSEMEN_SAY_SPECIAL);
me->CastSpell(me, FOURHORSEMEN_SPELL_BERSERK, true);
case EVENT_BERSERK:
Talk(SAY_SPECIAL);
me->CastSpell(me, SPELL_BERSERK, true);
return;
case EVENT_PRIMARY_SPELL:
Talk(FOURHORSEMEN_SAY_TAUNT);
Talk(SAY_TAUNT);
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
events.Repeat(15s);
return;
@@ -355,7 +357,7 @@ public:
else if (!me->IsWithinDistInMap(me->GetVictim(), 45.0f) || !me->IsValidAttackTarget(me->GetVictim()))
{
DoCastAOE(TABLE_SPELL_PUNISH[horsemanId]);
Talk(FOURHORSEMEN_EMOTE_RAGECAST);
Talk(EMOTE_RAGECAST);
}
}
else
@@ -423,20 +425,6 @@ public:
}
};
class spell_four_horsemen_consumption : public SpellScript
{
PrepareSpellScript(spell_four_horsemen_consumption);
void HandleDamageCalc(SpellEffIndex /*effIndex*/)
{
uint32 damage = GetCaster()->GetMap()->ToInstanceMap()->GetDifficulty() == REGULAR_DIFFICULTY ? 2750 : 4250;
SetHitDamage(damage);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_four_horsemen_consumption::HandleDamageCalc, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
} // namespace FourHorsemen
#endif

View File

@@ -23,6 +23,7 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
using namespace Gluth;
void AddSC_boss_gluth()
{

View File

@@ -7,6 +7,8 @@
#include "SpellScript.h"
#include "naxxramas.h"
namespace Gluth {
enum GluthSpells
{
GLUTH_SPELL_MORTAL_WOUND = 25646,
@@ -263,4 +265,6 @@ public:
}
};
}
#endif

View File

@@ -24,6 +24,8 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
using namespace Gothik;
void AddSC_boss_gothik()
{
new boss_gothik();

View File

@@ -8,6 +8,8 @@
#include "SpellScript.h"
#include "naxxramas.h"
namespace Gothik {
enum GothikYells
{
GOTHIK_SAY_INTRO_1 = 0,
@@ -699,4 +701,6 @@ public:
}
};
}
#endif

View File

@@ -25,6 +25,8 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
using namespace Grobbulus;
void AddSC_boss_grobbulus()
{
new boss_grobbulus();

View File

@@ -9,6 +9,8 @@
#include "SpellScript.h"
#include "naxxramas.h"
namespace Grobbulus {
enum GrobbulusSpells
{
GROBBULUS_SPELL_POISON_CLOUD = 28240,
@@ -305,4 +307,6 @@ class spell_grobbulus_mutating_injection : public SpellScriptLoader
}
};
}
#endif

View File

@@ -22,6 +22,8 @@
#include "boss_heigan.h"
using namespace Heigan;
void AddSC_boss_heigan()
{
new boss_heigan();

View File

@@ -6,6 +6,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
namespace Heigan {
enum HeiganSays
{
HEIGAN_SAY_AGGRO = 0,
@@ -232,4 +234,5 @@ public:
};
};
}
#endif

View File

@@ -23,6 +23,8 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
using namespace Kelthuzad;
void AddSC_boss_kelthuzad()
{
new boss_kelthuzad();

View File

@@ -7,6 +7,8 @@
#include "SpellScript.h"
#include "naxxramas.h"
namespace Kelthuzad {
enum KelthuzadYells
{
KELTHUZAD_SAY_ANSWER_REQUEST = 3,
@@ -729,4 +731,5 @@ public:
}
};
}
#endif

View File

@@ -20,6 +20,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
using namespace Loatheb;
void AddSC_boss_loatheb()
{
new boss_loatheb();

View File

@@ -5,6 +5,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
namespace Loatheb {
enum LoathebSpells
{
SPELL_NECROTIC_AURA = 55593,
@@ -183,4 +185,5 @@ public:
};
};
}
#endif

View File

@@ -1,14 +1,19 @@
#ifndef BOSS_MAEXXNA_H_
#define BOSS_MAEXXNA_H_
#include "CreatureScript.h"
#include "Player.h"
#include "PassiveAI.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "naxxramas.h"
enum MaexxnaSpells
namespace Maexxna {
enum Spells
{
SPELL_WEB_WRAP = 28622,
SPELL_WEB_SPRAY_10 = 29484,
SPELL_WEB_SPRAY_25 = 54125,
SPELL_POISON_SHOCK_10 = 28741,
@@ -16,37 +21,64 @@ enum MaexxnaSpells
SPELL_NECROTIC_POISON_10 = 54121,
SPELL_NECROTIC_POISON_25 = 28776,
SPELL_FRENZY_10 = 54123,
SPELL_FRENZY_25 = 54124
SPELL_FRENZY_25 = 54124,
SPELL_WEB_WRAP_STUN = 28622,
SPELL_WEB_WRAP_SUMMON = 28627,
SPELL_WEB_WRAP_KILL_WEBS = 52512,
SPELL_WEB_WRAP_PACIFY_5 = 28618 // 5 seconds pacify silence
};
enum MaexxnaEvents
enum Events
{
EVENT_WEB_SPRAY = 1,
EVENT_POISON_SHOCK = 2,
EVENT_NECROTIC_POISON = 3,
EVENT_WEB_WRAP = 4,
EVENT_HEALTH_CHECK = 5,
EVENT_SUMMON_SPIDERLINGS = 6
EVENT_SUMMON_SPIDERLINGS = 6,
EVENT_WEB_WRAP_APPLY_STUN = 7
};
enum MaexxnaEmotes
enum Emotes
{
EMOTE_SPIDERS = 0,
EMOTE_WEB_WRAP = 1,
EMOTE_WEB_SPRAY = 2
};
enum MaexxnaMisc
enum Misc
{
NPC_WEB_WRAP = 16486,
NPC_MAEXXNA_SPIDERLING = 17055
};
const Position PosWrap[3] =
const Position PosWrap[7] =
{
{3546.796f, -3869.082f, 296.450f, 0.0f},
{3531.271f, -3847.424f, 299.450f, 0.0f},
{3497.067f, -3843.384f, 302.384f, 0.0f}
{3496.615f, -3834.182f, 320.7863f},
{3509.108f, -3833.922f, 320.4750f},
{3523.644f, -3838.309f, 320.5775f},
{3538.152f, -3846.353f, 320.5188f},
{3546.219f, -3856.167f, 320.9324f},
{3555.135f, -3869.507f, 320.8307f},
{3560.282f, -3886.143f, 321.2827f}
};
struct WebTargetSelector
{
WebTargetSelector(Unit* maexxna) : _maexxna(maexxna) {}
bool operator()(Unit const* target) const
{
if (!target->IsPlayer()) // never web nonplayers (pets, guardians, etc.)
return false;
if (_maexxna->GetVictim() == target) // never target tank
return false;
if (target->HasAura(SPELL_WEB_WRAP_STUN)) // never target targets that are already webbed
return false;
return true;
}
private:
Unit const* _maexxna;
};
class boss_maexxna : public CreatureScript
@@ -70,6 +102,8 @@ public:
EventMap events;
SummonList summons;
GuidList wraps;
bool IsInRoom()
{
if (me->GetExactDist(3486.6f, -3890.6f, 291.8f) > 100.0f)
@@ -137,7 +171,55 @@ public:
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
summons.DespawnAll();
}
void DoCastWebWrap()
{
std::list<Unit*> candidates;
SelectTargetList(candidates, RAID_MODE(1, 2), SelectTargetMethod::Random, 0, WebTargetSelector(me));
std::vector<uint32> positions {0, 1, 2, 3, 4, 5, 6};
Acore::Containers::RandomShuffle(positions);
if (candidates.empty())
return;
for (int i = 0; i < RAID_MODE(1, 2) ; i++)
{
if (candidates.empty())
break;
const Position &randomPos = PosWrap[positions[i]];
auto itr = candidates.begin();
if (candidates.size() > 1)
std::advance(itr, urand(0, candidates.size() - 1));
Unit *target = *itr;
candidates.erase(itr);
float dx = randomPos.GetPositionX() - target->GetPositionX();
float dy = randomPos.GetPositionY() - target->GetPositionY();
float distXY = std::hypotf(dx, dy);
// smooth knockback arc that avoids the ceiling
float horizontalSpeed = distXY / 1.5f;
float verticalSpeed = 28.0f;
if (distXY <= 10.0f)
verticalSpeed = 12.0f;
else if (distXY <= 20.0f)
verticalSpeed = 16.0f;
else if (distXY <= 30.0f)
verticalSpeed = 20.0f;
else if (distXY <= 40.0f)
verticalSpeed = 24.0f;
target->KnockbackFrom(randomPos.GetPositionX(), randomPos.GetPositionY(), -horizontalSpeed, verticalSpeed);
me->CastSpell(target, SPELL_WEB_WRAP_PACIFY_5, true); // pacify silence for 5 seconds
wraps.push_back(target->GetGUID());
}
events.ScheduleEvent(EVENT_WEB_WRAP_APPLY_STUN, 2s);
}
void UpdateAI(uint32 diff) override
@@ -185,21 +267,21 @@ public:
break;
case EVENT_WEB_WRAP:
Talk(EMOTE_WEB_WRAP);
for (uint8 i = 0; i < RAID_MODE(1, 2); ++i)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0, true, true, -SPELL_WEB_WRAP))
{
target->RemoveAura(RAID_MODE(SPELL_WEB_SPRAY_10, SPELL_WEB_SPRAY_25));
uint8 pos = urand(0, 2);
if (Creature* wrap = me->SummonCreature(NPC_WEB_WRAP, PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000))
{
wrap->AI()->SetGUID(target->GetGUID());
target->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20);
}
}
}
DoCastWebWrap();
events.Repeat(40s);
break;
case EVENT_WEB_WRAP_APPLY_STUN:
{
for (auto& p : wraps)
{
if (Player* player = ObjectAccessor::GetPlayer(*me, p))
{
player->CastSpell(player, SPELL_WEB_WRAP_STUN, true);
}
}
wraps.clear();
break;
}
}
DoMeleeAttackIfReady();
}
@@ -218,34 +300,71 @@ public:
struct boss_maexxna_webwrapAI : public NullCreatureAI
{
explicit boss_maexxna_webwrapAI(Creature* c) : NullCreatureAI(c) {}
explicit boss_maexxna_webwrapAI(Creature* c) : NullCreatureAI(c) { }
ObjectGuid victimGUID;
void SetGUID(ObjectGuid guid, int32 /*param*/) override
void IsSummonedBy(WorldObject* summoner) override
{
victimGUID = guid;
if (me->m_spells[0] && victimGUID)
{
if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID))
{
victim->CastSpell(victim, me->m_spells[0], true, nullptr, nullptr, me->GetGUID());
}
}
if (!summoner)
return;
victimGUID = summoner->GetGUID();
}
void JustDied(Unit* /*killer*/) override
{
if (me->m_spells[0] && victimGUID)
if (victimGUID)
{
if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID))
{
victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID());
if (victim->IsAlive())
{
victim->RemoveAurasDueToSpell(SPELL_WEB_WRAP_STUN);
victim->RemoveAurasDueToSpell(SPELL_WEB_WRAP_SUMMON);
}
}
}
}
void UpdateAI(uint32 /*diff*/) override
{
if (victimGUID)
{
if (Unit* victim = ObjectAccessor::GetUnit(*me, victimGUID))
{
if (!victim->IsAlive())
{
me->CastSpell(me, SPELL_WEB_WRAP_KILL_WEBS, true);
}
}
}
}
};
};
class spell_web_wrap_damage : public AuraScript
{
public:
PrepareAuraScript(spell_web_wrap_damage);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_WEB_WRAP_SUMMON });
}
void OnPeriodic(AuraEffect const* aurEff)
{
if (aurEff->GetTickNumber() == 2)
{
GetTarget()->CastSpell(GetTarget(), SPELL_WEB_WRAP_SUMMON, true);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_web_wrap_damage::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
}
};
} // namespace Maexxna
#endif

View File

@@ -20,6 +20,7 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
using namespace Noth;
void AddSC_boss_noth()
{

View File

@@ -5,6 +5,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
namespace Noth {
enum NothSays
{
NOTH_SAY_AGGRO = 0,
@@ -285,5 +287,6 @@ public:
};
};
}
#endif

View File

@@ -20,6 +20,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
using namespace PatchWerk;
void AddSC_boss_patchwerk()
{
new boss_patchwerk();

View File

@@ -5,6 +5,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
namespace PatchWerk {
enum PatchwerkYells
{
PATCHWERK_SAY_AGGRO = 0,
@@ -180,4 +182,5 @@ public:
};
};
}
#endif

View File

@@ -20,6 +20,7 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
using namespace Razuvious;
void AddSC_boss_razuvious()
{

View File

@@ -5,6 +5,8 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
namespace Razuvious {
enum RazuviousSays
{
RAZUVIOUS_SAY_AGGRO = 0,
@@ -212,4 +214,5 @@ public:
};
};
}
#endif

View File

@@ -23,6 +23,8 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
using namespace Sapphiron;
void AddSC_boss_sapphiron()
{
new boss_sapphiron();

View File

@@ -7,6 +7,8 @@
#include "SpellScript.h"
#include "naxxramas.h"
namespace Sapphiron {
enum SapphironYells
{
EMOTE_AIR_PHASE = 0,
@@ -444,4 +446,6 @@ public:
}
};
}
#endif

View File

@@ -24,6 +24,7 @@
#include "SpellScriptLoader.h"
#include "naxxramas.h"
using namespace Thaddius;
void AddSC_boss_thaddius()
{

View File

@@ -7,6 +7,8 @@
#include "SpellScript.h"
#include "naxxramas.h"
namespace Thaddius {
enum ThaddiusSays
{
// Stalagg
@@ -750,4 +752,6 @@ public:
}
};
}
#endif