aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchaodhib <chaodhib@gmail.com>2016-03-21 23:17:02 +0100
committertreeston <treeston.mmoc@gmail.com>2016-04-16 10:54:13 +0200
commit383cc4d94bf76827819d738b608f545c143c675b (patch)
tree2e6663b67215bc8f45dad28c302b213547cf17ab
parentbdeeab13bdfd545192fd619028a9114379235394 (diff)
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).
-rw-r--r--sql/updates/world/9999_99_99_99_world_GLUTH.sql32
-rw-r--r--src/server/game/Spells/SpellEffects.cpp10
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp431
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp7
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h2
5 files changed, 420 insertions, 62 deletions
diff --git a/sql/updates/world/9999_99_99_99_world_GLUTH.sql b/sql/updates/world/9999_99_99_99_world_GLUTH.sql
new file mode 100644
index 00000000000..7e33e6be07a
--- /dev/null
+++ b/sql/updates/world/9999_99_99_99_world_GLUTH.sql
@@ -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');
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3f0ff9a0f19..5b1def554e7 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3661,16 +3661,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:
{
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp
index ec47b0db101..412615afad4 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp
@@ -18,38 +18,69 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "naxxramas.h"
+#include "SpellScript.h"
+#include <math.h>
-enum Spells
+enum Texts
{
- SPELL_MORTAL_WOUND = 25646,
- SPELL_ENRAGE = 28371,
- SPELL_DECIMATE = 28374,
- SPELL_BERSERK = 26662,
- SPELL_INFECTED_WOUND = 29306
+ EMOTE_SPOTS_ONE = 0,
+ EMOTE_DECIMATE = 1,
+ EMOTE_ENRAGE = 2,
+ EMOTE_DEVOURS_ALL = 3,
+ EMOTE_BERSERKER = 4
};
-enum Creatures
+enum Spells
{
- NPC_ZOMBIE = 16360
+ // 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.
+
+ // 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)
+ 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())
{
- if (me->IsWithinMeleeRange(me->GetVictim()))
+ 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
+ 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->Kill(me->GetVictim());
- me->ModifyHealth(int32(me->CountPctFromMaxHealth(5)));
+ 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
+ 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();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index 02b82d255cd..e3971248513 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -153,6 +153,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;
@@ -327,6 +330,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:
@@ -582,6 +587,8 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid HorsemenChestGUID;
/* The Construct Quarter */
+ // Gluth
+ ObjectGuid GluthGUID;
// Thaddius
ObjectGuid ThaddiusGUID;
ObjectGuid FeugenGUID;
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index bece5a60bee..a3fedf5aa40 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -68,6 +68,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,