TrinityCore
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
boss_festergut.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 "icecrown_citadel.h"
19#include "Containers.h"
20#include "InstanceScript.h"
21#include "Map.h"
22#include "ObjectAccessor.h"
23#include "Player.h"
24#include "ScriptedCreature.h"
25#include "ScriptMgr.h"
26#include "SpellAuras.h"
27#include "SpellMgr.h"
28#include "SpellScript.h"
29
31{
42};
43
45{
46 // Festergut
49 SPELL_GASTRIC_BLOAT = 72219, // 72214 is the proper way (with proc) but atm procs can't have cooldown for creatures
54
55 // Stinky
59};
60
61// Used for HasAura checks
62#define PUNGENT_BLIGHT_HELPER RAID_MODE<uint32>(69195, 71219, 73031, 73032)
63#define INOCULATED_HELPER RAID_MODE<uint32>(69291, 72101, 72102, 72103)
64
65uint32 const gaseousBlight[3] = {69157, 69162, 69164};
66uint32 const gaseousBlightVisual[3] = {69126, 69152, 69154};
67
69{
75
78};
79
81{
83};
84
85// 36626 - Festergut
86struct boss_festergut : public BossAI
87{
89 {
92 }
93
94 void Reset() override
95 {
96 _Reset();
102 _inhaleCounter = 0;
104 if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true))
105 {
106 _gasDummyGUID = gasDummy->GetGUID();
107 for (uint8 i = 0; i < 3; ++i)
108 {
110 gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
111 }
112 }
113 }
114
115 void JustEngagedWith(Unit* who) override
116 {
118 {
121 return;
122 }
123
124 me->setActive(true);
126 if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true))
127 _gasDummyGUID = gasDummy->GetGUID();
129 professor->AI()->DoAction(ACTION_FESTERGUT_COMBAT);
131 }
132
133 void JustDied(Unit* /*killer*/) override
134 {
135 _JustDied();
138 professor->AI()->DoAction(ACTION_FESTERGUT_DEATH);
139
140 RemoveBlight();
141 }
142
143 void JustReachedHome() override
144 {
147 }
148
149 void EnterEvadeMode(EvadeReason why) override
150 {
153 professor->AI()->EnterEvadeMode();
154 }
155
156 void KilledUnit(Unit* victim) override
157 {
158 if (victim->GetTypeId() == TYPEID_PLAYER)
159 Talk(SAY_KILL);
160 }
161
162 void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
163 {
164 Unit* unitTarget = target->ToUnit();
165 if (!unitTarget)
166 return;
167
168 if (spellInfo->Id == PUNGENT_BLIGHT_HELPER)
170 }
171
172 void UpdateAI(uint32 diff) override
173 {
174 if (!UpdateVictim())
175 return;
176
177 events.Update(diff);
178
180 return;
181
182 while (uint32 eventId = events.ExecuteEvent())
183 {
184 switch (eventId)
185 {
187 {
188 RemoveBlight();
189 if (_inhaleCounter == 3)
190 {
194 _inhaleCounter = 0;
196 professor->AI()->DoAction(ACTION_FESTERGUT_GAS);
198 }
199 else
200 {
202 // just cast and dont bother with target, conditions will handle it
204 if (_inhaleCounter < 3)
206 }
207
209 break;
210 }
211 case EVENT_VILE_GAS:
212 {
213 std::list<Unit*> ranged, melee;
214 uint32 minTargets = RAID_MODE<uint32>(3, 8, 3, 8);
215 SelectTargetList(ranged, 25, SelectTargetMethod::Random, 0, -5.0f, true);
216 SelectTargetList(melee, 25, SelectTargetMethod::Random, 0, 5.0f, true);
217 while (ranged.size() < minTargets)
218 {
219 if (melee.empty())
220 break;
221
223 ranged.push_back(target);
224 melee.remove(target);
225 }
226
227 if (!ranged.empty())
228 {
229 Trinity::Containers::RandomResize(ranged, RAID_MODE<uint32>(1, 3, 1, 3));
230 for (std::list<Unit*>::iterator itr = ranged.begin(); itr != ranged.end(); ++itr)
231 DoCast(*itr, SPELL_VILE_GAS);
232 }
233
235 break;
236 }
237 case EVENT_GAS_SPORE:
240 me->CastSpell(me, SPELL_GAS_SPORE, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 3, 2, 3)));
243 break;
247 break;
248 case EVENT_BERSERK:
251 break;
252 default:
253 break;
254 }
255
257 return;
258 }
259
261 }
262
263 void SetData(uint32 type, uint32 data) override
264 {
265 if (type == DATA_INOCULATED_STACK && data > _maxInoculatedStack)
266 _maxInoculatedStack = data;
267 }
268
269 uint32 GetData(uint32 type) const override
270 {
271 if (type == DATA_INOCULATED_STACK)
273
274 return 0;
275 }
276
278 {
280 for (uint8 i = 0; i < 3; ++i)
281 {
283 gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
284 }
285 }
286
287private:
291};
292
293// 37025 - Stinky
295{
296 npc_stinky_icc(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
297
298 void Reset() override
299 {
300 _events.Reset();
303 }
304
305 void JustEngagedWith(Unit* /*target*/) override
306 {
308 }
309
310 void UpdateAI(uint32 diff) override
311 {
312 if (!UpdateVictim())
313 return;
314
315 _events.Update(diff);
316
318 return;
319
320 while (uint32 eventId = _events.ExecuteEvent())
321 {
322 switch (eventId)
323 {
324 case EVENT_DECIMATE:
327 break;
331 break;
332 default:
333 break;
334 }
335 }
336
338 }
339
340 void JustDied(Unit* /*killer*/) override
341 {
343 if (festergut->IsAlive())
344 festergut->AI()->Talk(SAY_STINKY_DEAD);
345 }
346
347private:
350};
351
352// 69195, 71219, 73031, 73032 - Pungent Blight
354{
356
357 bool Load() override
358 {
359 return GetCaster()->GetTypeId() == TYPEID_UNIT;
360 }
361
362 void HandleScript(SpellEffIndex /*effIndex*/)
363 {
364 // Get Inhaled Blight id for our difficulty
365 uint32 blightId = sSpellMgr->GetSpellIdForDifficulty(uint32(GetEffectValue()), GetCaster());
366
367 // ...and remove it
368 GetCaster()->RemoveAurasDueToSpell(blightId);
370 }
371
372 void Register() override
373 {
375 }
376};
377
378// 72219, 72551, 72552, 72553 - Gastric Bloat
380{
382
383 bool Validate(SpellInfo const* /*spell*/) override
384 {
386 }
387
388 void HandleScript(SpellEffIndex /*effIndex*/)
389 {
390 Aura const* aura = GetHitUnit()->GetAura(GetSpellInfo()->Id);
391 if (!(aura && aura->GetStackAmount() == 10))
392 return;
393
396 }
397
398 void Register() override
399 {
401 }
402};
403
404// 69290, 71222, 73033, 73034 - Blighted Spores
406{
408
409 bool Validate(SpellInfo const* /*spell*/) override
410 {
412 }
413
414 void ExtraEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
415 {
417 if (InstanceScript* instance = GetTarget()->GetInstanceScript())
418 if (Creature* festergut = ObjectAccessor::GetCreature(*GetTarget(), instance->GetGuidData(DATA_FESTERGUT)))
419 festergut->AI()->SetData(DATA_INOCULATED_STACK, GetStackAmount());
420
422 }
423
425 {
426 Player* target = GetUnitOwner()->ToPlayer();
427 if (!target)
428 return;
429
431 return;
432
434 if (target->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE)
435 return;
436
438 }
439
440 void Register() override
441 {
443 }
444};
445
447{
448 public:
449 achievement_flu_shot_shortage() : AchievementCriteriaScript("achievement_flu_shot_shortage") { }
450
451 bool OnCheck(Player* /*source*/, Unit* target) override
452 {
453 if (target && target->GetTypeId() == TYPEID_UNIT)
454 return target->ToCreature()->AI()->GetData(DATA_INOCULATED_STACK) < 3;
455
456 return false;
457 }
458};
459
461{
462 // Creatures
465
466 // Spells
470
471 // Achievements
473}
uint8_t uint8
Definition: Define.h:135
uint32_t uint32
Definition: Define.h:133
@ FAIL
@ TYPEID_UNIT
Definition: ObjectGuid.h:38
@ TYPEID_PLAYER
Definition: ObjectGuid.h:39
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:107
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1129
SpellEffIndex
Definition: SharedDefines.h:30
@ EFFECT_1
Definition: SharedDefines.h:32
@ EFFECT_0
Definition: SharedDefines.h:31
@ EFFECT_2
Definition: SharedDefines.h:33
@ SPELL_EFFECT_SCRIPT_EFFECT
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
@ SPELL_AURA_PERIODIC_DAMAGE
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:168
@ SPELLVALUE_MAX_TARGETS
Definition: SpellDefines.h:136
#define sSpellMgr
Definition: SpellMgr.h:738
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:384
#define AuraEffectRemoveFn(F, I, N, M)
Definition: SpellScript.h:809
@ UNIT_STATE_CASTING
Definition: Unit.h:235
FestergutSpells
@ SPELL_VILE_GAS
@ SPELL_PLAGUE_STENCH
@ SPELL_GASTRIC_EXPLOSION
@ SPELL_INHALE_BLIGHT
@ SPELL_GAS_SPORE
@ SPELL_GASTRIC_BLOAT
@ SPELL_INOCULATED
@ SPELL_DECIMATE
@ SPELL_MORTAL_WOUND
@ SPELL_PUNGENT_BLIGHT
uint32 const gaseousBlight[3]
#define INOCULATED_HELPER
#define PUNGENT_BLIGHT_HELPER
FestergutTexts
@ SAY_DEATH
@ EMOTE_PUNGENT_BLIGHT
@ SAY_AGGRO
@ EMOTE_GAS_SPORE
@ SAY_PUNGENT_BLIGHT
@ EMOTE_WARN_GAS_SPORE
@ SAY_KILL
@ EMOTE_WARN_PUNGENT_BLIGHT
@ SAY_STINKY_DEAD
@ SAY_BERSERK
FestergutEvents
@ EVENT_VILE_GAS
@ EVENT_MORTAL_WOUND
@ EVENT_GASTRIC_BLOAT
@ EVENT_BERSERK
@ EVENT_GAS_SPORE
@ EVENT_INHALE_BLIGHT
@ EVENT_DECIMATE
FestergutMisc
@ DATA_INOCULATED_STACK
void AddSC_boss_festergut()
uint32 const gaseousBlightVisual[3]
Unit * GetTarget() const
HookList< EffectApplyHandler > OnEffectRemove
Definition: SpellScript.h:804
Unit * GetUnitOwner() const
uint8 GetStackAmount() const
uint8 GetStackAmount() const
Definition: SpellAuras.h:164
InstanceScript *const instance
void _JustReachedHome()
EventMap events
void _JustDied()
@ EVADE_REASON_OTHER
Definition: CreatureAI.h:97
void DoZoneInCombat(Creature *creature=nullptr)
Definition: CreatureAI.cpp:73
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:48
bool UpdateVictim()
Definition: CreatureAI.cpp:240
Creature *const me
Definition: CreatureAI.h:81
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
Definition: CreatureAI.cpp:214
CreatureAI * AI() const
Definition: Creature.h:154
void Update(uint32 time)
Definition: EventMap.h:67
EventId ExecuteEvent()
Definition: EventMap.cpp:73
void RescheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition: EventMap.cpp:52
void ScheduleEvent(EventId eventId, Milliseconds time, GroupIndex group=0u, PhaseIndex phase=0u)
Definition: EventMap.cpp:36
void Reset()
Definition: EventMap.cpp:21
virtual bool SetBossState(uint32 id, EncounterState state)
void DoCastSpellOnPlayers(uint32 spell, bool includePets=false, bool includeControlled=false)
virtual ObjectGuid GetGuidData(uint32 type) const override
virtual bool CheckRequiredBosses(uint32, Player const *=nullptr) const
bool Is25ManRaid() const
Definition: Map.cpp:4259
static Creature * ToCreature(Object *o)
Definition: Object.h:185
static Unit * ToUnit(Object *o)
Definition: Object.h:191
TypeID GetTypeId() const
Definition: Object.h:92
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:77
static Player * ToPlayer(Object *o)
Definition: Object.h:179
Definition: Player.h:915
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: Player.cpp:15775
uint32 Id
Definition: SpellInfo.h:293
Unit * GetCaster() const
Unit * GetHitUnit() const
int32 GetEffectValue() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:382
SpellInfo const * GetSpellInfo() const
void DoMeleeAttackIfReady()
Definition: UnitAI.cpp:62
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:241
virtual uint32 GetData(uint32) const
Definition: UnitAI.h:155
SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.cpp:174
void SelectTargetList(std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:109
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:114
Definition: Unit.h:769
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:4435
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:4531
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3780
bool HasUnitState(const uint32 f) const
Definition: Unit.h:874
Map * GetMap() const
Definition: Object.h:449
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2831
void setActive(bool isActiveObject)
Definition: Object.cpp:980
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2099
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:145
bool OnCheck(Player *, Unit *target) override
void ExtraEffect(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
PrepareAuraScript(spell_festergut_blighted_spores)
void HandleScript(SpellEffIndex)
bool Validate(SpellInfo const *) override
PrepareSpellScript(spell_festergut_gastric_bloat)
void HandleScript(SpellEffIndex)
PrepareSpellScript(spell_festergut_pungent_blight)
@ SPELL_ORANGE_BLIGHT_RESIDUE
@ SPELL_BERSERK2
@ LIGHT_S_HAMMER_TELEPORT
#define RegisterIcecrownCitadelCreatureAI(ai_name)
@ ACTION_FESTERGUT_DEATH
@ ACTION_FESTERGUT_GAS
@ ACTION_FESTERGUT_COMBAT
@ DATA_PROFESSOR_PUTRICIDE
@ DATA_FESTERGUT
@ NPC_GAS_DUMMY
@ QUEST_RESIDUE_RENDEZVOUS_10
@ QUEST_RESIDUE_RENDEZVOUS_25
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:108
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:66
void SpellHitTarget(WorldObject *target, SpellInfo const *spellInfo) override
void UpdateAI(uint32 diff) override
void JustReachedHome() override
uint32 _maxInoculatedStack
void KilledUnit(Unit *victim) override
uint32 GetData(uint32 type) const override
void SetData(uint32 type, uint32 data) override
void Reset() override
ObjectGuid _gasDummyGUID
void JustDied(Unit *) override
void EnterEvadeMode(EvadeReason why) override
void JustEngagedWith(Unit *who) override
boss_festergut(Creature *creature)
void Reset() override
void JustEngagedWith(Unit *) override
npc_stinky_icc(Creature *creature)
void JustDied(Unit *) override
void UpdateAI(uint32 diff) override
InstanceScript * _instance