/* * 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 "black_temple.h" #include "MotionMaster.h" #include "PassiveAI.h" #include "ScriptedCreature.h" enum Texts { EMOTE_NEW_TARGET = 0, EMOTE_PUNCH_GROUND = 1, EMOTE_GROUND_CRACK = 2 }; enum Spells { SPELL_MOLTEN_PUNCH = 40126, SPELL_HATEFUL_STRIKE = 41926, SPELL_MOLTEN_FLAME = 40980, SPELL_VOLCANIC_ERUPTION = 40117, SPELL_VOLCANIC_SUMMON = 40276, SPELL_VOLCANIC_GEYSER = 42055, SPELL_BERSERK = 45078, SPELL_SNARE_SELF = 41922, SPELL_CHARGE = 41581 }; enum Events { EVENT_BERSERK = 1, EVENT_SWITCH_PHASE, EVENT_FLAME, EVENT_VOLCANO, EVENT_SWITCH_TARGET, EVENT_HATEFUL_STRIKE }; enum Phases { PHASE_INITIAL = 1, PHASE_STRIKE = 2, PHASE_CHASE = 3 }; enum Actions { ACTION_DISABLE_VULCANO = 1 }; struct boss_supremus : public BossAI { boss_supremus(Creature* creature) : BossAI(creature, DATA_SUPREMUS) { } void Reset() override { _Reset(); events.SetPhase(PHASE_INITIAL); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); } void EnterEvadeMode(EvadeReason /*why*/) override { summons.DespawnAll(); _DespawnAtEvade(); } void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); ChangePhase(); events.ScheduleEvent(EVENT_BERSERK, 15min); events.ScheduleEvent(EVENT_FLAME, 20s); } void ChangePhase() { if (events.IsInPhase(PHASE_INITIAL) || events.IsInPhase(PHASE_CHASE)) { events.SetPhase(PHASE_STRIKE); DummyEntryCheckPredicate pred; summons.DoAction(ACTION_DISABLE_VULCANO, pred); events.ScheduleEvent(EVENT_HATEFUL_STRIKE, Seconds(2), 0, PHASE_STRIKE); me->RemoveAurasDueToSpell(SPELL_SNARE_SELF); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); } else { events.SetPhase(PHASE_CHASE); events.ScheduleEvent(EVENT_VOLCANO, Seconds(5), 0, PHASE_CHASE); events.ScheduleEvent(EVENT_SWITCH_TARGET, Seconds(10), 0, PHASE_CHASE); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); DoCast(SPELL_SNARE_SELF); } ResetThreatList(); DoZoneInCombat(); events.ScheduleEvent(EVENT_SWITCH_PHASE, 1min); } Unit* CalculateHatefulStrikeTarget() { uint64 health = 0; Unit* target = nullptr; for (auto* ref : me->GetThreatManager().GetUnsortedThreatList()) { Unit* unit = ref->GetVictim(); if (me->IsWithinMeleeRange(unit)) { if (unit->GetHealth() > health) { health = unit->GetHealth(); target = unit; } } } return target; } void ExecuteEvent(uint32 eventId) override { switch (eventId) { case EVENT_BERSERK: DoCastSelf(SPELL_BERSERK, true); break; case EVENT_FLAME: DoCast(SPELL_MOLTEN_PUNCH); events.Repeat(Seconds(15), Seconds(20)); break; case EVENT_HATEFUL_STRIKE: if (Unit* target = CalculateHatefulStrikeTarget()) DoCast(target, SPELL_HATEFUL_STRIKE); events.Repeat(Seconds(5)); break; case EVENT_SWITCH_TARGET: if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true)) { ResetThreatList(); AddThreat(target, 1000000.0f); DoCast(target, SPELL_CHARGE); Talk(EMOTE_NEW_TARGET); } events.Repeat(Seconds(10)); break; case EVENT_VOLCANO: DoCastAOE(SPELL_VOLCANIC_SUMMON, true); Talk(EMOTE_GROUND_CRACK); events.Repeat(Seconds(10)); break; case EVENT_SWITCH_PHASE: ChangePhase(); break; default: break; } } }; struct npc_molten_flame : public NullCreatureAI { npc_molten_flame(Creature* creature) : NullCreatureAI(creature) { } void InitializeAI() override { float x, y, z; me->GetNearPoint(me, x, y, z, 100.0f, frand(0.f, 2.f * float(M_PI))); me->GetMotionMaster()->MovePoint(0, x, y, z); DoCastSelf(SPELL_MOLTEN_FLAME, true); } }; struct npc_volcano : public NullCreatureAI { npc_volcano(Creature* creature) : NullCreatureAI(creature) { } void Reset() override { _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { DoCastSelf(SPELL_VOLCANIC_ERUPTION); }); } void DoAction(int32 action) override { if (action == ACTION_DISABLE_VULCANO) { me->RemoveAurasDueToSpell(SPELL_VOLCANIC_ERUPTION); me->RemoveAurasDueToSpell(SPELL_VOLCANIC_GEYSER); } } void UpdateAI(uint32 diff) override { _scheduler.Update(diff); } private: TaskScheduler _scheduler; }; void AddSC_boss_supremus() { RegisterBlackTempleCreatureAI(boss_supremus); RegisterBlackTempleCreatureAI(npc_molten_flame); RegisterBlackTempleCreatureAI(npc_volcano); }