mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 19:35:42 +00:00
765 lines
27 KiB
C++
765 lines
27 KiB
C++
/*
|
|
REWRITTEN BY XINEF
|
|
*/
|
|
|
|
#include "ScriptMgr.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "sunwell_plateau.h"
|
|
#include "Player.h"
|
|
#include "WorldSession.h"
|
|
|
|
enum Yells
|
|
{
|
|
SAY_SATH_AGGRO = 0,
|
|
SAY_SATH_SLAY = 1,
|
|
SAY_SATH_DEATH = 2,
|
|
SAY_SATH_SPELL1 = 3,
|
|
SAY_SATH_SPELL2 = 4,
|
|
|
|
|
|
SAY_EVIL_AGGRO = 0,
|
|
SAY_EVIL_SLAY = 1,
|
|
SAY_GOOD_PLRWIN = 2,
|
|
SAY_EVIL_ENRAGE = 3,
|
|
SAY_SATH_ENRAGE_ME = 4,
|
|
SAY_KALEC_ENRAGE_SATH = 5,
|
|
|
|
SAY_GOOD_AGGRO = 0,
|
|
SAY_GOOD_NEAR_DEATH = 1,
|
|
SAY_GOOD_NEAR_DEATH2 = 2,
|
|
SAY_GOOD_MADRIGOSA = 3
|
|
};
|
|
|
|
enum Spells
|
|
{
|
|
SPELL_SPECTRAL_EXHAUSTION = 44867,
|
|
SPELL_SPECTRAL_BLAST = 44869,
|
|
SPELL_SPECTRAL_BLAST_PORTAL = 44866,
|
|
SPELL_SPECTRAL_BLAST_AA = 46648,
|
|
SPELL_TELEPORT_SPECTRAL = 46019,
|
|
|
|
SPELL_TELEPORT_NORMAL_REALM = 46020,
|
|
SPELL_SPECTRAL_REALM = 46021,
|
|
SPELL_SPECTRAL_INVISIBILITY = 44801,
|
|
SPELL_DEMONIC_VISUAL = 44800,
|
|
|
|
SPELL_ARCANE_BUFFET = 45018,
|
|
SPELL_FROST_BREATH = 44799,
|
|
SPELL_TAIL_LASH = 45122,
|
|
|
|
SPELL_BANISH = 44836,
|
|
SPELL_TRANSFORM_KALEC = 44670,
|
|
SPELL_CRAZED_RAGE = 44807,
|
|
|
|
SPELL_CORRUPTION_STRIKE = 45029,
|
|
SPELL_CURSE_OF_BOUNDLESS_AGONY = 45032,
|
|
SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR = 45034,
|
|
SPELL_SHADOW_BOLT = 45031,
|
|
|
|
SPELL_HEROIC_STRIKE = 45026,
|
|
SPELL_REVITALIZE = 45027
|
|
};
|
|
|
|
enum SWPActions
|
|
{
|
|
ACTION_ENRAGE = 1,
|
|
ACTION_BANISH = 2,
|
|
ACTION_SATH_BANISH = 3,
|
|
ACTION_KALEC_DIED = 4,
|
|
ACTION_ENRAGE_OTHER = 5,
|
|
};
|
|
|
|
enum kalEvents
|
|
{
|
|
EVENT_ARCANE_BUFFET = 1,
|
|
EVENT_FROST_BREATH = 2,
|
|
EVENT_WILD_MAGIC = 3,
|
|
EVENT_TAIL_LASH = 4,
|
|
EVENT_SPECTRAL_BLAST = 5,
|
|
EVENT_CHECK_HEALTH = 6,
|
|
EVENT_CHECK_HEALTH2 = 7,
|
|
EVENT_CHECK_POS = 8,
|
|
EVENT_SPAWN_SPECTRALS = 9,
|
|
|
|
EVENT_SPELL_REVITALIZE = 10,
|
|
EVENT_SPELL_HEROIC_STRIKE = 11,
|
|
EVENT_SHADOW_BOLT = 12,
|
|
EVENT_AGONY_CURSE = 13,
|
|
EVENT_CORRUPTION_STRIKE = 14,
|
|
|
|
EVENT_TALK_GOOD_1 = 20,
|
|
EVENT_TALK_GOOD_2 = 21,
|
|
EVENT_TALK_GOOD_3 = 22,
|
|
EVENT_TALK_GOOD_4 = 23,
|
|
EVENT_TALK_GOOD_5 = 24,
|
|
EVENT_TALK_BAD_1 = 25,
|
|
EVENT_TALK_BAD_2 = 26,
|
|
EVENT_TALK_BAD_3 = 27
|
|
};
|
|
|
|
#define DRAGON_REALM_Z 53.079f
|
|
|
|
class boss_kalecgos : public CreatureScript
|
|
{
|
|
public:
|
|
boss_kalecgos() : CreatureScript("boss_kalecgos") { }
|
|
|
|
struct boss_kalecgosAI : public BossAI
|
|
{
|
|
boss_kalecgosAI(Creature* creature) : BossAI(creature, DATA_KALECGOS)
|
|
{
|
|
}
|
|
|
|
bool sathBanished;
|
|
EventMap events2;
|
|
|
|
bool CanAIAttack(Unit const* target) const
|
|
{
|
|
return target->GetPositionZ() > 50.0f;
|
|
}
|
|
|
|
void JustReachedHome()
|
|
{
|
|
BossAI::JustReachedHome();
|
|
me->SetVisible(true);
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
BossAI::Reset();
|
|
me->SetHealth(me->GetMaxHealth());
|
|
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
|
me->SetDisableGravity(false);
|
|
me->SetReactState(REACT_AGGRESSIVE);
|
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
|
|
events2.Reset();
|
|
|
|
sathBanished = false;
|
|
ClearPlayerAuras();
|
|
}
|
|
|
|
void ClearPlayerAuras() const
|
|
{
|
|
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CURSE_OF_BOUNDLESS_AGONY);
|
|
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR);
|
|
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SPECTRAL_REALM);
|
|
}
|
|
|
|
void DoAction(int32 param)
|
|
{
|
|
if (param == ACTION_ENRAGE || param == ACTION_ENRAGE_OTHER)
|
|
{
|
|
Talk(param == ACTION_ENRAGE ? SAY_KALEC_ENRAGE_SATH : SAY_SATH_ENRAGE_ME);
|
|
me->CastSpell(me, SPELL_CRAZED_RAGE, true);
|
|
events.CancelEvent(EVENT_CHECK_HEALTH);
|
|
return;
|
|
}
|
|
else if (param == ACTION_BANISH)
|
|
{
|
|
me->CastSpell(me, SPELL_BANISH, true);
|
|
events.Reset();
|
|
}
|
|
else if (param == ACTION_SATH_BANISH)
|
|
sathBanished = true;
|
|
else if (param == ACTION_KALEC_DIED)
|
|
{
|
|
events.Reset();
|
|
events2.ScheduleEvent(EVENT_TALK_BAD_1, 0);
|
|
ClearPlayerAuras();
|
|
return;
|
|
}
|
|
|
|
if (me->HasAura(SPELL_BANISH) && sathBanished)
|
|
{
|
|
events.Reset();
|
|
events2.ScheduleEvent(EVENT_TALK_GOOD_1, 1000);
|
|
ClearPlayerAuras();
|
|
if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_SATHROVARR)))
|
|
{
|
|
Sath->RemoveAllAuras();
|
|
Sath->GetMotionMaster()->MovementExpired();
|
|
Sath->SetReactState(REACT_PASSIVE);
|
|
Sath->NearTeleportTo(1696.20f, 915.0f, DRAGON_REALM_Z, Sath->GetOrientation());
|
|
}
|
|
}
|
|
}
|
|
|
|
void JustDied(Unit* who)
|
|
{
|
|
BossAI::JustDied(who);
|
|
}
|
|
|
|
void EnterCombat(Unit* who)
|
|
{
|
|
BossAI::EnterCombat(who);
|
|
events.ScheduleEvent(EVENT_ARCANE_BUFFET, 6000);
|
|
events.ScheduleEvent(EVENT_FROST_BREATH, 15000);
|
|
events.ScheduleEvent(EVENT_WILD_MAGIC, 10000);
|
|
events.ScheduleEvent(EVENT_TAIL_LASH, 25000);
|
|
events.ScheduleEvent(EVENT_SPECTRAL_BLAST, 20000);
|
|
events.ScheduleEvent(EVENT_CHECK_POS, 5000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
|
events.ScheduleEvent(EVENT_SPAWN_SPECTRALS, 16000);
|
|
|
|
me->SetStandState(UNIT_STAND_STATE_STAND);
|
|
Talk(SAY_EVIL_AGGRO);
|
|
}
|
|
|
|
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask)
|
|
{
|
|
if (damage >= me->GetHealth() && attacker != me)
|
|
damage = 0;
|
|
}
|
|
|
|
void KilledUnit(Unit* victim)
|
|
{
|
|
if (victim->GetTypeId() == TYPEID_PLAYER && roll_chance_i(50))
|
|
Talk(SAY_EVIL_SLAY);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff)
|
|
{
|
|
events2.Update(diff);
|
|
switch (events2.ExecuteEvent())
|
|
{
|
|
case EVENT_TALK_GOOD_1:
|
|
me->SetRegeneratingHealth(false);
|
|
me->RemoveAllAuras();
|
|
me->SetReactState(REACT_PASSIVE);
|
|
me->CombatStop();
|
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
|
me->setFaction(35);
|
|
events2.ScheduleEvent(EVENT_TALK_GOOD_2, 1000);
|
|
break;
|
|
case EVENT_TALK_GOOD_2:
|
|
if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_SATHROVARR)))
|
|
{
|
|
summons.Despawn(Sath);
|
|
Unit::Kill(me, Sath);
|
|
}
|
|
events2.ScheduleEvent(EVENT_TALK_GOOD_3, 8000);
|
|
break;
|
|
case EVENT_TALK_GOOD_3:
|
|
Talk(SAY_GOOD_PLRWIN);
|
|
events2.ScheduleEvent(EVENT_TALK_GOOD_4, 10000);
|
|
break;
|
|
case EVENT_TALK_GOOD_4:
|
|
me->SetDisableGravity(true);
|
|
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
|
|
events2.ScheduleEvent(EVENT_TALK_GOOD_5, 10000);
|
|
break;
|
|
case EVENT_TALK_GOOD_5:
|
|
me->SetVisible(false);
|
|
Unit::Kill(me, me);
|
|
break;
|
|
case EVENT_TALK_BAD_1:
|
|
me->SetReactState(REACT_PASSIVE);
|
|
me->CombatStop();
|
|
me->RemoveAllAuras();
|
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
|
Talk(SAY_EVIL_ENRAGE);
|
|
events2.ScheduleEvent(EVENT_TALK_BAD_2, 3000);
|
|
break;
|
|
case EVENT_TALK_BAD_2:
|
|
me->SetDisableGravity(true);
|
|
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
|
|
events2.ScheduleEvent(EVENT_TALK_BAD_3, 15000);
|
|
break;
|
|
case EVENT_TALK_BAD_3:
|
|
me->SetVisible(false);
|
|
EnterEvadeMode();
|
|
break;
|
|
}
|
|
|
|
if (!events2.Empty())
|
|
return;
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_SPAWN_SPECTRALS:
|
|
me->SummonCreature(NPC_KALEC, 1702.21f, 931.7f, -74.56f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN);
|
|
me->SummonCreature(NPC_SATHROVARR, 1704.62f, 927.78f, -73.9f, 2.0f, TEMPSUMMON_MANUAL_DESPAWN);
|
|
break;
|
|
case EVENT_ARCANE_BUFFET:
|
|
me->CastSpell(me, SPELL_ARCANE_BUFFET, false);
|
|
events.ScheduleEvent(EVENT_ARCANE_BUFFET, 8000);
|
|
break;
|
|
case EVENT_FROST_BREATH:
|
|
me->CastSpell(me->GetVictim(), SPELL_FROST_BREATH, false);
|
|
events.ScheduleEvent(EVENT_FROST_BREATH, 15000);
|
|
break;
|
|
case EVENT_TAIL_LASH:
|
|
me->CastSpell(me->GetVictim(), SPELL_TAIL_LASH, false);
|
|
events.ScheduleEvent(EVENT_TAIL_LASH, 15000);
|
|
break;
|
|
case EVENT_WILD_MAGIC:
|
|
me->CastCustomSpell(RAND(44978, 45001, 45002, 45004, 45006, 45010), SPELLVALUE_MAX_TARGETS, 1, me, false);
|
|
events.ScheduleEvent(EVENT_WILD_MAGIC, 20000);
|
|
break;
|
|
case EVENT_SPECTRAL_BLAST:
|
|
me->CastSpell(me, SPELL_SPECTRAL_BLAST, false);
|
|
events.ScheduleEvent(EVENT_SPECTRAL_BLAST, urand(15000, 25000));
|
|
break;
|
|
case EVENT_CHECK_POS:
|
|
if (me->GetDistance(me->GetHomePosition()) > 50.0f)
|
|
{
|
|
EnterEvadeMode();
|
|
return;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_POS, 5000);
|
|
break;
|
|
case EVENT_CHECK_HEALTH:
|
|
if (me->HealthBelowPct(10))
|
|
{
|
|
if (Creature* Sath = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_SATHROVARR)))
|
|
Sath->AI()->DoAction(ACTION_ENRAGE_OTHER);
|
|
DoAction(ACTION_ENRAGE);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
break;
|
|
case EVENT_CHECK_HEALTH2:
|
|
if (me->HealthBelowPct(1))
|
|
{
|
|
DoAction(ACTION_BANISH);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const
|
|
{
|
|
return GetInstanceAI<boss_kalecgosAI>(creature);
|
|
}
|
|
};
|
|
|
|
enum Kalec
|
|
{
|
|
SPELL_OPEN_BRUTALLUS_BACK_DOOR = 46650,
|
|
MODEL_KALECGOS_DRAGON = 23487,
|
|
|
|
EVENT_KALEC_SCENE_1 = 101,
|
|
EVENT_KALEC_SCENE_2 = 102,
|
|
EVENT_KALEC_SCENE_3 = 103
|
|
};
|
|
|
|
class boss_kalec : public CreatureScript
|
|
{
|
|
public:
|
|
boss_kalec() : CreatureScript("boss_kalec") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const
|
|
{
|
|
return GetInstanceAI<boss_kalecAI>(creature);
|
|
}
|
|
|
|
struct boss_kalecAI : public ScriptedAI
|
|
{
|
|
boss_kalecAI(Creature* creature) : ScriptedAI(creature) { }
|
|
|
|
EventMap events;
|
|
EventMap events2;
|
|
|
|
void Reset()
|
|
{
|
|
events.Reset();
|
|
events2.Reset();
|
|
if (me->GetPositionY() < 750.0f)
|
|
{
|
|
me->SetSpeed(MOVE_RUN, 2.4f);
|
|
me->SetDisplayId(MODEL_KALECGOS_DRAGON);
|
|
me->SetDisableGravity(true);
|
|
me->GetMotionMaster()->MovePoint(0, 1483.30f, 657.99f, 28.0f, false, true);
|
|
events2.ScheduleEvent(EVENT_KALEC_SCENE_1, 9000);
|
|
events2.ScheduleEvent(EVENT_KALEC_SCENE_2, 16000);
|
|
events2.ScheduleEvent(EVENT_KALEC_SCENE_3, 22000);
|
|
}
|
|
else
|
|
me->CastSpell(me, SPELL_SPECTRAL_INVISIBILITY, true);
|
|
}
|
|
|
|
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask)
|
|
{
|
|
if (!who || who->GetEntry() != NPC_SATHROVARR)
|
|
damage = 0;
|
|
}
|
|
|
|
void EnterCombat(Unit*)
|
|
{
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
|
events.ScheduleEvent(EVENT_SPELL_REVITALIZE, 5000);
|
|
events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, 3000);
|
|
Talk(SAY_GOOD_AGGRO);
|
|
}
|
|
|
|
void JustDied(Unit*)
|
|
{
|
|
if (InstanceScript* instance = me->GetInstanceScript())
|
|
if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_KALECGOS)))
|
|
kalecgos->AI()->DoAction(ACTION_KALEC_DIED);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff)
|
|
{
|
|
events2.Update(diff);
|
|
switch (events2.ExecuteEvent())
|
|
{
|
|
case EVENT_KALEC_SCENE_1:
|
|
Talk(SAY_GOOD_MADRIGOSA);
|
|
me->GetMotionMaster()->MovePoint(0, 1509.0f, 560.0f, 30.0f, false, true);
|
|
break;
|
|
case EVENT_KALEC_SCENE_2:
|
|
me->CastSpell(me, SPELL_OPEN_BRUTALLUS_BACK_DOOR, true);
|
|
me->GetInstanceScript()->SetBossState(DATA_FELMYST_DOORS, NOT_STARTED);
|
|
me->GetInstanceScript()->SetBossState(DATA_FELMYST_DOORS, DONE);
|
|
break;
|
|
case EVENT_KALEC_SCENE_3:
|
|
me->GetMotionMaster()->MovePoint(0, 1400.0f, 630.0f, 90.0f, false, true);
|
|
me->DespawnOrUnsummon(6000);
|
|
break;
|
|
}
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_CHECK_HEALTH:
|
|
if (me->HealthBelowPct(50))
|
|
{
|
|
Talk(SAY_GOOD_NEAR_DEATH);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
break;
|
|
case EVENT_CHECK_HEALTH2:
|
|
if (me->HealthBelowPct(10))
|
|
{
|
|
Talk(SAY_GOOD_NEAR_DEATH2);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
|
break;
|
|
case EVENT_SPELL_REVITALIZE:
|
|
me->CastSpell(me, SPELL_REVITALIZE, false);
|
|
events.ScheduleEvent(EVENT_SPELL_REVITALIZE, 10000);
|
|
break;
|
|
case EVENT_SPELL_HEROIC_STRIKE:
|
|
me->CastSpell(me->GetVictim(), SPELL_HEROIC_STRIKE, false);
|
|
events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, 5000);
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
};
|
|
|
|
class boss_sathrovarr : public CreatureScript
|
|
{
|
|
public:
|
|
boss_sathrovarr() : CreatureScript("boss_sathrovarr") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const
|
|
{
|
|
return GetInstanceAI<boss_sathrovarrAI>(creature);
|
|
}
|
|
|
|
struct boss_sathrovarrAI : public ScriptedAI
|
|
{
|
|
boss_sathrovarrAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
instance = creature->GetInstanceScript();
|
|
}
|
|
|
|
InstanceScript* instance;
|
|
EventMap events;
|
|
|
|
bool CanAIAttack(Unit const* target) const
|
|
{
|
|
return target->GetPositionZ() < 50.0f;
|
|
}
|
|
|
|
void Reset()
|
|
{
|
|
events.Reset();
|
|
me->CastSpell(me, SPELL_DEMONIC_VISUAL, true);
|
|
me->CastSpell(me, SPELL_SPECTRAL_INVISIBILITY, true);
|
|
|
|
events.ScheduleEvent(EVENT_SHADOW_BOLT, 7000);
|
|
events.ScheduleEvent(EVENT_AGONY_CURSE, 20000);
|
|
events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, 13000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
|
}
|
|
|
|
void EnterCombat(Unit* /*who*/)
|
|
{
|
|
Talk(SAY_SATH_AGGRO);
|
|
}
|
|
|
|
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask)
|
|
{
|
|
if (damage >= me->GetHealth() && who != me)
|
|
damage = 0;
|
|
}
|
|
|
|
void KilledUnit(Unit* target)
|
|
{
|
|
if (target->GetTypeId() == TYPEID_PLAYER)
|
|
Talk(SAY_SATH_SLAY);
|
|
}
|
|
|
|
void JustDied(Unit* /*killer*/)
|
|
{
|
|
Talk(SAY_SATH_DEATH);
|
|
}
|
|
|
|
void DoAction(int32 param)
|
|
{
|
|
if (param == ACTION_ENRAGE || param == ACTION_ENRAGE_OTHER)
|
|
{
|
|
me->CastSpell(me, SPELL_CRAZED_RAGE, true);
|
|
events.CancelEvent(EVENT_CHECK_HEALTH);
|
|
}
|
|
else if (param == ACTION_BANISH)
|
|
{
|
|
me->CastSpell(me, SPELL_BANISH, true);
|
|
events.Reset();
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff)
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_SHADOW_BOLT:
|
|
if (roll_chance_i(20))
|
|
Talk(SAY_SATH_SPELL1);
|
|
me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false);
|
|
events.ScheduleEvent(EVENT_SHADOW_BOLT, 9000);
|
|
break;
|
|
case EVENT_AGONY_CURSE:
|
|
me->CastCustomSpell(SPELL_CURSE_OF_BOUNDLESS_AGONY, SPELLVALUE_MAX_TARGETS, 1, me, false);
|
|
events.ScheduleEvent(EVENT_AGONY_CURSE, 30000);
|
|
break;
|
|
case EVENT_CORRUPTION_STRIKE:
|
|
if (roll_chance_i(20))
|
|
Talk(SAY_SATH_SPELL2);
|
|
me->CastSpell(me->GetVictim(), SPELL_CORRUPTION_STRIKE, false);
|
|
events.ScheduleEvent(EVENT_CORRUPTION_STRIKE, 9000);
|
|
break;
|
|
case EVENT_CHECK_HEALTH:
|
|
if (me->HealthBelowPct(10))
|
|
{
|
|
if (InstanceScript* instance = me->GetInstanceScript())
|
|
if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_KALECGOS)))
|
|
kalecgos->AI()->DoAction(ACTION_ENRAGE_OTHER);
|
|
DoAction(ACTION_ENRAGE);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
|
break;
|
|
case EVENT_CHECK_HEALTH2:
|
|
if (me->HealthBelowPct(1))
|
|
{
|
|
if (Creature* kalecgos = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_KALECGOS)))
|
|
kalecgos->AI()->DoAction(ACTION_SATH_BANISH);
|
|
DoAction(ACTION_BANISH);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
};
|
|
|
|
class SpectralBlastCheck
|
|
{
|
|
public:
|
|
SpectralBlastCheck(Unit* victim) : _victim(victim) { }
|
|
|
|
bool operator()(WorldObject* unit)
|
|
{
|
|
return unit->GetPositionZ() < 50.0f || unit->ToUnit()->HasAura(SPELL_SPECTRAL_EXHAUSTION) || unit->GetGUID() == _victim->GetGUID();
|
|
}
|
|
private:
|
|
Unit* _victim;
|
|
};
|
|
|
|
class spell_kalecgos_spectral_blast_dummy : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kalecgos_spectral_blast_dummy() : SpellScriptLoader("spell_kalecgos_spectral_blast_dummy") { }
|
|
|
|
class spell_kalecgos_spectral_blast_dummy_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kalecgos_spectral_blast_dummy_SpellScript);
|
|
|
|
void FilterTargets(std::list<WorldObject*>& targets)
|
|
{
|
|
targets.remove_if(SpectralBlastCheck(GetCaster()->GetVictim()));
|
|
Trinity::Containers::RandomResizeList(targets, 1);
|
|
}
|
|
|
|
void HandleDummy(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
if (Unit* target = GetHitUnit())
|
|
{
|
|
target->CastSpell(target, SPELL_SPECTRAL_BLAST_PORTAL, true);
|
|
target->CastSpell(target, SPELL_SPECTRAL_BLAST_AA, true);
|
|
target->CastSpell(target, SPELL_TELEPORT_SPECTRAL, true);
|
|
}
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kalecgos_spectral_blast_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
|
OnEffectHitTarget += SpellEffectFn(spell_kalecgos_spectral_blast_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const
|
|
{
|
|
return new spell_kalecgos_spectral_blast_dummy_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kalecgos_curse_of_boundless_agony : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kalecgos_curse_of_boundless_agony() : SpellScriptLoader("spell_kalecgos_curse_of_boundless_agony") { }
|
|
|
|
class spell_kalecgos_curse_of_boundless_agony_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_kalecgos_curse_of_boundless_agony_AuraScript);
|
|
|
|
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript())
|
|
if (instance->IsEncounterInProgress())
|
|
GetUnitOwner()->CastCustomSpell(SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR, SPELLVALUE_MAX_TARGETS, 1, GetUnitOwner(), true);
|
|
}
|
|
|
|
void OnPeriodic(AuraEffect const* aurEff)
|
|
{
|
|
if (aurEff->GetTickNumber() > 1 && aurEff->GetTickNumber()%5 == 1)
|
|
GetAura()->GetEffect(aurEff->GetEffIndex())->SetAmount(aurEff->GetAmount()*2);
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
AfterEffectRemove += AuraEffectRemoveFn(spell_kalecgos_curse_of_boundless_agony_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kalecgos_curse_of_boundless_agony_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const
|
|
{
|
|
return new spell_kalecgos_curse_of_boundless_agony_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_kalecgos_spectral_realm_dummy : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kalecgos_spectral_realm_dummy() : SpellScriptLoader("spell_kalecgos_spectral_realm_dummy") { }
|
|
|
|
class spell_kalecgos_spectral_realm_dummy_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kalecgos_spectral_realm_dummy_SpellScript);
|
|
|
|
SpellCastResult CheckCast()
|
|
{
|
|
if (GetCaster()->HasAura(SPELL_SPECTRAL_EXHAUSTION))
|
|
return SPELL_FAILED_CASTER_AURASTATE;
|
|
|
|
return SPELL_CAST_OK;
|
|
}
|
|
|
|
void HandleScriptEffect(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
GetCaster()->CastSpell(GetCaster(), SPELL_TELEPORT_SPECTRAL, true);
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
OnCheckCast += SpellCheckCastFn(spell_kalecgos_spectral_realm_dummy_SpellScript::CheckCast);
|
|
OnEffectHitTarget += SpellEffectFn(spell_kalecgos_spectral_realm_dummy_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const
|
|
{
|
|
return new spell_kalecgos_spectral_realm_dummy_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kalecgos_spectral_realm : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kalecgos_spectral_realm() : SpellScriptLoader("spell_kalecgos_spectral_realm") { }
|
|
|
|
class spell_kalecgos_spectral_realm_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_kalecgos_spectral_realm_AuraScript);
|
|
|
|
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SPECTRAL_EXHAUSTION, true);
|
|
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_TELEPORT_NORMAL_REALM, true);
|
|
}
|
|
|
|
void Register()
|
|
{
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_kalecgos_spectral_realm_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_MOD_INVISIBILITY, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const
|
|
{
|
|
return new spell_kalecgos_spectral_realm_AuraScript();
|
|
}
|
|
};
|
|
|
|
void AddSC_boss_kalecgos()
|
|
{
|
|
new boss_kalecgos();
|
|
new boss_sathrovarr();
|
|
new boss_kalec();
|
|
new spell_kalecgos_spectral_blast_dummy();
|
|
new spell_kalecgos_curse_of_boundless_agony();
|
|
new spell_kalecgos_spectral_realm_dummy();
|
|
new spell_kalecgos_spectral_realm();
|
|
}
|