TrinityCore
boss_gluth.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "ScriptMgr.h"
19#include "InstanceScript.h"
20#include "MotionMaster.h"
21#include "naxxramas.h"
22#include "ObjectAccessor.h"
23#include "ScriptedCreature.h"
24#include "SpellScript.h"
25
27{
33};
34
36{
37 // Gluth
38 SPELL_MORTAL_WOUND = 54378, // spell effect dummy unused. what its supposed to do is unkown.
39 SPELL_ENRAGE = 28371, // 54427 in 25 man.
40 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).
43 SPELL_ZOMBIE_CHOW_SEARCH_SINGLE = 28239, // Insta kill spell. Single target. See spell script below.
44 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.
45
46 // Zombies
47 SPELL_INFECTED_WOUND = 29307 // Used by the zombies on self.
48};
49
51{
60};
61
63{
66
70};
71
73{
76};
77
78enum Misc
79{
80 EVENT_GLUTH_ZOMBIE_BEHAVIOR = 10495, // unused. event handled by spell_gluth_decimate_SpellScript::HandleEvent
83};
84
85struct boss_gluth : public BossAI
86{
87
89
90 void Reset() override
91 {
92 _Reset();
97 }
98
99 void JustEngagedWith(Unit* who) override
100 {
108 }
109
110 void SummonedCreatureDies(Creature* summoned, Unit* /* who */) override
111 {
112 summons.Despawn(summoned); // needed or else dead zombies not despawned yet will still be in the list
113 }
114
115 void UpdateAI(uint32 diff) override
116 {
117 if (!UpdateVictim() || !CheckInRoom())
118 return;
119
120 events.Update(diff);
121
123 return;
124
125 while (uint32 eventId = events.ExecuteEvent())
126 {
127 switch (eventId)
128 {
129 case EVENT_WOUND:
131 {
133 break;
134 }
135
137 events.Repeat(Seconds(10));
138 break;
139 case EVENT_ENRAGE:
141 {
143 break;
144 }
145
149 break;
150 case EVENT_DECIMATE:
152 {
154 break;
155 }
156
159 for (int i = 1; i <= 20; i++)
162 break;
163 case EVENT_BERSERK:
166 events.Repeat(Minutes(5)); //refresh the hard enrage buff
167 break;
168 case EVENT_SUMMON:
169 if (Is25ManRaid()) // one wave each 10s. one wave=1 zombie in 10man and 2 zombies in 25man.
171 else
173 events.Repeat(Seconds(10));
174 break;
176 {
177 Creature* zombie = nullptr;
178 for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr)
179 {
180 zombie = ObjectAccessor::GetCreature(*me, *itr);
181 if (!zombie || !zombie->IsAlive() || !zombie->IsWithinDistInMap(me, 10.0))
182 zombie = nullptr;
183 }
184
185 if (zombie)
186 {
187 zombieToBeEatenGUID = zombie->GetGUID(); // save for later use
188
189 // the soon-to-be-eaten zombie should stop moving and stop attacking
191
192 // gluth should stop AAs on his primary target and turn toward the zombie (2 yards away). He then pauses for a few seconds.
193 me->SetSpeed(MOVE_RUN, 36.0f);
194
196 me->AttackStop();
197
199
200 //me->SetTarget(ObjectGuid::Empty);
201
202 me->GetMotionMaster()->MoveCloserAndStop(1, zombie, 2.0f);
203
205 }
206
208 break;
209 }
211 {
213 if (zombieToBeEaten && zombieToBeEaten->IsAlive() && zombieToBeEaten->IsWithinDistInMap(me, 10.0))
214 DoCast(zombieToBeEaten, SPELL_ZOMBIE_CHOW_SEARCH_SINGLE); // do the killing + healing in done inside by spell script see below.
215
219
220 // and then return on primary target
222
223 break;
224 }
226 {
227 if (state == STATE_GLUTH_EATING) // skip and simply wait for the next occurence
228 break;
229
230 Creature* zombie = nullptr;
231 for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr)
232 {
233 zombie = ObjectAccessor::GetCreature(*me, *itr);
234 if (zombie && zombie->IsAlive() && zombie->GetExactDist2d(me) > 18.0)
235 zombie = nullptr;
236 }
237
238 if (zombie) // cast the aoe spell only if at least one zombie is found nearby
239 {
242 }
243 break;
244 }
245 }
246
248 return;
249 }
250 }
251
252 void MovementInform(uint32 /*type*/, uint32 id) override
253 {
254 if (id == 1){
257 }
258
259 }
260
261 void DoAction(int32 action) override
262 {
263 switch (action)
264 {
266 for (ObjectGuid zombieGuid : summons)
267 {
268 Creature* zombie = ObjectAccessor::GetCreature(*me, zombieGuid);
269 if (zombie && zombie->IsAlive())
271 }
272 break;
273 }
274 }
275
276private:
279};
280
281// 28374, 54426 - Decimate
283{
284 // handles the damaging effect of the decimate spell.
286 {
287 if (Unit *unit = GetHitUnit())
288 {
289 int32 damage = int32(unit->GetHealth()) - int32(unit->CountPctFromMaxHealth(5));
290 if (damage > 0)
291 {
293 args.AddSpellBP0(damage);
294 GetCaster()->CastSpell(unit, SPELL_DECIMATE_DMG, args);
295 }
296 }
297 }
298
299 // handles the change of zombies behavior after the decimate spell
300 void HandleEvent(SpellEffIndex /* index */)
301 {
303 }
304
305 bool Validate(SpellInfo const* /*spellInfo*/) override
306 {
308 }
309
310 void Register() override
311 {
314 }
315
316 bool Load() override
317 {
318 return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH;
319 }
320};
321
322// 28239, 28404 - Zombie Chow Search (single target and aoe zombie-kill spell) to heal Gluth on each target hit
324{
326 {
327 GetCaster()->ModifyHealth(int32(GetCaster()->CountPctFromMaxHealth(5)));
328 }
329
330 void Register() override
331 {
333 }
334
335 bool Load() override
336 {
337 return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH;
338 }
339};
340
341// creature 16360 (10man) / 30303 (25man)
343{
344 npc_zombie_chow(Creature* creature) : ScriptedAI(creature)
345 {
347
349 timer = 0;
351 }
352
353 void UpdateAI(uint32 diff) override
354 {
355 if (!UpdateVictim())
356 return;
357
359 {
360 timer += diff;
362 {
363 // 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.
364 // 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.
365 if (timer > 1600 && me->GetExactDist2d(gluth) > 10.0f && me->CanFreeMove()) // it takes about 1600 ms for the animation to cycle. This way, the animation looks relatively smooth.
366 {
367 me->GetMotionMaster()->MovePoint(0, gluth->GetPosition()); // isn't dynamic. So, to take into account Gluth's movement, it must be called periodicly.
368 timer = 0;
369 }
370
371 if (me->GetExactDist2d(gluth) <= 10.0f)
372 me->StopMoving();
373 }
374 }
375 }
376
377 void SetData(uint32 id, uint32 value) override
378 {
379 if (id == DATA_ZOMBIE_STATE) // change of state
380 {
381 state = value;
382 if (value == STATE_ZOMBIE_DECIMATED)
383 {
385 me->AttackStop();
386 me->SetCanMelee(false);
388 // at this point, the zombie should be non attacking and non moving.
389
390 me->SetWalk(true); // it doesnt seem to work with MoveFollow() (but it does work with MovePoint()).
391
392 timer = 1000;
393 }
394 else if (value == STATE_ZOMBIE_TOBE_EATEN)
395 {
396 // forced to stand still
398 me->StopMoving();
399
400 // and loose aggro behavior
402 me->AttackStop();
403 me->SetCanMelee(false);
405
406 me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true); // not sure if this is blizz-like but this is very convenient
407 }
408 }
409 }
410
411 uint32 GetData(uint32 index) const override
412 {
413 if (index == DATA_ZOMBIE_STATE)
414 return state;
415 return 0;
416 }
417
418private:
422};
423
425{
430}
Texts
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition: Duration.h:35
Spells
Definition: PlayerAI.cpp:32
Milliseconds randtime(Milliseconds min, Milliseconds max)
Definition: Random.cpp:62
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ EFFECT_2
Definition: SharedDefines.h:32
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_SEND_EVENT
@ MECHANIC_GRIP
@ IMMUNITY_MECHANIC
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define SpellHitFn(F)
Definition: SpellScript.h:854
@ MOVE_RUN
Definition: UnitDefines.h:118
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ UNIT_STATE_CASTING
Definition: Unit.h:270
@ SUMMON_GROUP_CHOW_25MAN
Definition: boss_gluth.cpp:75
@ SUMMON_GROUP_CHOW_10MAN
Definition: boss_gluth.cpp:74
@ DATA_ZOMBIE_STATE
Definition: boss_gluth.cpp:81
@ ACTION_DECIMATE_EVENT
Definition: boss_gluth.cpp:82
@ EVENT_GLUTH_ZOMBIE_BEHAVIOR
Definition: boss_gluth.cpp:80
@ SPELL_ENRAGE
Definition: boss_gluth.cpp:39
@ SPELL_ZOMBIE_CHOW_SEARCH_MULTI
Definition: boss_gluth.cpp:44
@ SPELL_ZOMBIE_CHOW_SEARCH_SINGLE
Definition: boss_gluth.cpp:43
@ SPELL_DECIMATE
Definition: boss_gluth.cpp:40
@ SPELL_DECIMATE_DMG
Definition: boss_gluth.cpp:41
@ SPELL_BERSERK
Definition: boss_gluth.cpp:42
@ SPELL_MORTAL_WOUND
Definition: boss_gluth.cpp:38
@ SPELL_INFECTED_WOUND
Definition: boss_gluth.cpp:47
States
Definition: boss_gluth.cpp:63
@ STATE_GLUTH_NORMAL
Definition: boss_gluth.cpp:64
@ STATE_ZOMBIE_TOBE_EATEN
Definition: boss_gluth.cpp:69
@ STATE_ZOMBIE_DECIMATED
Definition: boss_gluth.cpp:68
@ STATE_GLUTH_EATING
Definition: boss_gluth.cpp:65
@ STATE_ZOMBIE_NORMAL
Definition: boss_gluth.cpp:67
@ EMOTE_SPOTS_ONE
Definition: boss_gluth.cpp:28
@ EMOTE_BERSERKER
Definition: boss_gluth.cpp:32
@ EMOTE_ENRAGE
Definition: boss_gluth.cpp:30
@ EMOTE_DECIMATE
Definition: boss_gluth.cpp:29
@ EMOTE_DEVOURS_ALL
Definition: boss_gluth.cpp:31
void AddSC_boss_gluth()
Definition: boss_gluth.cpp:424
@ EVENT_SEARCH_ZOMBIE_SINGLE
Definition: boss_gluth.cpp:57
@ EVENT_ENRAGE
Definition: boss_gluth.cpp:53
@ EVENT_SEARCH_ZOMBIE_MULTI
Definition: boss_gluth.cpp:59
@ EVENT_WOUND
Definition: boss_gluth.cpp:52
@ EVENT_KILL_ZOMBIE_SINGLE
Definition: boss_gluth.cpp:58
@ EVENT_BERSERK
Definition: boss_gluth.cpp:55
@ EVENT_SUMMON
Definition: boss_gluth.cpp:56
@ EVENT_DECIMATE
Definition: boss_gluth.cpp:54
SummonGroups
void JustEngagedWith(Unit *who) override
SummonList summons
EventMap events
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
virtual bool CheckInRoom()
Definition: CreatureAI.cpp:453
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetCanMelee(bool canMelee, bool fleeFromMelee=false)
Definition: Creature.cpp:2822
void SetReactState(ReactStates st)
Definition: Creature.h:160
void SetTarget(ObjectGuid const &guid) override
Definition: Creature.cpp:3419
CreatureAI * AI() const
Definition: Creature.h:214
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
virtual ObjectGuid GetGuidData(uint32 type) const override
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveCloserAndStop(uint32 id, Unit *target, float distance)
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
void Clear()
Definition: ObjectGuid.h:286
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Unit * GetCaster() const
HookList< HitHandler > AfterHit
Definition: SpellScript.h:852
HookList< EffectHandler > OnEffectHit
Definition: SpellScript.h:839
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
void Despawn(Creature const *summon)
iterator begin()
StorageType::const_iterator const_iterator
iterator end()
virtual void SetData(uint32, uint32)
Definition: UnitAI.h:74
virtual void DoAction(int32)
Definition: UnitAI.h:72
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:180
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition: Unit.cpp:7845
int64 ModifyHealth(int64 val)
Definition: Unit.cpp:8182
void SetSpeed(UnitMoveType mtype, float newValue)
Definition: Unit.cpp:8520
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool CanFreeMove() const
Definition: Unit.cpp:9323
bool IsAlive() const
Definition: Unit.h:1164
void StopMoving()
Definition: Unit.cpp:10049
UnitAI * GetAI() const
Definition: Unit.h:660
bool SetWalk(bool enable)
Definition: Unit.cpp:12707
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool AttackStop()
Definition: Unit.cpp:5781
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=nullptr)
Definition: Object.cpp:2131
bool Validate(SpellInfo const *) override
Definition: boss_gluth.cpp:305
bool Load() override
Definition: boss_gluth.cpp:316
void HandleEvent(SpellEffIndex)
Definition: boss_gluth.cpp:300
void Register() override
Definition: boss_gluth.cpp:310
void HandleScriptEffect(SpellEffIndex)
Definition: boss_gluth.cpp:285
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
@ NPC_GLUTH
Definition: naxxramas.h:96
@ BOSS_GLUTH
Definition: naxxramas.h:38
@ DATA_GLUTH
Definition: naxxramas.h:71
#define RegisterNaxxramasCreatureAI(ai_name)
Definition: naxxramas.h:221
CastSpellExtraArgs & AddSpellBP0(int32 val)
Definition: SpellDefines.h:475
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:106
T const & RAID_MODE(T const &normal10, T const &normal25) const
bool Is25ManRaid() const
void UpdateAI(uint32 diff) override
Definition: boss_gluth.cpp:115
boss_gluth(Creature *creature)
Definition: boss_gluth.cpp:88
void Reset() override
Definition: boss_gluth.cpp:90
void JustEngagedWith(Unit *who) override
Definition: boss_gluth.cpp:99
ObjectGuid zombieToBeEatenGUID
Definition: boss_gluth.cpp:277
void DoAction(int32 action) override
Definition: boss_gluth.cpp:261
void SummonedCreatureDies(Creature *summoned, Unit *) override
Definition: boss_gluth.cpp:110
void MovementInform(uint32, uint32 id) override
Definition: boss_gluth.cpp:252
npc_zombie_chow(Creature *creature)
Definition: boss_gluth.cpp:344
void UpdateAI(uint32 diff) override
Definition: boss_gluth.cpp:353
ObjectGuid GluthGUID
Definition: boss_gluth.cpp:421
void SetData(uint32 id, uint32 value) override
Definition: boss_gluth.cpp:377
uint32 GetData(uint32 index) const override
Definition: boss_gluth.cpp:411