diff options
-rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp | 677 |
1 files changed, 312 insertions, 365 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index f27d4746d7f..4c101038c01 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -79,415 +79,357 @@ enum Misc DATA_INOCULATED_STACK = 69291 }; -class boss_festergut : public CreatureScript +struct boss_festergut : public BossAI { - public: - boss_festergut() : CreatureScript("boss_festergut") { } - - struct boss_festergutAI : public BossAI + boss_festergut(Creature* creature) : BossAI(creature, DATA_FESTERGUT) + { + _maxInoculatedStack = 0; + _inhaleCounter = 0; + } + + void Reset() override + { + _Reset(); + events.ScheduleEvent(EVENT_BERSERK, 5min); + events.ScheduleEvent(EVENT_INHALE_BLIGHT, 25s, 30s); + events.ScheduleEvent(EVENT_GAS_SPORE, 20s, 25s); + events.ScheduleEvent(EVENT_GASTRIC_BLOAT, 12500ms, 15s); + _maxInoculatedStack = 0; + _inhaleCounter = 0; + me->RemoveAurasDueToSpell(SPELL_BERSERK2); + if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true)) { - boss_festergutAI(Creature* creature) : BossAI(creature, DATA_FESTERGUT) + _gasDummyGUID = gasDummy->GetGUID(); + for (uint8 i = 0; i < 3; ++i) { - _maxInoculatedStack = 0; - _inhaleCounter = 0; + me->RemoveAurasDueToSpell(gaseousBlight[i]); + gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]); } + } + } - void Reset() override + void JustEngagedWith(Unit* who) override + { + if (!instance->CheckRequiredBosses(DATA_FESTERGUT, who->ToPlayer())) + { + EnterEvadeMode(EVADE_REASON_OTHER); + instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); + return; + } + + me->setActive(true); + Talk(SAY_AGGRO); + if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true)) + _gasDummyGUID = gasDummy->GetGUID(); + if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) + professor->AI()->DoAction(ACTION_FESTERGUT_COMBAT); + DoZoneInCombat(); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) + professor->AI()->DoAction(ACTION_FESTERGUT_DEATH); + + RemoveBlight(); + } + + void JustReachedHome() override + { + _JustReachedHome(); + instance->SetBossState(DATA_FESTERGUT, FAIL); + } + + void EnterEvadeMode(EvadeReason why) override + { + ScriptedAI::EnterEvadeMode(why); + if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) + professor->AI()->EnterEvadeMode(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_KILL); + } + + void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override + { + Unit* unitTarget = target->ToUnit(); + if (!unitTarget) + return; + + if (spellInfo->Id == PUNGENT_BLIGHT_HELPER) + unitTarget->RemoveAurasDueToSpell(INOCULATED_HELPER); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - _Reset(); - events.ScheduleEvent(EVENT_BERSERK, 5min); - events.ScheduleEvent(EVENT_INHALE_BLIGHT, 25s, 30s); - events.ScheduleEvent(EVENT_GAS_SPORE, 20s, 25s); - events.ScheduleEvent(EVENT_GASTRIC_BLOAT, 12500ms, 15s); - _maxInoculatedStack = 0; - _inhaleCounter = 0; - me->RemoveAurasDueToSpell(SPELL_BERSERK2); - if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true)) + case EVENT_INHALE_BLIGHT: { - _gasDummyGUID = gasDummy->GetGUID(); - for (uint8 i = 0; i < 3; ++i) + RemoveBlight(); + if (_inhaleCounter == 3) { - me->RemoveAurasDueToSpell(gaseousBlight[i]); - gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]); + Talk(EMOTE_WARN_PUNGENT_BLIGHT); + Talk(SAY_PUNGENT_BLIGHT); + DoCastSelf(SPELL_PUNGENT_BLIGHT); + _inhaleCounter = 0; + if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) + professor->AI()->DoAction(ACTION_FESTERGUT_GAS); + events.RescheduleEvent(EVENT_GAS_SPORE, 20s, 25s); + } + else + { + DoCastSelf(SPELL_INHALE_BLIGHT); + // just cast and dont bother with target, conditions will handle it + ++_inhaleCounter; + if (_inhaleCounter < 3) + me->CastSpell(me, gaseousBlight[_inhaleCounter], CastSpellExtraArgs(TRIGGERED_FULL_MASK) + .SetOriginalCaster(me->GetGUID())); } - } - } - void JustEngagedWith(Unit* who) override - { - if (!instance->CheckRequiredBosses(DATA_FESTERGUT, who->ToPlayer())) - { - EnterEvadeMode(EVADE_REASON_OTHER); - instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT); - return; + events.ScheduleEvent(EVENT_INHALE_BLIGHT, 33500ms, 35s); + break; } - - me->setActive(true); - Talk(SAY_AGGRO); - if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true)) - _gasDummyGUID = gasDummy->GetGUID(); - if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) - professor->AI()->DoAction(ACTION_FESTERGUT_COMBAT); - DoZoneInCombat(); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) - professor->AI()->DoAction(ACTION_FESTERGUT_DEATH); - - RemoveBlight(); - } - - void JustReachedHome() override - { - _JustReachedHome(); - instance->SetBossState(DATA_FESTERGUT, FAIL); - } - - void EnterEvadeMode(EvadeReason why) override - { - ScriptedAI::EnterEvadeMode(why); - if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) - professor->AI()->EnterEvadeMode(); - } - - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_KILL); - } - - void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override - { - Unit* unitTarget = target->ToUnit(); - if (!unitTarget) - return; - - if (spellInfo->Id == PUNGENT_BLIGHT_HELPER) - unitTarget->RemoveAurasDueToSpell(INOCULATED_HELPER); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) + case EVENT_VILE_GAS: { - switch (eventId) + std::list<Unit*> ranged, melee; + uint32 minTargets = RAID_MODE<uint32>(3, 8, 3, 8); + SelectTargetList(ranged, 25, SelectTargetMethod::Random, 0, -5.0f, true); + SelectTargetList(melee, 25, SelectTargetMethod::Random, 0, 5.0f, true); + while (ranged.size() < minTargets) { - case EVENT_INHALE_BLIGHT: - { - RemoveBlight(); - if (_inhaleCounter == 3) - { - Talk(EMOTE_WARN_PUNGENT_BLIGHT); - Talk(SAY_PUNGENT_BLIGHT); - DoCast(me, SPELL_PUNGENT_BLIGHT); - _inhaleCounter = 0; - if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) - professor->AI()->DoAction(ACTION_FESTERGUT_GAS); - events.RescheduleEvent(EVENT_GAS_SPORE, 20s, 25s); - } - else - { - DoCast(me, SPELL_INHALE_BLIGHT); - // just cast and dont bother with target, conditions will handle it - ++_inhaleCounter; - if (_inhaleCounter < 3) - me->CastSpell(me, gaseousBlight[_inhaleCounter], CastSpellExtraArgs(TRIGGERED_FULL_MASK) - .SetOriginalCaster(me->GetGUID())); - } - - events.ScheduleEvent(EVENT_INHALE_BLIGHT, 33500ms, 35s); - break; - } - case EVENT_VILE_GAS: - { - std::list<Unit*> ranged, melee; - uint32 minTargets = RAID_MODE<uint32>(3, 8, 3, 8); - SelectTargetList(ranged, 25, SelectTargetMethod::Random, 0, -5.0f, true); - SelectTargetList(melee, 25, SelectTargetMethod::Random, 0, 5.0f, true); - while (ranged.size() < minTargets) - { - if (melee.empty()) - break; - - Unit* target = Trinity::Containers::SelectRandomContainerElement(melee); - ranged.push_back(target); - melee.remove(target); - } - - if (!ranged.empty()) - { - Trinity::Containers::RandomResize(ranged, RAID_MODE<uint32>(1, 3, 1, 3)); - for (std::list<Unit*>::iterator itr = ranged.begin(); itr != ranged.end(); ++itr) - DoCast(*itr, SPELL_VILE_GAS); - } - - events.ScheduleEvent(EVENT_VILE_GAS, 28s, 35s); - break; - } - case EVENT_GAS_SPORE: - Talk(EMOTE_WARN_GAS_SPORE); - Talk(EMOTE_GAS_SPORE); - me->CastSpell(me, SPELL_GAS_SPORE, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 3, 2, 3))); - events.ScheduleEvent(EVENT_GAS_SPORE, 40s, 45s); - events.RescheduleEvent(EVENT_VILE_GAS, 28s, 35s); + if (melee.empty()) break; - case EVENT_GASTRIC_BLOAT: - DoCastVictim(SPELL_GASTRIC_BLOAT); - events.ScheduleEvent(EVENT_GASTRIC_BLOAT, 15s, 17500ms); - break; - case EVENT_BERSERK: - DoCast(me, SPELL_BERSERK2); - Talk(SAY_BERSERK); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - - void SetData(uint32 type, uint32 data) override - { - if (type == DATA_INOCULATED_STACK && data > _maxInoculatedStack) - _maxInoculatedStack = data; - } - - uint32 GetData(uint32 type) const override - { - if (type == DATA_INOCULATED_STACK) - return uint32(_maxInoculatedStack); - - return 0; - } - void RemoveBlight() - { - if (Creature* gasDummy = ObjectAccessor::GetCreature(*me, _gasDummyGUID)) - for (uint8 i = 0; i < 3; ++i) - { - me->RemoveAurasDueToSpell(gaseousBlight[i]); - gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]); + Unit* target = Trinity::Containers::SelectRandomContainerElement(melee); + ranged.push_back(target); + melee.remove(target); } - } - - private: - ObjectGuid _gasDummyGUID; - uint32 _maxInoculatedStack; - uint32 _inhaleCounter; - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI<boss_festergutAI>(creature); - } -}; - -class npc_stinky_icc : public CreatureScript -{ - public: - npc_stinky_icc() : CreatureScript("npc_stinky_icc") { } - - struct npc_stinky_iccAI : public ScriptedAI - { - npc_stinky_iccAI(Creature* creature) : ScriptedAI(creature) - { - _instance = creature->GetInstanceScript(); - } - - void Reset() override - { - _events.Reset(); - _events.ScheduleEvent(EVENT_DECIMATE, 20s, 25s); - _events.ScheduleEvent(EVENT_MORTAL_WOUND, 3s, 7s); - } - - void JustEngagedWith(Unit* /*target*/) override - { - DoCast(me, SPELL_PLAGUE_STENCH); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) + if (!ranged.empty()) { - case EVENT_DECIMATE: - DoCastVictim(SPELL_DECIMATE); - _events.ScheduleEvent(EVENT_DECIMATE, 20s, 25s); - break; - case EVENT_MORTAL_WOUND: - DoCastVictim(SPELL_MORTAL_WOUND); - _events.ScheduleEvent(EVENT_MORTAL_WOUND, 10s, 12500ms); - break; - default: - break; + Trinity::Containers::RandomResize(ranged, RAID_MODE<uint32>(1, 3, 1, 3)); + for (std::list<Unit*>::iterator itr = ranged.begin(); itr != ranged.end(); ++itr) + DoCast(*itr, SPELL_VILE_GAS); } - } - - DoMeleeAttackIfReady(); - } - void JustDied(Unit* /*killer*/) override - { - if (Creature* festergut = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FESTERGUT))) - if (festergut->IsAlive()) - festergut->AI()->Talk(SAY_STINKY_DEAD); + events.ScheduleEvent(EVENT_VILE_GAS, 28s, 35s); + break; + } + case EVENT_GAS_SPORE: + Talk(EMOTE_WARN_GAS_SPORE); + Talk(EMOTE_GAS_SPORE); + me->CastSpell(me, SPELL_GAS_SPORE, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 3, 2, 3))); + events.ScheduleEvent(EVENT_GAS_SPORE, 40s, 45s); + events.RescheduleEvent(EVENT_VILE_GAS, 28s, 35s); + break; + case EVENT_GASTRIC_BLOAT: + DoCastVictim(SPELL_GASTRIC_BLOAT); + events.ScheduleEvent(EVENT_GASTRIC_BLOAT, 15s, 17500ms); + break; + case EVENT_BERSERK: + DoCastSelf(SPELL_BERSERK2); + Talk(SAY_BERSERK); + break; + default: + break; } - private: - EventMap _events; - InstanceScript* _instance; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetIcecrownCitadelAI<npc_stinky_iccAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } -}; -class spell_festergut_pungent_blight : public SpellScriptLoader -{ - public: - spell_festergut_pungent_blight() : SpellScriptLoader("spell_festergut_pungent_blight") { } + DoMeleeAttackIfReady(); + } - class spell_festergut_pungent_blight_SpellScript : public SpellScript - { - PrepareSpellScript(spell_festergut_pungent_blight_SpellScript); + void SetData(uint32 type, uint32 data) override + { + if (type == DATA_INOCULATED_STACK && data > _maxInoculatedStack) + _maxInoculatedStack = data; + } - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_UNIT; - } + uint32 GetData(uint32 type) const override + { + if (type == DATA_INOCULATED_STACK) + return uint32(_maxInoculatedStack); - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->RemoveAurasDueToSpell(uint32(GetEffectValue())); - GetCaster()->ToCreature()->AI()->Talk(EMOTE_PUNGENT_BLIGHT); - } + return 0; + } - void Register() override + void RemoveBlight() + { + if (Creature* gasDummy = ObjectAccessor::GetCreature(*me, _gasDummyGUID)) + for (uint8 i = 0; i < 3; ++i) { - OnEffectHitTarget += SpellEffectFn(spell_festergut_pungent_blight_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + me->RemoveAurasDueToSpell(gaseousBlight[i]); + gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]); } - }; + } - SpellScript* GetSpellScript() const override - { - return new spell_festergut_pungent_blight_SpellScript(); - } +private: + ObjectGuid _gasDummyGUID; + uint32 _maxInoculatedStack; + uint32 _inhaleCounter; }; -class spell_festergut_gastric_bloat : public SpellScriptLoader +struct npc_stinky_icc : public ScriptedAI { - public: - spell_festergut_gastric_bloat() : SpellScriptLoader("spell_festergut_gastric_bloat") { } + npc_stinky_icc(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - class spell_festergut_gastric_bloat_SpellScript : public SpellScript - { - PrepareSpellScript(spell_festergut_gastric_bloat_SpellScript); + void Reset() override + { + _events.Reset(); + _events.ScheduleEvent(EVENT_DECIMATE, 20s, 25s); + _events.ScheduleEvent(EVENT_MORTAL_WOUND, 3s, 7s); + } - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_GASTRIC_EXPLOSION }); - } + void JustEngagedWith(Unit* /*target*/) override + { + DoCastSelf(SPELL_PLAGUE_STENCH); + } - void HandleScript(SpellEffIndex /*effIndex*/) - { - Aura const* aura = GetHitUnit()->GetAura(GetSpellInfo()->Id); - if (!(aura && aura->GetStackAmount() == 10)) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Id); - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GASTRIC_EXPLOSION, true); - } + _events.Update(diff); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_festergut_gastric_bloat_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - SpellScript* GetSpellScript() const override + while (uint32 eventId = _events.ExecuteEvent()) { - return new spell_festergut_gastric_bloat_SpellScript(); - } -}; - -class spell_festergut_blighted_spores : public SpellScriptLoader -{ - public: - spell_festergut_blighted_spores() : SpellScriptLoader("spell_festergut_blighted_spores") { } - - class spell_festergut_blighted_spores_AuraScript : public AuraScript - { - PrepareAuraScript(spell_festergut_blighted_spores_AuraScript); - - bool Validate(SpellInfo const* /*spell*/) override + switch (eventId) { - return ValidateSpellInfo({ SPELL_INOCULATED }); - } - - void ExtraEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_INOCULATED, true); - if (InstanceScript* instance = GetTarget()->GetInstanceScript()) - if (Creature* festergut = ObjectAccessor::GetCreature(*GetTarget(), instance->GetGuidData(DATA_FESTERGUT))) - festergut->AI()->SetData(DATA_INOCULATED_STACK, GetStackAmount()); - - HandleResidue(); + case EVENT_DECIMATE: + DoCastVictim(SPELL_DECIMATE); + _events.ScheduleEvent(EVENT_DECIMATE, 20s, 25s); + break; + case EVENT_MORTAL_WOUND: + DoCastVictim(SPELL_MORTAL_WOUND); + _events.ScheduleEvent(EVENT_MORTAL_WOUND, 10s, 12500ms); + break; + default: + break; } + } - void HandleResidue() - { - Player* target = GetUnitOwner()->ToPlayer(); - if (!target) - return; + DoMeleeAttackIfReady(); + } - if (target->HasAura(SPELL_ORANGE_BLIGHT_RESIDUE)) - return; + void JustDied(Unit* /*killer*/) override + { + if (Creature* festergut = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FESTERGUT))) + if (festergut->IsAlive()) + festergut->AI()->Talk(SAY_STINKY_DEAD); + } - uint32 questId = target->GetMap()->Is25ManRaid() ? QUEST_RESIDUE_RENDEZVOUS_25 : QUEST_RESIDUE_RENDEZVOUS_10; - if (target->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE) - return; +private: + EventMap _events; + InstanceScript* _instance; +}; - target->CastSpell(target, SPELL_ORANGE_BLIGHT_RESIDUE, TRIGGERED_FULL_MASK); - } +class spell_festergut_pungent_blight : public SpellScript +{ + PrepareSpellScript(spell_festergut_pungent_blight); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->RemoveAurasDueToSpell(uint32(GetEffectValue())); + GetCaster()->ToCreature()->AI()->Talk(EMOTE_PUNGENT_BLIGHT); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_festergut_pungent_blight::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_festergut_blighted_spores_AuraScript::ExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - } - }; +class spell_festergut_gastric_bloat : public SpellScript +{ + PrepareSpellScript(spell_festergut_gastric_bloat); + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_GASTRIC_EXPLOSION }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Aura const* aura = GetHitUnit()->GetAura(GetSpellInfo()->Id); + if (!(aura && aura->GetStackAmount() == 10)) + return; + + GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Id); + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GASTRIC_EXPLOSION, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_festergut_gastric_bloat::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; - AuraScript* GetAuraScript() const override - { - return new spell_festergut_blighted_spores_AuraScript(); - } +class spell_festergut_blighted_spores : public AuraScript +{ + PrepareAuraScript(spell_festergut_blighted_spores); + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_INOCULATED, SPELL_ORANGE_BLIGHT_RESIDUE }); + } + + void ExtraEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_INOCULATED, true); + if (InstanceScript* instance = GetTarget()->GetInstanceScript()) + if (Creature* festergut = ObjectAccessor::GetCreature(*GetTarget(), instance->GetGuidData(DATA_FESTERGUT))) + festergut->AI()->SetData(DATA_INOCULATED_STACK, GetStackAmount()); + + HandleResidue(); + } + + void HandleResidue() + { + Player* target = GetUnitOwner()->ToPlayer(); + if (!target) + return; + + if (target->HasAura(SPELL_ORANGE_BLIGHT_RESIDUE)) + return; + + uint32 questId = target->GetMap()->Is25ManRaid() ? QUEST_RESIDUE_RENDEZVOUS_25 : QUEST_RESIDUE_RENDEZVOUS_10; + if (target->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE) + return; + + target->CastSpell(target, SPELL_ORANGE_BLIGHT_RESIDUE, TRIGGERED_FULL_MASK); + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_festergut_blighted_spores::ExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } }; class achievement_flu_shot_shortage : public AchievementCriteriaScript @@ -506,10 +448,15 @@ class achievement_flu_shot_shortage : public AchievementCriteriaScript void AddSC_boss_festergut() { - new boss_festergut(); - new npc_stinky_icc(); - new spell_festergut_pungent_blight(); - new spell_festergut_gastric_bloat(); - new spell_festergut_blighted_spores(); + // Creatures + RegisterIcecrownCitadelCreatureAI(boss_festergut); + RegisterIcecrownCitadelCreatureAI(npc_stinky_icc); + + // Spells + RegisterSpellScript(spell_festergut_pungent_blight); + RegisterSpellScript(spell_festergut_gastric_bloat); + RegisterSpellScript(spell_festergut_blighted_spores); + + // Achievements new achievement_flu_shot_shortage(); } |