/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "ScriptMgr.h" #include "baradin_hold.h" #include "Containers.h" #include "InstanceScript.h" #include "Map.h" #include "ScriptedCreature.h" #include "SpellAuraEffects.h" #include "SpellScript.h" enum ArgalothTexts { SAY_ANNOUNCE_FEL_FIRESTORM = 0 }; enum ArgalothSpells { SPELL_FEL_FIRESTORM = 88972, SPELL_FEL_FIRESTORM_TRIGGERED = 88973, SPELL_BERSERK = 47008, SPELL_METEOR_SLASH_VISUAL = 88949, SPELL_METEOR_SLASH = 88942, SPELL_CONSUMING_DARKNESS = 88954 }; enum ArgalothEvents { EVENT_METEOR_SLASH = 1, EVENT_CONSUMING_DARKNESS, EVENT_FEL_FIRESTORM, EVENT_END_FEL_FIRESTORM, EVENT_BERSERK }; struct boss_argaloth : public BossAI { boss_argaloth(Creature* creature) : BossAI(creature, BOSS_ARGALOTH), _felFirestormCount(0), _isInFelFirestormPhase(false) { } void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); events.ScheduleEvent(EVENT_METEOR_SLASH, 11s); events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, 6s); events.ScheduleEvent(EVENT_BERSERK, 5min); } void EnterEvadeMode(EvadeReason /*why*/) override { instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); summons.DespawnAll(); _DespawnAtEvade(); } void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override { if (damage >= me->GetHealth() || _isInFelFirestormPhase) return; if ((me->HealthBelowPctDamaged(66, damage) && _felFirestormCount == 0) || (me->HealthBelowPctDamaged(33, damage) && _felFirestormCount == 1)) { events.ScheduleEvent(EVENT_FEL_FIRESTORM, 1ms); ++_felFirestormCount; } } void JustDied(Unit* /*killer*/) override { _JustDied(); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CONSUMING_DARKNESS); } 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) { case EVENT_METEOR_SLASH: DoCastSelf(SPELL_METEOR_SLASH_VISUAL); DoCastAOE(SPELL_METEOR_SLASH); events.ScheduleEvent(EVENT_METEOR_SLASH, 17s); break; case EVENT_CONSUMING_DARKNESS: DoCastAOE(SPELL_CONSUMING_DARKNESS, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_MAX_TARGETS, Is25ManRaid() ? 8 : 3)); events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, 22s, 24s); break; case EVENT_FEL_FIRESTORM: me->AttackStop(); me->SetReactState(REACT_PASSIVE); Talk(SAY_ANNOUNCE_FEL_FIRESTORM); DoCastAOE(SPELL_FEL_FIRESTORM); events.ScheduleEvent(EVENT_END_FEL_FIRESTORM, 21s); events.CancelEvent(EVENT_METEOR_SLASH); events.CancelEvent(EVENT_CONSUMING_DARKNESS); _isInFelFirestormPhase = true; break; case EVENT_END_FEL_FIRESTORM: me->SetReactState(REACT_AGGRESSIVE); instance->SetData(DATA_EXTINUISH_FEL_FLAMES, 0); events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, 6s); events.ScheduleEvent(EVENT_METEOR_SLASH, 9s); _isInFelFirestormPhase = false; break; case EVENT_BERSERK: DoCastSelf(SPELL_BERSERK); break; default: break; } if (me->HasUnitState(UNIT_STATE_CASTING)) return; } } private: uint8 _felFirestormCount; bool _isInFelFirestormPhase; }; // 88954 - Consuming Darkness class spell_argaloth_consuming_darkness : public AuraScript { void HandlePeriodic(AuraEffect const* /*aurEff*/) { if (AuraEffect* aurEff = GetEffect(EFFECT_0)) { int32 damage = aurEff->GetAmount() + CalculatePct(aurEff->GetAmount(), 10); aurEff->SetAmount(damage); } } void Register() override { OnEffectPeriodic += AuraEffectPeriodicFn(spell_argaloth_consuming_darkness::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); } }; // 88972 - Fel Firestorm class spell_argaloth_fel_firestorm : public AuraScript { bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo({ SPELL_FEL_FIRESTORM_TRIGGERED }); } void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { GetTarget()->CastSpell(nullptr, SPELL_FEL_FIRESTORM_TRIGGERED); } void Register() override { AfterEffectApply += AuraEffectApplyFn(spell_argaloth_fel_firestorm::AfterApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); } }; // 88987 - Fel Firestorm class spell_argaloth_fel_firestorm_forcecast : public SpellScript { void FilterTargets(std::list& targets) { if (targets.empty()) return; size_t targetSize = GetCaster()->GetMap()->Is25ManRaid() ? 8 : 3; if (targets.size() > targetSize) Trinity::Containers::RandomResize(targets, targetSize); } void Register() override { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_argaloth_fel_firestorm_forcecast::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); } }; void AddSC_boss_argaloth() { RegisterBaradinHoldCreatureAI(boss_argaloth); RegisterSpellScript(spell_argaloth_consuming_darkness); RegisterSpellScript(spell_argaloth_fel_firestorm); RegisterSpellScript(spell_argaloth_fel_firestorm_forcecast); }