Scripts/Naxxramas: Rework of Gluth

1) Gluth should be able to eat zombies close to him, one at the time, during the whole fight.
2) Gluth should be able to eat zombies at an accelerated rate after each Decimate.
3) The zombies should put the "Infected Wound" debuff on their auto-attack targets.
4) Zombies should have a normal threat table before decimate and should loose all kind of aggro behavior and walk toward Gluth after decimate.
5) Gluth shouldn't be affected by the decimate damage.
6) Newly poped zombies should have all players in their aggro list as soon as they spawn. So far, they were not moving and were only aggroed by proximity.
7) and several minor fixes (emotes, useless data in db).
This commit is contained in:
chaodhib
2016-03-21 23:17:02 +01:00
committed by Aokromes
parent 0b96416bda
commit 8a84d7de3e
5 changed files with 424 additions and 66 deletions

View File

@@ -0,0 +1,32 @@
-- The column `spell1` was misused for this NPC. This NPC is undead. He cannot be MCed. The spell 29307 should be cast using SmartAI or by Script.
-- Also, link the zombies chows to the custom ScriptedAI defined in boss_gluth.cpp.
UPDATE `creature_template` SET `spell1`=0, `ScriptName`='npc_zombie_chow' WHERE `entry`=16360;
UPDATE `creature_template` SET `spell1`=0 WHERE `entry`=30303;
-- connect the decimate spell (effect 0) used by Gluth (in both 10 man & 25) to the spell script defined in boss_gluth.cpp.
-- and connect the 2 zombie chow's search spells to a unique spell script used by both.
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_gluth_decimate', 'spell_gluth_zombiechow_search');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(28374, 'spell_gluth_decimate'),
(54426, 'spell_gluth_decimate'),
(28239, 'spell_gluth_zombiechow_search'),
(28404, 'spell_gluth_zombiechow_search');
-- add the condition to the multi-target insta-kill spell 28404 which is that only zombies are eligible targets to the spell.
-- add a condition to the decimate spell (28374/54426). It's damage component should only affect players and zombies.
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 13 AND `SourceEntry` IN (28374, 28404, 54426);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 28404, 0, 0, 31, 0, 3, 16360, 0, 0, 0, 0, '', 'Zombie Chow Search targets zombies only'),
(13, 1, 28374, 0, 0, 31, 0, 3, 16360, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'),
(13, 1, 28374, 0, 1, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'),
(13, 1, 54426, 0, 0, 31, 0, 3, 16360, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'),
(13, 1, 54426, 0, 1, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player');
-- adds Gluth's 5 emotes into the DB.
DELETE FROM `creature_text` WHERE `entry`=15932 AND `groupid` IN(0,1,2,3,4) AND `id`=0;
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(15932, 0, 0, '%s spots a zombie to devour!', 16, 0, 100, 0, 0, 0, 12242, 2/3, 'Gluth - spots one'),
(15932, 1, 0, '%s decimates all nearby flesh!', 41, 0, 100, 0, 0, 0, 32321, 2/3, 'Gluth - decimate'),
(15932, 2, 0, '%s becomes enraged!', 41, 0, 100, 0, 0, 0, 24144, 2/3, 'Gluth - enrage'),
(15932, 3, 0, '%s devours all nearby zombies!', 16, 0, 100, 0, 0, 0, 12348, 2/3, 'Gluth - devours all'),
(15932, 4, 0, '%s goes into a berserker rage!', 41, 0, 100, 0, 0, 0, 34057, 2/3, 'Gluth - berserker');

View File

@@ -3359,16 +3359,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
m_caster->CastSpell(unitTarget, 22682, true);
return;
}
// Decimate
case 28374:
case 54426:
if (unitTarget)
{
int32 decimateDamage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5));
if (decimateDamage > 0)
m_caster->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, decimateDamage, unitTarget);
}
return;
// Mirren's Drinking Hat
case 29830:
{

View File

@@ -18,38 +18,69 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "naxxramas.h"
#include "SpellScript.h"
#include <math.h>
enum Texts
{
EMOTE_SPOTS_ONE = 0,
EMOTE_DECIMATE = 1,
EMOTE_ENRAGE = 2,
EMOTE_DEVOURS_ALL = 3,
EMOTE_BERSERKER = 4
};
enum Spells
{
SPELL_MORTAL_WOUND = 25646,
SPELL_ENRAGE = 28371,
SPELL_DECIMATE = 28374,
SPELL_BERSERK = 26662,
SPELL_INFECTED_WOUND = 29306
};
// Gluth
SPELL_MORTAL_WOUND = 54378, // spell effect dummy unused. what its supposed to do is unkown.
SPELL_ENRAGE = 28371, // 54427 in 25 man.
SPELL_DECIMATE = 28374, // 54426 in 25 man. Effect0 is handled by SpellScript (see below) and 2 rows in conditions table. Effect2 is handled by SpellScript (see below).
SPELL_DECIMATE_DMG = 28375,
SPELL_BERSERK = 26662,
SPELL_ZOMBIE_CHOW_SEARCH_SINGLE = 28239, // Insta kill spell. Single target. See spell script below.
SPELL_ZOMBIE_CHOW_SEARCH_MULTI = 28404, // Insta kill spell. Affect all zombies 10 yards around Gluth's center. See one row conditions table + spell script below.
enum Creatures
{
NPC_ZOMBIE = 16360
// Zombies
SPELL_INFECTED_WOUND = 29307 // Used by the zombies on self.
};
Position const PosSummon[3] =
{
{3267.9f, -3172.1f, 297.42f, 0.94f},
{3253.2f, -3132.3f, 297.42f, 0},
{3308.3f, -3185.8f, 297.42f, 1.58f},
{ 3270.132f, -3169.948f, 297.5891f, 5.88176f },
{ 3307.298f, -3183.449f, 297.5891f, 5.742133f },
{ 3255.708f, -3135.677f, 297.5891f, 1.867502f }
};
enum Events
{
EVENT_WOUND = 1,
EVENT_WOUND = 1,
EVENT_ENRAGE,
EVENT_DECIMATE,
EVENT_BERSERK,
EVENT_SUMMON,
EVENT_SEARCH_ZOMBIE_SINGLE,
EVENT_KILL_ZOMBIE_SINGLE,
EVENT_SEARCH_ZOMBIE_MULTI
};
#define EMOTE_NEARBY " spots a nearby zombie to devour!"
enum States
{
STATE_GLUTH_NORMAL = 1,
STATE_GLUTH_EATING = 2,
STATE_ZOMBIE_NORMAL = 1,
STATE_ZOMBIE_DECIMATED = 2,
STATE_ZOMBIE_TOBE_EATEN = 3
};
enum Misc
{
NPC_ZOMBIE_CHOW = 16360,
EVENT_GLUTH_ZOMBIE_BEHAVIOR = 10495, // unused. event handled by spell_gluth_decimate_SpellScript::HandleEvent
DATA_ZOMBIE_STATE = 1,
ACTION_DECIMATE_EVENT = 2,
};
class boss_gluth : public CreatureScript
{
@@ -58,99 +89,395 @@ public:
CreatureAI* GetAI(Creature* creature) const override
{
return new boss_gluthAI(creature);
return GetInstanceAI<boss_gluthAI>(creature);
}
struct boss_gluthAI : public BossAI
{
boss_gluthAI(Creature* creature) : BossAI(creature, BOSS_GLUTH)
{
// Do not let Gluth be affected by zombies' debuff
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_INFECTED_WOUND, true);
}
void MoveInLineOfSight(Unit* who) override
boss_gluthAI(Creature* creature) : BossAI(creature, BOSS_GLUTH), state(STATE_GLUTH_NORMAL) {}
void Reset() override
{
if (who->GetEntry() == NPC_ZOMBIE && me->IsWithinDistInMap(who, 7))
{
SetGazeOn(who);
/// @todo use a script text
me->TextEmote(EMOTE_NEARBY, nullptr, true);
}
else
BossAI::MoveInLineOfSight(who);
_Reset();
zombieToBeEatenGUID.Clear();
state = STATE_GLUTH_NORMAL;
me->SetReactState(REACT_AGGRESSIVE);
me->SetSpeed(UnitMoveType::MOVE_RUN, 12.0f / baseMoveSpeed[MOVE_RUN]);
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(EVENT_WOUND, 10000);
events.ScheduleEvent(EVENT_ENRAGE, 15000);
events.ScheduleEvent(EVENT_DECIMATE, 105000);
events.ScheduleEvent(EVENT_BERSERK, 8*60000);
events.ScheduleEvent(EVENT_SUMMON, 15000);
events.ScheduleEvent(EVENT_WOUND, Seconds(10));
events.ScheduleEvent(EVENT_ENRAGE, randtime(Seconds(16), Seconds(22)));
events.ScheduleEvent(EVENT_DECIMATE, randtime(Minutes(1)+Seconds(50), Minutes(2)));
events.ScheduleEvent(EVENT_BERSERK, Minutes(8));
events.ScheduleEvent(EVENT_SUMMON, Seconds(15));
events.ScheduleEvent(EVENT_SEARCH_ZOMBIE_SINGLE, Seconds(12));
}
void JustSummoned(Creature* summon) override
void SummonedCreatureDies(Creature* summoned, Unit* /* who */) override
{
if (summon->GetEntry() == NPC_ZOMBIE)
summon->AI()->AttackStart(me);
summons.Summon(summon);
summons.Despawn(summoned); // needed or else dead zombies not despawned yet will still be in the list
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictimWithGaze())
if (!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_WOUND:
if (state == STATE_GLUTH_EATING)
{
events.Repeat(Seconds(3));
break;
}
DoCastVictim(SPELL_MORTAL_WOUND);
events.ScheduleEvent(EVENT_WOUND, 10000);
events.Repeat(Seconds(10));
break;
case EVENT_ENRAGE:
/// @todo Add missing text
if (state == STATE_GLUTH_EATING)
{
events.Repeat(Seconds(5));
break;
}
Talk(EMOTE_ENRAGE);
DoCast(me, SPELL_ENRAGE);
events.ScheduleEvent(EVENT_ENRAGE, 15000);
events.Repeat(randtime(Seconds(16), Seconds(22)));
break;
case EVENT_DECIMATE:
/// @todo Add missing text
if (state == STATE_GLUTH_EATING)
{
events.Repeat(Seconds(4));
break;
}
Talk(EMOTE_DECIMATE);
DoCastAOE(SPELL_DECIMATE);
events.ScheduleEvent(EVENT_DECIMATE, 105000);
for (int i = 1; i <= 20; i++)
events.ScheduleEvent(EVENT_SEARCH_ZOMBIE_MULTI, Seconds(3*i));
events.ScheduleEvent(EVENT_DECIMATE, randtime(Minutes(1)+Seconds(50), Minutes(2)));
break;
case EVENT_BERSERK:
Talk(EMOTE_BERSERKER);
DoCast(me, SPELL_BERSERK);
events.ScheduleEvent(EVENT_BERSERK, 5*60000);
events.Repeat(Minutes(5)); //refresh the hard enrage buff
break;
case EVENT_SUMMON:
for (int32 i = 0; i < RAID_MODE(1, 2); ++i)
DoSummon(NPC_ZOMBIE, PosSummon[rand32() % RAID_MODE(1, 3)]);
events.ScheduleEvent(EVENT_SUMMON, 10000);
if (Is25ManRaid()) // one wave each 10s. one wave=1 zombie in 10man and 2 zombies in 25man.
{
DoSummon(NPC_ZOMBIE_CHOW, PosSummon[1]);
DoSummon(NPC_ZOMBIE_CHOW, PosSummon[2]);
}
else
DoSummon(NPC_ZOMBIE_CHOW, PosSummon[0]);
events.Repeat(Seconds(10));
break;
case EVENT_SEARCH_ZOMBIE_SINGLE:
{
Creature* zombie = nullptr;
for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr)
{
zombie=ObjectAccessor::GetCreature(*me, *itr);
if (zombie == nullptr || !zombie->IsAlive() || !zombie->IsWithinDistInMap(me, 10.0))
zombie = nullptr;
}
if (zombie)
{
zombieToBeEatenGUID = zombie->GetGUID(); // save for later use// the soon-to-be-eaten zombie should stop moving and stop attacking
// the soon-to-be-eaten zombie should stop moving and stop attacking
zombie->AI()->SetData(DATA_ZOMBIE_STATE, STATE_ZOMBIE_TOBE_EATEN);
// gluth should stop AAs on his primary target and turn toward the zombie (2 yards away). He then pauses for a few seconds.
me->SetSpeed(MOVE_RUN, 36.0f / baseMoveSpeed[MOVE_RUN]);
me->SetReactState(ReactStates::REACT_PASSIVE);
me->AttackStop();
Talk(EMOTE_SPOTS_ONE);
//me->SetTarget(ObjectGuid::Empty);
me->GetMotionMaster()->MoveCloserAndStop(1, zombie, 2.0f);
state = STATE_GLUTH_EATING;
}
events.Repeat(RAID_MODE(Seconds(7), Seconds(5)));
break;
}
case EVENT_KILL_ZOMBIE_SINGLE:
{
Creature* zombieToBeEaten = ObjectAccessor::GetCreature(*me, zombieToBeEatenGUID);
if (zombieToBeEaten && zombieToBeEaten->IsAlive() && zombieToBeEaten->IsWithinDistInMap(me, 10.0))
DoCast(zombieToBeEaten, SPELL_ZOMBIE_CHOW_SEARCH_SINGLE); // do the killing + healing in done inside by spell script see below.
zombieToBeEatenGUID = ObjectGuid::Empty;
state = STATE_GLUTH_NORMAL;
me->SetSpeed(UnitMoveType::MOVE_RUN, 12.0f / baseMoveSpeed[MOVE_RUN]);
// and then return on primary target
me->SetReactState(REACT_AGGRESSIVE);
break;
}
case EVENT_SEARCH_ZOMBIE_MULTI:
{
if (state == STATE_GLUTH_EATING) // skip and simply wait for the next occurence
break;
Creature* zombie = nullptr;
for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr)
{
zombie = ObjectAccessor::GetCreature(*me, *itr);
if (zombie && zombie->IsAlive() && zombie->GetExactDist2d(me) > 18.0)
zombie = nullptr;
}
if (zombie) // cast the aoe spell only if at least one zombie is found nearby
{
Talk(EMOTE_DEVOURS_ALL);
DoCastAOE(SPELL_ZOMBIE_CHOW_SEARCH_MULTI);
}
break;
}
}
}
if (me->GetVictim() && me->EnsureVictim()->GetEntry() == NPC_ZOMBIE)
{
if (me->IsWithinMeleeRange(me->GetVictim()))
{
me->Kill(me->GetVictim());
me->ModifyHealth(int32(me->CountPctFromMaxHealth(5)));
}
DoMeleeAttackIfReady();
}
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id == 1){
me->GetMotionMaster()->MoveIdle();
events.ScheduleEvent(EVENT_KILL_ZOMBIE_SINGLE, Seconds(1));
}
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_DECIMATE_EVENT:
for (ObjectGuid zombieGuid : summons)
{
Creature* zombie = ObjectAccessor::GetCreature(*me, zombieGuid);
if (zombie && zombie->IsAlive())
zombie->AI()->SetData(DATA_ZOMBIE_STATE, STATE_ZOMBIE_DECIMATED);
}
break;
}
}
private:
ObjectGuid zombieToBeEatenGUID;
uint8 state;
};
};
// spell 28374 (10man) / 54426 (25man) - Decimate
class spell_gluth_decimate : public SpellScriptLoader
{
public:
spell_gluth_decimate() : SpellScriptLoader("spell_gluth_decimate") { }
class spell_gluth_decimate_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gluth_decimate_SpellScript);
// handles the damaging effect of the decimate spell.
void HandleScriptEffect(SpellEffIndex /* index */)
{
if (Unit *unit = GetHitUnit())
{
int32 damage = int32(unit->GetHealth()) - int32(unit->CountPctFromMaxHealth(5));
if (damage > 0)
GetCaster()->CastCustomSpell(SPELL_DECIMATE_DMG, SPELLVALUE_BASE_POINT0, damage, unit);
}
}
// handles the change of zombies behavior after the decimate spell
void HandleEvent(SpellEffIndex /* index */)
{
GetCaster()->GetAI()->DoAction(ACTION_DECIMATE_EVENT);
}
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (sSpellMgr->GetSpellInfo(SPELL_DECIMATE_DMG))
return true;
else
DoMeleeAttackIfReady();
return false;
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnEffectHit += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT);
}
bool Load()
{
return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH;
}
};
SpellScript* GetSpellScript() const
{
return new spell_gluth_decimate_SpellScript();
}
};
// used by both 28239 & 28404 (single target and aoe zombie-kill spell) to heal Gluth on each target hit.
class spell_gluth_zombiechow_search : public SpellScriptLoader
{
public:
spell_gluth_zombiechow_search() : SpellScriptLoader("spell_gluth_zombiechow_search") { }
class spell_gluth_zombiechow_search_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gluth_zombiechow_search_SpellScript);
void HealForEachTargetHit()
{
GetCaster()->ModifyHealth(int32(GetCaster()->CountPctFromMaxHealth(5)));
}
void Register() override
{
AfterHit += SpellHitFn(spell_gluth_zombiechow_search_SpellScript::HealForEachTargetHit);
}
bool Load()
{
return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH;
}
};
SpellScript* GetSpellScript() const
{
return new spell_gluth_zombiechow_search_SpellScript();
}
};
// creature 16360 (10man) / 30303 (25man)
class npc_zombie_chow : public CreatureScript
{
public:
npc_zombie_chow() : CreatureScript("npc_zombie_chow") { }
struct npc_zombie_chowAI : public ScriptedAI
{
npc_zombie_chowAI(Creature* creature) : ScriptedAI(creature)
{
GluthGUID = creature->GetInstanceScript()->GetGuidData(DATA_GLUTH);
DoCast(me, SPELL_INFECTED_WOUND);
state = STATE_ZOMBIE_NORMAL;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (state == STATE_ZOMBIE_DECIMATED)
{
timer += diff;
Creature* gluth = ObjectAccessor::GetCreature(*me, GluthGUID);
// Putting this in the UpdateAI loop fixes an issue where death gripping a decimated zombie would make the zombie stand still until the rest of the fight.
// Also fix the issue where if one or more zombie is rooted when decimates hits (and MovePoint() is called), the zombie teleport to the boss. pretty weird behavior.
if (gluth && timer>1600 && me->GetExactDist2d(gluth) > 10.0 && me->CanFreeMove()) // it takes about 1600 ms for the animation to cycle. This way, the animation looks relatively smooth.
{
me->GetMotionMaster()->MovePoint(0, gluth->GetPosition()); // isn't dynamic. So, to take into account Gluth's movement, it must be called periodicly.
//me->GetMotionMaster()->MoveFollow(gluth, 0, 0); // the zombies will stand still too far away from Gluth at the end of their movement. Also doesnt seem to work with SetWalk(true)
timer = 0;
}
if (me->GetExactDist2d(gluth) <= 10.0)
me->StopMoving();
}
else if (state == STATE_ZOMBIE_NORMAL)
DoMeleeAttackIfReady();
}
void SetData(uint32 id, uint32 value) override
{
if (id == DATA_ZOMBIE_STATE) // change of state
{
state = value;
if (value == STATE_ZOMBIE_DECIMATED)
{
me->SetReactState(ReactStates::REACT_PASSIVE);
me->AttackStop();
me->SetTarget(ObjectGuid::Empty);
// at this point, the zombie should be non attacking and non moving.
me->SetWalk(true); // it doesnt seem to work with MoveFollow() (but it does work with MovePoint()).
//me->SetSpeed(UnitMoveType::MOVE_RUN, baseMoveSpeed[UnitMoveType::MOVE_WALK] / baseMoveSpeed[UnitMoveType::MOVE_RUN]); // Hack to stay in run mode but with walk speed in case using MoveFollow()
timer = 1000;
}
else if (value == STATE_ZOMBIE_TOBE_EATEN)
{
// forced to stand still
me->GetMotionMaster()->Clear();
me->StopMoving();
// and loose aggro behavior
me->SetReactState(ReactStates::REACT_PASSIVE);
me->AttackStop();
me->SetTarget(ObjectGuid::Empty);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true); // not sure if this is blizz-like but this is very convenient
}
}
}
uint32 GetData(uint32 index) const override
{
if (index == DATA_ZOMBIE_STATE)
return state;
return 0;
}
private:
uint32 timer;
uint8 state;
ObjectGuid GluthGUID;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_zombie_chowAI>(creature);
}
};
void AddSC_boss_gluth()
{
new boss_gluth();
new spell_gluth_decimate();
new spell_gluth_zombiechow_search();
new npc_zombie_chow();
}

View File

@@ -182,6 +182,9 @@ class instance_naxxramas : public InstanceMapScript
case NPC_SIR:
SirGUID = creature->GetGUID();
break;
case NPC_GLUTH:
GluthGUID = creature->GetGUID();
break;
case NPC_HEIGAN:
HeiganGUID = creature->GetGUID();
break;
@@ -393,6 +396,8 @@ class instance_naxxramas : public InstanceMapScript
return SirGUID;
case DATA_HEIGAN:
return HeiganGUID;
case DATA_GLUTH:
return GluthGUID;
case DATA_FEUGEN:
return FeugenGUID;
case DATA_STALAGG:
@@ -670,6 +675,8 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid HorsemenChestGUID;
/* The Construct Quarter */
// Gluth
ObjectGuid GluthGUID;
// Thaddius
ObjectGuid ThaddiusGUID;
ObjectGuid FeugenGUID;

View File

@@ -69,6 +69,7 @@ enum Data64
DATA_LADY,
DATA_BARON,
DATA_SIR,
DATA_GLUTH,
DATA_THADDIUS,
DATA_HEIGAN,
DATA_FEUGEN,
@@ -92,6 +93,7 @@ enum CreaturesIds
NPC_LADY = 16065,
NPC_BARON = 30549,
NPC_SIR = 16063,
NPC_GLUTH = 15932,
NPC_HEIGAN = 15936,
NPC_THADDIUS = 15928,
NPC_FEUGEN = 15930,