287 lines
8.6 KiB
C++
287 lines
8.6 KiB
C++
/*
|
|
* Originally written by Xinef - Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
|
*/
|
|
|
|
#include "ScriptMgr.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "karazhan.h"
|
|
#include "SpellScript.h"
|
|
|
|
enum Yells
|
|
{
|
|
SAY_AGGRO = 0,
|
|
SAY_SPECIAL = 1,
|
|
SAY_KILL = 2,
|
|
SAY_DEATH = 3,
|
|
SAY_OUT_OF_COMBAT = 4,
|
|
|
|
SAY_GUEST = 0
|
|
};
|
|
|
|
enum Spells
|
|
{
|
|
SPELL_VANISH = 29448,
|
|
SPELL_GARROTE_DUMMY = 29433,
|
|
SPELL_GARROTE = 37066,
|
|
SPELL_BLIND = 34694,
|
|
SPELL_GOUGE = 29425,
|
|
SPELL_FRENZY = 37023,
|
|
SPELL_DUAL_WIELD = 29651,
|
|
SPELL_BERSERK = 26662,
|
|
SPELL_VANISH_TELEPORT = 29431,
|
|
};
|
|
|
|
enum Misc
|
|
{
|
|
EVENT_GUEST_TALK = 1,
|
|
EVENT_GUEST_TALK2 = 2,
|
|
EVENT_SPELL_VANISH = 3,
|
|
EVENT_SPELL_GARROTE = 4,
|
|
EVENT_SPELL_BLIND = 5,
|
|
EVENT_SPELL_GOUGE = 6,
|
|
EVENT_CHECK_HEALTH = 7,
|
|
EVENT_SPELL_ENRAGE = 8,
|
|
EVENT_KILL_TALK = 9,
|
|
|
|
ACTIVE_GUEST_COUNT = 4,
|
|
MAX_GUEST_COUNT = 6
|
|
};
|
|
|
|
const Position GuestsPosition[4] =
|
|
{
|
|
{-10987.38f, -1883.38f, 81.73f, 1.50f},
|
|
{-10989.60f, -1881.27f, 81.73f, 0.73f},
|
|
{-10978.81f, -1884.08f, 81.73f, 1.50f},
|
|
{-10976.38f, -1882.59f, 81.73f, 2.31f},
|
|
};
|
|
|
|
const uint32 GuestEntries[6] =
|
|
{
|
|
17007,
|
|
19872,
|
|
19873,
|
|
19874,
|
|
19875,
|
|
19876,
|
|
};
|
|
|
|
class boss_moroes : public CreatureScript
|
|
{
|
|
public:
|
|
boss_moroes() : CreatureScript("boss_moroes") { }
|
|
|
|
struct boss_moroesAI : public BossAI
|
|
{
|
|
boss_moroesAI(Creature* creature) : BossAI(creature, DATA_MOROES)
|
|
{
|
|
_activeGuests = 0;
|
|
instance = creature->GetInstanceScript();
|
|
}
|
|
|
|
InstanceScript* instance;
|
|
|
|
void InitializeAI() override
|
|
{
|
|
BossAI::InitializeAI();
|
|
InitializeGuests();
|
|
}
|
|
|
|
void JustReachedHome() override
|
|
{
|
|
BossAI::JustReachedHome();
|
|
InitializeGuests();
|
|
}
|
|
|
|
void InitializeGuests()
|
|
{
|
|
if (!me->IsAlive())
|
|
return;
|
|
|
|
if (_activeGuests == 0)
|
|
{
|
|
_activeGuests |= 0x3F;
|
|
uint8 rand1 = RAND(0x01, 0x02, 0x04);
|
|
uint8 rand2 = RAND(0x08, 0x10, 0x20);
|
|
_activeGuests &= ~(rand1 | rand2);
|
|
}
|
|
|
|
for (uint8 i = 0; i < MAX_GUEST_COUNT; ++i)
|
|
if ((1 << i) & _activeGuests)
|
|
me->SummonCreature(GuestEntries[i], GuestsPosition[summons.size()], TEMPSUMMON_MANUAL_DESPAWN);
|
|
|
|
_events2.Reset();
|
|
_events2.ScheduleEvent(EVENT_GUEST_TALK, 10000);
|
|
}
|
|
|
|
void Reset() override
|
|
{
|
|
BossAI::Reset();
|
|
me->CastSpell(me, SPELL_DUAL_WIELD, true);
|
|
}
|
|
|
|
void EnterCombat(Unit* who) override
|
|
{
|
|
BossAI::EnterCombat(who);
|
|
Talk(SAY_AGGRO);
|
|
|
|
events.ScheduleEvent(EVENT_SPELL_VANISH, 30000);
|
|
events.ScheduleEvent(EVENT_SPELL_BLIND, 20000);
|
|
events.ScheduleEvent(EVENT_SPELL_GOUGE, 13000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 5000);
|
|
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000);
|
|
|
|
_events2.Reset();
|
|
me->CallForHelp(20.0f);
|
|
DoZoneInCombat();
|
|
}
|
|
|
|
void KilledUnit(Unit* /*victim*/) override
|
|
{
|
|
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
|
{
|
|
Talk(SAY_KILL);
|
|
events.ScheduleEvent(EVENT_KILL_TALK, 5000);
|
|
}
|
|
}
|
|
|
|
void JustDied(Unit* killer) override
|
|
{
|
|
summons.clear();
|
|
BossAI::JustDied(killer);
|
|
Talk(SAY_DEATH);
|
|
instance->SetBossState(DATA_MOROES, DONE);
|
|
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GARROTE);
|
|
}
|
|
|
|
void JustSummoned(Creature* summon) override
|
|
{
|
|
summons.Summon(summon);
|
|
}
|
|
|
|
Creature* GetRandomGuest()
|
|
{
|
|
std::list<Creature*> guestList;
|
|
for (SummonList::const_iterator i = summons.begin(); i != summons.end(); ++i)
|
|
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
|
|
guestList.push_back(summon);
|
|
|
|
return acore::Containers::SelectRandomContainerElement(guestList);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
_events2.Update(diff);
|
|
switch (_events2.ExecuteEvent())
|
|
{
|
|
case EVENT_GUEST_TALK:
|
|
if (Creature* guest = GetRandomGuest())
|
|
guest->AI()->Talk(SAY_GUEST);
|
|
_events2.ScheduleEvent(EVENT_GUEST_TALK2, 5000);
|
|
break;
|
|
case EVENT_GUEST_TALK2:
|
|
Talk(SAY_OUT_OF_COMBAT);
|
|
_events2.ScheduleEvent(EVENT_GUEST_TALK, urand(60000, 120000));
|
|
break;
|
|
}
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_CHECK_HEALTH:
|
|
if (me->HealthBelowPct(31))
|
|
{
|
|
me->CastSpell(me, SPELL_FRENZY, true);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
break;
|
|
case EVENT_SPELL_ENRAGE:
|
|
me->CastSpell(me, SPELL_BERSERK, true);
|
|
break;
|
|
case EVENT_SPELL_BLIND:
|
|
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 10.0f, true))
|
|
me->CastSpell(target, SPELL_BLIND, false);
|
|
events.ScheduleEvent(EVENT_SPELL_BLIND, urand(25000, 40000));
|
|
break;
|
|
case EVENT_SPELL_GOUGE:
|
|
me->CastSpell(me->GetVictim(), SPELL_GOUGE, false);
|
|
events.ScheduleEvent(EVENT_SPELL_GOUGE, urand(25000, 40000));
|
|
return;
|
|
case EVENT_SPELL_VANISH:
|
|
events.DelayEvents(9000);
|
|
events.SetPhase(1);
|
|
me->CastSpell(me, SPELL_VANISH, false);
|
|
events.ScheduleEvent(EVENT_SPELL_VANISH, 30000);
|
|
events.ScheduleEvent(EVENT_SPELL_GARROTE, urand(5000, 7000));
|
|
return;
|
|
case EVENT_SPELL_GARROTE:
|
|
Talk(SAY_SPECIAL);
|
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
|
target->CastSpell(target, SPELL_GARROTE, true);
|
|
me->CastSpell(me, SPELL_VANISH_TELEPORT, false);
|
|
events.SetPhase(0);
|
|
break;
|
|
}
|
|
|
|
// Xinef: not in vanish
|
|
if (events.GetPhaseMask() == 0)
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
|
|
private:
|
|
EventMap _events2;
|
|
uint8 _activeGuests;
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetInstanceAI<boss_moroesAI>(creature);
|
|
}
|
|
};
|
|
|
|
class spell_moroes_vanish : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_moroes_vanish() : SpellScriptLoader("spell_moroes_vanish") { }
|
|
|
|
class spell_moroes_vanish_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_moroes_vanish_SpellScript);
|
|
|
|
void HandleDummy(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
if (Unit* target = GetHitUnit())
|
|
{
|
|
Position pos;
|
|
target->GetFirstCollisionPosition(pos, 5.0f, M_PI);
|
|
GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true);
|
|
GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH);
|
|
GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
|
|
}
|
|
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_moroes_vanish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_moroes_vanish_SpellScript();
|
|
}
|
|
};
|
|
|
|
void AddSC_boss_moroes()
|
|
{
|
|
new boss_moroes();
|
|
new spell_moroes_vanish();
|
|
}
|