This commit is contained in:
Jelle Meeus
2025-07-13 10:29:10 +02:00
parent e0aebbbd81
commit 01036ef134

View File

@@ -15,45 +15,48 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CreatureScript.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "naxxramas.h"
enum Spells
{
SPELL_MORTAL_WOUND = 25646,
SPELL_ENRAGE = 28371,
SPELL_DECIMATE = 28374,
SPELL_DECIMATE_DAMAGE = 28375,
SPELL_BERSERK = 26662,
SPELL_INFECTED_WOUND = 29306,
SPELL_CHOW_SEARCHER = 28404
SPELL_MORTAL_WOUND = 25646,
SPELL_ENRAGE_10 = 28371,
SPELL_ENRAGE_25 = 54427,
SPELL_DECIMATE_10 = 28374,
SPELL_DECIMATE_25 = 54426,
SPELL_DECIMATE_DAMAGE = 28375,
SPELL_BERSERK = 26662,
SPELL_INFECTED_WOUND = 29306,
SPELL_CHOW_SEARCHER = 28404
};
enum Events
{
EVENT_MORTAL_WOUND = 1,
EVENT_ENRAGE = 2,
EVENT_DECIMATE = 3,
EVENT_BERSERK = 4,
EVENT_SUMMON_ZOMBIE = 5,
EVENT_CAN_EAT_ZOMBIE = 6
EVENT_MORTAL_WOUND = 1,
EVENT_ENRAGE = 2,
EVENT_DECIMATE = 3,
EVENT_BERSERK = 4,
EVENT_SUMMON_ZOMBIE = 5,
EVENT_CAN_EAT_ZOMBIE = 6
};
enum Misc
{
NPC_ZOMBIE_CHOW = 351069
// NPC_ZOMBIE_CHOW = 16360
};
enum Emotes
{
EMOTE_SPOTS_ONE = 0,
EMOTE_DECIMATE = 1,
EMOTE_ENRAGE = 2,
EMOTE_DEVOURS_ALL = 3,
EMOTE_BERSERK = 4
EMOTE_SPOTS_ONE = 0,
EMOTE_DECIMATE = 1,
EMOTE_ENRAGE = 2,
EMOTE_DEVOURS_ALL = 3,
EMOTE_BERSERK = 4
};
const Position zombiePos[3] =
@@ -76,13 +79,10 @@ public:
struct boss_gluth_40AI : public BossAI
{
explicit boss_gluth_40AI(Creature* c) : BossAI(c, BOSS_GLUTH), summons(me)
{
pInstance = me->GetInstanceScript();
}
{}
EventMap events;
SummonList summons;
InstanceScript* pInstance;
void Reset() override
{
@@ -113,12 +113,12 @@ public:
{
BossAI::JustEngagedWith(who);
me->SetInCombatWithZone();
events.ScheduleEvent(EVENT_MORTAL_WOUND, 10000);
events.ScheduleEvent(EVENT_ENRAGE, 22000);
events.ScheduleEvent(EVENT_DECIMATE, 105000);
events.ScheduleEvent(EVENT_BERSERK, 360000);
events.ScheduleEvent(EVENT_SUMMON_ZOMBIE, 10000);
events.ScheduleEvent(EVENT_CAN_EAT_ZOMBIE, 1000);
events.ScheduleEvent(EVENT_MORTAL_WOUND, 10s);
events.ScheduleEvent(EVENT_ENRAGE, 22s);
events.ScheduleEvent(EVENT_DECIMATE, RAID_MODE(110000, 90000, 110000, 90000));
events.ScheduleEvent(EVENT_BERSERK, 6min);
events.ScheduleEvent(EVENT_SUMMON_ZOMBIE, 10s);
events.ScheduleEvent(EVENT_CAN_EAT_ZOMBIE, 1s);
}
void JustSummoned(Creature* summon) override
@@ -135,16 +135,13 @@ public:
void KilledUnit(Unit* who) override
{
if (me->IsAlive() && who->GetEntry() == NPC_ZOMBIE_CHOW)
{
me->ModifyHealth(int32(me->GetMaxHealth() * 0.05f));
}
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
{
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
}
if (who->IsPlayer())
instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1);
}
void JustDied(Unit* killer) override
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
summons.DespawnAll();
@@ -156,7 +153,7 @@ public:
return false;
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
for (const auto& itr : pList)
for (auto const& itr : pList)
{
Player* player = itr.GetSource();
if (!player || !player->IsAlive())
@@ -182,69 +179,78 @@ public:
switch (events.ExecuteEvent())
{
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_ENRAGE:
{
Talk(EMOTE_ENRAGE);
int32 bp1 = 99; // Enrage melee haste
int32 bp2 = 49; // Enrage damage percent
me->CastCustomSpell(me, SPELL_ENRAGE, &bp1, &bp2, 0, true);
events.RepeatEvent(22000);
break;
}
case EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.RepeatEvent(10000);
break;
case EVENT_DECIMATE:
Talk(EMOTE_DECIMATE);
me->CastSpell(me, SPELL_DECIMATE, false);
// Apply Decimate effect to zombies
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_ENRAGE:
{
std::list<Creature*> zombies;
me->GetCreatureListWithEntryInGrid(zombies, NPC_ZOMBIE_CHOW, 150.0f);
for (Creature* zombie : zombies)
Talk(EMOTE_ENRAGE);
int32 bp1 = 99; // Enrage melee haste
int32 bp2 = 49; // Enrage damage percent
me->CastCustomSpell(me, SPELL_ENRAGE_10, &bp1, &bp2, 0, true);
events.Repeat(22s);
break;
}
case EVENT_MORTAL_WOUND:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
events.Repeat(10s);
break;
case EVENT_DECIMATE:
Talk(EMOTE_DECIMATE);
me->CastSpell(me, SPELL_DECIMATE_10, false);
// Apply Decimate effect to zombies
// TODO: Is this block required?
{
if (zombie->IsAlive())
std::list<Creature*> zombies;
me->GetCreatureListWithEntryInGrid(zombies, NPC_ZOMBIE_CHOW, 150.0f);
for (Creature* zombie : zombies)
{
uint32 reduceHp = uint32(zombie->GetMaxHealth() * 0.05f);
if (zombie->GetHealth() > reduceHp)
zombie->SetHealth(reduceHp); // Reduce HP to 5%
zombie->SetWalk(true); // Set to walk
zombie->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED); // Move to boss
zombie->SetReactState(REACT_PASSIVE); // Set to passive
if (zombie->IsAlive())
{
uint32 reduceHp = uint32(zombie->GetMaxHealth() * 0.05f);
if (zombie->GetHealth() > reduceHp)
zombie->SetHealth(reduceHp); // Reduce HP to 5%
zombie->SetWalk(true); // Set to walk
zombie->GetMotionMaster()->MoveFollow(me,
0.0f,
0.0f,
MOTION_SLOT_CONTROLLED); // Move to boss
zombie->SetReactState(REACT_PASSIVE); // Set to passive
}
}
}
}
events.RepeatEvent(105000);
break;
case EVENT_SUMMON_ZOMBIE:
{
uint8 rand = urand(0, 2);
for (int32 i = 0; i < 1; ++i)
{
// In 40 man raid, use all gates
me->SummonCreature(NPC_ZOMBIE_CHOW, zombiePos[urand(0, 2)]);
(rand == 2 ? rand = 0 : rand++);
}
events.RepeatEvent(10000);
break;
}
case EVENT_CAN_EAT_ZOMBIE:
events.RepeatEvent(1000);
if (me->GetVictim() && me->GetVictim()->GetEntry() == NPC_ZOMBIE_CHOW && me->IsWithinMeleeRange(me->GetVictim()))
{
if (me->GetVictim()->GetHealth() > 0) // Check if the zombie is alive
events.RepeatEvent(105000);
break;
case EVENT_SUMMON_ZOMBIE:
{
me->ModifyHealth(int32(me->GetMaxHealth() * 0.05f)); // Heal for 5% of max health
uint8 rand = urand(0, 2);
for (int32 i = 0; i < RAID_MODE(1, 2, 2, 2); ++i)
{
// In 10 man raid, normal mode - should spawn only from mid gate
// \1 |0 /2 pos
// In 25 man raid - should spawn from all 3 gates
if (me->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
{
me->SummonCreature(NPC_ZOMBIE_CHOW, zombiePos[0]);
}
else
{
me->SummonCreature(NPC_ZOMBIE_CHOW, zombiePos[urand(0, 2)]);
}
(rand == 2 ? rand = 0 : rand++);
}
events.Repeat(10s);
break;
}
case EVENT_CAN_EAT_ZOMBIE:
events.RepeatEvent(1000);
if (me->GetVictim()->GetEntry() == NPC_ZOMBIE_CHOW && me->IsWithinMeleeRange(me->GetVictim()))
{
me->CastCustomSpell(SPELL_CHOW_SEARCHER, SPELLVALUE_RADIUS_MOD, 20000, me, true);
Talk(EMOTE_DEVOURS_ALL);
Unit::DealDamage(me, me->GetVictim(), me->GetVictim()->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); // Kill the zombie
return; // leave it to skip DoMeleeAttackIfReady
}
}
break;
break;
}
DoMeleeAttackIfReady();
}