336 lines
12 KiB
C++
336 lines
12 KiB
C++
/*
|
|
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
|
* Free Software Foundation; either version 3 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 Affero 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "ScriptMgr.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "SpellInfo.h"
|
|
#include "magtheridons_lair.h"
|
|
|
|
enum Yells
|
|
{
|
|
SAY_TAUNT = 0,
|
|
SAY_FREE = 1,
|
|
SAY_AGGRO = 2,
|
|
SAY_SLAY = 3,
|
|
SAY_BANISH = 4,
|
|
SAY_PHASE3 = 5,
|
|
SAY_DEATH = 6,
|
|
};
|
|
|
|
enum Emotes
|
|
{
|
|
SAY_EMOTE_BEGIN = 7,
|
|
SAY_EMOTE_NEARLY = 8,
|
|
SAY_EMOTE_FREE = 9,
|
|
SAY_EMOTE_NOVA = 10
|
|
};
|
|
|
|
enum Spells
|
|
{
|
|
SPELL_SHADOW_CAGE = 30205,
|
|
SPELL_BLAST_NOVA = 30616,
|
|
SPELL_CLEAVE = 30619,
|
|
SPELL_BLAZE = 30541,
|
|
SPELL_BLAZE_SUMMON = 30542,
|
|
SPELL_BERSERK = 27680,
|
|
SPELL_SHADOW_GRASP_VISUAL = 30166,
|
|
SPELL_MIND_EXHAUSTION = 44032,
|
|
SPELL_QUAKE = 30657,
|
|
SPELL_COLLAPSE_DAMAGE = 36449,
|
|
SPELL_CAMERA_SHAKE = 36455,
|
|
SPELL_DEBRIS_VISUAL = 30632,
|
|
SPELL_DEBRIS_DAMAGE = 30631
|
|
};
|
|
|
|
enum Events
|
|
{
|
|
EVENT_EMOTE1 = 1,
|
|
EVENT_EMOTE2 = 2,
|
|
EVENT_EMOTE3 = 3,
|
|
EVENT_ENTER_COMBAT = 4,
|
|
EVENT_RECENTLY_SPOKEN = 5,
|
|
|
|
EVENT_CLEAVE = 10,
|
|
EVENT_BLAST_NOVA = 11,
|
|
EVENT_BLAZE = 12,
|
|
EVENT_ENRAGE = 13,
|
|
EVENT_QUAKE = 14,
|
|
EVENT_CHECK_HEALTH = 15,
|
|
EVENT_COLLAPSE_CEIL = 16,
|
|
EVENT_COLLAPSE_DAMAGE = 17,
|
|
EVENT_DEBRIS = 18,
|
|
|
|
EVENT_RANDOM_TAUNT = 30,
|
|
EVENT_CHECK_GRASP = 31,
|
|
EVENT_CANCEL_GRASP_CHECK = 32
|
|
};
|
|
|
|
class DealDebrisDamage : public BasicEvent
|
|
{
|
|
public:
|
|
DealDebrisDamage(Creature& creature, ObjectGuid targetGUID) : _owner(creature), _targetGUID(targetGUID) { }
|
|
|
|
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
|
|
{
|
|
if (Unit* target = ObjectAccessor::GetUnit(_owner, _targetGUID))
|
|
target->CastSpell(target, SPELL_DEBRIS_DAMAGE, true, nullptr, nullptr, _owner.GetGUID());
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
Creature& _owner;
|
|
ObjectGuid _targetGUID;
|
|
};
|
|
|
|
class boss_magtheridon : public CreatureScript
|
|
{
|
|
public:
|
|
boss_magtheridon() : CreatureScript("boss_magtheridon") { }
|
|
|
|
struct boss_magtheridonAI : public BossAI
|
|
{
|
|
boss_magtheridonAI(Creature* creature) : BossAI(creature, TYPE_MAGTHERIDON) { }
|
|
|
|
EventMap events2;
|
|
|
|
void Reset() override
|
|
{
|
|
events2.Reset();
|
|
events2.ScheduleEvent(EVENT_RANDOM_TAUNT, 90000);
|
|
_Reset();
|
|
me->CastSpell(me, SPELL_SHADOW_CAGE, true);
|
|
me->SetReactState(REACT_PASSIVE);
|
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
|
|
}
|
|
|
|
void KilledUnit(Unit* /*victim*/) override
|
|
{
|
|
if (events.GetNextEventTime(EVENT_RECENTLY_SPOKEN) == 0)
|
|
{
|
|
events.ScheduleEvent(EVENT_RECENTLY_SPOKEN, 5000);
|
|
Talk(SAY_SLAY);
|
|
}
|
|
}
|
|
|
|
void JustDied(Unit* /*killer*/) override
|
|
{
|
|
_JustDied();
|
|
Talk(SAY_DEATH);
|
|
}
|
|
|
|
void MoveInLineOfSight(Unit* /*who*/) override { }
|
|
|
|
void EnterCombat(Unit* /*who*/) override
|
|
{
|
|
events2.Reset();
|
|
_EnterCombat();
|
|
events.ScheduleEvent(EVENT_EMOTE1, 0);
|
|
events.ScheduleEvent(EVENT_EMOTE2, 60000);
|
|
events.ScheduleEvent(EVENT_EMOTE3, 120000);
|
|
events.ScheduleEvent(EVENT_ENTER_COMBAT, 123000);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
events2.Update(diff);
|
|
switch (events2.ExecuteEvent())
|
|
{
|
|
case EVENT_RANDOM_TAUNT:
|
|
Talk(SAY_TAUNT);
|
|
events2.ScheduleEvent(EVENT_RANDOM_TAUNT, 90000);
|
|
break;
|
|
case EVENT_CHECK_GRASP:
|
|
if (me->GetAuraCount(SPELL_SHADOW_GRASP_VISUAL) == 5)
|
|
{
|
|
Talk(SAY_BANISH);
|
|
me->InterruptNonMeleeSpells(true);
|
|
break;
|
|
}
|
|
events2.ScheduleEvent(EVENT_CHECK_GRASP, 0);
|
|
break;
|
|
}
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_EMOTE1:
|
|
Talk(SAY_EMOTE_BEGIN);
|
|
break;
|
|
case EVENT_EMOTE2:
|
|
Talk(SAY_EMOTE_NEARLY);
|
|
break;
|
|
case EVENT_EMOTE3:
|
|
Talk(SAY_EMOTE_FREE);
|
|
Talk(SAY_FREE);
|
|
break;
|
|
case EVENT_ENTER_COMBAT:
|
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
|
|
me->SetReactState(REACT_AGGRESSIVE);
|
|
events.ScheduleEvent(EVENT_CLEAVE, 9000);
|
|
events.ScheduleEvent(EVENT_BLAST_NOVA, 60000);
|
|
events.ScheduleEvent(EVENT_BLAZE, 10000);
|
|
events.ScheduleEvent(EVENT_QUAKE, 40000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
|
events.ScheduleEvent(EVENT_ENRAGE, 22 * MINUTE * IN_MILLISECONDS);
|
|
|
|
instance->SetData(DATA_ACTIVATE_CUBES, 1);
|
|
me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE);
|
|
break;
|
|
case EVENT_CLEAVE:
|
|
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
|
events.ScheduleEvent(EVENT_CLEAVE, 10000);
|
|
break;
|
|
case EVENT_BLAST_NOVA:
|
|
me->CastSpell(me, SPELL_BLAST_NOVA, false);
|
|
events.ScheduleEvent(EVENT_BLAST_NOVA, 60000);
|
|
events.ScheduleEvent(EVENT_CANCEL_GRASP_CHECK, 12000);
|
|
events2.ScheduleEvent(EVENT_CHECK_GRASP, 0);
|
|
break;
|
|
case EVENT_BLAZE:
|
|
me->CastCustomSpell(SPELL_BLAZE, SPELLVALUE_MAX_TARGETS, 1);
|
|
events.ScheduleEvent(EVENT_BLAZE, 30000);
|
|
break;
|
|
case EVENT_ENRAGE:
|
|
me->CastSpell(me, SPELL_BERSERK, true);
|
|
break;
|
|
case EVENT_CANCEL_GRASP_CHECK:
|
|
events2.Reset();
|
|
break;
|
|
case EVENT_QUAKE:
|
|
me->CastSpell(me, SPELL_QUAKE, false);
|
|
events.ScheduleEvent(EVENT_QUAKE, 50000);
|
|
break;
|
|
case EVENT_CHECK_HEALTH:
|
|
if (me->HealthBelowPct(30))
|
|
{
|
|
Talk(SAY_PHASE3);
|
|
events.SetPhase(1);
|
|
events.DelayEvents(18000);
|
|
events.ScheduleEvent(EVENT_COLLAPSE_CEIL, 8000);
|
|
events.ScheduleEvent(EVENT_COLLAPSE_DAMAGE, 15000);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
|
break;
|
|
case EVENT_COLLAPSE_CEIL:
|
|
me->CastSpell(me, SPELL_CAMERA_SHAKE, true);
|
|
instance->SetData(DATA_COLLAPSE, GO_STATE_ACTIVE);
|
|
break;
|
|
case EVENT_COLLAPSE_DAMAGE:
|
|
me->CastSpell(me, SPELL_COLLAPSE_DAMAGE, true);
|
|
me->resetAttackTimer();
|
|
events.SetPhase(0);
|
|
events.ScheduleEvent(EVENT_DEBRIS, 20000);
|
|
break;
|
|
case EVENT_DEBRIS:
|
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
|
{
|
|
target->CastSpell(target, SPELL_DEBRIS_VISUAL, true, nullptr, nullptr, me->GetGUID());
|
|
me->m_Events.AddEvent(new DealDebrisDamage(*me, target->GetGUID()), me->m_Events.CalculateTime(5000));
|
|
}
|
|
events.ScheduleEvent(EVENT_DEBRIS, 20000);
|
|
break;
|
|
}
|
|
|
|
if (!events.IsInPhase(1))
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetMagtheridonsLairAI<boss_magtheridonAI>(creature);
|
|
}
|
|
};
|
|
|
|
class spell_magtheridon_blaze : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_magtheridon_blaze() : SpellScriptLoader("spell_magtheridon_blaze") { }
|
|
|
|
class spell_magtheridon_blaze_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_magtheridon_blaze_SpellScript);
|
|
|
|
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (Unit* target = GetHitUnit())
|
|
target->CastSpell(target, SPELL_BLAZE_SUMMON, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_magtheridon_blaze_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_magtheridon_blaze_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_magtheridon_shadow_grasp : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_magtheridon_shadow_grasp() : SpellScriptLoader("spell_magtheridon_shadow_grasp") { }
|
|
|
|
class spell_magtheridon_shadow_grasp_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_magtheridon_shadow_grasp_AuraScript)
|
|
|
|
void HandleDummyApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
GetUnitOwner()->CastSpell((Unit*)nullptr, SPELL_SHADOW_GRASP_VISUAL, false);
|
|
}
|
|
|
|
void HandleDummyRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
GetUnitOwner()->InterruptNonMeleeSpells(true);
|
|
}
|
|
|
|
void HandlePeriodicRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_MIND_EXHAUSTION, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectApply += AuraEffectApplyFn(spell_magtheridon_shadow_grasp_AuraScript::HandleDummyApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_magtheridon_shadow_grasp_AuraScript::HandleDummyRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_magtheridon_shadow_grasp_AuraScript::HandlePeriodicRemove, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_magtheridon_shadow_grasp_AuraScript();
|
|
}
|
|
};
|
|
|
|
void AddSC_boss_magtheridon()
|
|
{
|
|
new boss_magtheridon();
|
|
new spell_magtheridon_blaze();
|
|
new spell_magtheridon_shadow_grasp();
|
|
}
|