283 lines
8.8 KiB
C++
283 lines
8.8 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 "gundrak.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "ScriptMgr.h"
|
|
|
|
enum Spells
|
|
{
|
|
SPELL_START_VISUAL = 54988,
|
|
SPELL_ENRAGE = 55285,
|
|
SPELL_IMPALING_CHARGE = 54956,
|
|
SPELL_IMPALING_CHARGE_VEHICLE = 54958,
|
|
SPELL_STOMP = 55292,
|
|
SPELL_PUNCTURE = 55276,
|
|
SPELL_STAMPEDE = 55218,
|
|
SPELL_STAMPEDE_DMG = 55220,
|
|
SPELL_WHIRLING_SLASH = 55250,
|
|
SPELL_TRANSFORM_TO_RHINO = 55297,
|
|
SPELL_TRANSFORM_TO_TROLL = 55299
|
|
};
|
|
|
|
enum Yells
|
|
{
|
|
SAY_AGGRO = 0,
|
|
SAY_SLAY = 1,
|
|
SAY_DEATH = 2,
|
|
SAY_SUMMON_RHINO = 3,
|
|
SAY_TRANSFORM_1 = 4,
|
|
SAY_TRANSFORM_2 = 5
|
|
};
|
|
|
|
enum Events
|
|
{
|
|
EVENT_STAMPEDE = 1,
|
|
EVENT_WHIRLING_SLASH = 2,
|
|
EVENT_PUNCTURE = 3,
|
|
EVENT_ENRAGE = 4,
|
|
EVENT_IMPALING_CHARGE = 5,
|
|
EVENT_UNSUMMON_RHINO = 6,
|
|
EVENT_STOMP = 7,
|
|
EVENT_KILL_TALK = 8
|
|
};
|
|
|
|
class boss_gal_darah : public CreatureScript
|
|
{
|
|
public:
|
|
boss_gal_darah() : CreatureScript("boss_gal_darah") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetGundrakAI<boss_gal_darahAI>(creature);
|
|
}
|
|
|
|
struct boss_gal_darahAI : public BossAI
|
|
{
|
|
boss_gal_darahAI(Creature* creature) : BossAI(creature, DATA_GAL_DARAH)
|
|
{
|
|
}
|
|
|
|
uint8 phaseCounter;
|
|
GuidSet impaledList;
|
|
|
|
void Reset() override
|
|
{
|
|
BossAI::Reset();
|
|
impaledList.clear();
|
|
phaseCounter = 0;
|
|
}
|
|
|
|
void InitializeAI() override
|
|
{
|
|
BossAI::InitializeAI();
|
|
me->CastSpell(me, SPELL_START_VISUAL, false);
|
|
}
|
|
|
|
void JustReachedHome() override
|
|
{
|
|
BossAI::JustReachedHome();
|
|
me->CastSpell(me, SPELL_START_VISUAL, false);
|
|
}
|
|
|
|
void ScheduleEvents(bool troll)
|
|
{
|
|
events.Reset();
|
|
if (troll)
|
|
{
|
|
events.RescheduleEvent(EVENT_STAMPEDE, 10000);
|
|
events.RescheduleEvent(EVENT_WHIRLING_SLASH, 21000);
|
|
}
|
|
else
|
|
{
|
|
events.RescheduleEvent(EVENT_PUNCTURE, 10000);
|
|
events.RescheduleEvent(EVENT_ENRAGE, 15000);
|
|
events.RescheduleEvent(EVENT_IMPALING_CHARGE, 21000);
|
|
events.RescheduleEvent(EVENT_STOMP, 5000);
|
|
}
|
|
}
|
|
|
|
void EnterCombat(Unit* who) override
|
|
{
|
|
Talk(SAY_AGGRO);
|
|
BossAI::EnterCombat(who);
|
|
|
|
ScheduleEvents(true);
|
|
me->RemoveAurasDueToSpell(SPELL_START_VISUAL);
|
|
me->InterruptNonMeleeSpells(true);
|
|
}
|
|
|
|
void JustSummoned(Creature* summon) override
|
|
{
|
|
uint32 despawnTime = 0;
|
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
|
|
{
|
|
summon->CastSpell(target, SPELL_STAMPEDE_DMG, true);
|
|
despawnTime = (summon->GetDistance(target) / 40.0f * 1000) + 500;
|
|
}
|
|
|
|
summon->DespawnOrUnsummon(despawnTime);
|
|
}
|
|
|
|
uint32 GetData(uint32 /*type*/) const override
|
|
{
|
|
return impaledList.size();
|
|
}
|
|
|
|
void JustDied(Unit* killer) override
|
|
{
|
|
Talk(SAY_DEATH);
|
|
BossAI::JustDied(killer);
|
|
}
|
|
|
|
void KilledUnit(Unit*) override
|
|
{
|
|
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
|
{
|
|
Talk(SAY_SLAY);
|
|
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_CHARGING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_STAMPEDE:
|
|
Talk(SAY_SUMMON_RHINO);
|
|
me->CastSpell(me->GetVictim(), SPELL_STAMPEDE, false);
|
|
events.ScheduleEvent(EVENT_STAMPEDE, 15000);
|
|
break;
|
|
case EVENT_WHIRLING_SLASH:
|
|
if (++phaseCounter >= 3)
|
|
{
|
|
ScheduleEvents(false);
|
|
me->CastSpell(me, SPELL_TRANSFORM_TO_RHINO, false);
|
|
Talk(SAY_TRANSFORM_1);
|
|
phaseCounter = 0;
|
|
return;
|
|
}
|
|
events.ScheduleEvent(EVENT_WHIRLING_SLASH, 21000);
|
|
me->CastSpell(me, SPELL_WHIRLING_SLASH, false);
|
|
break;
|
|
case EVENT_PUNCTURE:
|
|
me->CastSpell(me->GetVictim(), SPELL_PUNCTURE, false);
|
|
events.ScheduleEvent(EVENT_PUNCTURE, 8000);
|
|
break;
|
|
case EVENT_ENRAGE:
|
|
me->CastSpell(me, SPELL_ENRAGE, false);
|
|
events.ScheduleEvent(EVENT_ENRAGE, 20000);
|
|
break;
|
|
case EVENT_STOMP:
|
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true))
|
|
me->CastSpell(target, SPELL_STOMP, false);
|
|
events.ScheduleEvent(EVENT_STOMP, 20000);
|
|
break;
|
|
case EVENT_IMPALING_CHARGE:
|
|
if (++phaseCounter >= 3)
|
|
{
|
|
ScheduleEvents(true);
|
|
me->CastSpell(me, SPELL_TRANSFORM_TO_TROLL, false);
|
|
Talk(SAY_TRANSFORM_2);
|
|
phaseCounter = 0;
|
|
return;
|
|
}
|
|
events.ScheduleEvent(EVENT_IMPALING_CHARGE, 21000);
|
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
|
|
{
|
|
me->CastSpell(target, SPELL_IMPALING_CHARGE, false);
|
|
impaledList.insert(target->GetGUID());
|
|
}
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
};
|
|
|
|
class spell_galdarah_impaling_charge : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_galdarah_impaling_charge() : SpellScriptLoader("spell_galdarah_impaling_charge") { }
|
|
|
|
class spell_galdarah_impaling_charge_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_galdarah_impaling_charge_SpellScript);
|
|
|
|
void HandleApplyAura(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (Unit* target = GetHitUnit())
|
|
target->CastSpell(GetCaster(), SPELL_IMPALING_CHARGE_VEHICLE, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_galdarah_impaling_charge_SpellScript::HandleApplyAura, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_galdarah_impaling_charge_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_galdarah_transform : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_galdarah_transform() : SpellScriptLoader("spell_galdarah_transform") { }
|
|
|
|
class spell_galdarah_transform_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_galdarah_transform_SpellScript);
|
|
|
|
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (Unit* target = GetHitUnit())
|
|
target->RemoveAurasDueToSpell(SPELL_TRANSFORM_TO_RHINO);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_galdarah_transform_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_galdarah_transform_SpellScript();
|
|
}
|
|
};
|
|
|
|
class achievement_share_the_love : public AchievementCriteriaScript
|
|
{
|
|
public:
|
|
achievement_share_the_love() : AchievementCriteriaScript("achievement_share_the_love")
|
|
{
|
|
}
|
|
|
|
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
|
|
{
|
|
if (!target)
|
|
return false;
|
|
|
|
return target->GetAI()->GetData(target->GetEntry()) >= 5;
|
|
}
|
|
};
|
|
|
|
void AddSC_boss_gal_darah()
|
|
{
|
|
new boss_gal_darah();
|
|
new spell_galdarah_impaling_charge();
|
|
new spell_galdarah_transform();
|
|
new achievement_share_the_love();
|
|
}
|