mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-15 10:00:28 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_AZJOL_NERUB_H
|
||||
#define DEF_AZJOL_NERUB_H
|
||||
|
||||
enum ANData
|
||||
{
|
||||
DATA_KRIKTHIR_THE_GATEWATCHER_EVENT = 0,
|
||||
DATA_HADRONOX_EVENT = 1,
|
||||
DATA_ANUBARAK_EVENT = 2,
|
||||
MAX_ENCOUNTERS = 3
|
||||
};
|
||||
|
||||
enum ANIds
|
||||
{
|
||||
NPC_SKITTERING_SWARMER = 28735,
|
||||
NPC_SKITTERING_INFECTIOR = 28736,
|
||||
NPC_KRIKTHIR_THE_GATEWATCHER = 28684,
|
||||
NPC_HADRONOX = 28921,
|
||||
NPC_ANUB_AR_CHAMPION = 29062,
|
||||
NPC_ANUB_AR_NECROMANCER = 29063,
|
||||
NPC_ANUB_AR_CRYPTFIEND = 29064,
|
||||
|
||||
GO_KRIKTHIR_DOORS = 192395,
|
||||
GO_ANUBARAK_DOORS1 = 192396,
|
||||
GO_ANUBARAK_DOORS2 = 192397,
|
||||
GO_ANUBARAK_DOORS3 = 192398,
|
||||
|
||||
SPELL_WEB_WRAP_TRIGGER = 52087
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,321 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "azjol_nerub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CARRION_BEETLES = 53520,
|
||||
SPELL_SUMMON_CARRION_BEETLES = 53521,
|
||||
SPELL_LEECHING_SWARM = 53467,
|
||||
SPELL_POUND = 53472,
|
||||
SPELL_POUND_DAMAGE = 53509,
|
||||
SPELL_IMPALE_PERIODIC = 53456,
|
||||
SPELL_EMERGE = 53500,
|
||||
SPELL_SUBMERGE = 53421,
|
||||
SPELL_SELF_ROOT = 42716,
|
||||
|
||||
SPELL_SUMMON_DARTER = 53599,
|
||||
SPELL_SUMMON_ASSASSIN = 53610,
|
||||
SPELL_SUMMON_GUARDIAN = 53614,
|
||||
SPELL_SUMMON_VENOMANCER = 53615,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_LOCUST = 3,
|
||||
SAY_SUBMERGE = 4,
|
||||
SAY_INTRO = 5
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACHIEV_TIMED_START_EVENT = 20381,
|
||||
|
||||
EVENT_CHECK_HEALTH_25 = 1,
|
||||
EVENT_CHECK_HEALTH_50 = 2,
|
||||
EVENT_CHECK_HEALTH_75 = 3,
|
||||
EVENT_CARRION_BEETELS = 4,
|
||||
EVENT_LEECHING_SWARM = 5,
|
||||
EVENT_IMPALE = 6,
|
||||
EVENT_POUND = 7,
|
||||
EVENT_CLOSE_DOORS = 8,
|
||||
EVENT_EMERGE = 9,
|
||||
EVENT_SUMMON_VENOMANCER = 10,
|
||||
EVENT_SUMMON_DARTER = 11,
|
||||
EVENT_SUMMON_GUARDIAN = 12,
|
||||
EVENT_SUMMON_ASSASSINS = 13,
|
||||
EVENT_ENABLE_ROTATE = 14,
|
||||
EVENT_KILL_TALK = 15
|
||||
};
|
||||
|
||||
class boss_anub_arak : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_anub_arak() : CreatureScript("boss_anub_arak") { }
|
||||
|
||||
struct boss_anub_arakAI : public BossAI
|
||||
{
|
||||
boss_anub_arakAI(Creature* creature) : BossAI(creature, DATA_ANUBARAK_EVENT)
|
||||
{
|
||||
me->m_SightDistance = 120.0f;
|
||||
intro = false;
|
||||
}
|
||||
|
||||
bool intro;
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->DisableRotate(false);
|
||||
BossAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!intro && who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
intro = true;
|
||||
Talk(SAY_INTRO);
|
||||
}
|
||||
BossAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (!summon->IsTrigger())
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* )
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
|
||||
events.ScheduleEvent(EVENT_CARRION_BEETELS, 6500);
|
||||
events.ScheduleEvent(EVENT_LEECHING_SWARM, 20000);
|
||||
events.ScheduleEvent(EVENT_POUND, 15000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_75, 1000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_50, 1000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 1000);
|
||||
events.ScheduleEvent(EVENT_CLOSE_DOORS, 5000);
|
||||
}
|
||||
|
||||
void SummonHelpers(float x, float y, float z, uint32 spellId)
|
||||
{
|
||||
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
me->SummonCreature(spellInfo->Effects[EFFECT_0].MiscValue, x, y, z);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CLOSE_DOORS:
|
||||
_EnterCombat();
|
||||
break;
|
||||
case EVENT_CARRION_BEETELS:
|
||||
me->CastSpell(me, SPELL_CARRION_BEETLES, false);
|
||||
events.ScheduleEvent(EVENT_CARRION_BEETELS, 25000);
|
||||
break;
|
||||
case EVENT_LEECHING_SWARM:
|
||||
Talk(SAY_LOCUST);
|
||||
me->CastSpell(me, SPELL_LEECHING_SWARM, false);
|
||||
events.ScheduleEvent(EVENT_LEECHING_SWARM, 20000);
|
||||
break;
|
||||
case EVENT_POUND:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f))
|
||||
{
|
||||
me->CastSpell(me, SPELL_SELF_ROOT, true);
|
||||
me->DisableRotate(true);
|
||||
me->SendMovementFlagUpdate();
|
||||
events.ScheduleEvent(EVENT_ENABLE_ROTATE, 3300);
|
||||
me->CastSpell(target, SPELL_POUND, false);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_POUND, 18000);
|
||||
break;
|
||||
case EVENT_ENABLE_ROTATE:
|
||||
me->RemoveAurasDueToSpell(SPELL_SELF_ROOT);
|
||||
me->DisableRotate(false);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH_25:
|
||||
case EVENT_CHECK_HEALTH_50:
|
||||
case EVENT_CHECK_HEALTH_75:
|
||||
if (me->HealthBelowPct(eventId*25))
|
||||
{
|
||||
Talk(SAY_SUBMERGE);
|
||||
me->CastSpell(me, SPELL_IMPALE_PERIODIC, true);
|
||||
me->CastSpell(me, SPELL_SUBMERGE, false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
events.DelayEvents(46000, 0);
|
||||
events.ScheduleEvent(EVENT_EMERGE, 45000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 2000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 15000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 20000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_DARTER, 30000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 35000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(eventId, 500);
|
||||
break;
|
||||
case EVENT_EMERGE:
|
||||
me->CastSpell(me, SPELL_EMERGE, true);
|
||||
me->RemoveAura(SPELL_SUBMERGE);
|
||||
me->RemoveAura(SPELL_IMPALE_PERIODIC);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case EVENT_SUMMON_ASSASSINS:
|
||||
SummonHelpers(509.32f, 247.42f, 239.48f, SPELL_SUMMON_ASSASSIN);
|
||||
SummonHelpers(589.51f, 240.19f, 236.0f, SPELL_SUMMON_ASSASSIN);
|
||||
break;
|
||||
case EVENT_SUMMON_DARTER:
|
||||
SummonHelpers(509.32f, 247.42f, 239.48f, SPELL_SUMMON_DARTER);
|
||||
SummonHelpers(589.51f, 240.19f, 236.0f, SPELL_SUMMON_DARTER);
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDIAN:
|
||||
SummonHelpers(550.34f, 316.00f, 234.30f, SPELL_SUMMON_GUARDIAN);
|
||||
break;
|
||||
case EVENT_SUMMON_VENOMANCER:
|
||||
SummonHelpers(550.34f, 316.00f, 234.30f, SPELL_SUMMON_VENOMANCER);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_anub_arakAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_azjol_nerub_carrion_beetels : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_azjol_nerub_carrion_beetels() : SpellScriptLoader("spell_azjol_nerub_carrion_beetels") { }
|
||||
|
||||
class spell_azjol_nerub_carrion_beetelsAuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_azjol_nerub_carrion_beetelsAuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
// Xinef: 2 each second
|
||||
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SUMMON_CARRION_BEETLES, true);
|
||||
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SUMMON_CARRION_BEETLES, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_azjol_nerub_carrion_beetelsAuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_azjol_nerub_carrion_beetelsAuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_azjol_nerub_pound : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_azjol_nerub_pound() : SpellScriptLoader("spell_azjol_nerub_pound") { }
|
||||
|
||||
class spell_azjol_nerub_pound_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_azjol_nerub_pound_SpellScript);
|
||||
|
||||
void HandleApplyAura(SpellEffIndex effIndex)
|
||||
{
|
||||
if (Unit* unitTarget = GetHitUnit())
|
||||
GetCaster()->CastSpell(unitTarget, SPELL_POUND_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_azjol_nerub_pound_SpellScript::HandleApplyAura, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_azjol_nerub_pound_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_azjol_nerub_impale_summon : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_azjol_nerub_impale_summon() : SpellScriptLoader("spell_azjol_nerub_impale_summon") { }
|
||||
|
||||
class spell_azjol_nerub_impale_summon_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_azjol_nerub_impale_summon_SpellScript);
|
||||
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
// Adjust effect summon position
|
||||
float floorZ = GetCaster()->GetMap()->GetHeight(GetCaster()->GetPositionX(), GetCaster()->GetPositionY(), GetCaster()->GetPositionZ(), true);
|
||||
if (floorZ > INVALID_HEIGHT)
|
||||
dest._position.m_positionZ = floorZ;
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_azjol_nerub_impale_summon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_azjol_nerub_impale_summon_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_anub_arak()
|
||||
{
|
||||
new boss_anub_arak();
|
||||
new spell_azjol_nerub_carrion_beetels();
|
||||
new spell_azjol_nerub_pound();
|
||||
new spell_azjol_nerub_impale_summon();
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "azjol_nerub.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SUMMON_ANUBAR_CHAMPION = 53064,
|
||||
SPELL_SUMMON_ANUBAR_CRYPT_FIEND = 53065,
|
||||
SPELL_SUMMON_ANUBAR_NECROMANCER = 53066,
|
||||
SPELL_WEB_FRONT_DOORS = 53177,
|
||||
SPELL_WEB_SIDE_DOORS = 53185,
|
||||
SPELL_ACID_CLOUD = 53400,
|
||||
SPELL_LEECH_POISON = 53030,
|
||||
SPELL_LEECH_POISON_HEAL = 53800,
|
||||
SPELL_WEB_GRAB = 57731,
|
||||
SPELL_PIERCE_ARMOR = 53418,
|
||||
|
||||
SPELL_SMASH = 53318,
|
||||
SPELL_FRENZY = 53801
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HADRONOX_MOVE1 = 1,
|
||||
EVENT_HADRONOX_MOVE2 = 2,
|
||||
EVENT_HADRONOX_MOVE3 = 3,
|
||||
EVENT_HADRONOX_MOVE4 = 4,
|
||||
EVENT_HADRONOX_ACID = 5,
|
||||
EVENT_HADRONOX_LEECH = 6,
|
||||
EVENT_HADRONOX_PIERCE = 7,
|
||||
EVENT_HADRONOX_GRAB = 8,
|
||||
EVENT_HADRONOX_SUMMON = 9,
|
||||
|
||||
EVENT_CRUSHER_SMASH = 20,
|
||||
EVENT_CHECK_HEALTH = 21
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_ANUB_AR_CRUSHER = 28922,
|
||||
|
||||
SAY_CRUSHER_AGGRO = 0,
|
||||
SAY_CRUSHER_EMOTE = 1,
|
||||
SAY_HADRONOX_EMOTE = 0,
|
||||
|
||||
ACTION_DESPAWN_ADDS = 1,
|
||||
ACTION_START_EVENT = 2
|
||||
};
|
||||
|
||||
const Position hadronoxSteps[4] =
|
||||
{
|
||||
{607.9f, 512.8f, 695.3f, 0.0f},
|
||||
{611.67f, 564.11f, 720.0f, 0.0f},
|
||||
{576.1f, 580.0f, 727.5f, 0.0f},
|
||||
{534.87f, 554.0f, 733.0f, 0.0f}
|
||||
};
|
||||
|
||||
class boss_hadronox : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_hadronox() : CreatureScript("boss_hadronox") { }
|
||||
|
||||
struct boss_hadronoxAI : public BossAI
|
||||
{
|
||||
boss_hadronoxAI(Creature* creature) : BossAI(creature, DATA_HADRONOX_EVENT)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS);
|
||||
BossAI::Reset();
|
||||
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 542.9f, 519.5f, 741.24f, 2.14f);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_START_EVENT)
|
||||
{
|
||||
instance->SetBossState(DATA_HADRONOX_EVENT, IN_PROGRESS);
|
||||
me->setActive(true);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 20000);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 40000);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 60000);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE4, 80000);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return !me->isActiveObject() || events.GetNextEventTime(EVENT_HADRONOX_MOVE4) != 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
|
||||
// Xinef: cannot use pathfinding...
|
||||
if (summon->GetDistance(477.0f, 618.0f, 771.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MovePath(3000012, false);
|
||||
else if (summon->GetDistance(583.0f, 617.0f, 771.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MovePath(3000013, false);
|
||||
else if (summon->GetDistance(581.0f, 608.5f, 739.0f) < 5.0f)
|
||||
summon->GetMotionMaster()->MovePath(3000014, false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!me->IsAlive() || !victim->HasAura(SPELL_LEECH_POISON))
|
||||
return;
|
||||
|
||||
me->ModifyHealth(int32(me->CountPctFromMaxHealth(10)));
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
events.RescheduleEvent(EVENT_HADRONOX_ACID, 10000);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_LEECH, 4000);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_PIERCE, 1000);
|
||||
events.RescheduleEvent(EVENT_HADRONOX_GRAB, 15000);
|
||||
}
|
||||
|
||||
bool AnyPlayerValid() const
|
||||
{
|
||||
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
|
||||
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
|
||||
if (me->GetDistance(itr->GetSource()) < 130.0f && itr->GetSource()->IsAlive() && !itr->GetSource()->IsGameMaster() && me->CanCreatureAttack(itr->GetSource()) && me->_CanDetectFeignDeathOf(itr->GetSource()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HADRONOX_PIERCE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PIERCE_ARMOR, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_PIERCE, 8000);
|
||||
break;
|
||||
case EVENT_HADRONOX_ACID:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, false))
|
||||
me->CastSpell(target, SPELL_ACID_CLOUD, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_ACID, 25000);
|
||||
break;
|
||||
case EVENT_HADRONOX_LEECH:
|
||||
me->CastSpell(me, SPELL_LEECH_POISON, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_LEECH, 12000);
|
||||
break;
|
||||
case EVENT_HADRONOX_GRAB:
|
||||
me->CastSpell(me, SPELL_WEB_GRAB, false);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_GRAB, 25000);
|
||||
break;
|
||||
case EVENT_HADRONOX_MOVE4:
|
||||
me->CastSpell(me, SPELL_WEB_FRONT_DOORS, true);
|
||||
case EVENT_HADRONOX_MOVE1:
|
||||
case EVENT_HADRONOX_MOVE2:
|
||||
case EVENT_HADRONOX_MOVE3:
|
||||
Talk(SAY_HADRONOX_EMOTE);
|
||||
me->GetMotionMaster()->MoveCharge(hadronoxSteps[eventId-1].GetPositionX(), hadronoxSteps[eventId-1].GetPositionY(), hadronoxSteps[eventId-1].GetPositionZ(), 10.0f, 0, NULL, true);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
EnterEvadeIfOutOfCombatArea();
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const
|
||||
{
|
||||
return me->isActiveObject() && !AnyPlayerValid();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_hadronoxAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_anub_ar_crusher : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_anub_ar_crusher() : CreatureScript("npc_anub_ar_crusher") { }
|
||||
|
||||
struct npc_anub_ar_crusherAI : public ScriptedAI
|
||||
{
|
||||
npc_anub_ar_crusherAI(Creature *c) : ScriptedAI(c), summons(me) {}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
summons.DespawnAll();
|
||||
events.Reset();
|
||||
|
||||
if (me->ToTempSummon())
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummoner())
|
||||
if (summoner->GetEntry() == me->GetEntry())
|
||||
{
|
||||
me->CastSpell(me, RAND(SPELL_SUMMON_ANUBAR_CHAMPION, SPELL_SUMMON_ANUBAR_CRYPT_FIEND, SPELL_SUMMON_ANUBAR_NECROMANCER), true);
|
||||
me->CastSpell(me, RAND(SPELL_SUMMON_ANUBAR_CHAMPION, SPELL_SUMMON_ANUBAR_CRYPT_FIEND, SPELL_SUMMON_ANUBAR_NECROMANCER), true);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if(summon->GetEntry() != me->GetEntry())
|
||||
{
|
||||
summon->GetMotionMaster()->MovePoint(0, *me, false);
|
||||
summon->GetMotionMaster()->MoveFollow(me, 0.1f, 0.0f + M_PI*0.3f*summons.size());
|
||||
}
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_DESPAWN_ADDS)
|
||||
{
|
||||
summons.DoAction(ACTION_DESPAWN_ADDS);
|
||||
summons.DespawnAll();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
if (me->ToTempSummon())
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummoner())
|
||||
if (summoner->GetEntry() != me->GetEntry())
|
||||
{
|
||||
summoner->GetAI()->DoAction(ACTION_START_EVENT);
|
||||
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 519.58f, 573.73f, 734.30f, 4.50f);
|
||||
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 539.38f, 573.25f, 732.20f, 4.738f);
|
||||
Talk(SAY_CRUSHER_AGGRO);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 8000, 0, 0);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CRUSHER_SMASH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SMASH, false);
|
||||
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 15000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(30))
|
||||
{
|
||||
Talk(SAY_CRUSHER_EMOTE);
|
||||
me->CastSpell(me, SPELL_FRENZY, false);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_anub_ar_crusherAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_hadronox_summon_periodic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_hadronox_summon_periodic(const char* name, uint32 delay, uint32 spellEntry) : SpellScriptLoader(name), _delay(delay), _spellEntry(spellEntry) { }
|
||||
|
||||
class spell_hadronox_summon_periodic_AuraScript : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_hadronox_summon_periodic_AuraScript(uint32 delay, uint32 spellEntry) : _delay(delay), _spellEntry(spellEntry) { }
|
||||
PrepareAuraScript(spell_hadronox_summon_periodic_AuraScript);
|
||||
|
||||
void HandlePeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit* owner = GetUnitOwner();
|
||||
if (InstanceScript* instance = owner->GetInstanceScript())
|
||||
if (instance->GetBossState(DATA_HADRONOX_EVENT) != DONE)
|
||||
{
|
||||
if (!owner->HasAura(SPELL_WEB_FRONT_DOORS))
|
||||
owner->CastSpell(owner, _spellEntry, true);
|
||||
else if (!instance->IsEncounterInProgress())
|
||||
owner->RemoveAurasDueToSpell(SPELL_WEB_FRONT_DOORS);
|
||||
}
|
||||
}
|
||||
|
||||
void OnApply(AuraEffect const* auraEffect, AuraEffectHandleModes)
|
||||
{
|
||||
GetAura()->GetEffect(auraEffect->GetEffIndex())->SetPeriodicTimer(_delay);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_hadronox_summon_periodic_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
OnEffectApply += AuraEffectApplyFn(spell_hadronox_summon_periodic_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _spellEntry;
|
||||
uint32 _delay;
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_hadronox_summon_periodic_AuraScript(_delay, _spellEntry);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _spellEntry;
|
||||
uint32 _delay;
|
||||
};
|
||||
|
||||
class spell_hadronox_leech_poison : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_hadronox_leech_poison() : SpellScriptLoader("spell_hadronox_leech_poison") { }
|
||||
|
||||
class spell_hadronox_leech_poison_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_hadronox_leech_poison_AuraScript)
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(caster, SPELL_LEECH_POISON_HEAL, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_hadronox_leech_poison_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_LEECH, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_hadronox_leech_poison_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_hadronox_denied : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied")
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return target->GetAI()->GetData(target->GetEntry());
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_hadronox()
|
||||
{
|
||||
new boss_hadronox();
|
||||
new npc_anub_ar_crusher();
|
||||
new spell_hadronox_summon_periodic("spell_hadronox_summon_periodic_champion", 15000, SPELL_SUMMON_ANUBAR_CHAMPION);
|
||||
new spell_hadronox_summon_periodic("spell_hadronox_summon_periodic_necromancer", 10000, SPELL_SUMMON_ANUBAR_NECROMANCER);
|
||||
new spell_hadronox_summon_periodic("spell_hadronox_summon_periodic_crypt_fiend", 5000, SPELL_SUMMON_ANUBAR_CRYPT_FIEND);
|
||||
new spell_hadronox_leech_poison();
|
||||
new achievement_hadronox_denied();
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "azjol_nerub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SUBBOSS_AGGRO_TRIGGER = 52343,
|
||||
SPELL_SWARM = 52440,
|
||||
SPELL_MIND_FLAY = 52586,
|
||||
SPELL_CURSE_OF_FATIGUE = 52592,
|
||||
SPELL_FRENZY = 28747
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_KRIK_START_WAVE = 1,
|
||||
EVENT_KRIK_SUMMON = 2,
|
||||
EVENT_KRIK_MIND_FLAY = 3,
|
||||
EVENT_KRIK_CURSE = 4,
|
||||
EVENT_KRIK_HEALTH_CHECK = 5,
|
||||
EVENT_KRIK_ENTER_COMBAT = 6,
|
||||
EVENT_KILL_TALK = 7,
|
||||
EVENT_CALL_ADDS = 8,
|
||||
EVENT_KRIK_CHECK_EVADE = 9
|
||||
};
|
||||
|
||||
enum Npcs
|
||||
{
|
||||
NPC_WATCHER_NARJIL = 28729,
|
||||
NPC_WATCHER_GASHRA = 28730,
|
||||
NPC_WATCHER_SILTHIK = 28731,
|
||||
NPC_WARRIOR = 28732,
|
||||
NPC_SKIRMISHER = 28734,
|
||||
NPC_SHADOWCASTER = 28733
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_SWARM = 3,
|
||||
SAY_PREFIGHT = 4,
|
||||
SAY_SEND_GROUP = 5
|
||||
};
|
||||
|
||||
class boss_krik_thir : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_krik_thir() : CreatureScript("boss_krik_thir") { }
|
||||
|
||||
struct boss_krik_thirAI : public BossAI
|
||||
{
|
||||
boss_krik_thirAI(Creature* creature) : BossAI(creature, DATA_KRIKTHIR_THE_GATEWATCHER_EVENT)
|
||||
{
|
||||
_initTalk = false;
|
||||
}
|
||||
|
||||
EventMap events2;
|
||||
bool _initTalk;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
events2.Reset();
|
||||
|
||||
me->SummonCreature(NPC_WATCHER_NARJIL, 511.8f, 666.493f, 776.278f, 0.977f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SHADOWCASTER, 518.13f, 667.0f, 775.74f, 1.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_WARRIOR, 506.75f, 670.7f, 776.24f, 0.92f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_WATCHER_GASHRA, 526.66f, 663.605f, 775.805f, 1.23f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SKIRMISHER, 522.23f, 668.97f, 775.66f, 1.18f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_WARRIOR, 532.4f, 666.47f, 775.67f, 1.45f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_WATCHER_SILTHIK, 543.826f, 665.123f, 776.245f, 1.55f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SKIRMISHER, 547.5f, 669.96f, 776.1f, 2.3f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SHADOWCASTER, 536.96f, 667.28f, 775.6f, 1.72f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!_initTalk)
|
||||
{
|
||||
_initTalk = true;
|
||||
Talk(SAY_PREFIGHT);
|
||||
}
|
||||
|
||||
if (events.Empty() && who->GetPositionZ() < 785.0f)
|
||||
{
|
||||
events2.ScheduleEvent(EVENT_KRIK_START_WAVE, 10000);
|
||||
events2.ScheduleEvent(EVENT_KRIK_START_WAVE, 40000);
|
||||
events2.ScheduleEvent(EVENT_KRIK_START_WAVE, 70000);
|
||||
events2.ScheduleEvent(EVENT_KRIK_ENTER_COMBAT, 100000);
|
||||
events2.ScheduleEvent(EVENT_KRIK_CHECK_EVADE, 5000);
|
||||
|
||||
events.ScheduleEvent(EVENT_KRIK_HEALTH_CHECK, 1000);
|
||||
events.ScheduleEvent(EVENT_KRIK_MIND_FLAY, 13000);
|
||||
events.ScheduleEvent(EVENT_KRIK_SUMMON, 17000);
|
||||
events.ScheduleEvent(EVENT_KRIK_CURSE, 8000);
|
||||
events.ScheduleEvent(EVENT_CALL_ADDS, 1000);
|
||||
me->setActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return summons.HasEntry(NPC_WATCHER_NARJIL) && summons.HasEntry(NPC_WATCHER_GASHRA) && summons.HasEntry(NPC_WATCHER_SILTHIK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
events2.Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* )
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summon->SetNoCallAssistance(true);
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_KRIK_START_WAVE:
|
||||
me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true);
|
||||
Talk(SAY_SEND_GROUP);
|
||||
break;
|
||||
case EVENT_KRIK_ENTER_COMBAT:
|
||||
me->SetInCombatWithZone();
|
||||
break;
|
||||
case EVENT_KRIK_CHECK_EVADE:
|
||||
if (!SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
events2.ScheduleEvent(EVENT_KRIK_CHECK_EVADE, 5000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_KRIK_HEALTH_CHECK:
|
||||
if (HealthBelowPct(10))
|
||||
{
|
||||
events.PopEvent();
|
||||
me->CastSpell(me, SPELL_FRENZY, true);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_KRIK_HEALTH_CHECK, 1000);
|
||||
break;
|
||||
case EVENT_KRIK_SUMMON:
|
||||
Talk(SAY_SWARM);
|
||||
me->CastSpell(me, SPELL_SWARM, false);
|
||||
events.ScheduleEvent(EVENT_KRIK_SUMMON, 20000);
|
||||
break;
|
||||
case EVENT_KRIK_MIND_FLAY:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MIND_FLAY, false);
|
||||
events.ScheduleEvent(EVENT_KRIK_MIND_FLAY, 15000);
|
||||
break;
|
||||
case EVENT_KRIK_CURSE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->CastSpell(target, SPELL_CURSE_OF_FATIGUE, true);
|
||||
events.ScheduleEvent(EVENT_KRIK_CURSE, 10000);
|
||||
break;
|
||||
case EVENT_CALL_ADDS:
|
||||
summons.DoZoneInCombat();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new boss_krik_thirAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_watch_him_die : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_watch_him_die() : AchievementCriteriaScript("achievement_watch_him_die")
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return target->GetAI()->GetData(target->GetEntry());
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_krik_thir()
|
||||
{
|
||||
new boss_krik_thir();
|
||||
new achievement_watch_him_die();
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "azjol_nerub.h"
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_KRIKTHIR_DOORS, DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
|
||||
{ GO_ANUBARAK_DOORS1, DATA_ANUBARAK_EVENT, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ GO_ANUBARAK_DOORS2, DATA_ANUBARAK_EVENT, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ GO_ANUBARAK_DOORS3, DATA_ANUBARAK_EVENT, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
|
||||
};
|
||||
|
||||
class instance_azjol_nerub : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_azjol_nerub() : InstanceMapScript("instance_azjol_nerub", 601) { }
|
||||
|
||||
struct instance_azjol_nerub_InstanceScript : public InstanceScript
|
||||
{
|
||||
instance_azjol_nerub_InstanceScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
_krikthirGUID = 0;
|
||||
_hadronoxGUID = 0;
|
||||
};
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_KRIKTHIR_THE_GATEWATCHER:
|
||||
_krikthirGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HADRONOX:
|
||||
_hadronoxGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_SKITTERING_SWARMER:
|
||||
case NPC_SKITTERING_INFECTIOR:
|
||||
if (Creature* krikthir = instance->GetCreature(_krikthirGUID))
|
||||
krikthir->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_ANUB_AR_CHAMPION:
|
||||
case NPC_ANUB_AR_NECROMANCER:
|
||||
case NPC_ANUB_AR_CRYPTFIEND:
|
||||
if (Creature* hadronox = instance->GetCreature(_hadronoxGUID))
|
||||
hadronox->AI()->JustSummoned(creature);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_KRIKTHIR_DOORS:
|
||||
case GO_ANUBARAK_DOORS1:
|
||||
case GO_ANUBARAK_DOORS2:
|
||||
case GO_ANUBARAK_DOORS3:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_KRIKTHIR_DOORS:
|
||||
case GO_ANUBARAK_DOORS1:
|
||||
case GO_ANUBARAK_DOORS2:
|
||||
case GO_ANUBARAK_DOORS3:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 id, EncounterState state)
|
||||
{
|
||||
return InstanceScript::SetBossState(id, state);
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "A N " << GetBossSaveData();
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if( !in )
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'A' && dataHead2 == 'N')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
|
||||
tmpState = NOT_STARTED;
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint64 _krikthirGUID;
|
||||
uint64 _hadronoxGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap *map) const
|
||||
{
|
||||
return new instance_azjol_nerub_InstanceScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_azjol_nerub_fixate : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_azjol_nerub_fixate() : SpellScriptLoader("spell_azjol_nerub_fixate") { }
|
||||
|
||||
class spell_azjol_nerub_fixate_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_azjol_nerub_fixate_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(GetCaster(), GetEffectValue(), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_azjol_nerub_fixate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_azjol_nerub_fixate_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_azjol_nerub_web_wrap : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_azjol_nerub_web_wrap() : SpellScriptLoader("spell_azjol_nerub_web_wrap") { }
|
||||
|
||||
class spell_azjol_nerub_web_wrap_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_azjol_nerub_web_wrap_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (!target->HasAura(SPELL_WEB_WRAP_TRIGGER))
|
||||
target->CastSpell(target, SPELL_WEB_WRAP_TRIGGER, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_azjol_nerub_web_wrap_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_ROOT, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_azjol_nerub_web_wrap_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_azjol_nerub()
|
||||
{
|
||||
new instance_azjol_nerub();
|
||||
new spell_azjol_nerub_fixate();
|
||||
new spell_azjol_nerub_web_wrap();
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
#ifndef DEF_AHNKAHET_H
|
||||
#define DEF_AHNKAHET_H
|
||||
|
||||
#define MAX_ENCOUNTER 5
|
||||
enum Data64
|
||||
{
|
||||
DATA_ELDER_NADOX,
|
||||
DATA_PRINCE_TALDARAM,
|
||||
DATA_JEDOGA_SHADOWSEEKER,
|
||||
DATA_HERALD_VOLAZJ,
|
||||
DATA_AMANITAR,
|
||||
DATA_PRINCE_TALDARAM_PLATFORM,
|
||||
};
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_ELDER_NADOX_EVENT,
|
||||
DATA_PRINCE_TALDARAM_EVENT,
|
||||
DATA_JEDOGA_SHADOWSEEKER_EVENT,
|
||||
DATA_HERALD_VOLAZJ_EVENT,
|
||||
DATA_AMANITAR_EVENT,
|
||||
DATA_SPHERE_EVENT,
|
||||
|
||||
DATA_NADOX_ACHIEVEMENT,
|
||||
DATA_JEDOGA_ACHIEVEMENT,
|
||||
};
|
||||
|
||||
enum Npc
|
||||
{
|
||||
NPC_ELDER_NADOX = 29309,
|
||||
NPC_PRINCE_TALDARAM = 29308,
|
||||
NPC_JEDOGA_SHADOWSEEKER = 29310,
|
||||
NPC_HERALD_JOLAZJ = 29311,
|
||||
NPC_AMANITAR = 30258,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BASH = 57094,
|
||||
SPELL_ENTANGLING_ROOTS = 57095,
|
||||
SPELL_MINI = 57055,
|
||||
SPELL_VENOM_BOLT_VOLLEY = 57088,
|
||||
SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS = 56648,
|
||||
SPELL_POISONOUS_MUSHROOM_POISON_CLOUD = 57061,
|
||||
SPELL_POISONOUS_MUSHROOM_VISUAL_AURA = 56741,
|
||||
SPELL_HEALTHY_MUSHROOM_VISUAL_AURA = 56740,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_HEALTHY_MUSHROOM = 30391,
|
||||
NPC_POISONOUS_MUSHROOM = 30435
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_AMANITAR_SPAWN = 1,
|
||||
EVENT_AMANITAR_ROOTS = 2,
|
||||
EVENT_AMANITAR_BASH = 3,
|
||||
EVENT_AMANITAR_BOLT = 4,
|
||||
};
|
||||
|
||||
class boss_amanitar : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_amanitar() : CreatureScript("boss_amanitar") { }
|
||||
|
||||
struct boss_amanitarAI : public ScriptedAI
|
||||
{
|
||||
boss_amanitarAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_AMANITAR_EVENT, NOT_STARTED);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_AMANITAR_EVENT, DONE);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_AMANITAR_EVENT, IN_PROGRESS);
|
||||
|
||||
me->CastSpell(me, SPELL_MINI, false);
|
||||
|
||||
events.ScheduleEvent(EVENT_AMANITAR_ROOTS, urand(5000, 9000));
|
||||
events.ScheduleEvent(EVENT_AMANITAR_BASH, urand(10000, 14000));
|
||||
events.ScheduleEvent(EVENT_AMANITAR_BOLT, urand(15000, 20000));
|
||||
events.ScheduleEvent(EVENT_AMANITAR_SPAWN, 0);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *cr) { summons.Summon(cr); }
|
||||
|
||||
void SpawnAdds()
|
||||
{
|
||||
summons.DespawnAll();
|
||||
Position center;
|
||||
center.Relocate(362.6f, -870, -75);
|
||||
|
||||
for (uint8 i = 0; i < 25; ++i)
|
||||
{
|
||||
float orientation = 2*rand_norm()*M_PI;
|
||||
float x = center.GetPositionX() + i*2*cos(orientation);
|
||||
float y = center.GetPositionY() + i*2*sin(orientation);
|
||||
me->SummonCreature(NPC_POISONOUS_MUSHROOM, x, y, me->GetMap()->GetHeight(x, y, MAX_HEIGHT));
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < 25; ++i)
|
||||
{
|
||||
float orientation = 2*rand_norm()*M_PI;
|
||||
float x = center.GetPositionX() + i*2*cos(orientation);
|
||||
float y = center.GetPositionY() + i*2*sin(orientation);
|
||||
me->SummonCreature(NPC_HEALTHY_MUSHROOM, x, y, me->GetMap()->GetHeight(x, y, MAX_HEIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_AMANITAR_SPAWN:
|
||||
{
|
||||
SpawnAdds();
|
||||
events.RepeatEvent(urand(35000, 40000));
|
||||
break;
|
||||
}
|
||||
case EVENT_AMANITAR_ROOTS:
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->CastSpell(pTarget, SPELL_ENTANGLING_ROOTS, false);
|
||||
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
break;
|
||||
}
|
||||
case EVENT_AMANITAR_BASH:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_BASH, false);
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
break;
|
||||
}
|
||||
case EVENT_AMANITAR_BOLT:
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->CastSpell(pTarget, SPELL_VENOM_BOLT_VOLLEY, false);
|
||||
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new boss_amanitarAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_amanitar_mushrooms : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_amanitar_mushrooms() : CreatureScript("npc_amanitar_mushrooms") { }
|
||||
|
||||
struct npc_amanitar_mushroomsAI : public ScriptedAI
|
||||
{
|
||||
npc_amanitar_mushroomsAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
uint32 Timer;
|
||||
void Reset()
|
||||
{
|
||||
me->CastSpell(me, 31690, true);
|
||||
|
||||
Timer = 0;
|
||||
if (me->GetEntry() == NPC_POISONOUS_MUSHROOM)
|
||||
{
|
||||
me->CastSpell(me, SPELL_POISONOUS_MUSHROOM_VISUAL_AURA, true);
|
||||
me->CastSpell(me, SPELL_POISONOUS_MUSHROOM_POISON_CLOUD, false);
|
||||
}
|
||||
else
|
||||
me->CastSpell(me, SPELL_HEALTHY_MUSHROOM_VISUAL_AURA, true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (!killer)
|
||||
return;
|
||||
|
||||
if (me->GetEntry() == NPC_HEALTHY_MUSHROOM)
|
||||
me->CastSpell(me, SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) {}
|
||||
void AttackStart(Unit* /*victim*/) {}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (me->GetEntry() == NPC_POISONOUS_MUSHROOM)
|
||||
{
|
||||
Timer += diff;
|
||||
if (Timer >= 7000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_POISONOUS_MUSHROOM_POISON_CLOUD, false);
|
||||
Timer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new npc_amanitar_mushroomsAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_amanitar()
|
||||
{
|
||||
new boss_amanitar;
|
||||
new npc_amanitar_mushrooms;
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum misc
|
||||
{
|
||||
// ACTIONS
|
||||
ACTION_GUARDIAN_DIED = 1,
|
||||
};
|
||||
|
||||
enum spells
|
||||
{
|
||||
// NADOX
|
||||
SPELL_BROOD_PLAGUE = 56130,
|
||||
SPELL_BROOD_PLAGUE_H = 59467,
|
||||
SPELL_BROOD_RAGE_H = 59465,
|
||||
SPELL_ENRAGE = 26662, // Enraged if too far away from home
|
||||
//SPELL_SUMMON_SWARMERS = 56119, //2x 30178 -- 2x every 10secs, spell works fine but i need specific coords
|
||||
//SPELL_SUMMON_SWARM_GUARD = 56120, //1x 30176 -- at 50%hp, spell works fine but i need specific coords
|
||||
|
||||
// ADDS
|
||||
SPELL_SPRINT = 56354,
|
||||
SPELL_GUARDIAN_AURA = 56151,
|
||||
SPELL_SWARMER_AURA = 56158,
|
||||
};
|
||||
|
||||
enum creatures
|
||||
{
|
||||
NPC_AHNKAHAR_SWARMER = 30178,
|
||||
NPC_AHNKAHAR_GUARDIAN_ENTRY = 30176,
|
||||
};
|
||||
|
||||
enum events
|
||||
{
|
||||
EVENT_CHECK_HEALTH = 1,
|
||||
EVENT_CHECK_HOME = 2,
|
||||
EVENT_PLAGUE = 3,
|
||||
EVENT_BROOD_RAGE = 4,
|
||||
EVENT_SWARMER = 5,
|
||||
EVENT_SUMMON_GUARD = 6,
|
||||
};
|
||||
|
||||
enum sounds
|
||||
{
|
||||
SOUND_AGGRO = 14033,
|
||||
SOUND_SUMMON1 = 14034,
|
||||
SOUND_SUMMON2 = 14035,
|
||||
SOUND_SLAY1 = 14036,
|
||||
SOUND_SLAY2 = 14037,
|
||||
SOUND_SLAY3 = 14038,
|
||||
SOUND_DEATH = 14039,
|
||||
};
|
||||
|
||||
#define EMOTE_HATCHES "An Ahn'kahar Guardian hatches!"
|
||||
|
||||
class boss_elder_nadox : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_elder_nadox() : CreatureScript("boss_elder_nadox") { }
|
||||
|
||||
struct boss_elder_nadoxAI : public ScriptedAI
|
||||
{
|
||||
boss_elder_nadoxAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript *pInstance;
|
||||
SummonList summons;
|
||||
|
||||
void SummonHelpers(bool swarm)
|
||||
{
|
||||
Creature *cr;
|
||||
if (swarm)
|
||||
{
|
||||
if (cr = me->SummonCreature(NPC_AHNKAHAR_SWARMER, 640.425f, -919.544f, 25.8701f, 2.56563f))
|
||||
summons.Summon(cr);
|
||||
if (cr = me->SummonCreature(NPC_AHNKAHAR_SWARMER, 655.891f, -930.445f, 25.6978f, 3.64774f))
|
||||
summons.Summon(cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cr = me->SummonCreature(NPC_AHNKAHAR_GUARDIAN_ENTRY, 658.677f, -934.332f, 25.6978f, 3.03687f))
|
||||
summons.Summon(cr);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_ELDER_NADOX_EVENT, NOT_STARTED);
|
||||
pInstance->SetData(DATA_NADOX_ACHIEVEMENT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
me->MonsterYell("The secrets of the deep shall remain hidden.", LANG_UNIVERSAL, 0);
|
||||
me->PlayDirectSound(SOUND_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
events.ScheduleEvent(EVENT_SWARMER, 10000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HOME, 2000);
|
||||
events.ScheduleEvent(EVENT_PLAGUE, 5000+rand()%3000);
|
||||
events.ScheduleEvent(EVENT_BROOD_RAGE, 5000);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_ELDER_NADOX_EVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_GUARDIAN_DIED)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_NADOX_ACHIEVEMENT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * /*victim*/)
|
||||
{
|
||||
if (urand(0,1))
|
||||
return;
|
||||
|
||||
switch (rand()%3)
|
||||
{
|
||||
case 0:
|
||||
me->MonsterYell("Sleep now, in the cold dark.", LANG_UNIVERSAL,0);
|
||||
me->PlayDirectSound(SOUND_SLAY1);
|
||||
break;
|
||||
case 1:
|
||||
me->MonsterYell("For the Lich King!", LANG_UNIVERSAL,0);
|
||||
me->PlayDirectSound(SOUND_SLAY2);
|
||||
break;
|
||||
case 2:
|
||||
me->MonsterYell("Perhaps we will be allies soon.", LANG_UNIVERSAL,0);
|
||||
me->PlayDirectSound(SOUND_SLAY3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
me->MonsterYell("Master, is my service complete?", LANG_UNIVERSAL, 0);
|
||||
me->PlayDirectSound(SOUND_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_ELDER_NADOX_EVENT, DONE);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr)
|
||||
{
|
||||
if (cr)
|
||||
{
|
||||
if (cr->GetEntry() == NPC_AHNKAHAR_GUARDIAN_ENTRY )
|
||||
{
|
||||
switch (rand()%2)
|
||||
{
|
||||
case 0:
|
||||
me->MonsterYell("The young must not grow hungry...", LANG_UNIVERSAL, 0);
|
||||
me->PlayDirectSound(SOUND_SUMMON1);
|
||||
break;
|
||||
case 1:
|
||||
me->MonsterYell("Shhhad ak kereeesshh chak-k-k!", LANG_UNIVERSAL, 0);
|
||||
me->PlayDirectSound(SOUND_SUMMON2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
}
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch ( events.GetEvent() )
|
||||
{
|
||||
case EVENT_CHECK_HEALTH:
|
||||
{
|
||||
events.RepeatEvent(1000);
|
||||
if (HealthBelowPct(50))
|
||||
{
|
||||
events.CancelEvent(EVENT_CHECK_HEALTH);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARD, 100);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_SUMMON_GUARD:
|
||||
{
|
||||
me->MonsterTextEmote(EMOTE_HATCHES, me, true);
|
||||
SummonHelpers(false);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
case EVENT_BROOD_RAGE:
|
||||
{
|
||||
if (Creature *pSwarmer = me->FindNearestCreature(NPC_AHNKAHAR_SWARMER, 40, true))
|
||||
me->CastSpell(pSwarmer, SPELL_BROOD_RAGE_H, true);
|
||||
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
}
|
||||
case EVENT_PLAGUE:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_BROOD_PLAGUE, SPELL_BROOD_PLAGUE_H), false);
|
||||
events.RepeatEvent(12000+rand()%5000);
|
||||
break;
|
||||
}
|
||||
case EVENT_SWARMER:
|
||||
{
|
||||
SummonHelpers(true);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
}
|
||||
case EVENT_CHECK_HOME:
|
||||
{
|
||||
if (me->HasAura(SPELL_ENRAGE))
|
||||
break;
|
||||
|
||||
if (me->GetPositionZ() < 24)
|
||||
{
|
||||
me->CastSpell(me, SPELL_ENRAGE, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
events.RepeatEvent(2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new boss_elder_nadoxAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_ahnkahar_nerubian : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ahnkahar_nerubian() : CreatureScript("npc_ahnkahar_nerubian") { }
|
||||
|
||||
struct npc_ahnkahar_nerubianAI : public ScriptedAI
|
||||
{
|
||||
npc_ahnkahar_nerubianAI(Creature *c) : ScriptedAI(c) { }
|
||||
|
||||
|
||||
uint32 uiSprintTimer;
|
||||
void Reset()
|
||||
{
|
||||
if (me->GetEntry() == NPC_AHNKAHAR_GUARDIAN_ENTRY)
|
||||
me->CastSpell(me, SPELL_GUARDIAN_AURA, true);
|
||||
else // Swarmers
|
||||
me->CastSpell(me, SPELL_SWARMER_AURA, true);
|
||||
|
||||
if (me->GetEntry() == NPC_AHNKAHAR_SWARMER || me->GetEntry() == NPC_AHNKAHAR_GUARDIAN_ENTRY)
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
uiSprintTimer = 10000;
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*killer*/)
|
||||
{
|
||||
if (me->GetEntry() == NPC_AHNKAHAR_GUARDIAN_ENTRY)
|
||||
{
|
||||
if (InstanceScript *pInstance = me->GetInstanceScript())
|
||||
if (Creature *nadox = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_ELDER_NADOX)))
|
||||
nadox->AI()->DoAction(ACTION_GUARDIAN_DIED);
|
||||
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiSprintTimer <= diff)
|
||||
{
|
||||
me->CastSpell(me, SPELL_SPRINT, false);
|
||||
uiSprintTimer = 15000;
|
||||
}
|
||||
else
|
||||
uiSprintTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new npc_ahnkahar_nerubianAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ahn_kahet_swarmer_aura : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ahn_kahet_swarmer_aura() : SpellScriptLoader("spell_ahn_kahet_swarmer_aura") { }
|
||||
|
||||
class spell_ahn_kahet_swarmer_aura_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ahn_kahet_swarmer_aura_SpellScript)
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
std::list<Creature*> swarm, swarm2;
|
||||
caster->GetCreaturesWithEntryInRange(swarm, 40.0f, 30338);
|
||||
caster->GetCreaturesWithEntryInRange(swarm2, 40.0f, 30178);
|
||||
int32 aliveCount = -1; // minus self
|
||||
|
||||
std::list<Creature*>::const_iterator itr;
|
||||
for (itr = swarm.begin(); itr != swarm.end(); ++itr)
|
||||
if ((*itr)->IsAlive())
|
||||
aliveCount++;
|
||||
for (itr = swarm2.begin(); itr != swarm2.end(); ++itr)
|
||||
if ((*itr)->IsAlive())
|
||||
aliveCount++;
|
||||
|
||||
if (Aura *aur = caster->GetAura(56281))
|
||||
{
|
||||
if (aliveCount > 0)
|
||||
aur->SetStackAmount(aliveCount);
|
||||
else
|
||||
aur->Remove();
|
||||
}
|
||||
else if (aliveCount > 0)
|
||||
{
|
||||
caster->CastCustomSpell(caster, 56281, &aliveCount, &aliveCount, &aliveCount, true);
|
||||
if (Aura *aur = caster->GetAura(56281))
|
||||
aur->SetStackAmount(aliveCount);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ahn_kahet_swarmer_aura_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_ahn_kahet_swarmer_aura_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_elder_nadox()
|
||||
{
|
||||
new boss_elder_nadox();
|
||||
new npc_ahnkahar_nerubian();
|
||||
new spell_ahn_kahet_swarmer_aura();
|
||||
}
|
||||
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// BASIC FIGHT
|
||||
SPELL_MIND_FLAY = 57941,
|
||||
SPELL_MIND_FLAY_H = 59974,
|
||||
SPELL_SHADOW_BOLT_VOLLEY = 57942,
|
||||
SPELL_SHADOW_BOLT_VOLLEY_H = 59975,
|
||||
SPELL_SHIVER = 57949,
|
||||
SPELL_SHIVER_H = 59978,
|
||||
|
||||
// INSANITY
|
||||
SPELL_INSANITY = 57496, //Dummy
|
||||
INSANITY_VISUAL = 57561,
|
||||
SPELL_INSANITY_TARGET = 57508,
|
||||
SPELL_CLONE_PLAYER = 57507, //casted on player during insanity
|
||||
SPELL_INSANITY_PHASING_1 = 57508,
|
||||
SPELL_INSANITY_PHASING_2 = 57509,
|
||||
SPELL_INSANITY_PHASING_3 = 57510,
|
||||
SPELL_INSANITY_PHASING_4 = 57511,
|
||||
SPELL_INSANITY_PHASING_5 = 57512
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_PHASE = 3
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_TWISTED_VISAGE = 30625,
|
||||
ACHIEV_QUICK_DEMISE_START_EVENT = 20382,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HERALD_MIND_FLAY = 1,
|
||||
EVENT_HERALD_SHADOW = 2,
|
||||
EVENT_HERALD_SHIVER = 3,
|
||||
EVENT_HERALD_HEALTH = 4,
|
||||
};
|
||||
|
||||
class boss_volazj : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_volazj() : CreatureScript("boss_volazj") { }
|
||||
|
||||
struct boss_volazjAI : public ScriptedAI
|
||||
{
|
||||
boss_volazjAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript *pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 insanityTimes;
|
||||
uint8 insanityHandled;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
insanityTimes = insanityHandled = 0;
|
||||
|
||||
// Visible for all players in insanity
|
||||
me->SetPhaseMask((1|16|32|64|128|256), true);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
ResetPlayersPhaseMask();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_HERALD_VOLAZJ, NOT_STARTED);
|
||||
pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* pTarget, const SpellInfo *spell)
|
||||
{
|
||||
if (spell->Id == SPELL_INSANITY)
|
||||
{
|
||||
// Not good target or too many players
|
||||
if (pTarget->GetTypeId() != TYPEID_PLAYER || insanityHandled > 4)
|
||||
return;
|
||||
|
||||
// First target - start channel visual and set self as unnattackable
|
||||
if (!insanityHandled)
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, INSANITY_VISUAL, true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
}
|
||||
|
||||
// phase mask
|
||||
pTarget->CastSpell(pTarget, SPELL_INSANITY_TARGET+insanityHandled, true);
|
||||
|
||||
// summon twisted party members for this target
|
||||
Map::PlayerList const &players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
Player *plr = i->GetSource();
|
||||
if (!plr || !plr->IsAlive() || pTarget->GetGUID() == plr->GetGUID())
|
||||
continue;
|
||||
|
||||
// Summon clone
|
||||
if (Unit* summon = me->SummonCreature(NPC_TWISTED_VISAGE, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), plr->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
summon->AddThreat(pTarget, 0.0f);
|
||||
summon->SetInCombatWith(pTarget);
|
||||
pTarget->SetInCombatWith(summon);
|
||||
|
||||
plr->CastSpell(summon, SPELL_CLONE_PLAYER, true);
|
||||
summon->SetPhaseMask(1|(1<<(4+insanityHandled)), true);
|
||||
summon->SetUInt32Value(UNIT_FIELD_MINDAMAGE, plr->GetUInt32Value(UNIT_FIELD_MINDAMAGE));
|
||||
summon->SetUInt32Value(UNIT_FIELD_MAXDAMAGE, plr->GetUInt32Value(UNIT_FIELD_MAXDAMAGE));
|
||||
}
|
||||
}
|
||||
|
||||
++insanityHandled;
|
||||
}
|
||||
}
|
||||
|
||||
void ResetPlayersPhaseMask()
|
||||
{
|
||||
Map::PlayerList const &players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
if (Player* pPlayer = i->GetSource())
|
||||
if (uint32 spellId = GetSpellForPhaseMask(pPlayer->GetPhaseMask()))
|
||||
pPlayer->RemoveAurasDueToSpell(spellId);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_HERALD_MIND_FLAY, 8000);
|
||||
events.ScheduleEvent(EVENT_HERALD_SHADOW, 5000);
|
||||
events.ScheduleEvent(EVENT_HERALD_SHIVER, 15000);
|
||||
events.ScheduleEvent(EVENT_HERALD_HEALTH, 1000);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_HERALD_VOLAZJ, IN_PROGRESS);
|
||||
pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
}
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *summon) { summons.Summon(summon); }
|
||||
|
||||
uint32 GetSpellForPhaseMask(uint32 phase)
|
||||
{
|
||||
uint32 spell = 0;
|
||||
switch (phase)
|
||||
{
|
||||
case 16:
|
||||
spell = SPELL_INSANITY_PHASING_1;
|
||||
break;
|
||||
case 32:
|
||||
spell = SPELL_INSANITY_PHASING_2;
|
||||
break;
|
||||
case 64:
|
||||
spell = SPELL_INSANITY_PHASING_3;
|
||||
break;
|
||||
case 128:
|
||||
spell = SPELL_INSANITY_PHASING_4;
|
||||
break;
|
||||
case 256:
|
||||
spell = SPELL_INSANITY_PHASING_5;
|
||||
break;
|
||||
}
|
||||
return spell;
|
||||
}
|
||||
|
||||
bool CheckPhaseMinions()
|
||||
{
|
||||
summons.RemoveNotExisting();
|
||||
if (summons.empty())
|
||||
{
|
||||
ResetPlayersPhaseMask();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16 phase = 1;
|
||||
for (std::list<uint64>::iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
{
|
||||
if (Creature *summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
phase |= summon->GetPhaseMask();
|
||||
}
|
||||
|
||||
Map::PlayerList const &players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
if (Player* pPlayer = i->GetSource())
|
||||
if ((pPlayer->GetPhaseMask() & phase) == 0)
|
||||
pPlayer->RemoveAurasDueToSpell(GetSpellForPhaseMask(pPlayer->GetPhaseMask()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (insanityHandled)
|
||||
{
|
||||
if (!CheckPhaseMinions())
|
||||
return;
|
||||
|
||||
insanityHandled = 0;
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveAurasDueToSpell(INSANITY_VISUAL);
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_HERALD_HEALTH:
|
||||
{
|
||||
if (insanityTimes == 0 && me->GetHealthPct() <= 66)
|
||||
{
|
||||
me->CastSpell(me, SPELL_INSANITY, false);
|
||||
insanityTimes++;
|
||||
}
|
||||
else if (insanityTimes == 1 && me->GetHealthPct() <= 33)
|
||||
{
|
||||
me->CastSpell(me, SPELL_INSANITY, false);
|
||||
insanityTimes++;
|
||||
}
|
||||
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
}
|
||||
case EVENT_HERALD_MIND_FLAY:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), IsHeroic() ? SPELL_MIND_FLAY_H : SPELL_MIND_FLAY, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
}
|
||||
case EVENT_HERALD_SHADOW:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), IsHeroic() ? SPELL_SHADOW_BOLT_VOLLEY_H : SPELL_SHADOW_BOLT_VOLLEY, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
}
|
||||
case EVENT_HERALD_SHIVER:
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
me->CastSpell(pTarget, IsHeroic() ? SPELL_SHIVER_H : SPELL_SHIVER, false);
|
||||
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HERALD_VOLAZJ, DONE);
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
summons.DespawnAll();
|
||||
ResetPlayersPhaseMask();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * /*victim*/)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new boss_volazjAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_volazj()
|
||||
{
|
||||
new boss_volazj();
|
||||
}
|
||||
@@ -1,538 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
|
||||
|
||||
enum Yells
|
||||
{
|
||||
TEXT_AGGRO = 0,
|
||||
TEXT_SACRIFICE_1 = 1,
|
||||
TEXT_SACRIFICE_2 = 2,
|
||||
TEXT_SLAY = 3,
|
||||
TEXT_DEATH = 4,
|
||||
TEXT_PREACHING = 5
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// VISUALS
|
||||
SPELL_PINK_SPHERE = 56075,
|
||||
SPELL_WHITE_SPHERE = 56102,
|
||||
SPELL_LIGHTNING_BOLTS = 56327,
|
||||
SPELL_ACTIVATE_INITIATE = 56868,
|
||||
SPELL_FREEZE_ANIM = 55591,
|
||||
SPELL_SACRIFICE_VISUAL = 56133,
|
||||
|
||||
// FIGHT
|
||||
SPELL_GIFT_OF_THE_HERALD = 56219,
|
||||
SPELL_CYCLONE_STRIKE = 56855, // Self
|
||||
SPELL_CYCLONE_STRIKE_H = 60030,
|
||||
SPELL_LIGHTNING_BOLT = 56891, // 40Y
|
||||
SPELL_LIGHTNING_BOLT_H = 60032, // 40Y
|
||||
SPELL_THUNDERSHOCK = 56926, // 30Y
|
||||
SPELL_THUNDERSHOCK_H = 60029 // 30Y
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_JEDOGA_CYCLONE = 1,
|
||||
EVENT_JEDOGA_LIGHTNING_BOLT = 2,
|
||||
EVENT_JEDOGA_THUNDERSHOCK = 3,
|
||||
EVENT_JEDOGA_MOVE_UP = 4,
|
||||
EVENT_JEDOGA_MOVE_DOWN = 5,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_JEDOGA_CONTROLLER = 30181,
|
||||
NPC_INITIATE = 30114,
|
||||
|
||||
ACTION_INITIATE_DIED = 1,
|
||||
ACTION_ACTIVATE = 2,
|
||||
ACTION_HERALD = 3,
|
||||
ACTION_SACRIFICE_FAILED = 4,
|
||||
|
||||
POINT_DOWN = 1,
|
||||
POINT_UP = 2,
|
||||
POINT_UP_START = 3,
|
||||
POINT_RITUAL = 4,
|
||||
};
|
||||
|
||||
const Position JedogaPosition[2] =
|
||||
{
|
||||
{372.330994f, -705.278015f, 0.624178f, 5.427970f},
|
||||
{372.330994f, -705.278015f, -16.179716f, 5.427970f}
|
||||
};
|
||||
|
||||
class boss_jedoga_shadowseeker : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_jedoga_shadowseeker() : CreatureScript("boss_jedoga_shadowseeker") { }
|
||||
|
||||
struct boss_jedoga_shadowseekerAI : public ScriptedAI
|
||||
{
|
||||
boss_jedoga_shadowseekerAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
uint8 initiates;
|
||||
uint32 introCheck;
|
||||
bool isFlying;
|
||||
bool startFly;
|
||||
|
||||
void JustSummoned(Creature *cr) { summons.Summon(cr); }
|
||||
void MoveInLineOfSight(Unit *) { }
|
||||
|
||||
void SpawnInitiate(bool start)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (start)
|
||||
{
|
||||
me->SummonCreature(NPC_INITIATE, 362.458f, -714.166f, -16.0964f, 0.977384f);
|
||||
me->SummonCreature(NPC_INITIATE, 368.781f, -713.932f, -16.0964f, 1.46608f);
|
||||
me->SummonCreature(NPC_INITIATE, 364.937f, -716.11f, -16.0964f, 1.25664f);
|
||||
me->SummonCreature(NPC_INITIATE, 362.02f, -719.828f, -16.0964f, 1.20428f);
|
||||
me->SummonCreature(NPC_INITIATE, 368.151f, -719.763f, -16.0964f, 1.53589f);
|
||||
me->SummonCreature(NPC_INITIATE, 392.276f, -695.895f, -16.0964f, 3.40339f);
|
||||
me->SummonCreature(NPC_INITIATE, 387.224f, -698.006f, -16.0964f, 3.36848f);
|
||||
me->SummonCreature(NPC_INITIATE, 389.626f, -702.3f, -16.0964f, 3.07178f);
|
||||
me->SummonCreature(NPC_INITIATE, 383.812f, -700.41f, -16.0964f, 3.15905f);
|
||||
me->SummonCreature(NPC_INITIATE, 385.693f, -694.376f, -16.0964f, 3.59538f);
|
||||
me->SummonCreature(NPC_INITIATE, 379.204f, -716.697f, -16.0964f, 2.1293f);
|
||||
me->SummonCreature(NPC_INITIATE, 375.4f, -711.434f, -16.0964f, 2.09439f);
|
||||
me->SummonCreature(NPC_INITIATE, 382.583f, -711.713f, -16.0964f, 2.53073f);
|
||||
me->SummonCreature(NPC_INITIATE, 379.049f, -712.899f, -16.0964f, 2.28638f);
|
||||
me->SummonCreature(NPC_INITIATE, 378.424f, -708.388f, -16.0964f, 2.58309f);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SummonCreature(NPC_INITIATE, 394.197f, -701.164f, -16.1797f, 4.09901f);
|
||||
me->SummonCreature(NPC_INITIATE, 391.003f, -697.814f, -16.1797f, 4.11079f);
|
||||
me->SummonCreature(NPC_INITIATE, 386.5f, -694.973f, -16.1797f, 4.12649f);
|
||||
me->SummonCreature(NPC_INITIATE, 381.762f, -692.405f, -16.1797f, 4.12257f);
|
||||
me->SummonCreature(NPC_INITIATE, 377.411f, -691.198f, -16.1797f, 4.6095f);
|
||||
me->SummonCreature(NPC_INITIATE, 395.122f, -686.975f, -16.1797f, 2.72063f);
|
||||
me->SummonCreature(NPC_INITIATE, 398.823f, -692.51f, -16.1797f, 2.72063f);
|
||||
me->SummonCreature(NPC_INITIATE, 399.819f, -698.815f, -16.1797f, 2.72455f);
|
||||
me->SummonCreature(NPC_INITIATE, 395.996f, -705.291f, -16.1309f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 391.505f, -710.883f, -16.0589f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 387.872f, -716.186f, -16.1797f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 383.276f, -722.431f, -16.1797f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 377.175f, -730.652f, -16.1797f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 371.625f, -735.5f, -16.1797f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 364.932f, -735.808f, -16.1797f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 358.966f, -733.199f, -16.1797f, 0.376213f);
|
||||
me->SummonCreature(NPC_INITIATE, 376.348f, -725.037f, -16.1797f, 5.65409f);
|
||||
me->SummonCreature(NPC_INITIATE, 371.435f, -723.892f, -16.1797f, 5.65409f);
|
||||
me->SummonCreature(NPC_INITIATE, 366.861f, -721.702f, -16.1797f, 5.65409f);
|
||||
me->SummonCreature(NPC_INITIATE, 362.343f, -718.019f, -16.1797f, 5.51665f);
|
||||
me->SummonCreature(NPC_INITIATE, 358.906f, -714.357f, -16.1797f, 5.35957f);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ActivateInitiate()
|
||||
{
|
||||
if (!summons.size())
|
||||
return;
|
||||
|
||||
uint8 rnd = urand(0, summons.size()-1);
|
||||
uint8 loop = 0;
|
||||
for (std::list<uint64>::iterator i = summons.begin(); i != summons.end();)
|
||||
{
|
||||
Creature *summon = ObjectAccessor::GetCreature(*me, *i);
|
||||
if (summon && summon->GetEntry() == NPC_INITIATE && loop >= rnd)
|
||||
{
|
||||
summon->AI()->DoAction(ACTION_ACTIVATE);
|
||||
break;
|
||||
}
|
||||
|
||||
++i;
|
||||
++loop;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ScheduleEvents()
|
||||
{
|
||||
events.RescheduleEvent(EVENT_JEDOGA_CYCLONE, 3000);
|
||||
events.RescheduleEvent(EVENT_JEDOGA_LIGHTNING_BOLT, 7000);
|
||||
events.RescheduleEvent(EVENT_JEDOGA_THUNDERSHOCK, 12000);
|
||||
events.RescheduleEvent(EVENT_JEDOGA_MOVE_UP, urand(20000, 25000));
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_INITIATE_DIED)
|
||||
{
|
||||
// all killed
|
||||
if (initiates++ > 13)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
MoveDown();
|
||||
initiates = 0;
|
||||
}
|
||||
}
|
||||
else if (param == ACTION_HERALD)
|
||||
{
|
||||
me->CastSpell(me, SPELL_GIFT_OF_THE_HERALD, true);
|
||||
events.DelayEvents(1001);
|
||||
events.ScheduleEvent(EVENT_JEDOGA_MOVE_DOWN, 1000);
|
||||
isFlying = false;
|
||||
}
|
||||
else if (param == ACTION_SACRIFICE_FAILED)
|
||||
{
|
||||
events.DelayEvents(1001);
|
||||
events.ScheduleEvent(EVENT_JEDOGA_MOVE_DOWN, 1000);
|
||||
isFlying = false;
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_JEDOGA_ACHIEVEMENT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, NOT_STARTED);
|
||||
pInstance->SetData(DATA_JEDOGA_ACHIEVEMENT, true);
|
||||
}
|
||||
|
||||
events.Reset();
|
||||
SpawnInitiate(true);
|
||||
initiates = 0;
|
||||
introCheck = 1; // leave 1
|
||||
isFlying = false;
|
||||
startFly = false;
|
||||
|
||||
MoveUp(true);
|
||||
me->CastSpell(me, SPELL_PINK_SPHERE, true);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_BOLTS, true);
|
||||
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, IN_PROGRESS);
|
||||
|
||||
Talk(TEXT_AGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* Victim)
|
||||
{
|
||||
if (!Victim || Victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Talk(TEXT_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
Talk(TEXT_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, DONE);
|
||||
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void MoveDown()
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->GetMotionMaster()->MovePoint(POINT_DOWN, JedogaPosition[1]);
|
||||
}
|
||||
|
||||
void MoveUp(bool start)
|
||||
{
|
||||
isFlying = true;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->Clear(true);
|
||||
me->SetFacingTo(5.66f);
|
||||
me->GetMotionMaster()->MovePoint((start ? POINT_UP_START : POINT_UP), JedogaPosition[0]);
|
||||
|
||||
me->SetDisableGravity(true);
|
||||
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 Type, uint32 PointId)
|
||||
{
|
||||
if (Type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (PointId == POINT_DOWN)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveAurasDueToSpell(SPELL_PINK_SPHERE);
|
||||
me->RemoveAurasDueToSpell(SPELL_LIGHTNING_BOLTS);
|
||||
me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
|
||||
|
||||
isFlying = false;
|
||||
me->SetInCombatWithZone();
|
||||
me->SetDisableGravity(false);
|
||||
if (!summons.HasEntry(NPC_INITIATE))
|
||||
SpawnInitiate(false);
|
||||
|
||||
if (UpdateVictim())
|
||||
{
|
||||
me->StopMoving();
|
||||
ScheduleEvents();
|
||||
AttackStart(me->GetVictim());
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
}
|
||||
}
|
||||
else if (PointId == POINT_UP)
|
||||
ActivateInitiate();
|
||||
else if (PointId == POINT_RITUAL)
|
||||
startFly = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// Start text
|
||||
if (introCheck)
|
||||
{
|
||||
introCheck += diff;
|
||||
if (introCheck >= 2000)
|
||||
{
|
||||
if (SelectTargetFromPlayerList(80.0f))
|
||||
{
|
||||
introCheck = 0;
|
||||
Talk(TEXT_PREACHING);
|
||||
}
|
||||
else
|
||||
introCheck = 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (startFly)
|
||||
{
|
||||
startFly = false;
|
||||
MoveUp(false);
|
||||
}
|
||||
|
||||
if (isFlying && !SelectTargetFromPlayerList(80.0f))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFlying)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_JEDOGA_CYCLONE:
|
||||
{
|
||||
me->CastSpell(me, IsHeroic() ? SPELL_CYCLONE_STRIKE_H : SPELL_CYCLONE_STRIKE, false);
|
||||
events.RepeatEvent(urand(10000, 14000));
|
||||
break;
|
||||
}
|
||||
case EVENT_JEDOGA_LIGHTNING_BOLT:
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->CastSpell(pTarget, IsHeroic() ? SPELL_LIGHTNING_BOLT_H : SPELL_LIGHTNING_BOLT, false);
|
||||
|
||||
events.RepeatEvent(urand(11000, 15000));
|
||||
break;
|
||||
}
|
||||
case EVENT_JEDOGA_THUNDERSHOCK:
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->CastSpell(pTarget, IsHeroic() ? SPELL_THUNDERSHOCK_H : SPELL_THUNDERSHOCK, false);
|
||||
|
||||
events.RepeatEvent(urand(16000, 22000));
|
||||
break;
|
||||
}
|
||||
case EVENT_JEDOGA_MOVE_UP:
|
||||
{
|
||||
events.PopEvent();
|
||||
if (!summons.HasEntry(NPC_INITIATE))
|
||||
break;
|
||||
|
||||
if (Creature *cr = me->SummonCreature(NPC_JEDOGA_CONTROLLER, 373.48f, -706.00f, -16.18f))
|
||||
{
|
||||
cr->CastSpell(cr, SPELL_SACRIFICE_VISUAL, true);
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
Talk(TEXT_SACRIFICE_1);
|
||||
|
||||
isFlying = true;
|
||||
me->GetMotionMaster()->Clear(true);
|
||||
me->GetMotionMaster()->MovePoint(POINT_RITUAL, JedogaPosition[1]);
|
||||
break;
|
||||
}
|
||||
case EVENT_JEDOGA_MOVE_DOWN:
|
||||
{
|
||||
Talk(TEXT_SACRIFICE_2);
|
||||
summons.DespawnEntry(NPC_JEDOGA_CONTROLLER);
|
||||
MoveDown();
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new boss_jedoga_shadowseekerAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_jedoga_initiand : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_jedoga_initiand() : CreatureScript("npc_jedoga_initiand") { }
|
||||
|
||||
struct npc_jedoga_initiandAI : public ScriptedAI
|
||||
{
|
||||
npc_jedoga_initiandAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
int32 Timer;
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (!Timer)
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!Timer)
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Timer = 0;
|
||||
|
||||
if (!pInstance)
|
||||
return;
|
||||
|
||||
if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS)
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveAurasDueToSpell(SPELL_WHITE_SPHERE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetOrientation(me->GetAngle(372.6f, -705.12f));
|
||||
me->SendMovementFlagUpdate();
|
||||
me->CastSpell(me, SPELL_WHITE_SPHERE, false);
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
if (!pInstance || Killer == me)
|
||||
return;
|
||||
|
||||
Creature* boss = me->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER));
|
||||
if (boss)
|
||||
{
|
||||
if (Timer)
|
||||
boss->AI()->DoAction(ACTION_SACRIFICE_FAILED);
|
||||
else
|
||||
boss->AI()->DoAction(ACTION_INITIATE_DIED);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_ACTIVATE)
|
||||
{
|
||||
Timer = 1500;
|
||||
me->CastSpell(me, SPELL_ACTIVATE_INITIATE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 Type, uint32 PointId)
|
||||
{
|
||||
if (Type == POINT_MOTION_TYPE && PointId == POINT_RITUAL)
|
||||
{
|
||||
Unit::Kill(me, me);
|
||||
me->DespawnOrUnsummon(5000);
|
||||
Creature* boss = me->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER));
|
||||
if (boss)
|
||||
boss->AI()->DoAction(ACTION_HERALD);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (Timer)
|
||||
{
|
||||
Timer -= diff;
|
||||
if (Timer <= 0)
|
||||
{
|
||||
me->CombatStop();
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveAurasDueToSpell(SPELL_WHITE_SPHERE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
float distance = me->GetDistance(373.48f, -706.00f, -16.18f);
|
||||
|
||||
if (distance < 9.0f)
|
||||
me->SetSpeed(MOVE_RUN, 0.5f, true);
|
||||
else if (distance < 15.0f)
|
||||
me->SetSpeed(MOVE_RUN, 0.75f, true);
|
||||
else if (distance < 20.0f)
|
||||
me->SetSpeed(MOVE_RUN, 1.0f, true);
|
||||
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MovePoint(POINT_RITUAL, 373.48f, -706.00f, -16.18f);
|
||||
|
||||
Timer = 10000000;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new npc_jedoga_initiandAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_jedoga_shadowseeker()
|
||||
{
|
||||
new boss_jedoga_shadowseeker();
|
||||
new npc_jedoga_initiand();
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BLOODTHIRST = 55968, //Trigger Spell + add aura
|
||||
SPELL_CONJURE_FLAME_SPHERE = 55931,
|
||||
SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
|
||||
SPELL_FLAME_SPHERE_VISUAL = 55928,
|
||||
SPELL_FLAME_SPHERE_PERIODIC = 55926,
|
||||
SPELL_FLAME_SPHERE_PERIODIC_H = 59508,
|
||||
SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
|
||||
SPELL_BEAM_VISUAL = 60342,
|
||||
SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
|
||||
SPELL_EMBRACE_OF_THE_VAMPYR_H = 59513,
|
||||
SPELL_VANISH = 55964,
|
||||
CREATURE_FLAME_SPHERE = 30106,
|
||||
CREATURE_FLAME_SPHERE_1 = 31686,
|
||||
CREATURE_FLAME_SPHERE_2 = 31687,
|
||||
};
|
||||
enum Misc
|
||||
{
|
||||
DATA_EMBRACE_DMG = 20000,
|
||||
DATA_EMBRACE_DMG_H = 40000,
|
||||
DATA_SPHERE_DISTANCE = 30,
|
||||
ACTION_FREE = 1,
|
||||
ACTION_SPHERE = 2,
|
||||
};
|
||||
|
||||
enum Event
|
||||
{
|
||||
EVENT_PRINCE_FLAME_SPHERES = 1,
|
||||
EVENT_PRINCE_VANISH = 2,
|
||||
EVENT_PRINCE_BLOODTHIRST = 3,
|
||||
EVENT_PRINCE_VANISH_RUN = 4,
|
||||
EVENT_PRINCE_RESCHEDULE = 5,
|
||||
};
|
||||
|
||||
#define DATA_GROUND_POSITION_Z 11.4f
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_1 = 0,
|
||||
SAY_WARNING = 1,
|
||||
SAY_AGGRO = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
SAY_FEED = 5,
|
||||
SAY_VANISH = 6,
|
||||
};
|
||||
|
||||
class boss_taldaram : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_taldaram() : CreatureScript("boss_taldaram") { }
|
||||
|
||||
struct boss_taldaramAI : public ScriptedAI
|
||||
{
|
||||
boss_taldaramAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint64 vanishTarget;
|
||||
uint32 vanishDamage;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (me->GetPositionZ() > 15.0f)
|
||||
me->CastSpell(me, SPELL_BEAM_VISUAL, true);
|
||||
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
vanishDamage = 0;
|
||||
vanishTarget = 0;
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, NOT_STARTED);
|
||||
|
||||
// Event not started
|
||||
if (pInstance->GetData(DATA_SPHERE_EVENT) == DONE)
|
||||
DoAction(ACTION_FREE);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_FREE)
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation());
|
||||
me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation(), true);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM), true);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
ScheduleEvents();
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
}
|
||||
|
||||
void ScheduleEvents()
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_PRINCE_FLAME_SPHERES, 10000);
|
||||
events.ScheduleEvent(EVENT_PRINCE_BLOODTHIRST, 10000);
|
||||
vanishTarget = 0;
|
||||
vanishDamage = 0;
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit *, const SpellInfo *spellInfo)
|
||||
{
|
||||
if (spellInfo->Id == SPELL_CONJURE_FLAME_SPHERE)
|
||||
summons.DoAction(ACTION_SPHERE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_PRINCE_BLOODTHIRST:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_BLOODTHIRST, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
}
|
||||
case EVENT_PRINCE_FLAME_SPHERES:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_CONJURE_FLAME_SPHERE, false);
|
||||
events.RescheduleEvent(EVENT_PRINCE_VANISH, 14000);
|
||||
Creature *cr;
|
||||
if (cr = me->SummonCreature(CREATURE_FLAME_SPHERE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+5.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS))
|
||||
summons.Summon(cr);
|
||||
|
||||
if (me->GetMap()->IsHeroic())
|
||||
{
|
||||
if (cr = me->SummonCreature(CREATURE_FLAME_SPHERE_1, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+5.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS))
|
||||
summons.Summon(cr);
|
||||
|
||||
if (cr = me->SummonCreature(CREATURE_FLAME_SPHERE_2, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+5.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS))
|
||||
summons.Summon(cr);
|
||||
}
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
}
|
||||
case EVENT_PRINCE_VANISH:
|
||||
{
|
||||
events.PopEvent();
|
||||
//Count alive players
|
||||
uint8 count = 0;
|
||||
Unit *pTarget;
|
||||
std::list<HostileReference *> t_list = me->getThreatManager().getThreatList();
|
||||
for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
|
||||
{
|
||||
pTarget = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
|
||||
if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->IsAlive())
|
||||
count++;
|
||||
}
|
||||
//He only vanishes if there are 3 or more alive players
|
||||
if (count > 2)
|
||||
{
|
||||
Talk(SAY_VANISH);
|
||||
me->CastSpell(me, SPELL_VANISH, false);
|
||||
|
||||
events.CancelEvent(EVENT_PRINCE_FLAME_SPHERES);
|
||||
events.CancelEvent(EVENT_PRINCE_BLOODTHIRST);
|
||||
events.ScheduleEvent(EVENT_PRINCE_VANISH_RUN, 2499);
|
||||
if (Unit* pEmbraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
vanishTarget = pEmbraceTarget->GetGUID();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_PRINCE_VANISH_RUN:
|
||||
{
|
||||
if (Unit *vT = ObjectAccessor::GetUnit(*me, vanishTarget))
|
||||
{
|
||||
me->UpdatePosition(vT->GetPositionX(), vT->GetPositionY(), vT->GetPositionZ(), me->GetAngle(vT), true);
|
||||
me->CastSpell(vT, SPELL_EMBRACE_OF_THE_VAMPYR, false);
|
||||
me->RemoveAura(SPELL_VANISH);
|
||||
}
|
||||
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_PRINCE_RESCHEDULE, 20000);
|
||||
break;
|
||||
}
|
||||
case EVENT_PRINCE_RESCHEDULE:
|
||||
{
|
||||
events.PopEvent();
|
||||
ScheduleEvents();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->IsVisible())
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (vanishTarget)
|
||||
{
|
||||
vanishDamage += damage;
|
||||
if (vanishDamage > (uint32) DUNGEON_MODE(DATA_EMBRACE_DMG, DATA_EMBRACE_DMG_H))
|
||||
{
|
||||
ScheduleEvents();
|
||||
me->CastStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * victim)
|
||||
{
|
||||
if (urand(0,1))
|
||||
return;
|
||||
|
||||
if (vanishTarget && victim->GetGUID() == vanishTarget)
|
||||
ScheduleEvents();
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new boss_taldaramAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_taldaram_flamesphere : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_taldaram_flamesphere() : CreatureScript("npc_taldaram_flamesphere") { }
|
||||
|
||||
struct npc_taldaram_flamesphereAI : public ScriptedAI
|
||||
{
|
||||
npc_taldaram_flamesphereAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 uiDespawnTimer;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_SPHERE)
|
||||
{
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_FLAME_SPHERE_PERIODIC_H : SPELL_FLAME_SPHERE_PERIODIC, true);
|
||||
|
||||
float angle = rand_norm()*2*M_PI;
|
||||
float x = me->GetPositionX() + DATA_SPHERE_DISTANCE * cos(angle);
|
||||
float y = me->GetPositionY() + DATA_SPHERE_DISTANCE * sin(angle);
|
||||
me->GetMotionMaster()->MovePoint(0, x, y, me->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (id == 0)
|
||||
me->DisappearAndDie();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->CastSpell(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT, true);
|
||||
me->CastSpell(me, SPELL_FLAME_SPHERE_VISUAL, true);
|
||||
uiDespawnTimer = 13*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) {}
|
||||
void MoveInLineOfSight(Unit * /*who*/) {}
|
||||
|
||||
void JustDied(Unit* /*who*/)
|
||||
{
|
||||
me->CastSpell(me, SPELL_FLAME_SPHERE_DEATH_EFFECT, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (uiDespawnTimer <= diff)
|
||||
me->DisappearAndDie();
|
||||
else
|
||||
uiDespawnTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return new npc_taldaram_flamesphereAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class go_prince_taldaram_sphere : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_prince_taldaram_sphere() : GameObjectScript("go_prince_taldaram_sphere") { }
|
||||
|
||||
bool OnGossipHello(Player * /*pPlayer*/, GameObject *pGO)
|
||||
{
|
||||
InstanceScript *pInstance = pGO->GetInstanceScript();
|
||||
if (!pInstance)
|
||||
return false;
|
||||
|
||||
Creature *pPrinceTaldaram = ObjectAccessor::GetCreature(*pGO, pInstance->GetData64(DATA_PRINCE_TALDARAM));
|
||||
if (pPrinceTaldaram && pPrinceTaldaram->IsAlive())
|
||||
{
|
||||
pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
pGO->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
if (pInstance->GetData(DATA_SPHERE_EVENT) == NOT_STARTED)
|
||||
{
|
||||
pInstance->SetData(DATA_SPHERE_EVENT, DONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
pPrinceTaldaram->AI()->DoAction(ACTION_FREE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_taldaram()
|
||||
{
|
||||
new boss_taldaram();
|
||||
new npc_taldaram_flamesphere();
|
||||
new go_prince_taldaram_sphere();
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DEF_AHNKAHET_H
|
||||
#define DEF_AHNKAHET_H
|
||||
|
||||
#define DATA_ELDER_NADOX 1
|
||||
#define DATA_PRINCE_TALDARAM 2
|
||||
#define DATA_JEDOGA_SHADOWSEEKER 3
|
||||
#define DATA_HERALD_VOLAZJ 4
|
||||
#define DATA_AMANITAR 5
|
||||
|
||||
#define DATA_ELDER_NADOX_EVENT 6
|
||||
#define DATA_PRINCE_TALDARAM_EVENT 7
|
||||
#define DATA_JEDOGA_SHADOWSEEKER_EVENT 8
|
||||
#define DATA_HERALD_VOLAZJ_EVENT 9
|
||||
#define DATA_AMANITAR_EVENT 10
|
||||
|
||||
#define DATA_SPHERE1 11
|
||||
#define DATA_SPHERE2 12
|
||||
#define DATA_SPHERE1_EVENT 13
|
||||
#define DATA_SPHERE2_EVENT 14
|
||||
#define DATA_PRINCE_TALDARAM_PLATFORM 15
|
||||
|
||||
#endif
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
|
||||
class instance_ahnkahet : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_ahnkahet() : InstanceMapScript("instance_ahnkahet", 619) { }
|
||||
|
||||
struct instance_ahnkahet_InstanceScript : public InstanceScript
|
||||
{
|
||||
instance_ahnkahet_InstanceScript(Map* pMap) : InstanceScript(pMap) {Initialize();};
|
||||
|
||||
uint64 Elder_Nadox;
|
||||
uint64 Prince_Taldaram;
|
||||
uint64 Jedoga_Shadowseeker;
|
||||
uint64 Herald_Volazj;
|
||||
uint64 Amanitar;
|
||||
|
||||
uint64 Prince_TaldaramPlatform;
|
||||
uint64 Prince_TaldaramGate;
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
uint32 spheres;
|
||||
|
||||
bool nadoxAchievement;
|
||||
bool jedogaAchievement;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
Elder_Nadox = 0;
|
||||
Prince_Taldaram = 0;
|
||||
Jedoga_Shadowseeker = 0;
|
||||
Herald_Volazj = 0;
|
||||
Amanitar = 0;
|
||||
|
||||
Prince_TaldaramPlatform = 0;
|
||||
Prince_TaldaramGate = 0;
|
||||
spheres = NOT_STARTED;
|
||||
|
||||
nadoxAchievement = false;
|
||||
jedogaAchievement = false;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case NPC_ELDER_NADOX:
|
||||
Elder_Nadox = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_PRINCE_TALDARAM:
|
||||
Prince_Taldaram = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_JEDOGA_SHADOWSEEKER:
|
||||
Jedoga_Shadowseeker = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_HERALD_JOLAZJ:
|
||||
Herald_Volazj = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_AMANITAR:
|
||||
Amanitar = pCreature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case 193564:
|
||||
Prince_TaldaramPlatform = pGo->GetGUID();
|
||||
if (m_auiEncounter[1] == DONE)
|
||||
HandleGameObject(0,true,pGo);
|
||||
|
||||
break;
|
||||
case 193093:
|
||||
if (spheres == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
else
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
break;
|
||||
case 193094:
|
||||
if (spheres == DONE)
|
||||
{
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
else
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
|
||||
break;
|
||||
case 192236:
|
||||
Prince_TaldaramGate = pGo->GetGUID(); // Web gate past Prince Taldaram
|
||||
if (m_auiEncounter[1] == DONE)
|
||||
HandleGameObject(0,true,pGo);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch(identifier)
|
||||
{
|
||||
case DATA_ELDER_NADOX: return Elder_Nadox;
|
||||
case DATA_PRINCE_TALDARAM: return Prince_Taldaram;
|
||||
case DATA_JEDOGA_SHADOWSEEKER: return Jedoga_Shadowseeker;
|
||||
case DATA_HERALD_VOLAZJ: return Herald_Volazj;
|
||||
case DATA_AMANITAR: return Amanitar;
|
||||
case DATA_PRINCE_TALDARAM_PLATFORM: return Prince_TaldaramPlatform;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
|
||||
{
|
||||
switch(criteria_id)
|
||||
{
|
||||
case 7317: // Respect Your Elders (2038)
|
||||
return nadoxAchievement;
|
||||
case 7359: // Volunteer Work (2056)
|
||||
return jedogaAchievement;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_HERALD_VOLAZJ_EVENT:
|
||||
case DATA_AMANITAR_EVENT:
|
||||
case DATA_ELDER_NADOX_EVENT:
|
||||
case DATA_JEDOGA_SHADOWSEEKER_EVENT:
|
||||
m_auiEncounter[type] = data;
|
||||
break;
|
||||
case DATA_PRINCE_TALDARAM_EVENT:
|
||||
if (data == DONE)
|
||||
HandleGameObject(Prince_TaldaramGate, true);
|
||||
|
||||
m_auiEncounter[type] = data;
|
||||
break;
|
||||
case DATA_SPHERE_EVENT:
|
||||
spheres = data;
|
||||
break;
|
||||
case DATA_NADOX_ACHIEVEMENT:
|
||||
nadoxAchievement = (bool)data;
|
||||
return;
|
||||
case DATA_JEDOGA_ACHIEVEMENT:
|
||||
jedogaAchievement = (bool)data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_ELDER_NADOX_EVENT:
|
||||
case DATA_PRINCE_TALDARAM_EVENT:
|
||||
case DATA_JEDOGA_SHADOWSEEKER_EVENT:
|
||||
case DATA_HERALD_VOLAZJ:
|
||||
case DATA_AMANITAR_EVENT:
|
||||
return m_auiEncounter[type];
|
||||
|
||||
case DATA_SPHERE_EVENT:
|
||||
return spheres;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "A K " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' '
|
||||
<< m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' '
|
||||
<< spheres;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1, data2, data3, data4, data5;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5;
|
||||
|
||||
if (dataHead1 == 'A' && dataHead2 == 'K')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
m_auiEncounter[2] = data2;
|
||||
m_auiEncounter[3] = data3;
|
||||
m_auiEncounter[4] = data4;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
|
||||
spheres = data5;
|
||||
|
||||
} else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap *map) const
|
||||
{
|
||||
return new instance_ahnkahet_InstanceScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_ahnkahet()
|
||||
{
|
||||
new instance_ahnkahet;
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
# Copyright (C)
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
set(scripts_STAT_SRCS
|
||||
${scripts_STAT_SRCS}
|
||||
Northrend/isle_of_conquest.cpp
|
||||
Northrend/zone_storm_peaks.cpp
|
||||
Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
|
||||
Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
|
||||
Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h
|
||||
Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
|
||||
Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
|
||||
Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
|
||||
Northrend/Ulduar/Ulduar/ulduar.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_thorim.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_ignis.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
|
||||
Northrend/Ulduar/Ulduar/instance_ulduar.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_auriaya.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_hodir.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_xt002.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_mimiron.cpp
|
||||
Northrend/Ulduar/Ulduar/ulduar.h
|
||||
Northrend/Ulduar/Ulduar/boss_freya.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_razorscale.cpp
|
||||
Northrend/Ulduar/Ulduar/boss_kologarn.cpp
|
||||
Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
|
||||
Northrend/Ulduar/HallsOfStone/halls_of_stone.h
|
||||
Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
|
||||
Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp
|
||||
Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp
|
||||
Northrend/Ulduar/HallsOfStone/halls_of_stone.h
|
||||
Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp
|
||||
Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
|
||||
Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h
|
||||
Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
|
||||
Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
|
||||
Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h
|
||||
Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
|
||||
Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
|
||||
Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
|
||||
Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
|
||||
Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
|
||||
Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
|
||||
Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
|
||||
Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
|
||||
Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp
|
||||
Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
|
||||
Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
|
||||
Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp
|
||||
Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
|
||||
Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
|
||||
Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
|
||||
Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.cpp
|
||||
Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
|
||||
Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
|
||||
Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
|
||||
Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h
|
||||
Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
|
||||
Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
|
||||
Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
|
||||
Northrend/Nexus/Oculus/boss_eregos.cpp
|
||||
Northrend/Nexus/Oculus/boss_drakos.cpp
|
||||
Northrend/Nexus/Oculus/oculus.h
|
||||
Northrend/Nexus/Oculus/boss_varos.cpp
|
||||
Northrend/Nexus/Oculus/boss_urom.cpp
|
||||
Northrend/Nexus/Oculus/oculus.cpp
|
||||
Northrend/Nexus/Oculus/instance_oculus.cpp
|
||||
Northrend/Nexus/Nexus/boss_commander_stoutbeard_kolurg.cpp
|
||||
Northrend/Nexus/Nexus/boss_ormorok.cpp
|
||||
Northrend/Nexus/Nexus/boss_magus_telestra.cpp
|
||||
Northrend/Nexus/Nexus/instance_nexus.cpp
|
||||
Northrend/Nexus/Nexus/boss_keristrasza.cpp
|
||||
Northrend/Nexus/Nexus/boss_anomalus.cpp
|
||||
Northrend/Nexus/Nexus/nexus.h
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.h
|
||||
Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheChampion/instance_trial_of_the_champion.cpp
|
||||
Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
|
||||
Northrend/Naxxramas/boss_loatheb.cpp
|
||||
Northrend/Naxxramas/boss_anubrekhan.cpp
|
||||
Northrend/Naxxramas/boss_maexxna.cpp
|
||||
Northrend/Naxxramas/boss_patchwerk.cpp
|
||||
Northrend/Naxxramas/boss_gothik.cpp
|
||||
Northrend/Naxxramas/boss_faerlina.cpp
|
||||
Northrend/Naxxramas/boss_gluth.cpp
|
||||
Northrend/Naxxramas/boss_four_horsemen.cpp
|
||||
Northrend/Naxxramas/naxxramas.h
|
||||
Northrend/Naxxramas/boss_kelthuzad.cpp
|
||||
Northrend/Naxxramas/boss_heigan.cpp
|
||||
Northrend/Naxxramas/boss_thaddius.cpp
|
||||
Northrend/Naxxramas/boss_razuvious.cpp
|
||||
Northrend/Naxxramas/boss_sapphiron.cpp
|
||||
Northrend/Naxxramas/instance_naxxramas.cpp
|
||||
Northrend/Naxxramas/boss_grobbulus.cpp
|
||||
Northrend/Naxxramas/boss_noth.cpp
|
||||
Northrend/zone_crystalsong_forest.cpp
|
||||
Northrend/VaultOfArchavon/boss_archavon.cpp
|
||||
Northrend/VaultOfArchavon/boss_koralon.cpp
|
||||
Northrend/VaultOfArchavon/vault_of_archavon.h
|
||||
Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp
|
||||
Northrend/VaultOfArchavon/boss_emalon.cpp
|
||||
Northrend/VaultOfArchavon/boss_toravon.cpp
|
||||
Northrend/zone_sholazar_basin.cpp
|
||||
Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
|
||||
Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
|
||||
Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
|
||||
Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
|
||||
Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
|
||||
Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
|
||||
Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
|
||||
Northrend/UtgardeKeep/UtgardeKeep/boss_skarvald_dalronn.cpp
|
||||
Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.h
|
||||
Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp
|
||||
Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
|
||||
Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp
|
||||
Northrend/zone_dragonblight.cpp
|
||||
Northrend/zone_grizzly_hills.cpp
|
||||
Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h
|
||||
Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
|
||||
Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
|
||||
Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
|
||||
Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/boss_herald_volazj.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/boss_prince_taldaram.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/instance_ahnkahet.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/boss_elder_nadox.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/boss_amanitar.cpp
|
||||
Northrend/AzjolNerub/ahnkahet/ahnkahet.h
|
||||
Northrend/VioletHold/boss_zuramat.cpp
|
||||
Northrend/VioletHold/instance_violet_hold.cpp
|
||||
Northrend/VioletHold/boss_lavanthor.cpp
|
||||
Northrend/VioletHold/boss_cyanigosa.cpp
|
||||
Northrend/VioletHold/violet_hold.h
|
||||
Northrend/VioletHold/boss_ichoron.cpp
|
||||
Northrend/VioletHold/boss_moragg.cpp
|
||||
Northrend/VioletHold/boss_xevozz.cpp
|
||||
Northrend/VioletHold/boss_erekem.cpp
|
||||
Northrend/VioletHold/violet_hold.cpp
|
||||
Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
|
||||
Northrend/IcecrownCitadel/icecrown_citadel.cpp
|
||||
Northrend/IcecrownCitadel/icecrown_citadel.h
|
||||
Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp
|
||||
Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
|
||||
Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
|
||||
Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
|
||||
Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
|
||||
Northrend/IcecrownCitadel/boss_festergut.cpp
|
||||
Northrend/IcecrownCitadel/boss_rotface.cpp
|
||||
Northrend/IcecrownCitadel/boss_professor_putricide.cpp
|
||||
Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
|
||||
Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
|
||||
Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
|
||||
Northrend/IcecrownCitadel/boss_sindragosa.cpp
|
||||
Northrend/IcecrownCitadel/boss_the_lich_king.cpp
|
||||
Northrend/zone_zuldrak.cpp
|
||||
Northrend/zone_wintergrasp.cpp
|
||||
Northrend/zone_icecrown.cpp
|
||||
Northrend/Gundrak/boss_slad_ran.cpp
|
||||
Northrend/Gundrak/instance_gundrak.cpp
|
||||
Northrend/Gundrak/boss_drakkari_colossus.cpp
|
||||
Northrend/Gundrak/gundrak.h
|
||||
Northrend/Gundrak/boss_gal_darah.cpp
|
||||
Northrend/Gundrak/boss_moorabi.cpp
|
||||
Northrend/Gundrak/boss_eck.cpp
|
||||
Northrend/zone_borean_tundra.cpp
|
||||
Northrend/zone_howling_fjord.cpp
|
||||
Northrend/zone_dalaran.cpp
|
||||
Northrend/DraktharonKeep/boss_trollgore.cpp
|
||||
Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp
|
||||
Northrend/DraktharonKeep/boss_novos.cpp
|
||||
Northrend/DraktharonKeep/drak_tharon_keep.h
|
||||
Northrend/DraktharonKeep/boss_tharon_ja.cpp
|
||||
Northrend/DraktharonKeep/boss_dred.cpp
|
||||
)
|
||||
|
||||
AC_ADD_SCRIPT_LOADER("Northrend" "ScriptLoader.h")
|
||||
|
||||
message(" -> Prepared: Northrend")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "obsidian_sanctum.h"
|
||||
#include "Player.h"
|
||||
|
||||
class instance_obsidian_sanctum : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_obsidian_sanctum() : InstanceMapScript("instance_obsidian_sanctum", 615) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
|
||||
{
|
||||
return new instance_obsidian_sanctum_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
struct instance_obsidian_sanctum_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_obsidian_sanctum_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {}
|
||||
|
||||
uint64 m_uiSartharionGUID;
|
||||
uint64 m_uiTenebronGUID;
|
||||
uint64 m_uiShadronGUID;
|
||||
uint64 m_uiVesperonGUID;
|
||||
uint32 Encounters[MAX_ENCOUNTERS];
|
||||
uint64 m_uiPortalGUID;
|
||||
uint8 portalCount;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_uiSartharionGUID = 0;
|
||||
m_uiTenebronGUID = 0;
|
||||
m_uiShadronGUID = 0;
|
||||
m_uiVesperonGUID = 0;
|
||||
m_uiPortalGUID = 0;
|
||||
portalCount = 0;
|
||||
memset(&Encounters, 0, sizeof(Encounters));
|
||||
};
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case NPC_SARTHARION:
|
||||
m_uiSartharionGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_TENEBRON:
|
||||
m_uiTenebronGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_SHADRON:
|
||||
m_uiShadronGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_VESPERON:
|
||||
m_uiVesperonGUID = pCreature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case BOSS_SARTHARION_EVENT:
|
||||
case BOSS_TENEBRON_EVENT:
|
||||
case BOSS_SHADRON_EVENT:
|
||||
case BOSS_VESPERON_EVENT:
|
||||
return Encounters[id];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 uiData) const
|
||||
{
|
||||
switch(uiData)
|
||||
{
|
||||
case DATA_SARTHARION:
|
||||
return m_uiSartharionGUID;
|
||||
case DATA_TENEBRON:
|
||||
return m_uiTenebronGUID;
|
||||
case DATA_SHADRON:
|
||||
return m_uiShadronGUID;
|
||||
case DATA_VESPERON:
|
||||
return m_uiVesperonGUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
|
||||
{
|
||||
switch(criteria_id)
|
||||
{
|
||||
// Gonna Go When the Volcano Blows (10 player) (2047)
|
||||
case 7326:
|
||||
// Gonna Go When the Volcano Blows (25 player) (2048)
|
||||
case 7327:
|
||||
if (Creature* cr = instance->GetCreature(m_uiSartharionGUID))
|
||||
if (!cr->AI()->GetData(source->GetGUIDLow()))
|
||||
return true;
|
||||
break;
|
||||
// Less Is More (10 player) (624)
|
||||
case 7189:
|
||||
case 7190:
|
||||
case 7191:
|
||||
case 522:
|
||||
if (instance->GetPlayersCountExceptGMs() < 9)
|
||||
return true;
|
||||
break;
|
||||
// Less Is More (25 player) (1877)
|
||||
case 7185:
|
||||
case 7186:
|
||||
case 7187:
|
||||
case 7188:
|
||||
if (instance->GetPlayersCountExceptGMs() < 21)
|
||||
return true;
|
||||
break;
|
||||
// Twilight Assist (10 player) (2049)
|
||||
case 7328:
|
||||
// Twilight Assist (25 player) (2052)
|
||||
case 7331:
|
||||
if (Creature* cr = instance->GetCreature(m_uiSartharionGUID))
|
||||
if (cr->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 1)
|
||||
return true;
|
||||
break;
|
||||
// Twilight Duo (10 player) (2050)
|
||||
case 7329:
|
||||
// Twilight Duo (25 player) (2053)
|
||||
case 7332:
|
||||
if (Creature* cr = instance->GetCreature(m_uiSartharionGUID))
|
||||
if (cr->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 2)
|
||||
return true;
|
||||
break;
|
||||
// Twilight Zone (10 player) (2051)
|
||||
case 7330:
|
||||
// Twilight Zone (25 player) (2054)
|
||||
case 7333:
|
||||
if (Creature* cr = instance->GetCreature(m_uiSartharionGUID))
|
||||
if (cr->AI()->GetData(DATA_ACHIEVEMENT_DRAGONS_COUNT) >= 3)
|
||||
return true;
|
||||
break;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case BOSS_SARTHARION_EVENT:
|
||||
case BOSS_TENEBRON_EVENT:
|
||||
case BOSS_SHADRON_EVENT:
|
||||
case BOSS_VESPERON_EVENT:
|
||||
Encounters[type] = data;
|
||||
break;
|
||||
case DATA_ADD_PORTAL:
|
||||
if (!m_uiPortalGUID)
|
||||
{
|
||||
if (Creature* cr = instance->GetCreature(m_uiSartharionGUID))
|
||||
if (GameObject* go = cr->SummonGameObject(GO_TWILIGHT_PORTAL, 3247.29f, 529.804f, 58.9595f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
||||
{
|
||||
cr->RemoveGameObject(go, false);
|
||||
m_uiPortalGUID = go->GetGUID();
|
||||
}
|
||||
|
||||
portalCount = 0;
|
||||
}
|
||||
|
||||
portalCount++;
|
||||
break;
|
||||
case DATA_CLEAR_PORTAL:
|
||||
portalCount--;
|
||||
if (!portalCount || data == 2)
|
||||
{
|
||||
if (GameObject* go = instance->GetGameObject(m_uiPortalGUID))
|
||||
go->Delete();
|
||||
|
||||
DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_SHIFT);
|
||||
m_uiPortalGUID = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "O S " << Encounters[0] << ' ' << Encounters[1] << ' ' << Encounters[2] << ' ' << Encounters[3];
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* strIn)
|
||||
{
|
||||
if (!strIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(strIn);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
|
||||
std::istringstream loadStream(strIn);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
|
||||
if (dataHead1 == 'O' && dataHead2 == 'S')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
loadStream >> Encounters[i];
|
||||
if (Encounters[i] == IN_PROGRESS)
|
||||
Encounters[i] = NOT_STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_obsidian_sanctum()
|
||||
{
|
||||
new instance_obsidian_sanctum();
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_OBSIDIAN_SANCTUM_H
|
||||
#define DEF_OBSIDIAN_SANCTUM_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
// Encounter
|
||||
BOSS_SARTHARION_EVENT = 0,
|
||||
BOSS_TENEBRON_EVENT = 1,
|
||||
BOSS_VESPERON_EVENT = 2,
|
||||
BOSS_SHADRON_EVENT = 3,
|
||||
MAX_ENCOUNTERS = 4,
|
||||
|
||||
// GUIDs
|
||||
DATA_SARTHARION = 10,
|
||||
DATA_TENEBRON = 11,
|
||||
DATA_SHADRON = 12,
|
||||
DATA_VESPERON = 13,
|
||||
|
||||
// Portal
|
||||
DATA_CLEAR_PORTAL = 20,
|
||||
DATA_ADD_PORTAL = 21,
|
||||
|
||||
// Achievements
|
||||
DATA_ACHIEVEMENT_DRAGONS_COUNT = 30,
|
||||
DATA_VOLCANO_BLOWS = 31,
|
||||
|
||||
// NPCs
|
||||
NPC_SARTHARION = 28860,
|
||||
NPC_TENEBRON = 30452,
|
||||
NPC_SHADRON = 30451,
|
||||
NPC_VESPERON = 30449,
|
||||
NPC_FIRE_CYCLONE = 30648,
|
||||
|
||||
// GOs
|
||||
GO_TWILIGHT_PORTAL = 193988,
|
||||
GO_NORMAL_PORTAL = 193989,
|
||||
|
||||
// Spells
|
||||
SPELL_TWILIGHT_SHIFT = 57620,
|
||||
SPELL_TWILIGHT_TORMENT_SARTHARION = 58853,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,473 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "ruby_sanctum.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_BALTHARUS_INTRO = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_KILL = 2,
|
||||
SAY_CLONE = 3,
|
||||
SAY_DEATH = 4,
|
||||
|
||||
SAY_XERESTRASZA_EVENT = 0,
|
||||
SAY_XERESTRASZA_EVENT_1 = 1,
|
||||
SAY_XERESTRASZA_EVENT_2 = 2,
|
||||
SAY_XERESTRASZA_EVENT_3 = 3,
|
||||
SAY_XERESTRASZA_EVENT_4 = 4,
|
||||
SAY_XERESTRASZA_EVENT_5 = 5,
|
||||
SAY_XERESTRASZA_EVENT_6 = 6,
|
||||
SAY_XERESTRASZA_EVENT_7 = 7,
|
||||
SAY_XERESTRASZA_INTRO = 8
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BARRIER_CHANNEL = 76221,
|
||||
|
||||
SPELL_ENERVATING_BRAND = 74502,
|
||||
SPELL_SIPHONED_MIGHT = 74507,
|
||||
SPELL_CLEAVE = 40504,
|
||||
SPELL_BLADE_TEMPEST = 75125,
|
||||
SPELL_CLONE = 74511,
|
||||
SPELL_REPELLING_WAVE = 74509,
|
||||
SPELL_CLEAR_DEBUFFS = 34098,
|
||||
SPELL_SPAWN_EFFECT = 64195
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_BLADE_TEMPEST = 1,
|
||||
EVENT_CLEAVE = 2,
|
||||
EVENT_ENERVATING_BRAND = 3,
|
||||
EVENT_CHECK_HEALTH1 = 4,
|
||||
EVENT_CHECK_HEALTH2 = 5,
|
||||
EVENT_CHECK_HEALTH3 = 6,
|
||||
EVENT_KILL_TALK = 7,
|
||||
EVENT_SUMMON_CLONE = 8,
|
||||
|
||||
EVENT_XERESTRASZA_EVENT_0 = 1,
|
||||
EVENT_XERESTRASZA_EVENT_1 = 2,
|
||||
EVENT_XERESTRASZA_EVENT_2 = 3,
|
||||
EVENT_XERESTRASZA_EVENT_3 = 4,
|
||||
EVENT_XERESTRASZA_EVENT_4 = 5,
|
||||
EVENT_XERESTRASZA_EVENT_5 = 6,
|
||||
EVENT_XERESTRASZA_EVENT_6 = 7,
|
||||
EVENT_XERESTRASZA_EVENT_7 = 8
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_INTRO_BALTHARUS = -3975101,
|
||||
ACTION_BALTHARUS_DEATH = -3975102,
|
||||
ACTION_CLONE = 1
|
||||
};
|
||||
|
||||
class DelayedTalk : public BasicEvent
|
||||
{
|
||||
public:
|
||||
DelayedTalk(Creature* owner, uint32 talkId) : _owner(owner), _talkId(talkId) { }
|
||||
|
||||
bool Execute(uint64 /*execTime*/, uint32 /*diff*/)
|
||||
{
|
||||
_owner->AI()->Talk(_talkId);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature* _owner;
|
||||
uint32 _talkId;
|
||||
};
|
||||
|
||||
class RestoreFight : public BasicEvent
|
||||
{
|
||||
public:
|
||||
RestoreFight(Creature* owner) : _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*execTime*/, uint32 /*diff*/)
|
||||
{
|
||||
_owner->SetReactState(REACT_AGGRESSIVE);
|
||||
_owner->SetInCombatWithZone();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature* _owner;
|
||||
};
|
||||
|
||||
class boss_baltharus_the_warborn : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_baltharus_the_warborn() : CreatureScript("boss_baltharus_the_warborn") { }
|
||||
|
||||
struct boss_baltharus_the_warbornAI : public BossAI
|
||||
{
|
||||
boss_baltharus_the_warbornAI(Creature* creature) : BossAI(creature, DATA_BALTHARUS_THE_WARBORN)
|
||||
{
|
||||
_introDone = false;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
me->CastSpell(me, SPELL_BARRIER_CHANNEL, false);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
BossAI::JustReachedHome();
|
||||
me->CastSpell(me, SPELL_BARRIER_CHANNEL, false);
|
||||
}
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
if (action == ACTION_INTRO_BALTHARUS && !_introDone)
|
||||
{
|
||||
_introDone = true;
|
||||
me->m_Events.AddEvent(new DelayedTalk(me, SAY_BALTHARUS_INTRO), me->m_Events.CalculateTime(6000));
|
||||
}
|
||||
else if (action == ACTION_CLONE)
|
||||
{
|
||||
me->CastSpell(me, SPELL_REPELLING_WAVE, false);
|
||||
me->CastSpell(me, SPELL_CLEAR_DEBUFFS, false);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CLONE, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::EnterCombat(who);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 11000);
|
||||
events.ScheduleEvent(EVENT_ENERVATING_BRAND, 13000);
|
||||
events.ScheduleEvent(EVENT_BLADE_TEMPEST, 15000);
|
||||
if (!Is25ManRaid())
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH1, 1000);
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH3, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
|
||||
if (Creature* xerestrasza = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_XERESTRASZA)))
|
||||
xerestrasza->AI()->DoAction(ACTION_BALTHARUS_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
summon->SetHealth(me->GetHealth());
|
||||
summon->CastSpell(summon, SPELL_SPAWN_EFFECT, true);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->m_Events.AddEvent(new RestoreFight(summon), summon->m_Events.CalculateTime(2000));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 24000);
|
||||
break;
|
||||
case EVENT_BLADE_TEMPEST:
|
||||
me->CastSpell(me, SPELL_BLADE_TEMPEST, false);
|
||||
events.ScheduleEvent(EVENT_BLADE_TEMPEST, 24000);
|
||||
break;
|
||||
case EVENT_ENERVATING_BRAND:
|
||||
for (uint8 i = 0; i < RAID_MODE<uint8>(2, 4, 2, 4); i++)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true, -SPELL_ENERVATING_BRAND))
|
||||
me->CastSpell(target, SPELL_ENERVATING_BRAND, true);
|
||||
events.ScheduleEvent(EVENT_ENERVATING_BRAND, 26000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH1:
|
||||
if (me->HealthBelowPct(50))
|
||||
{
|
||||
DoAction(ACTION_CLONE);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH1, 1000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH2:
|
||||
if (me->HealthBelowPct(66))
|
||||
{
|
||||
DoAction(ACTION_CLONE);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH3:
|
||||
if (me->HealthBelowPct(33))
|
||||
{
|
||||
DoAction(ACTION_CLONE);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH3, 1000);
|
||||
break;
|
||||
case EVENT_SUMMON_CLONE:
|
||||
me->CastSpell(me, SPELL_CLONE, false);
|
||||
Talk(SAY_CLONE);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _introDone;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_baltharus_the_warbornAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_baltharus_the_warborn_clone : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_baltharus_the_warborn_clone() : CreatureScript("npc_baltharus_the_warborn_clone") { }
|
||||
|
||||
struct npc_baltharus_the_warborn_cloneAI : public ScriptedAI
|
||||
{
|
||||
npc_baltharus_the_warborn_cloneAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_CLEAVE, urand(5000, 10000));
|
||||
_events.ScheduleEvent(EVENT_BLADE_TEMPEST, urand(18000, 25000));
|
||||
_events.ScheduleEvent(EVENT_ENERVATING_BRAND, urand(10000, 15000));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
_events.ScheduleEvent(EVENT_CLEAVE, 24000);
|
||||
break;
|
||||
case EVENT_BLADE_TEMPEST:
|
||||
me->CastSpell(me, SPELL_BLADE_TEMPEST, false);
|
||||
_events.ScheduleEvent(EVENT_BLADE_TEMPEST, 24000);
|
||||
break;
|
||||
case EVENT_ENERVATING_BRAND:
|
||||
for (uint8 i = 0; i < RAID_MODE<uint8>(4, 10, 4, 10); i++)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true, -SPELL_ENERVATING_BRAND))
|
||||
me->CastSpell(target, SPELL_ENERVATING_BRAND, true);
|
||||
_events.ScheduleEvent(EVENT_ENERVATING_BRAND, 26000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_baltharus_the_warborn_cloneAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_baltharus_enervating_brand_trigger : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_baltharus_enervating_brand_trigger() : SpellScriptLoader("spell_baltharus_enervating_brand_trigger") { }
|
||||
|
||||
class spell_baltharus_enervating_brand_trigger_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_baltharus_enervating_brand_trigger_SpellScript);
|
||||
|
||||
void CheckDistance()
|
||||
{
|
||||
if (Unit* caster = GetOriginalCaster())
|
||||
if (Unit* target = GetHitUnit())
|
||||
if (target == GetCaster())
|
||||
target->CastSpell(caster, SPELL_SIPHONED_MIGHT, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnHit += SpellHitFn(spell_baltharus_enervating_brand_trigger_SpellScript::CheckDistance);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_baltharus_enervating_brand_trigger_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class npc_xerestrasza : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_xerestrasza() : CreatureScript("npc_xerestrasza") { }
|
||||
|
||||
struct npc_xerestraszaAI : public ScriptedAI
|
||||
{
|
||||
npc_xerestraszaAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_isIntro = true;
|
||||
_introDone = false;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_events.Reset();
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER);
|
||||
|
||||
// Xinef: after soft reset npc is no longer present
|
||||
if (me->GetInstanceScript()->GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE)
|
||||
me->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
if (action == ACTION_BALTHARUS_DEATH)
|
||||
{
|
||||
me->setActive(true);
|
||||
_isIntro = false;
|
||||
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_0, 6000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_1, 22000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_2, 31000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_3, 38000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_4, 48000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_5, 57000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_6, 67000);
|
||||
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_7, 75000);
|
||||
}
|
||||
else if (action == ACTION_INTRO_BALTHARUS && !_introDone && me->IsAlive())
|
||||
{
|
||||
_introDone = true;
|
||||
Talk(SAY_XERESTRASZA_INTRO);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (_isIntro)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_XERESTRASZA_EVENT_0:
|
||||
Talk(SAY_XERESTRASZA_EVENT);
|
||||
me->SetWalk(true);
|
||||
me->GetMotionMaster()->MovePoint(0, 3151.236f, 379.8733f, 86.31996f);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_1:
|
||||
Talk(SAY_XERESTRASZA_EVENT_1);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_2:
|
||||
Talk(SAY_XERESTRASZA_EVENT_2);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_3:
|
||||
Talk(SAY_XERESTRASZA_EVENT_3);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_4:
|
||||
Talk(SAY_XERESTRASZA_EVENT_4);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_5:
|
||||
Talk(SAY_XERESTRASZA_EVENT_5);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_6:
|
||||
Talk(SAY_XERESTRASZA_EVENT_6);
|
||||
break;
|
||||
case EVENT_XERESTRASZA_EVENT_7:
|
||||
me->SetFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER);
|
||||
Talk(SAY_XERESTRASZA_EVENT_7);
|
||||
me->setActive(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
bool _isIntro;
|
||||
bool _introDone;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_xerestraszaAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class at_baltharus_plateau : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_baltharus_plateau() : AreaTriggerScript("at_baltharus_plateau") { }
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/)
|
||||
{
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
{
|
||||
if (Creature* xerestrasza = ObjectAccessor::GetCreature(*player, instance->GetData64(NPC_XERESTRASZA)))
|
||||
xerestrasza->AI()->DoAction(ACTION_INTRO_BALTHARUS);
|
||||
|
||||
if (Creature* baltharus = ObjectAccessor::GetCreature(*player, instance->GetData64(NPC_BALTHARUS_THE_WARBORN)))
|
||||
baltharus->AI()->DoAction(ACTION_INTRO_BALTHARUS);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_baltharus_the_warborn()
|
||||
{
|
||||
new boss_baltharus_the_warborn();
|
||||
new npc_baltharus_the_warborn_clone();
|
||||
new spell_baltharus_enervating_brand_trigger();
|
||||
new npc_xerestrasza();
|
||||
new at_baltharus_plateau();
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ruby_sanctum.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_ADDS = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// General Zarithrian
|
||||
SPELL_INTIMIDATING_ROAR = 74384,
|
||||
SPELL_CLEAVE_ARMOR = 74367,
|
||||
SPELL_SUMMON_FLAMECALLER = 74398,
|
||||
|
||||
// Onyx Flamecaller
|
||||
SPELL_BLAST_NOVA = 74392,
|
||||
SPELL_LAVA_GOUT = 74394
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
// General Zarithrian
|
||||
EVENT_CLEAVE = 1,
|
||||
EVENT_INTIDMDATING_ROAR = 2,
|
||||
EVENT_SUMMON_ADDS1 = 3,
|
||||
EVENT_SUMMON_ADDS2 = 4,
|
||||
EVENT_KILL_TALK = 5,
|
||||
|
||||
// Onyx Flamecaller
|
||||
EVENT_BLAST_NOVA = 6,
|
||||
EVENT_LAVA_GOUT = 7,
|
||||
|
||||
MAX_PATH_FLAMECALLER_WAYPOINTS = 12
|
||||
};
|
||||
|
||||
// East
|
||||
Position const FlamecallerWaypointsE[MAX_PATH_FLAMECALLER_WAYPOINTS] =
|
||||
{
|
||||
{3042.971f, 419.8809f, 86.94320f, 0.0f},
|
||||
{3043.971f, 419.8809f, 86.94320f, 0.0f},
|
||||
{3044.885f, 428.8281f, 86.19320f, 0.0f},
|
||||
{3045.494f, 434.7930f, 85.56398f, 0.0f},
|
||||
{3045.900f, 438.7695f, 84.81398f, 0.0f},
|
||||
{3045.657f, 456.8290f, 85.95601f, 0.0f},
|
||||
{3043.657f, 459.0790f, 87.20601f, 0.0f},
|
||||
{3042.157f, 460.5790f, 87.70601f, 0.0f},
|
||||
{3040.907f, 462.0790f, 88.45601f, 0.0f},
|
||||
{3038.907f, 464.0790f, 89.20601f, 0.0f},
|
||||
{3025.907f, 478.0790f, 89.70601f, 0.0f},
|
||||
{3003.832f, 501.2510f, 89.47303f, 0.0f}
|
||||
};
|
||||
|
||||
// West
|
||||
Position const FlamecallerWaypointsW[MAX_PATH_FLAMECALLER_WAYPOINTS] =
|
||||
{
|
||||
{3062.596f, 636.9980f, 82.50338f, 0.0f},
|
||||
{3062.514f, 624.9980f, 83.70634f, 0.0f},
|
||||
{3062.486f, 620.9980f, 84.33134f, 0.0f},
|
||||
{3062.445f, 613.9930f, 84.45634f, 0.0f},
|
||||
{3062.445f, 613.9930f, 84.45634f, 0.0f},
|
||||
{3059.208f, 610.6501f, 85.39581f, 0.0f},
|
||||
{3055.958f, 606.9001f, 86.14581f, 0.0f},
|
||||
{3046.458f, 596.4001f, 86.89581f, 0.0f},
|
||||
{3043.958f, 593.4001f, 87.64581f, 0.0f},
|
||||
{3040.458f, 589.9001f, 88.39581f, 0.0f},
|
||||
{3034.458f, 583.1501f, 88.89581f, 0.0f},
|
||||
{3014.970f, 561.8073f, 88.83527f, 0.0f},
|
||||
};
|
||||
|
||||
class boss_general_zarithrian : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_general_zarithrian() : CreatureScript("boss_general_zarithrian") { }
|
||||
|
||||
struct boss_general_zarithrianAI : public BossAI
|
||||
{
|
||||
boss_general_zarithrianAI(Creature* creature) : BossAI(creature, DATA_GENERAL_ZARITHRIAN)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
if (instance->GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE && instance->GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE)
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 9000);
|
||||
events.ScheduleEvent(EVENT_INTIDMDATING_ROAR, 14000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ADDS1, 18000);
|
||||
if (Is25ManRaid())
|
||||
events.ScheduleEvent(EVENT_SUMMON_ADDS2, 20000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_ADDS1:
|
||||
Talk(SAY_ADDS);
|
||||
if (Creature* stalker1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHRIAN_SPAWN_STALKER_1)))
|
||||
stalker1->CastSpell(stalker1, SPELL_SUMMON_FLAMECALLER, false);
|
||||
if (Creature* stalker2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHRIAN_SPAWN_STALKER_2)))
|
||||
stalker2->CastSpell(stalker2, SPELL_SUMMON_FLAMECALLER, false);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ADDS1, 40000);
|
||||
break;
|
||||
case EVENT_SUMMON_ADDS2:
|
||||
if (Creature* stalker1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHRIAN_SPAWN_STALKER_1)))
|
||||
stalker1->CastSpell(stalker1, SPELL_SUMMON_FLAMECALLER, false);
|
||||
if (Creature* stalker2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ZARITHRIAN_SPAWN_STALKER_2)))
|
||||
stalker2->CastSpell(stalker2, SPELL_SUMMON_FLAMECALLER, false);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ADDS2, 40000);
|
||||
break;
|
||||
case EVENT_INTIDMDATING_ROAR:
|
||||
me->CastSpell(me, SPELL_INTIMIDATING_ROAR, false);
|
||||
events.ScheduleEvent(EVENT_INTIDMDATING_ROAR, 30000);
|
||||
break;
|
||||
case EVENT_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE_ARMOR, false);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 15000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
EnterEvadeIfOutOfCombatArea();
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const
|
||||
{
|
||||
return me->GetPositionX() > 3060.0f;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_general_zarithrianAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_onyx_flamecaller : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_onyx_flamecaller() : CreatureScript("npc_onyx_flamecaller") { }
|
||||
|
||||
struct npc_onyx_flamecallerAI : public npc_escortAI
|
||||
{
|
||||
npc_onyx_flamecallerAI(Creature* creature) : npc_escortAI(creature), _instance(creature->GetInstanceScript())
|
||||
{
|
||||
npc_escortAI::SetDespawnAtEnd(false);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_lavaGoutCount = 0;
|
||||
AddWaypoints();
|
||||
Start(true, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_BLAST_NOVA, urand(20000, 30000));
|
||||
_events.ScheduleEvent(EVENT_LAVA_GOUT, 5000);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
// Prevent EvadeMode
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/)
|
||||
{
|
||||
// Let Zarithrian count as summoner. _instance cant be null since we got GetRubySanctumAI
|
||||
if (Creature* zarithrian = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_GENERAL_ZARITHRIAN)))
|
||||
zarithrian->AI()->JustSummoned(me);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == MAX_PATH_FLAMECALLER_WAYPOINTS)
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void AddWaypoints()
|
||||
{
|
||||
if (me->GetPositionY() < 500.0f)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_PATH_FLAMECALLER_WAYPOINTS; i++)
|
||||
AddWaypoint(i+1, FlamecallerWaypointsE[i].GetPositionX(), FlamecallerWaypointsE[i].GetPositionY(), FlamecallerWaypointsE[i].GetPositionZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_PATH_FLAMECALLER_WAYPOINTS; i++)
|
||||
AddWaypoint(i+1, FlamecallerWaypointsW[i].GetPositionX(), FlamecallerWaypointsW[i].GetPositionY(), FlamecallerWaypointsW[i].GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BLAST_NOVA:
|
||||
DoCastAOE(SPELL_BLAST_NOVA);
|
||||
_events.ScheduleEvent(EVENT_BLAST_NOVA, urand(20000, 30000));
|
||||
break;
|
||||
case EVENT_LAVA_GOUT:
|
||||
if (_lavaGoutCount >= 3)
|
||||
{
|
||||
_lavaGoutCount = 0;
|
||||
_events.ScheduleEvent(EVENT_LAVA_GOUT, 8000);
|
||||
break;
|
||||
}
|
||||
DoCastVictim(SPELL_LAVA_GOUT);
|
||||
_lavaGoutCount++;
|
||||
_events.ScheduleEvent(EVENT_LAVA_GOUT, 1500);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
uint8 _lavaGoutCount;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_onyx_flamecallerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_general_zarithrian()
|
||||
{
|
||||
new boss_general_zarithrian();
|
||||
new npc_onyx_flamecaller();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ruby_sanctum.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_CONFLAGRATION = 1,
|
||||
EMOTE_ENRAGED = 2,
|
||||
SAY_KILL = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CONFLAGRATION = 74452,
|
||||
SPELL_FLAME_BEACON = 74453,
|
||||
SPELL_CONFLAGRATION_MISSLE = 74454,
|
||||
SPELL_ENRAGE = 78722,
|
||||
SPELL_FLAME_BREATH = 74403,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ENRAGE = 1,
|
||||
EVENT_FLIGHT = 2,
|
||||
EVENT_FLAME_BREATH = 3,
|
||||
EVENT_CONFLAGRATION = 4,
|
||||
EVENT_LAND_GROUND = 5,
|
||||
EVENT_AIR_MOVEMENT = 6,
|
||||
EVENT_LAND_BACK = 7,
|
||||
EVENT_KILL_TALK = 8
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
POINT_FLIGHT = 1,
|
||||
POINT_LAND = 2,
|
||||
POINT_TAKEOFF = 3,
|
||||
|
||||
SOUND_ID_DEATH = 17531
|
||||
};
|
||||
|
||||
class boss_saviana_ragefire : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_saviana_ragefire() : CreatureScript("boss_saviana_ragefire") { }
|
||||
|
||||
struct boss_saviana_ragefireAI : public BossAI
|
||||
{
|
||||
boss_saviana_ragefireAI(Creature* creature) : BossAI(creature, DATA_SAVIANA_RAGEFIRE)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 15000);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, 10000);
|
||||
events.ScheduleEvent(EVENT_FLIGHT, 30000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
me->PlayDirectSound(SOUND_ID_DEATH);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
switch (point)
|
||||
{
|
||||
case POINT_FLIGHT:
|
||||
me->SetFacingTo(4.69f);
|
||||
events.ScheduleEvent(EVENT_CONFLAGRATION, 1000);
|
||||
events.ScheduleEvent(EVENT_LAND_BACK, 7000);
|
||||
Talk(SAY_CONFLAGRATION);
|
||||
break;
|
||||
case POINT_LAND:
|
||||
me->SetDisableGravity(false);
|
||||
events.ScheduleEvent(EVENT_LAND_GROUND, 500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
BossAI::JustReachedHome();
|
||||
me->SetDisableGravity(false);
|
||||
me->SetHover(false);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_FLIGHT:
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->SetDisableGravity(true);
|
||||
me->GetMotionMaster()->MovePoint(POINT_TAKEOFF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+6.0f, false);
|
||||
events.ScheduleEvent(EVENT_FLIGHT, 50000);
|
||||
events.DelayEvents(15000);
|
||||
events.ScheduleEvent(EVENT_AIR_MOVEMENT, 2000);
|
||||
break;
|
||||
}
|
||||
case EVENT_CONFLAGRATION:
|
||||
me->CastCustomSpell(SPELL_CONFLAGRATION, SPELLVALUE_MAX_TARGETS, RAID_MODE(3, 6, 3, 6), me, true);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
me->CastSpell(me, SPELL_ENRAGE, false);
|
||||
Talk(EMOTE_ENRAGED);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_FLAME_BREATH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FLAME_BREATH, false);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand(20000, 30000));
|
||||
break;
|
||||
case EVENT_AIR_MOVEMENT:
|
||||
me->GetMotionMaster()->MovePoint(POINT_FLIGHT, 3155.51f, 683.844f, 95.0f, false);
|
||||
break;
|
||||
case EVENT_LAND_BACK:
|
||||
me->GetMotionMaster()->MovePoint(POINT_LAND, 3151.07f, 636.443f, 80.0f, false);
|
||||
break;
|
||||
case EVENT_LAND_GROUND:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (me->GetVictim())
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_saviana_ragefireAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_saviana_conflagration_init : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_saviana_conflagration_init() : SpellScriptLoader("spell_saviana_conflagration_init") { }
|
||||
|
||||
class spell_saviana_conflagration_init_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_saviana_conflagration_init_SpellScript);
|
||||
|
||||
void HandleDummy(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetCaster()->CastSpell(GetHitUnit(), SPELL_FLAME_BEACON, true);
|
||||
GetCaster()->CastSpell(GetHitUnit(), SPELL_CONFLAGRATION_MISSLE, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_saviana_conflagration_init_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_saviana_conflagration_throwback : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_saviana_conflagration_throwback() : SpellScriptLoader("spell_saviana_conflagration_throwback") { }
|
||||
|
||||
class spell_saviana_conflagration_throwback_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_saviana_conflagration_throwback_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_throwback_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_saviana_conflagration_throwback_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_saviana_ragefire()
|
||||
{
|
||||
new boss_saviana_ragefire();
|
||||
new spell_saviana_conflagration_init();
|
||||
new spell_saviana_conflagration_throwback();
|
||||
}
|
||||
@@ -1,313 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ruby_sanctum.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{GO_FIRE_FIELD, DATA_BALTHARUS_THE_WARBORN, DOOR_TYPE_PASSAGE, BOUNDARY_E },
|
||||
{GO_FLAME_WALLS, DATA_SAVIANA_RAGEFIRE, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
|
||||
{GO_FLAME_WALLS, DATA_BALTHARUS_THE_WARBORN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
|
||||
{GO_FLAME_WALLS, DATA_GENERAL_ZARITHRIAN, DOOR_TYPE_ROOM, BOUNDARY_NONE},
|
||||
{GO_BURNING_TREE_4, DATA_HALION_INTRO1, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
|
||||
{GO_BURNING_TREE_3, DATA_HALION_INTRO1, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
|
||||
{GO_BURNING_TREE_2, DATA_HALION_INTRO2, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
|
||||
{GO_BURNING_TREE_1, DATA_HALION_INTRO2, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
|
||||
{GO_TWILIGHT_FLAME_RING, DATA_HALION, DOOR_TYPE_ROOM, BOUNDARY_NONE},
|
||||
{0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE},
|
||||
};
|
||||
|
||||
class instance_ruby_sanctum : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_ruby_sanctum() : InstanceMapScript("instance_ruby_sanctum", 724) { }
|
||||
|
||||
struct instance_ruby_sanctum_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_ruby_sanctum_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
|
||||
BaltharusTheWarbornGUID = 0;
|
||||
XerestraszaGUID = 0;
|
||||
GeneralZarithrianGUID = 0;
|
||||
memset(ZarithrianSpawnStalkerGUID, 0, 2 * sizeof(uint64));
|
||||
|
||||
HalionGUID = 0;
|
||||
TwilightHalionGUID = 0;
|
||||
OrbCarrierGUID = 0;
|
||||
HalionControllerGUID = 0;
|
||||
FlameRingGUID = 0;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* /*player*/)
|
||||
{
|
||||
if (GetBossState(DATA_HALION_INTRO_DONE) != DONE && GetBossState(DATA_GENERAL_ZARITHRIAN) == DONE)
|
||||
{
|
||||
instance->LoadGrid(3156.0f, 537.0f);
|
||||
if (Creature* halionController = instance->GetCreature(HalionControllerGUID))
|
||||
halionController->AI()->DoAction(ACTION_INTRO_HALION);
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_BALTHARUS_THE_WARBORN:
|
||||
BaltharusTheWarbornGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_XERESTRASZA:
|
||||
XerestraszaGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_GENERAL_ZARITHRIAN:
|
||||
GeneralZarithrianGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ZARITHRIAN_SPAWN_STALKER:
|
||||
if (!ZarithrianSpawnStalkerGUID[0])
|
||||
ZarithrianSpawnStalkerGUID[0] = creature->GetGUID();
|
||||
else
|
||||
ZarithrianSpawnStalkerGUID[1] = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HALION:
|
||||
HalionGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_TWILIGHT_HALION:
|
||||
TwilightHalionGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HALION_CONTROLLER:
|
||||
HalionControllerGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ORB_CARRIER:
|
||||
OrbCarrierGUID = creature->GetGUID();
|
||||
break;
|
||||
|
||||
case NPC_LIVING_INFERNO:
|
||||
case NPC_LIVING_EMBER:
|
||||
case NPC_METEOR_STRIKE_NORTH:
|
||||
case NPC_METEOR_STRIKE_SOUTH:
|
||||
case NPC_METEOR_STRIKE_EAST:
|
||||
case NPC_METEOR_STRIKE_WEST:
|
||||
case NPC_METEOR_STRIKE_FLAME:
|
||||
case NPC_COMBUSTION:
|
||||
case NPC_CONSUMPTION:
|
||||
if (Creature* halion = instance->GetCreature(HalionGUID))
|
||||
halion->AI()->JustSummoned(creature);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_FIRE_FIELD:
|
||||
case GO_FLAME_WALLS:
|
||||
case GO_BURNING_TREE_1:
|
||||
case GO_BURNING_TREE_2:
|
||||
case GO_BURNING_TREE_3:
|
||||
case GO_BURNING_TREE_4:
|
||||
case GO_TWILIGHT_FLAME_RING:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
case GO_FLAME_RING:
|
||||
FlameRingGUID = go->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_FIRE_FIELD:
|
||||
case GO_FLAME_WALLS:
|
||||
case GO_BURNING_TREE_1:
|
||||
case GO_BURNING_TREE_2:
|
||||
case GO_BURNING_TREE_3:
|
||||
case GO_BURNING_TREE_4:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NPC_BALTHARUS_THE_WARBORN:
|
||||
return BaltharusTheWarbornGUID;
|
||||
case NPC_XERESTRASZA:
|
||||
return XerestraszaGUID;
|
||||
case NPC_GENERAL_ZARITHRIAN:
|
||||
return GeneralZarithrianGUID;
|
||||
case DATA_ZARITHRIAN_SPAWN_STALKER_1:
|
||||
case DATA_ZARITHRIAN_SPAWN_STALKER_2:
|
||||
return ZarithrianSpawnStalkerGUID[type - DATA_ZARITHRIAN_SPAWN_STALKER_1];
|
||||
case NPC_HALION_CONTROLLER:
|
||||
return HalionControllerGUID;
|
||||
case NPC_HALION:
|
||||
return HalionGUID;
|
||||
case NPC_TWILIGHT_HALION:
|
||||
return TwilightHalionGUID;
|
||||
case NPC_ORB_CARRIER:
|
||||
return OrbCarrierGUID;
|
||||
|
||||
case GO_FLAME_RING:
|
||||
return FlameRingGUID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state)
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SAVIANA_RAGEFIRE:
|
||||
case DATA_BALTHARUS_THE_WARBORN:
|
||||
if (GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE && GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE)
|
||||
if (Creature* zarithrian = instance->GetCreature(GeneralZarithrianGUID))
|
||||
zarithrian->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case DATA_GENERAL_ZARITHRIAN:
|
||||
if (state == DONE)
|
||||
if (Creature* halionController = instance->GetCreature(HalionControllerGUID))
|
||||
halionController->AI()->DoAction(ACTION_INTRO_HALION);
|
||||
break;
|
||||
case DATA_HALION:
|
||||
DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TOGGLE, 0);
|
||||
DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 0);
|
||||
DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, 0);
|
||||
HandleGameObject(FlameRingGUID, true);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "R S " << GetBossSaveData();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(WORLDSTATE_CORPOREALITY_MATERIAL) << uint32(50);
|
||||
data << uint32(WORLDSTATE_CORPOREALITY_TWILIGHT) << uint32(50);
|
||||
data << uint32(WORLDSTATE_CORPOREALITY_TOGGLE) << uint32(0);
|
||||
}
|
||||
|
||||
void Load(char const* str)
|
||||
{
|
||||
if (!str)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(str);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
|
||||
std::istringstream loadStream(str);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
|
||||
if (dataHead1 == 'R' && dataHead2 == 'S')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
|
||||
tmpState = NOT_STARTED;
|
||||
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
|
||||
// Xinef: additional check
|
||||
if (GetBossState(DATA_HALION_INTRO_DONE) != DONE)
|
||||
{
|
||||
SetBossState(DATA_HALION_INTRO1, NOT_STARTED);
|
||||
SetBossState(DATA_HALION_INTRO2, NOT_STARTED);
|
||||
}
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint64 BaltharusTheWarbornGUID;
|
||||
uint64 XerestraszaGUID;
|
||||
uint64 GeneralZarithrianGUID;
|
||||
uint64 ZarithrianSpawnStalkerGUID[2];
|
||||
|
||||
uint64 HalionGUID;
|
||||
uint64 TwilightHalionGUID;
|
||||
uint64 HalionControllerGUID;
|
||||
uint64 OrbCarrierGUID;
|
||||
uint64 FlameRingGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_ruby_sanctum_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ruby_sanctum_rallying_shout : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ruby_sanctum_rallying_shout() : SpellScriptLoader("spell_ruby_sanctum_rallying_shout") { }
|
||||
|
||||
class spell_ruby_sanctum_rallying_shout_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ruby_sanctum_rallying_shout_SpellScript);
|
||||
|
||||
void CountAllies()
|
||||
{
|
||||
uint32 count = GetSpell()->GetUniqueTargetInfo()->size();
|
||||
if (count == GetCaster()->GetAuraCount(SPELL_RALLY))
|
||||
return;
|
||||
|
||||
GetCaster()->RemoveAurasDueToSpell(SPELL_RALLY);
|
||||
if (count > 0)
|
||||
GetCaster()->CastCustomSpell(SPELL_RALLY, SPELLVALUE_AURA_STACK, count, GetCaster(), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterHit += SpellHitFn(spell_ruby_sanctum_rallying_shout_SpellScript::CountAllies);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_ruby_sanctum_rallying_shout_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_ruby_sanctum()
|
||||
{
|
||||
new instance_ruby_sanctum();
|
||||
new spell_ruby_sanctum_rallying_shout();
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef RUBY_SANCTUM_H_
|
||||
#define RUBY_SANCTUM_H_
|
||||
|
||||
#include "SpellScript.h"
|
||||
#include "Map.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObjectAI.h"
|
||||
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
// Encounter States/Boss GUIDs
|
||||
DATA_BALTHARUS_THE_WARBORN = 0,
|
||||
DATA_GENERAL_ZARITHRIAN = 1,
|
||||
DATA_SAVIANA_RAGEFIRE = 2,
|
||||
DATA_HALION_INTRO1 = 3,
|
||||
DATA_HALION_INTRO2 = 4,
|
||||
DATA_HALION_INTRO_DONE = 5,
|
||||
DATA_HALION = 6,
|
||||
|
||||
MAX_ENCOUNTERS = 7,
|
||||
|
||||
// Etc
|
||||
DATA_ZARITHRIAN_SPAWN_STALKER_1 = 8,
|
||||
DATA_ZARITHRIAN_SPAWN_STALKER_2 = 9
|
||||
};
|
||||
|
||||
enum SharedActions
|
||||
{
|
||||
ACTION_INTRO_HALION = -4014601,
|
||||
};
|
||||
|
||||
enum CreaturesIds
|
||||
{
|
||||
// Baltharus the Warborn
|
||||
NPC_BALTHARUS_THE_WARBORN = 39751,
|
||||
NPC_BALTHARUS_THE_WARBORN_CLONE = 39899,
|
||||
NPC_XERESTRASZA = 40429,
|
||||
|
||||
// General Zarithrian
|
||||
NPC_GENERAL_ZARITHRIAN = 39746,
|
||||
NPC_ONYX_FLAMECALLER = 39814,
|
||||
NPC_ZARITHRIAN_SPAWN_STALKER = 39794,
|
||||
|
||||
// Saviana Ragefire
|
||||
NPC_SAVIANA_RAGEFIRE = 39747,
|
||||
|
||||
// Halion
|
||||
NPC_HALION = 39863,
|
||||
NPC_TWILIGHT_HALION = 40142,
|
||||
NPC_HALION_CONTROLLER = 40146,
|
||||
NPC_LIVING_INFERNO = 40681,
|
||||
NPC_LIVING_EMBER = 40683,
|
||||
NPC_ORB_CARRIER = 40081,
|
||||
NPC_METEOR_STRIKE_MARK = 40029,
|
||||
NPC_METEOR_STRIKE_NORTH = 40041,
|
||||
NPC_METEOR_STRIKE_EAST = 40042,
|
||||
NPC_METEOR_STRIKE_WEST = 40043,
|
||||
NPC_METEOR_STRIKE_SOUTH = 40044,
|
||||
NPC_METEOR_STRIKE_FLAME = 40055,
|
||||
NPC_COMBUSTION = 40001,
|
||||
NPC_CONSUMPTION = 40135,
|
||||
NPC_COMBAT_STALKER = 40151 // Seen in sniffs but not used, so no wonder.
|
||||
};
|
||||
|
||||
enum GameObjectsIds
|
||||
{
|
||||
GO_HALION_PORTAL_1 = 202794,
|
||||
GO_HALION_PORTAL_2 = 202795,
|
||||
GO_HALION_PORTAL_EXIT = 202796,
|
||||
GO_FIRE_FIELD = 203005,
|
||||
GO_FLAME_WALLS = 203006,
|
||||
GO_FLAME_RING = 203007,
|
||||
GO_TWILIGHT_FLAME_RING = 203624,
|
||||
GO_BURNING_TREE_1 = 203034,
|
||||
GO_BURNING_TREE_2 = 203035,
|
||||
GO_BURNING_TREE_3 = 203036,
|
||||
GO_BURNING_TREE_4 = 203037
|
||||
};
|
||||
|
||||
enum WorldStatesRS
|
||||
{
|
||||
WORLDSTATE_CORPOREALITY_MATERIAL = 5049,
|
||||
WORLDSTATE_CORPOREALITY_TWILIGHT = 5050,
|
||||
WORLDSTATE_CORPOREALITY_TOGGLE = 5051
|
||||
};
|
||||
|
||||
enum InstanceSpell
|
||||
{
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_RALLY = 75416
|
||||
};
|
||||
|
||||
#endif // RUBY_SANCTUM_H_
|
||||
@@ -1,841 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "trial_of_the_champion.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum EadricSpells
|
||||
{
|
||||
//Eadric
|
||||
SPELL_EADRIC_ACHIEVEMENT = 68197,
|
||||
ACHIEV_FACEROLLER = 3803,
|
||||
|
||||
SPELL_RADIANCE = 66935,
|
||||
SPELL_VENGEANCE = 66865,
|
||||
SPELL_HAMMER_JUSTICE = 66863,
|
||||
SPELL_HAMMER_RIGHTEOUS = 66867,
|
||||
SPELL_HAMMER_RIGHTEOUS_DAMAGE = 66903,
|
||||
SPELL_HAMMER_RIGHTEOUS_ACTION_BAR = 66904,
|
||||
SPELL_HAMMER_RIGHTEOUS_THROW_BACK = 66905,
|
||||
};
|
||||
|
||||
enum EadricEvents
|
||||
{
|
||||
EVENT_SPELL_RADIANCE = 1,
|
||||
EVENT_SPELL_HAMMER_RIGHTEOUS,
|
||||
};
|
||||
|
||||
enum PaletressSpells
|
||||
{
|
||||
SPELL_SMITE_N = 66536,
|
||||
SPELL_SMITE_H = 67674,
|
||||
SPELL_HOLY_FIRE_N = 66538,
|
||||
SPELL_HOLY_FIRE_H = 67676,
|
||||
SPELL_RENEW_N = 66537,
|
||||
SPELL_RENEW_H = 67675,
|
||||
|
||||
SPELL_HOLY_NOVA = 66546,
|
||||
SPELL_SHIELD = 66515,
|
||||
SPELL_CONFESS = 66680,
|
||||
SPELL_SUMMON_MEMORY = 66545,
|
||||
|
||||
//Memory
|
||||
SPELL_OLD_WOUNDS_N = 66620,
|
||||
SPELL_OLD_WOUNDS_H = 67679,
|
||||
SPELL_SHADOWS_PAST_N = 66619,
|
||||
SPELL_SHADOWS_PAST_H = 67678,
|
||||
SPELL_WAKING_NIGHTMARE_N = 66552,
|
||||
SPELL_WAKING_NIGHTMARE_H = 67677,
|
||||
};
|
||||
|
||||
#define SPELL_SMITE DUNGEON_MODE(SPELL_SMITE_N, SPELL_SMITE_H)
|
||||
#define SPELL_HOLY_FIRE DUNGEON_MODE(SPELL_HOLY_FIRE_N, SPELL_HOLY_FIRE_H)
|
||||
#define SPELL_RENEW DUNGEON_MODE(SPELL_RENEW_N, SPELL_RENEW_H)
|
||||
#define SPELL_OLD_WOUNDS DUNGEON_MODE(SPELL_OLD_WOUNDS_N, SPELL_OLD_WOUNDS_H)
|
||||
#define SPELL_SHADOWS_PAST DUNGEON_MODE(SPELL_SHADOWS_PAST_N, SPELL_SHADOWS_PAST_H)
|
||||
#define SPELL_WAKING_NIGHTMARE DUNGEON_MODE(SPELL_WAKING_NIGHTMARE_N, SPELL_WAKING_NIGHTMARE_H)
|
||||
|
||||
enum PaletressEvents
|
||||
{
|
||||
EVENT_SPELL_SMITE = 1,
|
||||
EVENT_SPELL_HOLY_FIRE,
|
||||
EVENT_SPELL_RENEW,
|
||||
|
||||
EVENT_MEMORY_SCALE,
|
||||
EVENT_MEMORY_START_ATTACK,
|
||||
EVENT_SPELL_OLD_WOUNDS,
|
||||
EVENT_SPELL_SHADOWS_PAST,
|
||||
EVENT_SPELL_WAKING_NIGHTMARE,
|
||||
};
|
||||
|
||||
#define TEXT_RADIATE "Eadric the Pure begins to radiate light. Shield your eyes!"
|
||||
|
||||
class boss_eadric : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_eadric() : CreatureScript("boss_eadric") { }
|
||||
struct boss_eadricAI : public ScriptedAI
|
||||
{
|
||||
boss_eadricAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, NOT_STARTED);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if( type == POINT_MOTION_TYPE && id == 1 )
|
||||
me->SetFacingTo(3*M_PI/2);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
if( urand(0,1) )
|
||||
Talk(TEXT_EADRIC_SLAIN_1);
|
||||
else
|
||||
Talk(TEXT_EADRIC_SLAIN_2);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_RADIANCE, 16000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER_RIGHTEOUS, 25000);
|
||||
Talk(TEXT_EADRIC_AGGRO);
|
||||
me->CastSpell(me, SPELL_VENGEANCE, false);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id == 66905 && me->GetHealth() == 1) // hammer throw back damage (15k)
|
||||
me->CastSpell(me, 68197, true);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if( damage >= me->GetHealth() )
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
if( me->getFaction() != 35 )
|
||||
{
|
||||
me->CastSpell((Unit*)NULL, 68575, true); // achievements
|
||||
me->GetMap()->UpdateEncounterState(ENCOUNTER_CREDIT_CAST_SPELL, 68574, me); // paletress' spell credits encounter, but shouldn't credit achievements
|
||||
me->setFaction(35);
|
||||
events.Reset();
|
||||
Talk(TEXT_EADRIC_DEATH);
|
||||
me->getThreatManager().clearReferences();
|
||||
me->SetRegeneratingHealth(false);
|
||||
_EnterEvadeMode();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_RADIANCE:
|
||||
me->CastSpell((Unit*)NULL, SPELL_RADIANCE, false);
|
||||
me->MonsterTextEmote(TEXT_RADIATE, 0, true);
|
||||
events.RepeatEvent(16000);
|
||||
break;
|
||||
case EVENT_SPELL_HAMMER_RIGHTEOUS:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 55.0f, true) )
|
||||
{
|
||||
char buffer[100];
|
||||
sprintf(buffer, "Eadric the Pure targets %s with the Hammer of the Righteous!", target->GetName().c_str());
|
||||
me->MonsterTextEmote(buffer, 0, true);
|
||||
Talk(TEXT_EADRIC_HAMMER);
|
||||
me->CastSpell(target, SPELL_HAMMER_JUSTICE, true);
|
||||
me->CastSpell(target, SPELL_HAMMER_RIGHTEOUS, false);
|
||||
}
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_eadricAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class boss_paletress : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_paletress() : CreatureScript("boss_paletress") { }
|
||||
|
||||
struct boss_paletressAI : public ScriptedAI
|
||||
{
|
||||
boss_paletressAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
bool summoned;
|
||||
uint64 MemoryGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summoned = false;
|
||||
if( MemoryGUID )
|
||||
{
|
||||
if( Creature* memory = ObjectAccessor::GetCreature(*me, MemoryGUID) )
|
||||
memory->DespawnOrUnsummon();
|
||||
MemoryGUID = 0;
|
||||
}
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, NOT_STARTED);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if( type == POINT_MOTION_TYPE && id == 1 )
|
||||
me->SetFacingTo(3*M_PI/2);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
if( urand(0,1) )
|
||||
Talk(TEXT_PALETRESS_SLAIN_1);
|
||||
else
|
||||
Talk(TEXT_PALETRESS_SLAIN_2);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_FIRE, urand(9000,12000));
|
||||
events.ScheduleEvent(EVENT_SPELL_SMITE, urand(2000,3000));
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
Talk(TEXT_PALETRESS_AGGRO);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if( param == 1 )
|
||||
{
|
||||
MemoryGUID = 0;
|
||||
me->RemoveAura(SPELL_SHIELD);
|
||||
Talk(TEXT_PALETRESS_MEMORY_DEFEATED);
|
||||
}
|
||||
else if( param == (-1) )
|
||||
{
|
||||
if( MemoryGUID )
|
||||
if( Creature* memory = ObjectAccessor::GetCreature(*me, MemoryGUID) )
|
||||
{
|
||||
memory->DespawnOrUnsummon();
|
||||
MemoryGUID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
//if( me->HasAura(SPELL_SHIELD) )
|
||||
// return;
|
||||
|
||||
if( damage >= me->GetHealth() )
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
|
||||
if( me->getFaction() != 35 )
|
||||
{
|
||||
me->CastSpell((Unit*)NULL, 68574, true); // achievements
|
||||
me->setFaction(35);
|
||||
events.Reset();
|
||||
Talk(TEXT_PALETRESS_DEATH);
|
||||
me->getThreatManager().clearReferences();
|
||||
me->SetRegeneratingHealth(false);
|
||||
_EnterEvadeMode();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( pInstance )
|
||||
{
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, DONE);
|
||||
pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 68206);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if( pInstance )
|
||||
pInstance->SetData(DATA_MEMORY_ENTRY, summon->GetEntry());
|
||||
MemoryGUID = summon->GetGUID();
|
||||
}
|
||||
|
||||
void SummonMemory()
|
||||
{
|
||||
uint8 uiRandom = urand(0,25);
|
||||
uint32 uiSpells[26] = {66704,66705,66706,66707,66709,66710,66711,66712,66713,66714,66715,66708,66708,66691,66692,66694,66695,66696,66697,66698,66699,66700,66701,66702,66703,66543};
|
||||
me->CastSpell(me, uiSpells[uiRandom], true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( !summoned && HealthBelowPct(25) )
|
||||
{
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
Talk(TEXT_PALETRESS_MEMORY_SUMMON);
|
||||
me->CastSpell((Unit*)NULL, SPELL_HOLY_NOVA, false);
|
||||
me->CastSpell(me, SPELL_SHIELD, false);
|
||||
me->CastSpell((Unit*)NULL, SPELL_SUMMON_MEMORY, false);
|
||||
SummonMemory();
|
||||
me->CastSpell((Unit*)NULL, SPELL_CONFESS, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_RENEW, urand(6000,8000));
|
||||
summoned = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_SMITE:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true) )
|
||||
me->CastSpell(target, SPELL_SMITE, false);
|
||||
events.RepeatEvent(urand(3000,4000));
|
||||
break;
|
||||
case EVENT_SPELL_HOLY_FIRE:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) )
|
||||
me->CastSpell(target, SPELL_HOLY_FIRE, false);
|
||||
events.RepeatEvent(urand(9000,12000));
|
||||
break;
|
||||
case EVENT_SPELL_RENEW:
|
||||
if( !MemoryGUID )
|
||||
{
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
if( urand(0,1) )
|
||||
me->CastSpell(me, SPELL_RENEW, false);
|
||||
else if( Creature* memory = ObjectAccessor::GetCreature(*me, MemoryGUID) )
|
||||
if( memory->IsAlive() )
|
||||
me->CastSpell(memory, SPELL_RENEW, false);
|
||||
events.RepeatEvent(urand(15000,17000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_paletressAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_memory : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_memory() : CreatureScript("npc_memory") { }
|
||||
|
||||
struct npc_memoryAI : public ScriptedAI
|
||||
{
|
||||
npc_memoryAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
events.Reset();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetObjectScale(0.01f);
|
||||
events.ScheduleEvent(EVENT_MEMORY_SCALE, 500);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void Reset() {}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
me->DespawnOrUnsummon(20000);
|
||||
if( pInstance )
|
||||
if( Creature* paletress = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_PALETRESS)) )
|
||||
paletress->AI()->DoAction(1);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
UpdateVictim();
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_MEMORY_SCALE:
|
||||
me->SetObjectScale(1.0f);
|
||||
events.ScheduleEvent(EVENT_MEMORY_START_ATTACK, 5000);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_MEMORY_START_ATTACK:
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( Unit* target = me->SelectNearestTarget(200.0f) )
|
||||
{
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.ScheduleEvent(EVENT_SPELL_OLD_WOUNDS, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOWS_PAST, 4000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WAKING_NIGHTMARE, urand(20000,30000));
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_OLD_WOUNDS:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f, true) )
|
||||
me->CastSpell(target, SPELL_OLD_WOUNDS, true);
|
||||
events.RepeatEvent(12000);
|
||||
break;
|
||||
case EVENT_SPELL_SHADOWS_PAST:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true) )
|
||||
me->CastSpell(target, SPELL_SHADOWS_PAST, false);
|
||||
events.RepeatEvent(urand(15000,20000));
|
||||
break;
|
||||
case EVENT_SPELL_WAKING_NIGHTMARE:
|
||||
me->CastSpell(me, SPELL_WAKING_NIGHTMARE, false);
|
||||
events.RepeatEvent(35000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_memoryAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
enum ArgentSoldierSpells
|
||||
{
|
||||
// monk
|
||||
SPELL_FLURRY_OF_BLOWS = 67233,
|
||||
SPELL_PUMMEL = 67235,
|
||||
SPELL_DIVINE_SHIELD_H = 67251,
|
||||
SPELL_FINAL_MEDITATION_H = 67255,
|
||||
|
||||
// priestess
|
||||
SPELL_HOLY_SMITE_N = 36176,
|
||||
SPELL_HOLY_SMITE_H = 67289,
|
||||
SPELL_FOUNTAIN_OF_LIGHT = 67194,
|
||||
NPC_FOUNTAIN_OF_LIGHT = 35311,
|
||||
SPELL_SHADOW_WORD_PAIN_N = 34941,
|
||||
SPELL_SHADOW_WORD_PAIN_H = 34942,
|
||||
SPELL_MIND_CONTROL_H = 67229,
|
||||
|
||||
// lightwielder
|
||||
SPELL_BLAZING_LIGHT_N = 67247,
|
||||
SPELL_BLAZING_LIGHT_H = 67290,
|
||||
SPELL_CLEAVE = 15284,
|
||||
SPELL_UNBALANCING_STRIKE_H = 67237,
|
||||
};
|
||||
|
||||
#define SPELL_HOLY_SMITE DUNGEON_MODE(SPELL_HOLY_SMITE_N, SPELL_HOLY_SMITE_H)
|
||||
#define SPELL_SHADOW_WORD_PAIN DUNGEON_MODE(SPELL_SHADOW_WORD_PAIN_N, SPELL_SHADOW_WORD_PAIN_H)
|
||||
#define SPELL_BLAZING_LIGHT DUNGEON_MODE(SPELL_BLAZING_LIGHT_N, SPELL_BLAZING_LIGHT_H)
|
||||
|
||||
enum ArgentSoldierEvents
|
||||
{
|
||||
EVENT_MONK_SPELL_FLURRY_OF_BLOWS = 1,
|
||||
EVENT_MONK_SPELL_PUMMEL,
|
||||
EVENT_PRIESTESS_SPELL_HOLY_SMITE,
|
||||
EVENT_PRIESTESS_SPELL_SHADOW_WORD_PAIN,
|
||||
EVENT_PRIESTESS_SPELL_FOUNTAIN_OF_LIGHT,
|
||||
EVENT_PRIESTESS_SPELL_MIND_CONTROL_H,
|
||||
EVENT_LIGHTWIELDER_SPELL_BLAZING_LIGHT,
|
||||
EVENT_LIGHTWIELDER_SPELL_CLEAVE,
|
||||
EVENT_LIGHTWIELDER_SPELL_UNBALANCING_STRIKE_H,
|
||||
};
|
||||
|
||||
class npc_argent_soldier : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_argent_soldier() : CreatureScript("npc_argent_soldier") { }
|
||||
|
||||
struct npc_argent_soldierAI : public npc_escortAI
|
||||
{
|
||||
npc_argent_soldierAI(Creature* pCreature) : npc_escortAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
SetDespawnAtEnd(false);
|
||||
uiWaypoint = 0;
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint8 uiWaypoint;
|
||||
bool bCheck;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
bCheck = false;
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 uiPoint)
|
||||
{
|
||||
if( uiPoint == 1 )
|
||||
{
|
||||
switch( uiWaypoint )
|
||||
{
|
||||
case 0:
|
||||
me->SetFacingTo(5.4f);
|
||||
break;
|
||||
case 1:
|
||||
me->SetFacingTo(4.6f);
|
||||
break;
|
||||
case 2:
|
||||
me->SetFacingTo(4.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 uiType, uint32 /*uiData*/)
|
||||
{
|
||||
AddWaypoint(0, me->GetPositionX(), 660.0f, 411.80f);
|
||||
switch( me->GetEntry() )
|
||||
{
|
||||
case NPC_ARGENT_LIGHTWIELDER:
|
||||
switch( uiType )
|
||||
{
|
||||
case 0:
|
||||
AddWaypoint(1,716.321f,647.047f,411.93f);
|
||||
break;
|
||||
case 1:
|
||||
AddWaypoint(1,742.44f,650.29f,411.79f);
|
||||
break;
|
||||
case 2:
|
||||
AddWaypoint(1,772.6314f,651.7f,411.93f);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_ARGENT_MONK:
|
||||
switch( uiType )
|
||||
{
|
||||
case 0:
|
||||
AddWaypoint(1,717.86f,649.0f,411.923f);
|
||||
break;
|
||||
case 1:
|
||||
AddWaypoint(1,746.73f,650.24f,411.56f);
|
||||
break;
|
||||
case 2:
|
||||
AddWaypoint(1,775.567f,648.26f,411.93f);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_PRIESTESS:
|
||||
switch( uiType )
|
||||
{
|
||||
case 0:
|
||||
AddWaypoint(1,719.872f,650.94f,411.93f);
|
||||
break;
|
||||
case 1:
|
||||
AddWaypoint(1,750.72f,650.20f,411.77f);
|
||||
break;
|
||||
case 2:
|
||||
AddWaypoint(1,777.78f,645.70f,411.93f);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Start(false,true,0);
|
||||
uiWaypoint = uiType;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if( bCheck && damage >= me->GetHealth() )
|
||||
{
|
||||
bCheck = false;
|
||||
damage = me->GetHealth()-1;
|
||||
events.DelayEvents(10000);
|
||||
me->CastSpell(me, SPELL_DIVINE_SHIELD_H, true);
|
||||
me->CastSpell((Unit*)NULL, SPELL_FINAL_MEDITATION_H, true);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
switch( me->GetEntry() )
|
||||
{
|
||||
case NPC_ARGENT_MONK:
|
||||
events.RescheduleEvent(EVENT_MONK_SPELL_FLURRY_OF_BLOWS, 5000);
|
||||
events.RescheduleEvent(EVENT_MONK_SPELL_PUMMEL, 7000);
|
||||
if( IsHeroic() )
|
||||
bCheck = true;
|
||||
break;
|
||||
case NPC_PRIESTESS:
|
||||
events.RescheduleEvent(EVENT_PRIESTESS_SPELL_HOLY_SMITE, urand(5000,8000));
|
||||
events.RescheduleEvent(EVENT_PRIESTESS_SPELL_SHADOW_WORD_PAIN, urand(3000,6000));
|
||||
events.RescheduleEvent(EVENT_PRIESTESS_SPELL_FOUNTAIN_OF_LIGHT, urand(8000,15000));
|
||||
if( IsHeroic() )
|
||||
events.RescheduleEvent(EVENT_PRIESTESS_SPELL_MIND_CONTROL_H, 12000);
|
||||
break;
|
||||
case NPC_ARGENT_LIGHTWIELDER:
|
||||
events.RescheduleEvent(EVENT_LIGHTWIELDER_SPELL_BLAZING_LIGHT, urand(12000,15000));
|
||||
events.RescheduleEvent(EVENT_LIGHTWIELDER_SPELL_CLEAVE, urand(3000,5000));
|
||||
if( IsHeroic() )
|
||||
events.RescheduleEvent(EVENT_LIGHTWIELDER_SPELL_UNBALANCING_STRIKE_H, urand(8000,12000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case EVENT_MONK_SPELL_FLURRY_OF_BLOWS:
|
||||
me->CastSpell(me, SPELL_FLURRY_OF_BLOWS, false);
|
||||
events.RepeatEvent(urand(12000,18000));
|
||||
break;
|
||||
case EVENT_MONK_SPELL_PUMMEL:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false);
|
||||
events.RepeatEvent(urand(8000,11000));
|
||||
break;
|
||||
|
||||
case EVENT_PRIESTESS_SPELL_HOLY_SMITE:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_HOLY_SMITE, false);
|
||||
events.RepeatEvent(urand(6000,8000));
|
||||
break;
|
||||
case EVENT_PRIESTESS_SPELL_SHADOW_WORD_PAIN:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_SHADOW_WORD_PAIN, false);
|
||||
events.RepeatEvent(urand(12000,15000));
|
||||
break;
|
||||
case EVENT_PRIESTESS_SPELL_FOUNTAIN_OF_LIGHT:
|
||||
me->CastSpell((Unit*)NULL, SPELL_FOUNTAIN_OF_LIGHT, false);
|
||||
events.RepeatEvent(urand(35000,45000));
|
||||
break;
|
||||
case EVENT_PRIESTESS_SPELL_MIND_CONTROL_H:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) )
|
||||
me->CastSpell(target, SPELL_MIND_CONTROL_H, false);
|
||||
events.RepeatEvent(urand(22000,30000));
|
||||
break;
|
||||
|
||||
case EVENT_LIGHTWIELDER_SPELL_BLAZING_LIGHT:
|
||||
{
|
||||
Unit* target = DoSelectLowestHpFriendly(40.0f);
|
||||
if( !target )
|
||||
target = me;
|
||||
me->CastSpell(target, SPELL_BLAZING_LIGHT, false);
|
||||
events.RepeatEvent(urand(8000,12000));
|
||||
}
|
||||
break;
|
||||
case EVENT_LIGHTWIELDER_SPELL_CLEAVE:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.RepeatEvent(urand(6000,8000));
|
||||
break;
|
||||
case EVENT_LIGHTWIELDER_SPELL_UNBALANCING_STRIKE_H:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_UNBALANCING_STRIKE_H, false);
|
||||
events.RepeatEvent(urand(12000,15000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
me->DespawnOrUnsummon(10000);
|
||||
if( pInstance )
|
||||
pInstance->SetData(DATA_ARGENT_SOLDIER_DEFEATED, 0);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_argent_soldierAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_eadric_radiance : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_eadric_radiance() : SpellScriptLoader("spell_eadric_radiance") { }
|
||||
|
||||
class spell_eadric_radiance_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_eadric_radiance_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
std::list<WorldObject*> tmplist;
|
||||
for( std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
if( (*itr)->ToUnit()->HasInArc(M_PI, GetCaster()) )
|
||||
tmplist.push_back(*itr);
|
||||
|
||||
targets.clear();
|
||||
for( std::list<WorldObject*>::iterator itr = tmplist.begin(); itr != tmplist.end(); ++itr )
|
||||
targets.push_back(*itr);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_eadric_radiance_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_toc5_light_rain : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_toc5_light_rain() : SpellScriptLoader("spell_toc5_light_rain") { }
|
||||
|
||||
class spell_toc5_light_rain_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_toc5_light_rain_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
for( std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); )
|
||||
{
|
||||
if ((*itr)->GetTypeId() == TYPEID_UNIT)
|
||||
if ((*itr)->ToCreature()->GetEntry() == NPC_FOUNTAIN_OF_LIGHT)
|
||||
{
|
||||
targets.erase(itr);
|
||||
itr = targets.begin();
|
||||
continue;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_toc5_light_rain_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_toc5_light_rain_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_reflective_shield : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_reflective_shield() : SpellScriptLoader("spell_reflective_shield") { }
|
||||
|
||||
class spell_reflective_shield_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_reflective_shield_AuraScript)
|
||||
|
||||
void HandleAfterEffectAbsorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
|
||||
{
|
||||
if( Unit* attacker = dmgInfo.GetAttacker() )
|
||||
if( GetOwner() && attacker->GetGUID() != GetOwner()->GetGUID() )
|
||||
{
|
||||
int32 damage = (int32)(absorbAmount*0.25f);
|
||||
GetOwner()->ToUnit()->CastCustomSpell(attacker, 33619, &damage, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectAbsorb += AuraEffectAbsorbFn(spell_reflective_shield_AuraScript::HandleAfterEffectAbsorb, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_reflective_shield_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_argent_challenge()
|
||||
{
|
||||
new boss_eadric();
|
||||
new boss_paletress();
|
||||
new npc_memory();
|
||||
new npc_argent_soldier();
|
||||
new spell_eadric_radiance();
|
||||
new spell_toc5_light_rain();
|
||||
new spell_reflective_shield();
|
||||
}
|
||||
@@ -1,479 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "trial_of_the_champion.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_RAISE_DEAD_JAEREN = 67715,
|
||||
SPELL_RAISE_DEAD_ARELAS = 67705,
|
||||
SPELL_BK_FEIGN_DEATH = 67691,
|
||||
SPELL_BLACK_KNIGHT_RES = 67693,
|
||||
SPELL_BK_KILL_CREDIT = 68663,
|
||||
|
||||
// phase 1
|
||||
SPELL_PLAGUE_STRIKE_N = 67724,
|
||||
SPELL_PLAGUE_STRIKE_H = 67884,
|
||||
SPELL_ICY_TOUCH_N = 67718,
|
||||
SPELL_ICY_TOUCH_H = 67881,
|
||||
SPELL_DEATH_RESPITE_N = 67745,
|
||||
SPELL_DEATH_RESPITE_H = 68306,
|
||||
SPELL_DEATH_RESPITE_DUMMY = 66798,
|
||||
SPELL_OBLITERATE_N = 67725,
|
||||
SPELL_OBLITERATE_H = 67883,
|
||||
|
||||
// phase 2 (+ abilities from phase 1 without death respite)
|
||||
SPELL_ARMY_DEAD_N = 67761,
|
||||
SPELL_ARMY_DEAD_H = 67874,
|
||||
SPELL_DESECRATION_N = 67778,
|
||||
SPELL_DESECRATION_H = 67877,
|
||||
SPELL_DESECRATION_SUMMON = 67779,
|
||||
SPELL_BK_GHOUL_EXPLODE = 67751,
|
||||
|
||||
// phase 3
|
||||
SPELL_DEATH_BITE_N = 67808,
|
||||
SPELL_DEATH_BITE_H = 67875,
|
||||
SPELL_MARKED_DEATH_N = 67823,
|
||||
SPELL_MARKED_DEATH_H = 67882,
|
||||
|
||||
// ghouls
|
||||
SPELL_CLAW_N = 67774,
|
||||
SPELL_CLAW_H = 67879,
|
||||
SPELL_EXPLODE_N = 67729,
|
||||
SPELL_EXPLODE_H = 67886,
|
||||
SPELL_LEAP_N = 67749,
|
||||
SPELL_LEAP_H = 67880,
|
||||
};
|
||||
#define SPELL_LEAP DUNGEON_MODE(SPELL_LEAP_N, SPELL_LEAP_H)
|
||||
#define SPELL_EXPLODE DUNGEON_MODE(SPELL_EXPLODE_N, SPELL_EXPLODE_H)
|
||||
|
||||
#define SPELL_PLAGUE_STRIKE DUNGEON_MODE(SPELL_PLAGUE_STRIKE_N, SPELL_PLAGUE_STRIKE_H)
|
||||
#define SPELL_ICY_TOUCH DUNGEON_MODE(SPELL_ICY_TOUCH_N, SPELL_ICY_TOUCH_H)
|
||||
#define SPELL_DEATH_RESPITE DUNGEON_MODE(SPELL_DEATH_RESPITE_N, SPELL_DEATH_RESPITE_H)
|
||||
#define SPELL_OBLITERATE DUNGEON_MODE(SPELL_OBLITERATE_N, SPELL_OBLITERATE_H)
|
||||
#define SPELL_ARMY_DEAD DUNGEON_MODE(SPELL_ARMY_DEAD_N, SPELL_ARMY_DEAD_H)
|
||||
#define SPELL_DESECRATION DUNGEON_MODE(SPELL_DESECRATION_N, SPELL_DESECRATION_H)
|
||||
#define SPELL_DEATH_BITE DUNGEON_MODE(SPELL_DEATH_BITE_N, SPELL_DEATH_BITE_H)
|
||||
#define SPELL_MARKED_DEATH DUNGEON_MODE(SPELL_MARKED_DEATH_N, SPELL_MARKED_DEATH_H)
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ANNOUNCER_SAY_ZOMBIE = 1,
|
||||
EVENT_SPELL_PLAGUE_STRIKE,
|
||||
EVENT_SPELL_ICY_TOUCH,
|
||||
EVENT_SPELL_DEATH_RESPITE,
|
||||
EVENT_SPELL_OBLITERATE,
|
||||
EVENT_SPELL_DESECRATION,
|
||||
EVENT_SPELL_DEATH_BITE,
|
||||
EVENT_SPELL_MARKED_DEATH,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_RISEN_CHAMPION = 35590,
|
||||
};
|
||||
|
||||
enum Models
|
||||
{
|
||||
MODEL_SKELETON = 29846,
|
||||
MODEL_GHOST = 21300
|
||||
};
|
||||
|
||||
|
||||
class boss_black_knight : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_black_knight() : CreatureScript("boss_black_knight") { }
|
||||
|
||||
struct boss_black_knightAI : public ScriptedAI
|
||||
{
|
||||
boss_black_knightAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 Phase;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
Phase = 1;
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_BLACK_KNIGHT, NOT_STARTED);
|
||||
|
||||
//me->SetLootMode(0); // [LOOT]
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->DespawnOrUnsummon(1);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
|
||||
{
|
||||
damage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if( Phase < 3 && damage >= me->GetHealth() )
|
||||
{
|
||||
damage = 0;
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
events.Reset();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveAllAuras();
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
me->CastSpell(me, SPELL_BK_GHOUL_EXPLODE, true);
|
||||
summons.clear();
|
||||
|
||||
me->CastSpell(me, SPELL_BK_FEIGN_DEATH, true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
|
||||
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
|
||||
me->AddUnitState(UNIT_STATE_DIED);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if( param == -1 )
|
||||
{
|
||||
summons.DespawnAll();
|
||||
}
|
||||
else if( param == 1 )
|
||||
{
|
||||
if( !pInstance )
|
||||
return;
|
||||
|
||||
pInstance->SetData(BOSS_BLACK_KNIGHT, IN_PROGRESS);
|
||||
Talk(TEXT_BK_AGGRO);
|
||||
me->CastSpell((Unit*)NULL, (pInstance->GetData(DATA_TEAMID_IN_INSTANCE)==TEAM_HORDE ? SPELL_RAISE_DEAD_JAEREN : SPELL_RAISE_DEAD_ARELAS), false);
|
||||
if( Creature* announcer = pInstance->instance->GetCreature(pInstance->GetData64(DATA_ANNOUNCER)) )
|
||||
announcer->DespawnOrUnsummon();
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_ANNOUNCER_SAY_ZOMBIE, 2500);
|
||||
events.ScheduleEvent(EVENT_SPELL_PLAGUE_STRIKE, urand(7000,9000));
|
||||
events.ScheduleEvent(EVENT_SPELL_ICY_TOUCH, urand(3500,7000));
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATH_RESPITE, urand(13000,15000));
|
||||
events.ScheduleEvent(EVENT_SPELL_OBLITERATE, urand(11000,19000));
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
switch( spell->Id )
|
||||
{
|
||||
case SPELL_BLACK_KNIGHT_RES:
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
|
||||
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
|
||||
me->ClearUnitState(UNIT_STATE_DIED);
|
||||
|
||||
++Phase;
|
||||
|
||||
switch( Phase )
|
||||
{
|
||||
case 2:
|
||||
me->SetDisplayId(MODEL_SKELETON);
|
||||
Talk(TEXT_BK_SKELETON_RES);
|
||||
me->CastSpell(me, SPELL_ARMY_DEAD, false);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_PLAGUE_STRIKE, urand(7000,9000));
|
||||
events.ScheduleEvent(EVENT_SPELL_ICY_TOUCH, urand(3500,7000));
|
||||
events.ScheduleEvent(EVENT_SPELL_OBLITERATE, urand(11000,19000));
|
||||
events.ScheduleEvent(EVENT_SPELL_DESECRATION, urand(2000,3000));
|
||||
break;
|
||||
case 3:
|
||||
me->SetDisplayId(MODEL_GHOST);
|
||||
Talk(TEXT_BK_GHOST_RES);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATH_BITE, 2000);
|
||||
events.ScheduleEvent(EVENT_SPELL_MARKED_DEATH, 1000);
|
||||
break;
|
||||
default:
|
||||
EnterEvadeMode();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_ANNOUNCER_SAY_ZOMBIE:
|
||||
if( pInstance && !summons.empty() )
|
||||
if( Creature* ghoul = pInstance->instance->GetCreature(*summons.begin()) )
|
||||
ghoul->MonsterYell("[Zombie] .... . Brains ....", LANG_UNIVERSAL, 0);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_PLAGUE_STRIKE:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_PLAGUE_STRIKE, false);
|
||||
events.RepeatEvent(urand(10000,12000));
|
||||
break;
|
||||
case EVENT_SPELL_ICY_TOUCH:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_ICY_TOUCH, false);
|
||||
events.RepeatEvent(urand(5000,6000));
|
||||
break;
|
||||
case EVENT_SPELL_DEATH_RESPITE:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true) )
|
||||
me->CastSpell(target, SPELL_DEATH_RESPITE, false);
|
||||
events.RepeatEvent(urand(13000,15000));
|
||||
break;
|
||||
case EVENT_SPELL_OBLITERATE:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_OBLITERATE, false);
|
||||
events.RepeatEvent(urand(15000,17000));
|
||||
break;
|
||||
case EVENT_SPELL_DESECRATION:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true) )
|
||||
me->CastSpell(target, SPELL_DESECRATION, false);
|
||||
events.RepeatEvent(urand(14000,17000));
|
||||
break;
|
||||
case EVENT_SPELL_DEATH_BITE:
|
||||
me->CastSpell((Unit*)NULL, SPELL_DEATH_BITE, false);
|
||||
events.RepeatEvent(urand(2000,4000));
|
||||
break;
|
||||
case EVENT_SPELL_MARKED_DEATH:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.000000f, true) )
|
||||
me->CastSpell(target, SPELL_MARKED_DEATH, false);
|
||||
events.RepeatEvent(9000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if( Unit* target = summon->SelectNearestTarget(200.0f) )
|
||||
{
|
||||
summon->AI()->AttackStart(target);
|
||||
DoZoneInCombat(summon);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if( victim->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
if( urand(0,1) )
|
||||
Talk(TEXT_BK_SLAIN_1);
|
||||
else
|
||||
Talk(TEXT_BK_SLAIN_2);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
me->CastSpell((Unit*)NULL, SPELL_BK_KILL_CREDIT, true);
|
||||
Talk(TEXT_BK_DEATH);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_BLACK_KNIGHT, DONE);
|
||||
if( me->ToTempSummon() )
|
||||
me->ToTempSummon()->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature *pCreature) const
|
||||
{
|
||||
return new boss_black_knightAI (pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_black_knight_skeletal_gryphon : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_black_knight_skeletal_gryphon() : CreatureScript("npc_black_knight_skeletal_gryphon") {}
|
||||
|
||||
struct npc_black_knight_skeletal_gryphonAI : public npc_escortAI
|
||||
{
|
||||
npc_black_knight_skeletal_gryphonAI(Creature* pCreature) : npc_escortAI(pCreature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Start(false,true,0,NULL);
|
||||
SetDespawnAtEnd(true);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if( param == 1 )
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
|
||||
SetEscortPaused(false);
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 i)
|
||||
{
|
||||
if( i == 12 )
|
||||
{
|
||||
SetEscortPaused(true);
|
||||
me->SetOrientation(3.62f);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SetFacingTo(3.62f);
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_MOUNT_SPECIAL);
|
||||
if( InstanceScript* pInstance = me->GetInstanceScript() )
|
||||
pInstance->SetData(DATA_SKELETAL_GRYPHON_LANDED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 uiDiff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(uiDiff);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_black_knight_skeletal_gryphonAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_black_knight_ghoul : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_black_knight_ghoul() : CreatureScript("npc_black_knight_ghoul") { }
|
||||
|
||||
struct npc_black_knight_ghoulAI : public ScriptedAI
|
||||
{
|
||||
npc_black_knight_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
events.Reset();
|
||||
if (me->GetEntry() == NPC_RISEN_JAEREN || me->GetEntry() == NPC_RISEN_ARELAS)
|
||||
events.RescheduleEvent(1, 1000); // leap
|
||||
events.RescheduleEvent(2, urand(3000,4000)); // claw
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_BK_GHOUL_EXPLODE)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
me->CastSpell(me, SPELL_EXPLODE, false);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
switch(spell->Id)
|
||||
{
|
||||
case SPELL_CLAW_N:
|
||||
case SPELL_CLAW_H:
|
||||
DoResetThreat();
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
|
||||
{
|
||||
me->AddThreat(target, 100.0f);
|
||||
AttackStart(target);
|
||||
}
|
||||
break;
|
||||
case SPELL_EXPLODE_H:
|
||||
if (target && target->GetTypeId() == TYPEID_PLAYER)
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_ACHIEV_IVE_HAD_WORSE, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1: // leap
|
||||
if (Unit* target = me->GetVictim())
|
||||
if (me->GetDistance(target) > 5.0f && me->GetDistance(target) < 30.0f)
|
||||
{
|
||||
me->CastSpell(target, SPELL_LEAP, false);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case 2: // claw
|
||||
if (Unit* target = me->GetVictim())
|
||||
me->CastSpell(target, SPELL_CLAW_N, false);
|
||||
events.RepeatEvent(urand(6000,8000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature *pCreature) const
|
||||
{
|
||||
return new npc_black_knight_ghoulAI (pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_black_knight()
|
||||
{
|
||||
new boss_black_knight();
|
||||
new npc_black_knight_skeletal_gryphon();
|
||||
new npc_black_knight_ghoul();
|
||||
}
|
||||
@@ -1,943 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Vehicle.h"
|
||||
#include "trial_of_the_champion.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum MountSpells
|
||||
{
|
||||
SPELL_PLAYER_VEHICLE_DEFEND = 66482,
|
||||
SPELL_MINIONS_DEFEND = 64100,
|
||||
SPELL_BOSS_DEFEND = 62719,
|
||||
SPELL_BOSS_DEFEND_PERIODIC = 64553,
|
||||
SPELL_SHIELD_LEVEL_1_VISUAL = 63130,
|
||||
SPELL_SHIELD_LEVEL_2_VISUAL = 63131,
|
||||
SPELL_SHIELD_LEVEL_3_VISUAL = 63132,
|
||||
|
||||
SPELL_PLAYER_VEHICLE_SHIELD_BREAKER = 62575,
|
||||
SPELL_PLAYER_SHIELD_BREAKER_DAMAGE = 62626,
|
||||
SPELL_NPC_SHIELD_BREAKER = 68504,
|
||||
|
||||
SPELL_PLAYER_VEHICLE_CHARGE = 68284,
|
||||
SPELL_CHARGE_DAMAGE_20000 = 68498,
|
||||
SPELL_MINIONS_CHARGE = 63010,
|
||||
SPELL_BOSS_CHARGE = 68301, // triggers SPELL_MINIONS_CHARGE (should be with custom damage?)
|
||||
|
||||
SPELL_PLAYER_VEHICLE_THRUST = 68505,
|
||||
|
||||
SPELL_TRAMPLE_AURA = 67865,
|
||||
SPELL_TRAMPLE_TRIGGERED_DUMMY = 67866,
|
||||
SPELL_TRAMPLE_STUN = 67867,
|
||||
};
|
||||
|
||||
enum ChampionSpells
|
||||
{
|
||||
// Mage (Ambrose Boltspark, Eressea Dawnsinger)
|
||||
SPELL_FIREBALL_N = 66042,
|
||||
SPELL_FIREBALL_H = 68310,
|
||||
SPELL_BLAST_WAVE_N = 66044,
|
||||
SPELL_BLAST_WAVE_H = 68312,
|
||||
SPELL_HASTE = 66045,
|
||||
SPELL_POLYMORPH_N = 66043,
|
||||
SPELL_POLYMORPH_H = 68311,
|
||||
|
||||
// Shaman (Colosos, Runok Wildmane)
|
||||
SPELL_CHAIN_LIGHTNING_N = 67529,
|
||||
SPELL_CHAIN_LIGHTNING_H = 68319,
|
||||
SPELL_EARTH_SHIELD = 67530,
|
||||
SPELL_HEALING_WAVE_N = 67528,
|
||||
SPELL_HEALING_WAVE_H = 68318,
|
||||
SPELL_HEX_OF_MENDING = 67534,
|
||||
|
||||
// Hunter (Jaelyne Evensong, Zul'tore)
|
||||
SPELL_DISENGAGE = 68339,
|
||||
SPELL_LIGHTNING_ARROWS = 66083,
|
||||
SPELL_MULTI_SHOT = 66081,
|
||||
SPELL_SHOOT_N = 65868,
|
||||
SPELL_SHOOT_H = 67988,
|
||||
|
||||
// Rogue (Lana Stouthammer Evensong, Deathstalker Visceri)
|
||||
SPELL_EVISCERATE_N = 67709,
|
||||
SPELL_EVISCERATE_H = 68317,
|
||||
SPELL_FAN_OF_KNIVES = 67706,
|
||||
SPELL_POISON_BOTTLE = 67701,
|
||||
|
||||
// Warrior (Marshal Jacob Alerius, Mokra the Skullcrusher)
|
||||
SPELL_MORTAL_STRIKE_N = 68783,
|
||||
SPELL_MORTAL_STRIKE_H = 68784,
|
||||
SPELL_BLADESTORM = 63784,
|
||||
SPELL_INTERCEPT = 67540,
|
||||
SPELL_ROLLING_THROW = 67546, // not implemented yet!
|
||||
};
|
||||
|
||||
#define SPELL_FIREBALL DUNGEON_MODE(SPELL_FIREBALL_N, SPELL_FIREBALL_H)
|
||||
#define SPELL_BLAST_WAVE DUNGEON_MODE(SPELL_BLAST_WAVE_N, SPELL_BLAST_WAVE_H)
|
||||
#define SPELL_POLYMORPH DUNGEON_MODE(SPELL_POLYMORPH_N, SPELL_POLYMORPH_H)
|
||||
#define SPELL_CHAIN_LIGHTNING DUNGEON_MODE(SPELL_CHAIN_LIGHTNING_N, SPELL_CHAIN_LIGHTNING_H)
|
||||
#define SPELL_HEALING_WAVE DUNGEON_MODE(SPELL_HEALING_WAVE_N, SPELL_HEALING_WAVE_H)
|
||||
#define SPELL_SHOOT DUNGEON_MODE(SPELL_SHOOT_N, SPELL_SHOOT_H)
|
||||
#define SPELL_EVISCERATE DUNGEON_MODE(SPELL_EVISCERATE_N, SPELL_EVISCERATE_H)
|
||||
#define SPELL_MORTAL_STRIKE DUNGEON_MODE(SPELL_MORTAL_STRIKE_N, SPELL_MORTAL_STRIKE_H)
|
||||
|
||||
enum MountEvents
|
||||
{
|
||||
EVENT_NONE = 0,
|
||||
EVENT_MOUNT_CHARGE,
|
||||
EVENT_SHIELD_BREAKER,
|
||||
EVENT_THRUST,
|
||||
EVENT_FIND_NEW_MOUNT,
|
||||
};
|
||||
|
||||
enum ChampionEvents
|
||||
{
|
||||
EVEMT_MAGE_SPELL_FIREBALL = 101,
|
||||
EVEMT_MAGE_SPELL_BLAST_WAVE,
|
||||
EVEMT_MAGE_SPELL_HASTE,
|
||||
EVEMT_MAGE_SPELL_POLYMORPH,
|
||||
|
||||
EVENT_SHAMAN_SPELL_CHAIN_LIGHTNING,
|
||||
EVENT_SHAMAN_SPELL_EARTH_SHIELD,
|
||||
EVENT_SHAMAN_SPELL_HEALING_WAVE,
|
||||
EVENT_SHAMAN_SPELL_HEX_OF_MENDING,
|
||||
|
||||
EVENT_HUNTER_SPELL_DISENGAGE,
|
||||
EVENT_HUNTER_SPELL_LIGHTNING_ARROWS,
|
||||
EVENT_HUNTER_SPELL_MULTI_SHOT,
|
||||
EVENT_HUNTER_SPELL_SHOOT,
|
||||
|
||||
EVENT_ROGUE_SPELL_EVISCERATE,
|
||||
EVENT_ROGUE_SPELL_FAN_OF_KNIVES,
|
||||
EVENT_ROGUE_SPELL_POISON_BOTTLE,
|
||||
|
||||
EVENT_WARRIOR_SPELL_MORTAL_STRIKE,
|
||||
EVENT_WARRIOR_SPELL_BLADESTORM,
|
||||
EVENT_WARRIOR_SPELL_INTERCEPT,
|
||||
EVENT_WARRIOR_SPELL_ROLLING_THROW,
|
||||
};
|
||||
|
||||
class npc_toc5_player_vehicle : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_toc5_player_vehicle() : CreatureScript("npc_toc5_player_vehicle") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_toc5_player_vehicleAI(pCreature);
|
||||
}
|
||||
|
||||
struct npc_toc5_player_vehicleAI : public NullCreatureAI
|
||||
{
|
||||
npc_toc5_player_vehicleAI(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry());
|
||||
m_ConditionsTimer = 1000;
|
||||
}
|
||||
|
||||
ConditionList conditions;
|
||||
uint16 m_ConditionsTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->getHostileRefManager().setOnlineOfflineState(false);
|
||||
}
|
||||
|
||||
void OnCharmed(bool apply)
|
||||
{
|
||||
if (me->IsDuringRemoveFromWorld())
|
||||
return;
|
||||
|
||||
if( apply )
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetSpeed(MOVE_RUN, 2.0f, false);
|
||||
me->CastSpell(me, SPELL_TRAMPLE_AURA, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->StopMoving();
|
||||
me->RemoveAura(SPELL_TRAMPLE_AURA);
|
||||
}
|
||||
}
|
||||
|
||||
// just in case, should be done in spell_gen_defend
|
||||
void PassengerBoarded(Unit* who, int8 seat, bool apply)
|
||||
{
|
||||
if (me->IsDuringRemoveFromWorld())
|
||||
return;
|
||||
|
||||
if( !apply )
|
||||
{
|
||||
me->RemoveAura(SPELL_PLAYER_VEHICLE_DEFEND);
|
||||
who->RemoveAura(SPELL_PLAYER_VEHICLE_DEFEND);
|
||||
for (uint8 i=0; i<3; ++i)
|
||||
who->RemoveAura(SPELL_SHIELD_LEVEL_1_VISUAL + i);
|
||||
}
|
||||
}
|
||||
|
||||
//void EnterEvadeMode() { CreatureAI::EnterEvadeMode(); }
|
||||
void MoveInLineOfSight(Unit* who) {}
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (m_ConditionsTimer <= diff)
|
||||
{
|
||||
if (!conditions.empty())
|
||||
if (Unit* passenger = me->GetVehicleKit()->GetPassenger(0))
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(passenger, me, conditions))
|
||||
passenger->ExitVehicle();
|
||||
m_ConditionsTimer = VEHICLE_CONDITION_CHECK_TIME;
|
||||
}
|
||||
else
|
||||
m_ConditionsTimer -= diff;
|
||||
}
|
||||
void AttackStart(Unit* who) {}
|
||||
void EnterCombat(Unit* who) {}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_toc5_grand_champion_minion : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_toc5_grand_champion_minion() : CreatureScript("npc_toc5_grand_champion_minion") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_toc5_grand_champion_minionAI(pCreature);
|
||||
}
|
||||
|
||||
struct npc_toc5_grand_champion_minionAI : public ScriptedAI
|
||||
{
|
||||
npc_toc5_grand_champion_minionAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
int32 ShieldTimer;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ShieldTimer = 0;
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_MOUNT_CHARGE, urand(2500,4000));
|
||||
events.ScheduleEvent(EVENT_SHIELD_BREAKER, urand(5000,8000));
|
||||
events.ScheduleEvent(EVENT_THRUST, urand(3000,5000));
|
||||
me->CastSpell(me, SPELL_TRAMPLE_AURA, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( ShieldTimer <= (int32)diff )
|
||||
{
|
||||
me->CastSpell(me, SPELL_MINIONS_DEFEND, true);
|
||||
ShieldTimer = 5000;
|
||||
}
|
||||
else
|
||||
ShieldTimer -= diff;
|
||||
|
||||
if ( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_MOUNT_CHARGE:
|
||||
{
|
||||
std::vector<uint64> LIST;
|
||||
Map::PlayerList const &pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* plr = itr->GetSource() )
|
||||
{
|
||||
if( me->GetExactDist(plr) < 8.0f || me->GetExactDist(plr) > 25.0f || plr->isDead() )
|
||||
continue;
|
||||
if( !plr->GetVehicle() )
|
||||
LIST.push_back(plr->GetGUID());
|
||||
else if( Vehicle* v = plr->GetVehicle() )
|
||||
{
|
||||
if( Unit* mount = v->GetBase() )
|
||||
LIST.push_back(mount->GetGUID());
|
||||
}
|
||||
}
|
||||
if( !LIST.empty() )
|
||||
{
|
||||
uint8 rnd = LIST.size()>1 ? urand(0,LIST.size()-1) : 0;
|
||||
if( Unit* target = ObjectAccessor::GetUnit(*me, LIST.at(rnd)) )
|
||||
{
|
||||
me->getThreatManager().resetAllAggro();
|
||||
me->AddThreat(target, 10000.0f);
|
||||
AttackStart(target);
|
||||
me->CastSpell(target, SPELL_MINIONS_CHARGE, false);
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(4500,6000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SHIELD_BREAKER:
|
||||
{
|
||||
std::vector<uint64> LIST;
|
||||
Map::PlayerList const &pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* plr = itr->GetSource() )
|
||||
{
|
||||
if( me->GetExactDist(plr) < 10.0f || me->GetExactDist(plr) > 30.0f )
|
||||
continue;
|
||||
if( Vehicle* v = plr->GetVehicle() )
|
||||
if( Unit* mount = v->GetBase() )
|
||||
LIST.push_back(mount->GetGUID());
|
||||
}
|
||||
if( !LIST.empty() )
|
||||
{
|
||||
uint8 rnd = LIST.size()>1 ? urand(0,LIST.size()-1) : 0;
|
||||
if( Unit* target = ObjectAccessor::GetCreature(*me, LIST.at(rnd)) )
|
||||
me->CastSpell(target, SPELL_NPC_SHIELD_BREAKER, false);
|
||||
}
|
||||
events.RepeatEvent(urand(6000,8000));
|
||||
}
|
||||
break;
|
||||
case EVENT_THRUST:
|
||||
if( me->GetVictim() && me->GetExactDist(me->GetVictim()) <= 5.5f )
|
||||
me->CastSpell(me->GetVictim(), SPELL_PLAYER_VEHICLE_THRUST, false);
|
||||
events.RepeatEvent(urand(3000,5000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
|
||||
me->DespawnOrUnsummon(10000);
|
||||
if( pInstance )
|
||||
pInstance->SetData(DATA_MOUNT_DIED, 0);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_grand_champion : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_grand_champion() : CreatureScript("boss_grand_champion") { }
|
||||
|
||||
struct boss_grand_championAI : public npc_escortAI
|
||||
{
|
||||
boss_grand_championAI(Creature* pCreature) : npc_escortAI(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
MountPhase = true;
|
||||
SetDespawnAtEnd(false);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
BossOrder = 0;
|
||||
NewMountGUID = 0;
|
||||
me->CastSpell(me, SPELL_BOSS_DEFEND_PERIODIC, true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_MOUNT_CHARGE, urand(2500,4000));
|
||||
events.ScheduleEvent(EVENT_SHIELD_BREAKER, urand(5000,8000));
|
||||
events.ScheduleEvent(EVENT_THRUST, urand(3000,5000));
|
||||
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISTRACT, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_KNOCKOUT, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SHACKLE, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_TURN, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SAPPED, true);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint32 BossOrder;
|
||||
bool MountPhase;
|
||||
uint64 NewMountGUID;
|
||||
uint64 UnitTargetGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if( pInstance && pInstance->GetData(DATA_INSTANCE_PROGRESS) == INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED )
|
||||
{
|
||||
DoAction(1);
|
||||
DoAction(2);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if( pInstance && pInstance->GetData(DATA_INSTANCE_PROGRESS) == INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED )
|
||||
me->CallForHelp(100.0f);
|
||||
}
|
||||
|
||||
void ScheduleAbilitiesEvents()
|
||||
{
|
||||
me->m_spellImmune[IMMUNITY_MECHANIC].clear();
|
||||
events.Reset();
|
||||
switch( me->GetEntry() )
|
||||
{
|
||||
case NPC_AMBROSE: // Ambrose Boltspark
|
||||
case NPC_ERESSEA: // Eressea Dawnsinger
|
||||
events.RescheduleEvent(EVEMT_MAGE_SPELL_FIREBALL, 5000);
|
||||
events.RescheduleEvent(EVEMT_MAGE_SPELL_BLAST_WAVE, 12000);
|
||||
events.RescheduleEvent(EVEMT_MAGE_SPELL_HASTE, 22000);
|
||||
events.RescheduleEvent(EVEMT_MAGE_SPELL_POLYMORPH, 8000);
|
||||
break;
|
||||
case NPC_COLOSOS: // Colosos
|
||||
case NPC_RUNOK: // Runok Wildmane
|
||||
events.RescheduleEvent(EVENT_SHAMAN_SPELL_CHAIN_LIGHTNING, 16000);
|
||||
events.RescheduleEvent(EVENT_SHAMAN_SPELL_EARTH_SHIELD, urand(30000,35000));
|
||||
events.RescheduleEvent(EVENT_SHAMAN_SPELL_HEALING_WAVE, 12000);
|
||||
events.RescheduleEvent(EVENT_SHAMAN_SPELL_HEX_OF_MENDING, urand(20000,25000));
|
||||
break;
|
||||
case NPC_JAELYNE: // Jaelyne Evensong
|
||||
case NPC_ZULTORE: // Zul'tore
|
||||
//events.RescheduleEvent(EVENT_HUNTER_SPELL_DISENGAGE, x);
|
||||
events.RescheduleEvent(EVENT_HUNTER_SPELL_LIGHTNING_ARROWS, 7000);
|
||||
events.RescheduleEvent(EVENT_HUNTER_SPELL_MULTI_SHOT, 12000);
|
||||
break;
|
||||
case NPC_LANA: // Lana Stouthammer
|
||||
case NPC_VISCERI: // Deathstalker Visceri
|
||||
events.RescheduleEvent(EVENT_ROGUE_SPELL_EVISCERATE, 8000);
|
||||
events.RescheduleEvent(EVENT_ROGUE_SPELL_FAN_OF_KNIVES, 14000);
|
||||
events.RescheduleEvent(EVENT_ROGUE_SPELL_POISON_BOTTLE, 19000);
|
||||
break;
|
||||
case NPC_JACOB: // Marshal Jacob Alerius
|
||||
case NPC_MOKRA: // Mokra the Skullcrusher
|
||||
events.RescheduleEvent(EVENT_WARRIOR_SPELL_MORTAL_STRIKE, urand(8000,12000));
|
||||
events.RescheduleEvent(EVENT_WARRIOR_SPELL_BLADESTORM, urand(15000,20000));
|
||||
events.RescheduleEvent(EVENT_WARRIOR_SPELL_INTERCEPT, 7000);
|
||||
//events.RescheduleEvent(EVENT_WARRIOR_SPELL_ROLLING_THROW, x);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AddCreatureAddonAuras()
|
||||
{
|
||||
CreatureAddon const *cainfo = me->GetCreatureAddon();
|
||||
if (!cainfo)
|
||||
return;
|
||||
|
||||
if (!cainfo->auras.empty())
|
||||
{
|
||||
for (std::vector<uint32>::const_iterator itr = cainfo->auras.begin(); itr != cainfo->auras.end(); ++itr)
|
||||
{
|
||||
SpellInfo const *AdditionalSpellInfo = sSpellMgr->GetSpellInfo(*itr);
|
||||
if (!AdditionalSpellInfo)
|
||||
continue;
|
||||
|
||||
if (me->HasAura(AdditionalSpellInfo->Id))
|
||||
continue;
|
||||
|
||||
me->AddAura(AdditionalSpellInfo->Id, me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if( param == 1 )
|
||||
{
|
||||
MountPhase = false;
|
||||
NewMountGUID = 0;
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
me->SetRegeneratingHealth(true);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
|
||||
me->SetSpeed(MOVE_RUN, 1.0f, false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
me->RemoveAllAuras();
|
||||
AddCreatureAddonAuras();
|
||||
events.Reset();
|
||||
}
|
||||
else if( param == 2 )
|
||||
ScheduleAbilitiesEvents();
|
||||
}
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
BossOrder = uiType;
|
||||
if( uiData > 1 )
|
||||
return;
|
||||
switch( BossOrder )
|
||||
{
|
||||
case 0:
|
||||
if (uiData == 0) // 1 == short version
|
||||
{
|
||||
AddWaypoint(0,747.36f,634.07f,411.572f);
|
||||
AddWaypoint(1,780.43f,607.15f,411.82f);
|
||||
}
|
||||
AddWaypoint(2,785.99f,599.41f,411.92f);
|
||||
AddWaypoint(3,778.44f,601.64f,411.79f);
|
||||
break;
|
||||
case 1:
|
||||
if (uiData == 0) // 1 == short version
|
||||
{
|
||||
AddWaypoint(0,747.35f,634.07f,411.57f);
|
||||
AddWaypoint(1,768.72f,581.01f,411.92f);
|
||||
}
|
||||
AddWaypoint(2,763.55f,590.52f,411.71f);
|
||||
break;
|
||||
case 2:
|
||||
if (uiData == 0) // 1 == short version
|
||||
{
|
||||
AddWaypoint(0,747.35f,634.07f,411.57f);
|
||||
AddWaypoint(1,784.02f,645.33f,412.39f);
|
||||
}
|
||||
AddWaypoint(2,775.67f,641.91f,411.91f);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
Start(false, true, 0, NULL);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if( MountPhase )
|
||||
{
|
||||
if( me->GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID) == 0 )
|
||||
damage = 0;
|
||||
else if( damage >= me->GetHealth() )
|
||||
{
|
||||
events.Reset();
|
||||
damage = me->GetHealth()-1;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->RemoveAllAuras();
|
||||
AddCreatureAddonAuras();
|
||||
me->DeleteThreatList();
|
||||
me->CombatStop(true);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->StopMoving();
|
||||
me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
if( pInstance )
|
||||
{
|
||||
pInstance->SetData(DATA_MOUNT_DIED, BossOrder);
|
||||
if( Creature* mount = me->FindNearestCreature( pInstance->GetData(DATA_TEAMID_IN_INSTANCE) == TEAM_HORDE ? VEHICLE_ARGENT_WARHORSE : VEHICLE_ARGENT_BATTLEWORG, 100.0f, true ) )
|
||||
{
|
||||
NewMountGUID = mount->GetGUID();
|
||||
me->GetMotionMaster()->MovePoint(7, *mount);
|
||||
events.RescheduleEvent(EVENT_FIND_NEW_MOUNT, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( damage >= me->GetHealth() )
|
||||
{
|
||||
events.Reset();
|
||||
damage = me->GetHealth()-1;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->RemoveAllAuras();
|
||||
AddCreatureAddonAuras();
|
||||
me->DeleteThreatList();
|
||||
me->CombatStop(true);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(DATA_GRAND_CHAMPION_DIED, BossOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode() {}
|
||||
|
||||
void WaypointReached(uint32 i)
|
||||
{
|
||||
if( !pInstance )
|
||||
return;
|
||||
|
||||
if( (i==2 && (BossOrder==1 || BossOrder==2)) || (i==3 && BossOrder==0) )
|
||||
pInstance->SetData(DATA_GRAND_CHAMPION_REACHED_DEST, BossOrder);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if( id < 4 )
|
||||
npc_escortAI::MovementInform(type, id);
|
||||
|
||||
if( type == POINT_MOTION_TYPE )
|
||||
{
|
||||
if( id == 5 )
|
||||
me->SetFacingTo(3*M_PI/2);
|
||||
else if( id == 7 ) // reached new mount!
|
||||
{
|
||||
if( NewMountGUID )
|
||||
if( Creature* mount = ObjectAccessor::GetCreature(*me, NewMountGUID) )
|
||||
{
|
||||
mount->DespawnOrUnsummon();
|
||||
me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, mount->GetDisplayId());
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
me->SetHealth(50000);
|
||||
me->CastSpell(me, SPELL_BOSS_DEFEND_PERIODIC, true);
|
||||
me->SetRegeneratingHealth(true);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_MOUNT_CHARGE, urand(2500,4000));
|
||||
events.ScheduleEvent(EVENT_SHIELD_BREAKER, urand(5000,8000));
|
||||
events.ScheduleEvent(EVENT_THRUST, urand(3000,5000));
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( Unit* target = me->SelectNearestTarget(200.0f) )
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
me->CastSpell(me, SPELL_TRAMPLE_AURA, true);
|
||||
if( pInstance )
|
||||
pInstance->SetData(DATA_REACHED_NEW_MOUNT, 0);
|
||||
NewMountGUID = 0;
|
||||
}
|
||||
}
|
||||
else if( id == 9 )
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
switch( spell->Id )
|
||||
{
|
||||
case SPELL_TRAMPLE_STUN:
|
||||
{
|
||||
char buffer[50];
|
||||
sprintf(buffer, "%s is trampled!", me->GetName().c_str());
|
||||
me->MonsterTextEmote(buffer, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if ( !UpdateVictim() && !NewMountGUID )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) || ((me->GetEntry()==NPC_JACOB || me->GetEntry()==NPC_MOKRA) && me->HasAura(SPELL_BLADESTORM)) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_FIND_NEW_MOUNT:
|
||||
{
|
||||
if( me->HasAura(SPELL_TRAMPLE_STUN) )
|
||||
{
|
||||
events.RepeatEvent(200);
|
||||
break;
|
||||
}
|
||||
|
||||
// hackfix, trample won't hit grand champions because of UNIT_FLAG_NON_ATTACKABLE
|
||||
if( pInstance )
|
||||
{
|
||||
bool trample = false;
|
||||
Map::PlayerList const &pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* plr = itr->GetSource() )
|
||||
if( me->GetExactDist(plr) <= 5.0f )
|
||||
if( Vehicle* v = plr->GetVehicle() )
|
||||
if( Unit* c = v->GetBase() )
|
||||
if( c->GetTypeId() == TYPEID_UNIT && c->ToCreature()->GetEntry() == (pInstance->GetData(DATA_TEAMID_IN_INSTANCE) == TEAM_HORDE ? VEHICLE_ARGENT_BATTLEWORG : VEHICLE_ARGENT_WARHORSE) )
|
||||
{
|
||||
me->GetMotionMaster()->MovementExpired();;
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->StopMoving();
|
||||
me->CastSpell(me, SPELL_TRAMPLE_STUN, false);
|
||||
trample = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if( trample )
|
||||
{
|
||||
events.RepeatEvent(15100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( Creature* mount = ObjectAccessor::GetCreature(*me, NewMountGUID) )
|
||||
if( mount->IsAlive() )
|
||||
{
|
||||
if( me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE )
|
||||
me->GetMotionMaster()->MovePoint(7, *mount);
|
||||
events.RepeatEvent(200);
|
||||
break;
|
||||
}
|
||||
|
||||
if( Creature* mount = me->FindNearestCreature( pInstance->GetData(DATA_TEAMID_IN_INSTANCE) == TEAM_HORDE ? VEHICLE_ARGENT_WARHORSE : VEHICLE_ARGENT_BATTLEWORG, 100.0f, true ) )
|
||||
{
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
NewMountGUID = mount->GetGUID();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->GetMotionMaster()->MovePoint(7, *mount);
|
||||
events.RepeatEvent(200);
|
||||
break;
|
||||
}
|
||||
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_MOUNT_CHARGE:
|
||||
{
|
||||
std::vector<uint64> LIST;
|
||||
Map::PlayerList const &pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* plr = itr->GetSource() )
|
||||
{
|
||||
if( me->GetExactDist(plr) < 8.0f || me->GetExactDist(plr) > 25.0f || plr->isDead() )
|
||||
continue;
|
||||
if( !plr->GetVehicle() )
|
||||
LIST.push_back(plr->GetGUID());
|
||||
else if( Vehicle* v = plr->GetVehicle() )
|
||||
{
|
||||
if( Unit* mount = v->GetBase() )
|
||||
LIST.push_back(mount->GetGUID());
|
||||
}
|
||||
}
|
||||
if( !LIST.empty() )
|
||||
{
|
||||
uint8 rnd = LIST.size()>1 ? urand(0,LIST.size()-1) : 0;
|
||||
if( Unit* target = ObjectAccessor::GetUnit(*me, LIST.at(rnd)) )
|
||||
{
|
||||
me->getThreatManager().resetAllAggro();
|
||||
me->AddThreat(target, 10000.0f);
|
||||
AttackStart(target);
|
||||
me->CastSpell(target, SPELL_MINIONS_CHARGE, false);
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(4500,6000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SHIELD_BREAKER:
|
||||
{
|
||||
std::vector<uint64> LIST;
|
||||
Map::PlayerList const &pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* plr = itr->GetSource() )
|
||||
{
|
||||
if( me->GetExactDist(plr) < 10.0f || me->GetExactDist(plr) > 30.0f )
|
||||
continue;
|
||||
if( Vehicle* v = plr->GetVehicle() )
|
||||
if( Unit* mount = v->GetBase() )
|
||||
LIST.push_back(mount->GetGUID());
|
||||
}
|
||||
if( !LIST.empty() )
|
||||
{
|
||||
uint8 rnd = LIST.size()>1 ? urand(0,LIST.size()-1) : 0;
|
||||
if( Unit* target = ObjectAccessor::GetCreature(*me, LIST.at(rnd)) )
|
||||
me->CastSpell(target, SPELL_NPC_SHIELD_BREAKER, false);
|
||||
}
|
||||
events.RepeatEvent(urand(6000,8000));
|
||||
}
|
||||
break;
|
||||
case EVENT_THRUST:
|
||||
if( Unit* victim = me->GetVictim() )
|
||||
if( me->GetExactDist(victim) <= 6.0f )
|
||||
me->CastSpell(victim, SPELL_PLAYER_VEHICLE_THRUST, false);
|
||||
events.RepeatEvent(urand(3000,5000));
|
||||
break;
|
||||
|
||||
/******************* MAGE *******************/
|
||||
case EVEMT_MAGE_SPELL_FIREBALL:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_FIREBALL, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
case EVEMT_MAGE_SPELL_BLAST_WAVE:
|
||||
me->CastSpell((Unit*)NULL, SPELL_BLAST_WAVE, false);
|
||||
events.RepeatEvent(13000);
|
||||
break;
|
||||
case EVEMT_MAGE_SPELL_HASTE:
|
||||
me->CastSpell(me, SPELL_HASTE, false);
|
||||
events.RepeatEvent(22000);
|
||||
break;
|
||||
case EVEMT_MAGE_SPELL_POLYMORPH:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) )
|
||||
me->CastSpell(target, SPELL_POLYMORPH, false);
|
||||
events.RepeatEvent(8000);
|
||||
break;
|
||||
/***************** MAGE END *****************/
|
||||
|
||||
/****************** SHAMAN ******************/
|
||||
case EVENT_SHAMAN_SPELL_CHAIN_LIGHTNING:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) )
|
||||
me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false);
|
||||
events.RepeatEvent(16000);
|
||||
break;
|
||||
case EVENT_SHAMAN_SPELL_EARTH_SHIELD:
|
||||
me->CastSpell(me, SPELL_EARTH_SHIELD, false);
|
||||
events.RepeatEvent(urand(30000,35000));
|
||||
break;
|
||||
case EVENT_SHAMAN_SPELL_HEALING_WAVE:
|
||||
{
|
||||
Unit* target = NULL;
|
||||
if( urand(0,1) )
|
||||
{
|
||||
target = DoSelectLowestHpFriendly(40.0f);
|
||||
if( !target )
|
||||
target = me;
|
||||
}
|
||||
else
|
||||
target = me;
|
||||
me->CastSpell(target, SPELL_HEALING_WAVE, false);
|
||||
events.RepeatEvent(22000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SHAMAN_SPELL_HEX_OF_MENDING:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_HEX_OF_MENDING, false);
|
||||
events.RepeatEvent(urand(20000,25000));
|
||||
break;
|
||||
/**************** SHAMAN END ****************/
|
||||
|
||||
/****************** HUNTER ******************/
|
||||
case EVENT_HUNTER_SPELL_DISENGAGE:
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_HUNTER_SPELL_LIGHTNING_ARROWS:
|
||||
me->CastSpell((Unit*)NULL, SPELL_LIGHTNING_ARROWS, false);
|
||||
events.RepeatEvent(urand(20000,25000));
|
||||
break;
|
||||
case EVENT_HUNTER_SPELL_MULTI_SHOT:
|
||||
{
|
||||
if( !UnitTargetGUID )
|
||||
{
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0, 30.0f, true) )
|
||||
{
|
||||
me->CastSpell(target, SPELL_SHOOT, false);
|
||||
UnitTargetGUID = target->GetGUID();
|
||||
}
|
||||
events.RepeatEvent(2000);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, UnitTargetGUID);
|
||||
if( target && me->IsInRange(target, 5.0f, 30.0f, false) )
|
||||
me->CastSpell(target, SPELL_MULTI_SHOT, false);
|
||||
else
|
||||
{
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
Player* player = itr->GetSource();
|
||||
if( player && me->IsInRange(player, 5.0f, 30.0f, false) )
|
||||
{
|
||||
me->CastSpell(player, SPELL_MULTI_SHOT, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UnitTargetGUID = 0;
|
||||
}
|
||||
events.RepeatEvent(urand(15000,20000));
|
||||
}
|
||||
break;
|
||||
/**************** HUNTER END ****************/
|
||||
|
||||
/****************** ROGUE *******************/
|
||||
case EVENT_ROGUE_SPELL_EVISCERATE:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_EVISCERATE, false);
|
||||
events.RepeatEvent(8000);
|
||||
break;
|
||||
case EVENT_ROGUE_SPELL_FAN_OF_KNIVES:
|
||||
me->CastSpell((Unit*)NULL, SPELL_FAN_OF_KNIVES, false);
|
||||
events.RepeatEvent(14000);
|
||||
break;
|
||||
case EVENT_ROGUE_SPELL_POISON_BOTTLE:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) )
|
||||
me->CastSpell(target, SPELL_POISON_BOTTLE, false);
|
||||
events.RepeatEvent(19000);
|
||||
break;
|
||||
/**************** ROGUE END *****************/
|
||||
|
||||
/***************** WARRIOR ******************/
|
||||
case EVENT_WARRIOR_SPELL_MORTAL_STRIKE:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
|
||||
events.RepeatEvent(urand(8000,12000));
|
||||
break;
|
||||
case EVENT_WARRIOR_SPELL_BLADESTORM:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_BLADESTORM, false);
|
||||
events.RepeatEvent(urand(15000,20000));
|
||||
break;
|
||||
case EVENT_WARRIOR_SPELL_INTERCEPT:
|
||||
{
|
||||
Map::PlayerList const& pl = me->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
{
|
||||
Player* player = itr->GetSource();
|
||||
if( player && me->IsInRange(player, 8.0f, 25.0f, false) )
|
||||
{
|
||||
DoResetThreat();
|
||||
me->AddThreat(player,5.0f);
|
||||
me->CastSpell(player, SPELL_INTERCEPT, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(7000);
|
||||
}
|
||||
break;
|
||||
case EVENT_WARRIOR_SPELL_ROLLING_THROW:
|
||||
events.PopEvent();
|
||||
break;
|
||||
/*************** WARRIOR END ****************/
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_grand_championAI(pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_grand_champions()
|
||||
{
|
||||
new boss_grand_champion();
|
||||
new npc_toc5_grand_champion_minion();
|
||||
new npc_toc5_player_vehicle();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "trial_of_the_champion.h"
|
||||
#include "Player.h"
|
||||
|
||||
#define GOSSIP_START_EVENT1a "I am ready."
|
||||
#define GOSSIP_START_EVENT1b "I am ready. However I'd like to skip the pageantry."
|
||||
#define GOSSIP_START_EVENT2 "I'm ready for the next challenge."
|
||||
#define GOSSIP_START_EVENT3 "I'm ready."
|
||||
|
||||
class npc_announcer_toc5 : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_announcer_toc5() : CreatureScript("npc_announcer_toc5") {}
|
||||
|
||||
bool OnGossipHello(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if( !pCreature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP) )
|
||||
return true;
|
||||
|
||||
InstanceScript* pInstance = pCreature->GetInstanceScript();
|
||||
if( !pInstance )
|
||||
return true;
|
||||
|
||||
uint32 gossipTextId = 0;
|
||||
switch( pInstance->GetData(DATA_INSTANCE_PROGRESS) )
|
||||
{
|
||||
case INSTANCE_PROGRESS_INITIAL:
|
||||
gossipTextId = 14688;
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1a, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1338);
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1b, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1341);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_CHAMPIONS_DEAD:
|
||||
gossipTextId = 14737;
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1339);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED:
|
||||
gossipTextId = 14738;
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1340);
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
pPlayer->SEND_GOSSIP_MENU(gossipTextId, pCreature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
if( !pCreature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP) )
|
||||
return true;
|
||||
|
||||
InstanceScript* pInstance = pCreature->GetInstanceScript();
|
||||
if( !pInstance )
|
||||
return true;
|
||||
|
||||
if( uiAction == GOSSIP_ACTION_INFO_DEF+1338 || uiAction == GOSSIP_ACTION_INFO_DEF+1341 || uiAction == GOSSIP_ACTION_INFO_DEF+1339 || uiAction == GOSSIP_ACTION_INFO_DEF+1340 )
|
||||
{
|
||||
pInstance->SetData(DATA_ANNOUNCER_GOSSIP_SELECT, (uiAction == GOSSIP_ACTION_INFO_DEF+1341 ? 1 : 0));
|
||||
pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_announcer_toc5AI(pCreature);
|
||||
}
|
||||
|
||||
struct npc_announcer_toc5AI : public CreatureAI
|
||||
{
|
||||
npc_announcer_toc5AI(Creature *pCreature) : CreatureAI(pCreature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
InstanceScript* pInstance = me->GetInstanceScript();
|
||||
if( !pInstance )
|
||||
return;
|
||||
if( pInstance->GetData(DATA_TEAMID_IN_INSTANCE) == TEAM_ALLIANCE )
|
||||
me->UpdateEntry(NPC_ARELAS);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); // removed during black knight scene
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (damage >= me->GetHealth()) // for bk scene so strangulate doesn't kill him
|
||||
damage = me->GetHealth()-1;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != EFFECT_MOTION_TYPE)
|
||||
return;
|
||||
InstanceScript* pInstance = me->GetInstanceScript();
|
||||
if( !pInstance )
|
||||
return;
|
||||
if (pInstance->GetData(DATA_INSTANCE_PROGRESS) < INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED)
|
||||
return;
|
||||
|
||||
Unit::Kill(me, me); // for bk scene, die after knockback
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) {}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_trial_of_the_champion()
|
||||
{
|
||||
new npc_announcer_toc5();
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_TOC_H
|
||||
#define DEF_TOC_H
|
||||
|
||||
enum eData
|
||||
{
|
||||
BOSS_GRAND_CHAMPIONS = 0,
|
||||
BOSS_ARGENT_CHALLENGE = 1,
|
||||
BOSS_BLACK_KNIGHT = 2,
|
||||
MAX_ENCOUNTER = 3,
|
||||
DATA_INSTANCE_PROGRESS = 4,
|
||||
|
||||
DATA_ANNOUNCER = 5,
|
||||
DATA_ANNOUNCER_GOSSIP_SELECT,
|
||||
DATA_GRAND_CHAMPION_REACHED_DEST,
|
||||
DATA_MOUNT_DIED,
|
||||
DATA_REACHED_NEW_MOUNT,
|
||||
DATA_GRAND_CHAMPION_PICKED_NEW_VEHICLE,
|
||||
DATA_GRAND_CHAMPION_DIED,
|
||||
DATA_ARGENT_SOLDIER_DEFEATED,
|
||||
DATA_SKELETAL_GRYPHON_LANDED,
|
||||
DATA_TEAMID_IN_INSTANCE,
|
||||
DATA_PALETRESS,
|
||||
DATA_MEMORY_ENTRY,
|
||||
DATA_ACHIEV_IVE_HAD_WORSE,
|
||||
};
|
||||
|
||||
enum eProgress
|
||||
{
|
||||
INSTANCE_PROGRESS_INITIAL = 0,
|
||||
INSTANCE_PROGRESS_GRAND_CHAMPIONS_REACHED_DEST,
|
||||
INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_1,
|
||||
INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_2,
|
||||
INSTANCE_PROGRESS_CHAMPION_GROUP_DIED_3,
|
||||
INSTANCE_PROGRESS_CHAMPIONS_UNMOUNTED,
|
||||
INSTANCE_PROGRESS_CHAMPIONS_DEAD,
|
||||
INSTANCE_PROGRESS_ARGENT_SOLDIERS_DIED,
|
||||
INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED,
|
||||
INSTANCE_PROGRESS_FINISHED,
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_NULL = 0,
|
||||
EVENT_CHECK_PLAYERS,
|
||||
EVENT_CLOSE_GATE,
|
||||
EVENT_SUMMON_GRAND_CHAMPION_1,
|
||||
EVENT_SUMMON_GRAND_CHAMPION_2,
|
||||
EVENT_SUMMON_GRAND_CHAMPION_3,
|
||||
EVENT_YELL_WELCOME_2,
|
||||
EVENT_GRAND_GROUP_1_MOVE_MIDDLE,
|
||||
EVENT_GRAND_GROUP_1_ATTACK,
|
||||
EVENT_GRAND_GROUP_2_MOVE_MIDDLE,
|
||||
EVENT_GRAND_GROUP_2_ATTACK,
|
||||
EVENT_GRAND_GROUP_3_MOVE_MIDDLE,
|
||||
EVENT_GRAND_GROUP_3_ATTACK,
|
||||
EVENT_GRAND_CHAMPIONS_MOVE_MIDDLE,
|
||||
EVENT_GRAND_CHAMPIONS_MOUNTS_ATTACK,
|
||||
EVENT_GRAND_CHAMPIONS_MOVE_SIDE,
|
||||
EVENT_GRAND_CHAMPIONS_ATTACK,
|
||||
EVENT_GRATZ_SLAIN_CHAMPIONS,
|
||||
EVENT_RESTORE_ANNOUNCER_GOSSIP,
|
||||
EVENT_START_ARGENT_CHALLENGE_INTRO,
|
||||
EVENT_SUMMON_ARGENT_CHALLENGE,
|
||||
EVENT_ARGENT_CHALLENGE_SAY_1,
|
||||
EVENT_ARGENT_CHALLENGE_SAY_2,
|
||||
EVENT_ARGENT_SOLDIER_GROUP_ATTACK,
|
||||
EVENT_ARGENT_CHALLENGE_MOVE_FORWARD,
|
||||
EVENT_ARGENT_CHALLENGE_ATTACK,
|
||||
EVENT_ARGENT_CHALLENGE_RUN_MIDDLE,
|
||||
EVENT_ARGENT_CHALLENGE_LEAVE_CHEST,
|
||||
EVENT_ARGENT_CHALLENGE_DISAPPEAR,
|
||||
EVENT_SUMMON_BLACK_KNIGHT,
|
||||
EVENT_START_BLACK_KNIGHT_SCENE,
|
||||
EVENT_BLACK_KNIGHT_CAST_ANNOUNCER,
|
||||
EVENT_BLACK_KNIGHT_KILL_ANNOUNCER,
|
||||
EVENT_BLACK_KNIGHT_MOVE_FORWARD,
|
||||
EVENT_BLACK_KNIGHT_SAY_TASK,
|
||||
EVENT_BLACK_KNIGHT_ATTACK,
|
||||
};
|
||||
|
||||
enum eNpcs
|
||||
{
|
||||
// Horde Champions
|
||||
NPC_MOKRA = 35572,
|
||||
NPC_ERESSEA = 35569,
|
||||
NPC_RUNOK = 35571,
|
||||
NPC_ZULTORE = 35570,
|
||||
NPC_VISCERI = 35617,
|
||||
|
||||
// Alliance Champions
|
||||
NPC_JACOB = 34705,
|
||||
NPC_AMBROSE = 34702,
|
||||
NPC_COLOSOS = 34701,
|
||||
NPC_JAELYNE = 34657,
|
||||
NPC_LANA = 34703,
|
||||
|
||||
// Grand Champion Minions
|
||||
NPC_IRONFORGE_MINION = 35329,
|
||||
NPC_STORMWIND_MINION = 35328,
|
||||
NPC_GNOMEREGAN_MINION = 35331,
|
||||
NPC_EXODAR_MINION = 35330,
|
||||
NPC_DARNASSUS_MINION = 35332,
|
||||
NPC_ORGRIMMAR_MINION = 35314,
|
||||
NPC_SILVERMOON_MINION = 35326,
|
||||
NPC_THUNDER_BLUFF_MINION = 35325,
|
||||
NPC_SENJIN_MINION = 35323,
|
||||
NPC_UNDERCITY_MINION = 35327,
|
||||
|
||||
NPC_EADRIC = 35119,
|
||||
NPC_EADRIC_H = 35518,
|
||||
NPC_PALETRESS = 34928,
|
||||
NPC_PALETRESS_H = 35517,
|
||||
|
||||
NPC_ARGENT_LIGHTWIELDER = 35309,
|
||||
NPC_ARGENT_MONK = 35305,
|
||||
NPC_PRIESTESS = 35307,
|
||||
|
||||
NPC_BLACK_KNIGHT = 35451,
|
||||
|
||||
NPC_JAEREN = 35004,
|
||||
NPC_ARELAS = 35005,
|
||||
NPC_RISEN_JAEREN = 35545,
|
||||
NPC_RISEN_ARELAS = 35564,
|
||||
NPC_TIRION = 33628,
|
||||
};
|
||||
|
||||
enum eGameObjects
|
||||
{
|
||||
GO_MAIN_GATE = 195647,
|
||||
GO_SOUTH_PORTCULLIS = 195649,
|
||||
GO_EAST_PORTCULLIS = 195648,
|
||||
|
||||
GO_CHAMPIONS_LOOT = 195709,
|
||||
GO_CHAMPIONS_LOOT_H = 195710,
|
||||
|
||||
GO_EADRIC_LOOT = 195374,
|
||||
GO_EADRIC_LOOT_H = 195375,
|
||||
|
||||
GO_PALETRESS_LOOT = 195323,
|
||||
GO_PALETRESS_LOOT_H = 195324,
|
||||
};
|
||||
|
||||
enum eVehicles
|
||||
{
|
||||
VEHICLE_ARGENT_WARHORSE = 35644,
|
||||
VEHICLE_ARGENT_BATTLEWORG = 36558,
|
||||
|
||||
VEHICLE_BLACK_KNIGHT = 35491,
|
||||
};
|
||||
|
||||
enum eTexts
|
||||
{
|
||||
TEXT_LANA_STOUTHAMMER = 1,
|
||||
TEXT_CHEER_LANA_STOUTHAMMER = 2,
|
||||
TEXT_COLOSOS = 3,
|
||||
TEXT_CHEER_COLOSOS = 4,
|
||||
TEXT_EVENSONG = 5,
|
||||
TEXT_CHEER_EVENSONG = 6,
|
||||
TEXT_MARSHAL_JACOB_ALERIUS = 7,
|
||||
TEXT_CHEER_MARSHAL_JACOB_ALERIUS = 8,
|
||||
TEXT_AMBROSE_BOLTSPARK = 9,
|
||||
TEXT_CHEER_AMBROSE_BOLTSPARK = 10,
|
||||
|
||||
TEXT_DEATHSTALKER_VESCERI = 11,
|
||||
TEXT_CHEER_DEATHSTALKER_VESCERI = 12,
|
||||
TEXT_RUNOK_WILDMANE = 13,
|
||||
TEXT_CHEER_RUNOK_WILDMANE = 14,
|
||||
TEXT_ZUL_TORE = 15,
|
||||
TEXT_CHEER_ZUL_TORE = 16,
|
||||
TEXT_MOKRA_SKILLCRUSHER = 17,
|
||||
TEXT_CHEER_MOKRA_SKILLCRUSHER = 18,
|
||||
TEXT_ERESSEA_DAWNSINGER = 19,
|
||||
TEXT_CHEER_ERESSEA_DAWNSINGER = 20,
|
||||
|
||||
TEXT_WELCOME = 21,
|
||||
TEXT_WELCOME_2 = 22,
|
||||
TEXT_BEGIN = 23,
|
||||
TEXT_GRATZ_SLAIN_CHAMPIONS = 24,
|
||||
TEXT_INTRODUCE_EADRIC = 25,
|
||||
TEXT_INTRODUCE_PALETRESS = 26,
|
||||
TEXT_CHEER_EADRIC_1 = 27,
|
||||
TEXT_CHEER_EADRIC_2 = 28,
|
||||
TEXT_EADRIC_SAY_1 = 39,
|
||||
TEXT_CHEER_PALETRESS_1 = 29,
|
||||
TEXT_CHEER_PALETRESS_2 = 30,
|
||||
TEXT_PALETRESS_SAY_1 = 37,
|
||||
TEXT_PALETRESS_SAY_2 = 38,
|
||||
TEXT_YOU_MAY_BEGIN = 41,
|
||||
|
||||
TEXT_BK_INTRO = 31,
|
||||
TEXT_BK_RAFTERS = 32,
|
||||
TEXT_BK_SPOILED = 33,
|
||||
TEXT_BK_MEANING = 34,
|
||||
TEXT_BK_LICH = 35,
|
||||
TEXT_BK_TASK = 36,
|
||||
|
||||
TEXT_EADRIC_AGGRO = 42,
|
||||
TEXT_EADRIC_HAMMER = 43,
|
||||
TEXT_EADRIC_SLAIN_1 = 44,
|
||||
TEXT_EADRIC_SLAIN_2 = 45,
|
||||
TEXT_EADRIC_DEATH = 46,
|
||||
|
||||
TEXT_PALETRESS_AGGRO = 47,
|
||||
TEXT_PALETRESS_MEMORY_SUMMON = 48,
|
||||
TEXT_PALETRESS_MEMORY_DEFEATED = 51,
|
||||
TEXT_PALETRESS_SLAIN_1 = 49,
|
||||
TEXT_PALETRESS_SLAIN_2 = 50,
|
||||
TEXT_PALETRESS_DEATH = 52,
|
||||
|
||||
TEXT_BK_AGGRO = 53,
|
||||
TEXT_BK_SLAIN_1 = 57,
|
||||
TEXT_BK_SLAIN_2 = 58,
|
||||
TEXT_BK_SKELETON_RES = 54,
|
||||
TEXT_BK_GHOST_RES = 55,
|
||||
TEXT_BK_DEATH = 56,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,964 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "trial_of_the_crusader.h"
|
||||
#include "SpellScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum AnubTexts
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
SAY_AGGRO = 1,
|
||||
EMOTE_SUBMERGE = 2,
|
||||
EMOTE_BURROWER = 3,
|
||||
SAY_EMERGE = 4,
|
||||
SAY_LEECHING_SWARM = 5,
|
||||
EMOTE_LEECHING_SWARM = 6,
|
||||
SAY_KILL_PLAYER = 7,
|
||||
SAY_DEATH = 8,
|
||||
|
||||
EMOTE_SPIKE = 0,
|
||||
};
|
||||
|
||||
enum AnubNPCs
|
||||
{
|
||||
NPC_FROST_SPHERE = 34606,
|
||||
NPC_BURROW = 34862,
|
||||
NPC_BURROWER = 34607,
|
||||
NPC_SCARAB = 34605,
|
||||
NPC_SPIKE = 34660,
|
||||
};
|
||||
|
||||
const Position AnubLocs[]=
|
||||
{
|
||||
// scarab's beginning pos
|
||||
{722.65f, 135.41f, 142.16f, M_PI},
|
||||
|
||||
// churning ground spawns
|
||||
{694.886353f, 102.484665f, 142.119614f, 0},
|
||||
{731.987244f, 83.3824690f, 142.119614f, 0},
|
||||
{694.500671f, 185.363968f, 142.117905f, 0},
|
||||
{740.184509f, 193.443390f, 142.117584f, 0},
|
||||
|
||||
// sphere spawns
|
||||
{ 786.6439f, 108.2498f, 155.6701f, 0 },
|
||||
{ 806.8429f, 150.5902f, 155.6701f, 0 },
|
||||
{ 759.1386f, 163.9654f, 155.6701f, 0 },
|
||||
{ 744.3701f, 119.5211f, 155.6701f, 0 },
|
||||
{ 710.0211f, 120.8152f, 155.6701f, 0 },
|
||||
{ 706.6383f, 161.5266f, 155.6701f, 0 },
|
||||
};
|
||||
|
||||
class HideNpcEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
HideNpcEvent(Creature& owner) : _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
|
||||
{
|
||||
_owner.SetVisible(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature& _owner;
|
||||
};
|
||||
|
||||
enum AnubSpells
|
||||
{
|
||||
// Anub'arak
|
||||
SPELL_SUBMERGE = 65981,
|
||||
SPELL_EMERGE = 65982,
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
SPELL_FREEZING_SLASH = 66012,
|
||||
SPELL_PENETRATING_COLD = 66013,
|
||||
SPELL_SUMMON_SCARAB = 66339,
|
||||
SPELL_SUMMON_BURROWER = 66332,
|
||||
SPELL_LEECHING_SWARM = 66118,
|
||||
|
||||
// Anub'arak Pursue
|
||||
SPELL_MARK = 67574,
|
||||
SPELL_SUMMON_SPIKE = 66169,
|
||||
SPELL_SPIKE_SPEED1 = 65920,
|
||||
SPELL_SPIKE_TRAIL = 65921,
|
||||
SPELL_SPIKE_SPEED2 = 65922,
|
||||
SPELL_SPIKE_SPEED3 = 65923,
|
||||
SPELL_SPIKE_FAIL = 66181,
|
||||
SPELL_SPIKE_TELE = 66170,
|
||||
SPELL_IMPALE = 65919,
|
||||
|
||||
// Scarab
|
||||
SPELL_DETERMINATION = 66092,
|
||||
SPELL_ACID_MANDIBLE = 65774,
|
||||
|
||||
// Burrow
|
||||
SPELL_CHURNING_GROUND = 66969,
|
||||
|
||||
// Frost Sphere
|
||||
SPELL_FROST_SPHERE = 67539,
|
||||
SPELL_PERMAFROST = 66193,
|
||||
SPELL_PERMAFROST_VISUAL = 65882,
|
||||
|
||||
// Burrower
|
||||
SPELL_SPIDER_FRENZY = 66128,
|
||||
SPELL_EXPOSE_WEAKNESS = 67720,
|
||||
SPELL_SHADOW_STRIKE = 66134,
|
||||
SPELL_SUBMERGE_EFFECT = 53421,
|
||||
SPELL_EMERGE_EFFECT = 66947,
|
||||
};
|
||||
|
||||
enum AnubEvents
|
||||
{
|
||||
EVENT_RESPAWN_SPHERE = 1,
|
||||
EVENT_ENRAGE,
|
||||
EVENT_SPELL_FREEZING_SLASH,
|
||||
EVENT_SPELL_PENETRATING_COLD,
|
||||
EVENT_SUMMON_NERUBIAN,
|
||||
EVENT_SUBMERGE,
|
||||
EVENT_EMERGE,
|
||||
EVENT_EMERGE_2,
|
||||
EVENT_SPELL_SUMMON_SPIKE,
|
||||
EVENT_SPELL_SHADOW_STRIKE,
|
||||
EVENT_SUMMON_SCARAB,
|
||||
};
|
||||
|
||||
#define SUBMERGE_INTERVAL 80000
|
||||
#define EMERGE_INTERVAL 60000
|
||||
|
||||
class boss_anubarak_trial : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_anubarak_trial() : CreatureScript("boss_anubarak_trial") {}
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_anubarak_trialAI(pCreature);
|
||||
};
|
||||
|
||||
struct boss_anubarak_trialAI : public ScriptedAI
|
||||
{
|
||||
boss_anubarak_trialAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = (InstanceScript*)pCreature->GetInstanceScript();
|
||||
events.Reset();
|
||||
bIntro = false;
|
||||
bPhase3 = false;
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, RAID_MODE(66193,67855,67856,67857), true);
|
||||
me->m_SightDistance = 90.0f; // for MoveInLineOfSight distance
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
SummonList summons;
|
||||
EventMap events;
|
||||
bool bIntro;
|
||||
bool bPhase3;
|
||||
uint64 SphereGUID[6];
|
||||
uint64 BurrowGUID[4];
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_SUBMERGED);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
summons.DespawnAll();
|
||||
for( uint8 i=0; i<10; ++i )
|
||||
{
|
||||
float angle = rand_norm()*2*M_PI;
|
||||
float dist = rand_norm()*40.0f;
|
||||
if( Creature* c = me->SummonCreature(NPC_SCARAB, AnubLocs[0].GetPositionX()+cos(angle)*dist, AnubLocs[0].GetPositionY()+sin(angle)*dist, AnubLocs[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000) )
|
||||
{
|
||||
c->setFaction(31);
|
||||
c->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
c->GetMotionMaster()->MoveRandom(15.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
switch( param )
|
||||
{
|
||||
case -1:
|
||||
summons.DespawnAll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->setActive(true);
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_ENRAGE, 600000);
|
||||
events.RescheduleEvent(EVENT_SPELL_FREEZING_SLASH, urand(7000,15000));
|
||||
events.RescheduleEvent(EVENT_SPELL_PENETRATING_COLD, urand(15000,20000));
|
||||
events.RescheduleEvent(EVENT_SUMMON_NERUBIAN, urand(5000,8000));
|
||||
events.RescheduleEvent(EVENT_SUBMERGE, SUBMERGE_INTERVAL);
|
||||
if( !IsHeroic() )
|
||||
events.RescheduleEvent(EVENT_RESPAWN_SPHERE, 4000);
|
||||
|
||||
for( std::list<uint64>::iterator itr = summons.begin(); itr != summons.end(); ++itr )
|
||||
if( Creature* c = pInstance->instance->GetCreature(*itr) )
|
||||
{
|
||||
c->GetMotionMaster()->MoveIdle();
|
||||
c->StopMoving();
|
||||
c->CastSpell(c, SPELL_SUBMERGE, false);
|
||||
c->AI()->DoAction(1);
|
||||
}
|
||||
summons.clear();
|
||||
for( uint8 i=0; i<4; ++i )
|
||||
if( Creature* c = me->SummonCreature(NPC_BURROW, AnubLocs[i+1]) )
|
||||
BurrowGUID[i] = c->GetGUID();
|
||||
for( uint8 i=0; i<6; ++i )
|
||||
if( Creature* c = me->SummonCreature(NPC_FROST_SPHERE, AnubLocs[i+5]) )
|
||||
SphereGUID[i] = c->GetGUID();
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_ANUBARAK, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
if( !bPhase3 && HealthBelowPct(30) && !me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && !me->HasAura(SPELL_SUBMERGE) && !me->HasAura(SPELL_EMERGE) )
|
||||
{
|
||||
bPhase3 = true;
|
||||
events.CancelEvent(EVENT_SUBMERGE);
|
||||
events.CancelEvent(EVENT_EMERGE);
|
||||
events.CancelEvent(EVENT_EMERGE_2);
|
||||
if( !IsHeroic() )
|
||||
events.CancelEvent(EVENT_SUMMON_NERUBIAN);
|
||||
me->CastSpell((Unit*)NULL, SPELL_LEECHING_SWARM, false);
|
||||
Talk(EMOTE_LEECHING_SWARM);
|
||||
Talk(SAY_LEECHING_SWARM);
|
||||
return;
|
||||
}
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
{
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_RESPAWN_SPHERE:
|
||||
{
|
||||
uint8 StartAt = urand(0,5);
|
||||
uint8 i = StartAt;
|
||||
do
|
||||
{
|
||||
if( Creature* c = ObjectAccessor::GetCreature(*me, SphereGUID[i]) )
|
||||
if( !c->HasAura(SPELL_FROST_SPHERE) )
|
||||
{
|
||||
if( Creature* c = me->SummonCreature(NPC_FROST_SPHERE, AnubLocs[i+5]) )
|
||||
SphereGUID[i] = c->GetGUID();
|
||||
break;
|
||||
}
|
||||
i = (i+1)%6;
|
||||
}
|
||||
while( i != StartAt );
|
||||
events.RepeatEvent(4000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_FREEZING_SLASH:
|
||||
{
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_FREEZING_SLASH, false);
|
||||
events.RepeatEvent(urand(15000,20000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_PENETRATING_COLD:
|
||||
{
|
||||
me->CastCustomSpell(SPELL_PENETRATING_COLD, SPELLVALUE_MAX_TARGETS, RAID_MODE(2,5,2,5));
|
||||
events.RepeatEvent(18000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_NERUBIAN:
|
||||
{
|
||||
me->CastCustomSpell(SPELL_SUMMON_BURROWER, SPELLVALUE_MAX_TARGETS, RAID_MODE(1,2,2,4));
|
||||
events.RepeatEvent(45000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SUBMERGE:
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
bool berserk = me->HasAura(SPELL_BERSERK);
|
||||
me->RemoveAllAuras();
|
||||
if (berserk)
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
Talk(EMOTE_SUBMERGE);
|
||||
Talk(EMOTE_BURROWER);
|
||||
me->CastSpell(me, SPELL_SUBMERGE, false);
|
||||
events.CancelEvent(EVENT_SUMMON_NERUBIAN);
|
||||
events.CancelEvent(EVENT_SPELL_FREEZING_SLASH);
|
||||
events.CancelEvent(EVENT_SPELL_PENETRATING_COLD);
|
||||
events.RescheduleEvent(EVENT_EMERGE, EMERGE_INTERVAL);
|
||||
events.RescheduleEvent(EVENT_SPELL_SUMMON_SPIKE, 2500);
|
||||
events.RescheduleEvent(EVENT_SUMMON_SCARAB, 3000);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_SCARAB:
|
||||
{
|
||||
uint8 i = urand(0,3);
|
||||
if( Creature* c = ObjectAccessor::GetCreature(*me, BurrowGUID[i]) )
|
||||
me->CastSpell(c, SPELL_SUMMON_SCARAB, true);
|
||||
events.RepeatEvent(4000);
|
||||
}
|
||||
break;
|
||||
case EVENT_EMERGE:
|
||||
{
|
||||
me->CastSpell(me, SPELL_SPIKE_TELE, true);
|
||||
summons.DespawnEntry(NPC_SPIKE);
|
||||
events.CancelEvent(EVENT_SUMMON_SCARAB);
|
||||
events.RescheduleEvent(EVENT_EMERGE_2, 2000);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_EMERGE_2:
|
||||
{
|
||||
Talk(SAY_EMERGE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setAttackTimer(BASE_ATTACK, 3000);
|
||||
me->RemoveAura(SPELL_SUBMERGE);
|
||||
me->CastSpell(me, SPELL_EMERGE, false);
|
||||
events.RescheduleEvent(EVENT_SUMMON_NERUBIAN, urand(5000,8000));
|
||||
events.RescheduleEvent(EVENT_SPELL_FREEZING_SLASH, urand(7000,15000));
|
||||
events.RescheduleEvent(EVENT_SPELL_PENETRATING_COLD, urand(15000,20000));
|
||||
events.RescheduleEvent(EVENT_SUBMERGE, SUBMERGE_INTERVAL);
|
||||
events.PopEvent();
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_SPIKE:
|
||||
me->CastSpell(me, SPELL_SUMMON_SPIKE, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if( !summon )
|
||||
return;
|
||||
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_ANUBARAK, DONE);
|
||||
|
||||
|
||||
Player* plr = NULL;
|
||||
if( !pInstance->instance->GetPlayers().isEmpty() )
|
||||
plr = pInstance->instance->GetPlayers().begin()->GetSource();
|
||||
|
||||
if( !plr )
|
||||
return;
|
||||
|
||||
// remove loot for the other faction (items are invisible for players, done in conditions), so corpse can be skinned
|
||||
for( std::vector<LootItem>::iterator itr = me->loot.items.begin(); itr != me->loot.items.end(); ++itr )
|
||||
if( ItemTemplate const *iProto = sObjectMgr->GetItemTemplate((*itr).itemid) )
|
||||
if( ((iProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && plr->GetTeamId() != TEAM_HORDE) || ((iProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && plr->GetTeamId() != TEAM_ALLIANCE) )
|
||||
{
|
||||
(*itr).count = 0;
|
||||
(*itr).is_looted = true;
|
||||
--me->loot.unlootedCount;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
Talk(SAY_KILL_PLAYER);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_FAILED, 1);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER || me->GetExactDistSq(who) > 6400.0f) // 80yd*80yd
|
||||
return;
|
||||
|
||||
if (me->getStandState() != UNIT_STAND_STATE_STAND)
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
if (!bIntro)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( !me->IsInCombat() )
|
||||
Talk(SAY_INTRO);
|
||||
bIntro = true;
|
||||
}
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit* target) const
|
||||
{
|
||||
return target->GetEntry() != NPC_FROST_SPHERE;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_swarm_scarab : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_swarm_scarab() : CreatureScript("npc_swarm_scarab") {}
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_swarm_scarabAI(pCreature);
|
||||
};
|
||||
|
||||
struct npc_swarm_scarabAI : public ScriptedAI
|
||||
{
|
||||
npc_swarm_scarabAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
int32 determinationTimer;
|
||||
int32 despawnTimer;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if( param == 1 )
|
||||
despawnTimer = 2000;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetCorpseDelay(10*60);
|
||||
me->CastSpell(me, SPELL_ACID_MANDIBLE, true);
|
||||
determinationTimer = urand(10000,50000);
|
||||
despawnTimer = 0;
|
||||
if( me->getFaction() == 16 ) // hostile - it's phase 2
|
||||
if( Unit* target = me->SelectNearestTarget(250.0f) )
|
||||
{
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
if( Unit* t = SelectTarget(SELECT_TARGET_RANDOM, 0, 250.0f, true) )
|
||||
{
|
||||
me->AddThreat(t, 20000.0f);
|
||||
AttackStart(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( despawnTimer )
|
||||
{
|
||||
if( despawnTimer <= (int32)diff )
|
||||
{
|
||||
despawnTimer = 0;
|
||||
me->DisappearAndDie();
|
||||
}
|
||||
else
|
||||
despawnTimer -= diff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
if( determinationTimer <= (int32)diff )
|
||||
{
|
||||
me->CastSpell(me, SPELL_DETERMINATION, false);
|
||||
determinationTimer = urand(20000,60000);
|
||||
}
|
||||
else
|
||||
determinationTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
me->CastSpell(me, RAID_MODE(SPELL_TRAITOR_KING_10, SPELL_TRAITOR_KING_25, SPELL_TRAITOR_KING_10, SPELL_TRAITOR_KING_25), true);
|
||||
me->m_Events.AddEvent(new HideNpcEvent(*me), me->m_Events.CalculateTime(5000));
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit* target) const
|
||||
{
|
||||
return target->GetEntry() != NPC_FROST_SPHERE && !me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_frost_sphere : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_frost_sphere() : CreatureScript("npc_frost_sphere") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_frost_sphereAI(pCreature);
|
||||
};
|
||||
|
||||
struct npc_frost_sphereAI : public NullCreatureAI
|
||||
{
|
||||
npc_frost_sphereAI(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
uint32 ID = 0;
|
||||
if (me->GetMap())
|
||||
switch (me->GetMap()->GetDifficulty())
|
||||
{
|
||||
case RAID_DIFFICULTY_10MAN_NORMAL: ID = 66118; break;
|
||||
case RAID_DIFFICULTY_25MAN_NORMAL: ID = 67630; break;
|
||||
case RAID_DIFFICULTY_10MAN_HEROIC: ID = 68646; break;
|
||||
case RAID_DIFFICULTY_25MAN_HEROIC: ID = 68647; break;
|
||||
}
|
||||
if (ID)
|
||||
me->ApplySpellImmune(0, IMMUNITY_ID, ID, true);
|
||||
|
||||
permafrostTimer = 0;
|
||||
me->CastSpell(me, SPELL_FROST_SPHERE, true);
|
||||
me->GetMotionMaster()->MoveRandom(20.0f);
|
||||
me->SetCorpseDelay(15*60*1000);
|
||||
}
|
||||
|
||||
uint32 permafrostTimer;
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if( me->GetHealth() <= damage )
|
||||
{
|
||||
damage = 0;
|
||||
if( !me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) )
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->GetMotionMaster()->MoveCharge(me->GetPositionX(), me->GetPositionY(), 143.0f, 20.0f);
|
||||
permafrostTimer = 1500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
if( spell->Id == SPELL_SPIKE_FAIL )
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->DespawnOrUnsummon(1500);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( permafrostTimer )
|
||||
{
|
||||
if( permafrostTimer <= diff )
|
||||
{
|
||||
permafrostTimer = 0;
|
||||
me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE);
|
||||
me->SetDisplayId(11686);
|
||||
me->SetObjectScale(2.0f);
|
||||
me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), 142.7f, me->GetOrientation(), false);
|
||||
me->SetFacingTo(me->GetOrientation());
|
||||
me->CastSpell(me, SPELL_PERMAFROST_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_PERMAFROST, true);
|
||||
me->SetCanFly(false);
|
||||
}
|
||||
else
|
||||
permafrostTimer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_nerubian_burrower : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_nerubian_burrower() : CreatureScript("npc_nerubian_burrower") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_nerubian_burrowerAI(pCreature);
|
||||
};
|
||||
|
||||
struct npc_nerubian_burrowerAI : public ScriptedAI
|
||||
{
|
||||
npc_nerubian_burrowerAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
// I am summoned by another npc (SPELL_EFFECT_FORCE_CAST), inform Anub'arak
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
if (uint64 guid = pInstance->GetData64(TYPE_ANUBARAK))
|
||||
if (Creature* anub = pInstance->instance->GetCreature(guid))
|
||||
CAST_AI(boss_anubarak_trial::boss_anubarak_trialAI, anub->AI())->JustSummoned(me);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetCorpseDelay(10*60);
|
||||
me->CastSpell(me, SPELL_EXPOSE_WEAKNESS, true);
|
||||
me->CastSpell(me, SPELL_SPIDER_FRENZY, true);
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SUBMERGE, 30000);
|
||||
if( IsHeroic() )
|
||||
events.RescheduleEvent(EVENT_SPELL_SHADOW_STRIKE, urand(30000,45000));
|
||||
if( Unit* target = me->SelectNearestTarget(250.0f) )
|
||||
{
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
if( !target || !spell )
|
||||
return;
|
||||
|
||||
if( spell->Id == SPELL_SHADOW_STRIKE )
|
||||
{
|
||||
float o = target->GetOrientation();
|
||||
if( o >= M_PI )
|
||||
o -= M_PI;
|
||||
else
|
||||
o += M_PI;
|
||||
me->NearTeleportTo(target->GetPositionX()+cos(o)*5.0f, target->GetPositionY()+sin(o)*5.0f, target->GetPositionZ()+0.6f, target->GetOrientation());
|
||||
AttackStart(target);
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
events.DelayEvents(3000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_STRIKE:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 250.0f, true) )
|
||||
me->CastSpell(target, SPELL_SHADOW_STRIKE, false);
|
||||
events.RepeatEvent(urand(30000,45000));
|
||||
break;
|
||||
case EVENT_SUBMERGE:
|
||||
if( HealthBelowPct(80) && !me->HasAura(RAID_MODE(66193,67855,67856,67857)) ) // not having permafrost - allow submerge
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, SPELL_EXPOSE_WEAKNESS, true);
|
||||
me->CastSpell(me, SPELL_SPIDER_FRENZY, true);
|
||||
me->CastSpell(me, SPELL_SUBMERGE, false);
|
||||
events.PopEvent();
|
||||
events.DelayEvents(15000);
|
||||
events.RescheduleEvent(EVENT_EMERGE, 10000);
|
||||
}
|
||||
else
|
||||
events.RepeatEvent(3000);
|
||||
break;
|
||||
case EVENT_EMERGE:
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->CastSpell(me, SPELL_EMERGE, false);
|
||||
me->RemoveAura(SPELL_SUBMERGE);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(EVENT_SUBMERGE, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
me->m_Events.AddEvent(new HideNpcEvent(*me), me->m_Events.CalculateTime(5000));
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit* target) const
|
||||
{
|
||||
return target->GetEntry() != NPC_FROST_SPHERE;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_anubarak_spike : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_anubarak_spike() : CreatureScript("npc_anubarak_spike") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_anubarak_spikeAI(pCreature);
|
||||
};
|
||||
|
||||
struct npc_anubarak_spikeAI : public ScriptedAI
|
||||
{
|
||||
npc_anubarak_spikeAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetCorpseDelay(0);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
uint64 TargetGUID;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if( param == -1 )
|
||||
{
|
||||
if( Unit* target = ObjectAccessor::GetPlayer(*me, TargetGUID) )
|
||||
target->RemoveAura(SPELL_MARK);
|
||||
TargetGUID = 0;
|
||||
me->RemoveAllAuras();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
events.Reset();
|
||||
events.RescheduleEvent(3, 4000);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectNewTarget(bool next)
|
||||
{
|
||||
if (TargetGUID)
|
||||
if( Unit* target = ObjectAccessor::GetPlayer(*me, TargetGUID) )
|
||||
target->RemoveAura(SPELL_MARK);
|
||||
TargetGUID = 0;
|
||||
if (!next)
|
||||
{
|
||||
events.Reset();
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
DoZoneInCombat();
|
||||
DoResetThreat();
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 250.0f, true) )
|
||||
{
|
||||
if (!next)
|
||||
{
|
||||
me->CastSpell(me, SPELL_SPIKE_SPEED1, true);
|
||||
me->CastSpell(me, SPELL_SPIKE_TRAIL, true);
|
||||
events.RescheduleEvent(1, 7000);
|
||||
}
|
||||
TargetGUID = target->GetGUID();
|
||||
me->CastSpell(target, SPELL_MARK, true);
|
||||
Talk(EMOTE_SPIKE, target);
|
||||
AttackStart(target);
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SelectNewTarget(false);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( TargetGUID )
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetPlayer(*me, TargetGUID);
|
||||
if( !target || !target->HasAura(SPELL_MARK) || !me->IsValidAttackTarget(target) || me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE || !me->HasUnitState(UNIT_STATE_CHASE_MOVE) )
|
||||
{
|
||||
SelectNewTarget(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
me->CastSpell(me, SPELL_SPIKE_SPEED2, true);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(2, 7000);
|
||||
break;
|
||||
case 2:
|
||||
me->CastSpell(me, SPELL_SPIKE_SPEED3, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case 3:
|
||||
Reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_pursuing_spikes : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_pursuing_spikes() : SpellScriptLoader("spell_pursuing_spikes") { }
|
||||
|
||||
class spell_pursuing_spikesAuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_pursuing_spikesAuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const * aurEff)
|
||||
{
|
||||
if( Unit* target = GetTarget() )
|
||||
{
|
||||
if( Creature* c = target->FindNearestCreature(NPC_FROST_SPHERE, 8.0f, true) )
|
||||
{
|
||||
target->UpdatePosition(*c, false);
|
||||
target->CastCustomSpell(SPELL_SPIKE_FAIL, SPELLVALUE_MAX_TARGETS, 1);
|
||||
if( target->GetTypeId() == TYPEID_UNIT )
|
||||
target->ToCreature()->AI()->DoAction(-1);
|
||||
Remove();
|
||||
return;
|
||||
}
|
||||
target->CastSpell((Unit*)NULL, SPELL_IMPALE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_pursuing_spikesAuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_pursuing_spikesAuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 66118 Leeching Swarm
|
||||
enum eLeechingSwarmSpells
|
||||
{
|
||||
SPELL_LEECHING_SWARM_DMG = 66240,
|
||||
SPELL_LEECHING_SWARM_HEAL = 66125,
|
||||
};
|
||||
|
||||
class spell_gen_leeching_swarm : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gen_leeching_swarm() : SpellScriptLoader("spell_gen_leeching_swarm") { }
|
||||
|
||||
class spell_gen_leeching_swarm_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_gen_leeching_swarm_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellEntry*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_LEECHING_SWARM_DMG))
|
||||
return false;
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_LEECHING_SWARM_HEAL))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
int32 lifeLeeched = GetTarget()->CountPctFromCurHealth(aurEff->GetAmount());
|
||||
if (lifeLeeched < 250)
|
||||
lifeLeeched = 250;
|
||||
// Damage
|
||||
caster->CastCustomSpell(GetTarget(), SPELL_LEECHING_SWARM_DMG, &lifeLeeched, 0, 0, true);
|
||||
// Heal is handled in damage spell. It has to heal the same amount, but some of the dmg can be resisted.
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_leeching_swarm_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_gen_leeching_swarm_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_gen_leeching_swarm_dmg : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gen_leeching_swarm_dmg() : SpellScriptLoader("spell_gen_leeching_swarm_dmg") {}
|
||||
|
||||
class spell_gen_leeching_swarm_dmg_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gen_leeching_swarm_dmg_SpellScript);
|
||||
|
||||
void HandleAfterHit()
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (GetHitDamage() > 0)
|
||||
{
|
||||
int32 damage = GetHitDamage();
|
||||
caster->CastCustomSpell(caster, SPELL_LEECHING_SWARM_HEAL, &damage, 0, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterHit += SpellHitFn(spell_gen_leeching_swarm_dmg_SpellScript::HandleAfterHit);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_gen_leeching_swarm_dmg_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_anubarak_trial()
|
||||
{
|
||||
new boss_anubarak_trial();
|
||||
new npc_swarm_scarab();
|
||||
new npc_frost_sphere();
|
||||
new npc_nerubian_burrower();
|
||||
new npc_anubarak_spike();
|
||||
new spell_pursuing_spikes();
|
||||
new spell_gen_leeching_swarm();
|
||||
new spell_gen_leeching_swarm_dmg();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,507 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "trial_of_the_crusader.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuras.h"
|
||||
|
||||
enum JaraxxusTexts
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
SAY_AGGRO = 1,
|
||||
EMOTE_LEGION_FLAME = 2,
|
||||
EMOTE_NETHER_PORTAL = 3,
|
||||
SAY_MISTRESS_OF_PAIN = 4,
|
||||
EMOTE_INCINERATE = 5,
|
||||
SAY_INCINERATE = 6,
|
||||
EMOTE_INFERNAL_ERUPTION = 7,
|
||||
SAY_INFERNAL_ERUPTION = 8,
|
||||
SAY_KILL_PLAYER = 9,
|
||||
SAY_DEATH = 10,
|
||||
SAY_BERSERK = 11,
|
||||
};
|
||||
|
||||
enum JaraxxusNPCs
|
||||
{
|
||||
NPC_LEGION_FLAME = 34784,
|
||||
NPC_INFERNAL_VOLCANO = 34813,
|
||||
NPC_FEL_INFERNAL = 34815,
|
||||
NPC_NETHER_PORTAL = 34825,
|
||||
NPC_MISTRESS_OF_PAIN = 34826,
|
||||
};
|
||||
|
||||
enum JaraxxusSpells
|
||||
{
|
||||
SPELL_NETHER_POWER = 66228,
|
||||
SPELL_INCINERATE_FLESH = 66237,
|
||||
SPELL_FEL_FIREBALL = 66532,
|
||||
SPELL_FEL_LIGHTNING = 66528,
|
||||
SPELL_TOUCH_OF_JARAXXUS = 66209,
|
||||
SPELL_LEGION_FLAME = 66197,
|
||||
SPELL_LEGION_FLAME_NPC_AURA = 66201,
|
||||
SPELL_SUMMON_VOLCANO = 66258,
|
||||
SPELL_SUMMON_NETHER_PORTAL = 66269,
|
||||
|
||||
SPELL_FEL_STEAK = 66494,
|
||||
SPELL_FEL_STEAK_MORPH = 66493,
|
||||
|
||||
SPELL_SHIVAN_SLASH = 66378,
|
||||
SPELL_SPINNING_PAIN_SPIKE = 66283,
|
||||
SPELL_MISTRESS_KISS = 66336,
|
||||
SPELL_MISTRESS_KISS_PERIODIC_DUMMY = 66334, // also 67905, 67906, 67907
|
||||
SPELL_MISTRESS_KISS_INTERRUPT = 66359,
|
||||
|
||||
SPELL_CHAINS = 67924,
|
||||
SPELL_BERSERK = 64238,
|
||||
};
|
||||
|
||||
enum JaraxxusEvents
|
||||
{
|
||||
EVENT_SPELL_FEL_FIREBALL = 1,
|
||||
EVENT_SPELL_FEL_LIGHTNING,
|
||||
EVENT_SPELL_INCINERATE_FLESH,
|
||||
EVENT_SPELL_NETHER_POWER,
|
||||
EVENT_SPELL_LEGION_FLAME,
|
||||
EVENT_SPELL_TOUCH_OF_JARAXXUS,
|
||||
EVENT_SUMMON_VOLCANO,
|
||||
EVENT_SUMMON_NETHER_PORTAL,
|
||||
|
||||
EVENT_SPELL_FEL_STEAK,
|
||||
|
||||
EVENT_SPELL_SHIVAN_SLASH,
|
||||
EVENT_SPELL_SPINNING_PAIN_SPIKE,
|
||||
EVENT_SPELL_MISTRESS_KISS,
|
||||
};
|
||||
|
||||
|
||||
class boss_jaraxxus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_jaraxxus() : CreatureScript("boss_jaraxxus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_jaraxxusAI(pCreature);
|
||||
}
|
||||
|
||||
struct boss_jaraxxusAI : public ScriptedAI
|
||||
{
|
||||
boss_jaraxxusAI(Creature* pCreature) : ScriptedAI(pCreature), summons(pCreature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_JARAXXUS, NOT_STARTED);
|
||||
|
||||
// checked for safety
|
||||
while( Creature* c = me->FindNearestCreature(NPC_INFERNAL_VOLCANO, 500.0f, true) )
|
||||
c->DespawnOrUnsummon();
|
||||
while( Creature* c = me->FindNearestCreature(NPC_NETHER_PORTAL, 500.0f, true) )
|
||||
c->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->setActive(true);
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_FEL_FIREBALL, 5000);
|
||||
events.RescheduleEvent(EVENT_SPELL_FEL_LIGHTNING, urand(10000,15000));
|
||||
events.RescheduleEvent(EVENT_SPELL_INCINERATE_FLESH, urand(24000,26000));
|
||||
events.RescheduleEvent(EVENT_SPELL_NETHER_POWER, urand(25000,45000));
|
||||
events.RescheduleEvent(EVENT_SPELL_LEGION_FLAME, 30000);
|
||||
//if( GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC )
|
||||
// events.RescheduleEvent(EVENT_SPELL_TOUCH_OF_JARAXXUS, urand(10000,15000));
|
||||
events.RescheduleEvent(EVENT_SUMMON_NETHER_PORTAL, 20000); // it schedules EVENT_SUMMON_VOLCANO
|
||||
|
||||
me->RemoveAura(SPELL_CHAINS);
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_JARAXXUS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
switch( spell->Id )
|
||||
{
|
||||
case 66228:
|
||||
case 67106:
|
||||
case 67107:
|
||||
case 67108:
|
||||
if( Aura* a = me->GetAura(spell->Id) )
|
||||
a->SetStackAmount(spell->StackAmount);
|
||||
break;
|
||||
case 30449:
|
||||
{
|
||||
if( !caster )
|
||||
return;
|
||||
uint32 id = 0;
|
||||
switch( me->GetMap()->GetDifficulty() )
|
||||
{
|
||||
case 0: id = 66228; break;
|
||||
case 1: id = 67106; break;
|
||||
case 2: id = 67107; break;
|
||||
case 3: id = 67108; break;
|
||||
}
|
||||
if( Aura* a = me->GetAura(id) )
|
||||
{
|
||||
if( a->GetStackAmount() > 1 )
|
||||
a->ModStackAmount(-1);
|
||||
else
|
||||
a->Remove();
|
||||
caster->CastSpell(caster, SPELL_NETHER_POWER, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_FEL_FIREBALL:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_FEL_FIREBALL, false);
|
||||
events.RepeatEvent(urand(10000,15000));
|
||||
break;
|
||||
case EVENT_SPELL_FEL_LIGHTNING:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true) )
|
||||
me->CastSpell(target, SPELL_FEL_LIGHTNING, false);
|
||||
events.RepeatEvent(urand(10000,15000));
|
||||
break;
|
||||
case EVENT_SPELL_INCINERATE_FLESH:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true) )
|
||||
{
|
||||
Talk(EMOTE_INCINERATE, target);
|
||||
Talk(SAY_INCINERATE);
|
||||
me->CastSpell(target, SPELL_INCINERATE_FLESH, false);
|
||||
}
|
||||
events.RepeatEvent(urand(20000,25000));
|
||||
break;
|
||||
case EVENT_SPELL_NETHER_POWER:
|
||||
me->CastSpell(me, SPELL_NETHER_POWER, false);
|
||||
events.DelayEvents(5000);
|
||||
events.RepeatEvent(urand(25000,45000));
|
||||
break;
|
||||
case EVENT_SPELL_LEGION_FLAME:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true) )
|
||||
{
|
||||
Talk(EMOTE_LEGION_FLAME, target);
|
||||
me->CastSpell(target, SPELL_LEGION_FLAME, false);
|
||||
}
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SPELL_TOUCH_OF_JARAXXUS:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true) )
|
||||
me->CastSpell(target, SPELL_TOUCH_OF_JARAXXUS, false);
|
||||
events.RepeatEvent(urand(10000,15000));
|
||||
break;
|
||||
case EVENT_SUMMON_NETHER_PORTAL:
|
||||
Talk(EMOTE_NETHER_PORTAL);
|
||||
Talk(SAY_MISTRESS_OF_PAIN);
|
||||
me->CastSpell((Unit*)NULL, SPELL_SUMMON_NETHER_PORTAL, false);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(EVENT_SUMMON_VOLCANO, 60000);
|
||||
break;
|
||||
case EVENT_SUMMON_VOLCANO:
|
||||
Talk(EMOTE_INFERNAL_ERUPTION);
|
||||
Talk(SAY_INFERNAL_ERUPTION);
|
||||
me->CastSpell((Unit*)NULL, SPELL_SUMMON_VOLCANO, false);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(EVENT_SUMMON_NETHER_PORTAL, 60000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_JARAXXUS, DONE);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_FAILED, 1);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) {}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_fel_infernal : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_fel_infernal() : CreatureScript("npc_fel_infernal") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_fel_infernalAI(pCreature);
|
||||
}
|
||||
|
||||
struct npc_fel_infernalAI : public ScriptedAI
|
||||
{
|
||||
npc_fel_infernalAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if( Unit* target = me->SelectNearestTarget(200.0f) )
|
||||
{
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_FEL_STEAK, urand(7000,20000));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_FEL_STEAK:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 44.0f, true) )
|
||||
{
|
||||
DoResetThreat();
|
||||
me->AddThreat(target, 50000.0f);
|
||||
me->CastSpell(target, SPELL_FEL_STEAK_MORPH, true);
|
||||
me->CastSpell(target, SPELL_FEL_STEAK, true);
|
||||
events.RepeatEvent(30000);
|
||||
}
|
||||
else
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
me->DespawnOrUnsummon(10000);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_mistress_of_pain : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_mistress_of_pain() : CreatureScript("npc_mistress_of_pain") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_mistress_of_painAI(pCreature);
|
||||
}
|
||||
|
||||
struct npc_mistress_of_painAI : public ScriptedAI
|
||||
{
|
||||
npc_mistress_of_painAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if( Unit* target = me->SelectNearestTarget(200.0f) )
|
||||
{
|
||||
AttackStart(target);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_SHIVAN_SLASH, urand(10000,20000));
|
||||
events.RescheduleEvent(EVENT_SPELL_SPINNING_PAIN_SPIKE, urand(22000,30000));
|
||||
if( IsHeroic() )
|
||||
events.RescheduleEvent(EVENT_SPELL_MISTRESS_KISS, urand(10000,15000));
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo* spell)
|
||||
{
|
||||
//if (caster && spell && spell->Id == 66287 /*control vehicle*/)
|
||||
// caster->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_SHIVAN_SLASH:
|
||||
if( me->GetVictim() )
|
||||
me->CastSpell(me->GetVictim(), SPELL_SHIVAN_SLASH, false);
|
||||
events.RepeatEvent(urand(15000,25000));
|
||||
break;
|
||||
case EVENT_SPELL_SPINNING_PAIN_SPIKE:
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 140.0f, true) )
|
||||
me->CastSpell(target, SPELL_SPINNING_PAIN_SPIKE, false);
|
||||
events.RepeatEvent(urand(25000,30000));
|
||||
break;
|
||||
case EVENT_SPELL_MISTRESS_KISS:
|
||||
me->CastSpell((Unit*)NULL, SPELL_MISTRESS_KISS, false);
|
||||
events.RepeatEvent(urand(25000,35000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
me->DespawnOrUnsummon(10000);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_toc25_mistress_kiss : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_toc25_mistress_kiss() : SpellScriptLoader("spell_toc25_mistress_kiss") { }
|
||||
|
||||
class spell_toc25_mistress_kiss_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_toc25_mistress_kiss_AuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const * aurEff)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetTarget())
|
||||
if( target->HasUnitState(UNIT_STATE_CASTING) )
|
||||
{
|
||||
caster->CastSpell(target, 66359, true);
|
||||
SetDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_toc25_mistress_kiss_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_toc25_mistress_kiss_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mistress_kiss_area : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mistress_kiss_area() : SpellScriptLoader("spell_mistress_kiss_area") {}
|
||||
|
||||
class spell_mistress_kiss_area_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mistress_kiss_area_SpellScript)
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
// get a list of players with mana
|
||||
targets.remove_if(Trinity::ObjectTypeIdCheck(TYPEID_PLAYER, false));
|
||||
targets.remove_if(Trinity::PowerCheck(POWER_MANA, false));
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mistress_kiss_area_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_mistress_kiss_area_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_mistress_kiss_area_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_jaraxxus()
|
||||
{
|
||||
new boss_jaraxxus();
|
||||
new npc_fel_infernal();
|
||||
new npc_mistress_of_pain();
|
||||
new spell_toc25_mistress_kiss();
|
||||
new spell_mistress_kiss_area();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,909 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
(!) ACTUALLY FJOLA CONTROLLS THE WHOLE FIGHT (SPECIAL ABILITIES, SHARED HEALTH, ETC.) SINCE THEY DIE SIMULTANEOUSLY
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "trial_of_the_crusader.h"
|
||||
#include "SpellScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_NIGHT = 2,
|
||||
SAY_LIGHT = 1,
|
||||
EMOTE_VORTEX = 3,
|
||||
EMOTE_TWINK_PACT = 4,
|
||||
SAY_TWINK_PACT = 5,
|
||||
SAY_KILL_PLAYER_1 = 6,
|
||||
SAY_BERSERK = 7,
|
||||
SAY_DEATH = 8,
|
||||
SAY_KILL_PLAYER_2 = 9,
|
||||
};
|
||||
|
||||
enum Equipment
|
||||
{
|
||||
EQUIP_MAIN_1 = 49303,
|
||||
EQUIP_OFFHAND_1 = 47146,
|
||||
EQUIP_RANGED_1 = 47267,
|
||||
EQUIP_MAIN_2 = 45990,
|
||||
EQUIP_OFFHAND_2 = 47470,
|
||||
EQUIP_RANGED_2 = 47267,
|
||||
};
|
||||
|
||||
enum ValkyrNPCs
|
||||
{
|
||||
NPC_DARK_ESSENCE = 34567,
|
||||
NPC_LIGHT_ESSENCE = 34568,
|
||||
NPC_CONCENTRATED_DARK = 34628,
|
||||
NPC_CONCENTRATED_LIGHT= 34630,
|
||||
};
|
||||
|
||||
enum ValkyrSpells
|
||||
{
|
||||
SPELL_LIGHT_ESSENCE = 65686,
|
||||
SPELL_LIGHT_ESSENCE_2 = 65811,
|
||||
SPELL_DARK_ESSENCE = 65684,
|
||||
SPELL_DARK_ESSENCE_2 = 65827,
|
||||
|
||||
SPELL_UNLEASHED_DARK = 65808,
|
||||
SPELL_UNLEASHED_LIGHT = 65795,
|
||||
SPELL_POWERING_UP = 67590,
|
||||
SPELL_EMPOWERED_DARK = 65724,
|
||||
SPELL_EMPOWERED_LIGHT = 65748,
|
||||
SPELL_SURGE_OF_SPEED = 65828,
|
||||
|
||||
SPELL_LIGHT_TWIN_SPIKE = 66075,
|
||||
SPELL_LIGHT_SURGE = 65766,
|
||||
SPELL_LIGHT_SHIELD = 65858,
|
||||
SPELL_LIGHT_TWIN_PACT = 65876,
|
||||
SPELL_LIGHT_VORTEX = 66046,
|
||||
SPELL_LIGHT_TOUCH = 67297,
|
||||
|
||||
SPELL_DARK_TWIN_SPIKE = 66069,
|
||||
SPELL_DARK_SURGE = 65768,
|
||||
SPELL_DARK_SHIELD = 65874,
|
||||
SPELL_DARK_TWIN_PACT = 65875,
|
||||
SPELL_DARK_VORTEX = 66058,
|
||||
SPELL_DARK_TOUCH = 67282,
|
||||
|
||||
SPELL_TWIN_POWER = 65916,
|
||||
SPELL_BERSERK = 64238,
|
||||
};
|
||||
|
||||
enum ValkyrEvents
|
||||
{
|
||||
EVENT_BERSERK = 1,
|
||||
EVENT_SUMMON_BALLS_1,
|
||||
EVENT_SUMMON_BALLS_2,
|
||||
EVENT_SUMMON_BALLS_3,
|
||||
EVENT_SPELL_SPIKE,
|
||||
EVENT_SPELL_TOUCH,
|
||||
EVENT_SPECIAL,
|
||||
EVENT_REMOVE_DUAL_WIELD,
|
||||
};
|
||||
|
||||
struct boss_twin_valkyrAI : public ScriptedAI
|
||||
{
|
||||
boss_twin_valkyrAI(Creature* pCreature) : ScriptedAI(pCreature), summons(me)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceScript();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetModifierValue(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, 1.0f);
|
||||
me->UpdateDamagePhysical(OFF_ATTACK);
|
||||
LastSynchroHP = (int32)me->GetMaxHealth();
|
||||
SpecialMask = 0;
|
||||
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_HASTE_SPELLS, true);
|
||||
|
||||
events.Reset();
|
||||
if( me->GetEntry() == NPC_LIGHTBANE )
|
||||
{
|
||||
if( pInstance )
|
||||
pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, 21853);
|
||||
|
||||
// special events here
|
||||
events.RescheduleEvent(EVENT_BERSERK, IsHeroic() ? 360000 : 600000);
|
||||
events.RescheduleEvent(EVENT_SUMMON_BALLS_1, urand(10000,15000));
|
||||
events.RescheduleEvent(EVENT_SPECIAL, 45000);
|
||||
}
|
||||
events.RescheduleEvent(EVENT_SPELL_SPIKE, urand(5000,8000));
|
||||
if( IsHeroic() )
|
||||
events.RescheduleEvent(EVENT_SPELL_TOUCH, urand(10000,25000), 1);
|
||||
|
||||
me->SetDisableGravity(true);
|
||||
me->SetHover(true);
|
||||
me->SetCanFly(true);
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
SummonList summons;
|
||||
EventMap events;
|
||||
int32 LastSynchroHP;
|
||||
uint8 SpecialMask;
|
||||
|
||||
void DoAction(int32 a)
|
||||
{
|
||||
switch( a )
|
||||
{
|
||||
case -1:
|
||||
summons.DespawnAll();
|
||||
if( pInstance && me->GetEntry() == NPC_LIGHTBANE )
|
||||
{
|
||||
uint32 essenceId1 = 0, empoweredId1 = 0, touchId1 = 0, essenceId2 = 0, empoweredId2 = 0, touchId2 = 0;
|
||||
switch( me->GetMap()->GetDifficulty() )
|
||||
{
|
||||
case 0:
|
||||
essenceId1 = 65684;
|
||||
empoweredId1 = 65724;
|
||||
touchId1 = 65950;
|
||||
essenceId2 = 65686;
|
||||
empoweredId2 = 65748;
|
||||
touchId2 = 66001;
|
||||
break;
|
||||
case 1:
|
||||
essenceId1 = 67176;
|
||||
empoweredId1 = 67213;
|
||||
touchId1 = 67296;
|
||||
essenceId2 = 67222;
|
||||
empoweredId2 = 67216;
|
||||
touchId2 = 67281;
|
||||
break;
|
||||
case 2:
|
||||
essenceId1 = 67177;
|
||||
empoweredId1 = 67214;
|
||||
touchId1 = 67297;
|
||||
essenceId2 = 67223;
|
||||
empoweredId2 = 67217;
|
||||
touchId2 = 67282;
|
||||
break;
|
||||
case 3:
|
||||
essenceId1 = 67178;
|
||||
empoweredId1 = 67215;
|
||||
touchId1 = 67298;
|
||||
essenceId2 = 67224;
|
||||
empoweredId2 = 67218;
|
||||
touchId2 = 67283;
|
||||
break;
|
||||
}
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(essenceId1);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(empoweredId1);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(touchId1);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(essenceId2);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(empoweredId2);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(touchId2);
|
||||
}
|
||||
break;
|
||||
case -3:
|
||||
me->SetCanDualWield(true);
|
||||
me->CastSpell(me, SPELL_TWIN_POWER, true);
|
||||
events.RescheduleEvent(EVENT_REMOVE_DUAL_WIELD, 15000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* GetSister()
|
||||
{
|
||||
return ObjectAccessor::GetCreature(*me, pInstance->GetData64(me->GetEntry()==NPC_DARKBANE ? NPC_LIGHTBANE : NPC_DARKBANE));
|
||||
}
|
||||
|
||||
/*void AttackStart(Unit* victim)
|
||||
{
|
||||
if( victim && me->Attack(victim, true) )
|
||||
me->GetMotionMaster()->MoveChase(victim, 0.0f, 0.0f, 6.0f);
|
||||
}*/
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->setActive(true);
|
||||
me->LowerPlayerDamageReq(me->GetMaxHealth());
|
||||
DoZoneInCombat();
|
||||
if( Creature* twin = GetSister() )
|
||||
if( !twin->IsInCombat() )
|
||||
if( Unit* target = twin->SelectNearestTarget(200.0f) )
|
||||
twin->AI()->AttackStart(target);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
me->CastSpell(me, me->GetEntry() == NPC_LIGHTBANE ? SPELL_LIGHT_SURGE : SPELL_DARK_SURGE, true);
|
||||
|
||||
if( pInstance && me->GetEntry() == NPC_LIGHTBANE )
|
||||
pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, 21853);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
me->setActive(false);
|
||||
}
|
||||
|
||||
void myDoMeleeAttackIfReady()
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
Unit *victim = me->GetVictim();
|
||||
if (!victim || !victim->IsInWorld())
|
||||
return;
|
||||
|
||||
float allowedDist = sqrt(MELEE_RANGE * MELEE_RANGE + 6.0f * 6.0f);
|
||||
if (!me->IsWithinMeleeRange(victim, allowedDist))
|
||||
return;
|
||||
|
||||
if (me->isAttackReady())
|
||||
{
|
||||
me->AttackerStateUpdate(victim);
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
|
||||
if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
me->AttackerStateUpdate(victim, OFF_ATTACK);
|
||||
me->resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSharedHealth()
|
||||
{
|
||||
// lightbane synchronizes
|
||||
if( me->GetEntry() == NPC_LIGHTBANE )
|
||||
if( Creature* twin = GetSister() )
|
||||
if( twin->IsAlive() && me->IsAlive() )
|
||||
{
|
||||
int32 d = CAST_AI(boss_twin_valkyrAI, twin->AI())->LastSynchroHP - (int32)twin->GetHealth();
|
||||
int32 newhealth = (int32)me->GetHealth() - d;
|
||||
if( newhealth <= 0 )
|
||||
newhealth = 1;
|
||||
me->SetHealth( (uint32)newhealth );
|
||||
twin->SetHealth(me->GetHealth());
|
||||
CAST_AI(boss_twin_valkyrAI, twin->AI())->LastSynchroHP = (int32)twin->GetHealth();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( !UpdateVictim() )
|
||||
return;
|
||||
|
||||
UpdateSharedHealth();
|
||||
events.Update(diff);
|
||||
|
||||
if( me->HasUnitState(UNIT_STATE_CASTING) )
|
||||
return;
|
||||
|
||||
switch( events.GetEvent() )
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
Talk(SAY_BERSERK);
|
||||
if( Creature* twin = GetSister() )
|
||||
{
|
||||
twin->CastSpell(twin, SPELL_BERSERK, true);
|
||||
twin->AI()->Talk(SAY_BERSERK);
|
||||
}
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SUMMON_BALLS_1:
|
||||
case EVENT_SUMMON_BALLS_2:
|
||||
case EVENT_SUMMON_BALLS_3:
|
||||
{
|
||||
uint8 eventId = events.GetEvent();
|
||||
uint8 count = 0;
|
||||
if( IsHeroic() )
|
||||
count = eventId==EVENT_SUMMON_BALLS_3 ? 36 : 6;
|
||||
else
|
||||
count = eventId==EVENT_SUMMON_BALLS_3 ? 24 : 4;
|
||||
for( uint8 i=0; i<count; ++i )
|
||||
{
|
||||
float angle = rand_norm()*2*M_PI;
|
||||
if( Creature* ball = me->SummonCreature((i%2) ? NPC_CONCENTRATED_DARK : NPC_CONCENTRATED_LIGHT, Locs[LOC_CENTER].GetPositionX()+cos(angle)*47.0f, Locs[LOC_CENTER].GetPositionY()+sin(angle)*47.0f, Locs[LOC_CENTER].GetPositionZ()+1.5f, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1500) )
|
||||
boss_twin_valkyrAI::JustSummoned(ball);
|
||||
}
|
||||
events.PopEvent();
|
||||
switch( eventId )
|
||||
{
|
||||
case EVENT_SUMMON_BALLS_1:
|
||||
events.RescheduleEvent(EVENT_SUMMON_BALLS_2, 8000);
|
||||
break;
|
||||
case EVENT_SUMMON_BALLS_2:
|
||||
events.RescheduleEvent(EVENT_SUMMON_BALLS_3, 8000);
|
||||
break;
|
||||
case EVENT_SUMMON_BALLS_3:
|
||||
events.RescheduleEvent(EVENT_SUMMON_BALLS_1, 15000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_SPIKE:
|
||||
me->CastSpell(me->GetVictim(), me->GetEntry()==NPC_LIGHTBANE ? SPELL_LIGHT_TWIN_SPIKE : SPELL_DARK_TWIN_SPIKE, false);
|
||||
events.RepeatEvent(urand(7000,10000));
|
||||
break;
|
||||
case EVENT_SPELL_TOUCH:
|
||||
{
|
||||
uint32 essenceId = 0;
|
||||
switch( me->GetEntry() )
|
||||
{
|
||||
case NPC_LIGHTBANE:
|
||||
switch( GetDifficulty() )
|
||||
{
|
||||
case 0:
|
||||
essenceId = 65684;
|
||||
break;
|
||||
case 1:
|
||||
essenceId = 67176;
|
||||
break;
|
||||
case 2:
|
||||
essenceId = 67177;
|
||||
break;
|
||||
case 3:
|
||||
essenceId = 67178;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_DARKBANE:
|
||||
switch( GetDifficulty() )
|
||||
{
|
||||
case 0:
|
||||
essenceId = 65686;
|
||||
break;
|
||||
case 1:
|
||||
essenceId = 67222;
|
||||
break;
|
||||
case 2:
|
||||
essenceId = 67223;
|
||||
break;
|
||||
case 3:
|
||||
essenceId = 67224;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
if( Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, essenceId) )
|
||||
me->CastSpell(target, me->GetEntry()==NPC_LIGHTBANE ? SPELL_LIGHT_TOUCH : SPELL_DARK_TOUCH, false);
|
||||
events.RepeatEvent(urand(45000,50000));
|
||||
*/
|
||||
|
||||
std::vector<uint64> tList;
|
||||
Map::PlayerList const &pList = me->GetMap()->GetPlayers();
|
||||
if (pList.getSize())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
if (Player* plr = itr->GetSource())
|
||||
if (Creature* sister = GetSister())
|
||||
if ((!me->GetVictim() || me->GetVictim()->GetGUID() != plr->GetGUID()) && (!sister->GetVictim() || sister->GetVictim()->GetGUID() != plr->GetGUID()) && plr->HasAura(essenceId))
|
||||
tList.push_back(plr->GetGUID());
|
||||
|
||||
if (!tList.empty())
|
||||
if (Player* target = ObjectAccessor::GetPlayer(*me, tList[urand(0,tList.size()-1)]))
|
||||
{
|
||||
me->CastSpell(target, me->GetEntry()==NPC_LIGHTBANE ? SPELL_LIGHT_TOUCH : SPELL_DARK_TOUCH, false);
|
||||
events.RepeatEvent(urand(45000,50000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(10000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SPECIAL:
|
||||
{
|
||||
uint8 s;
|
||||
do s=urand(0,3); while( SpecialMask & (1<<s) && (SpecialMask & 0xF) != 0xF );
|
||||
SpecialMask |= (1<<s);
|
||||
switch( s )
|
||||
{
|
||||
case 0: // light vortex
|
||||
me->CastSpell((Unit*)NULL, SPELL_LIGHT_VORTEX, false);
|
||||
Talk(EMOTE_VORTEX);
|
||||
Talk(SAY_LIGHT);
|
||||
if( Creature* twin = GetSister() )
|
||||
twin->AI()->Talk(SAY_LIGHT);
|
||||
break;
|
||||
case 1: // dark vortex
|
||||
if( Creature* twin = GetSister() )
|
||||
{
|
||||
twin->CastSpell((Unit*)NULL, SPELL_DARK_VORTEX, false);
|
||||
twin->AI()->Talk(EMOTE_VORTEX);
|
||||
twin->AI()->Talk(SAY_NIGHT);
|
||||
Talk(SAY_NIGHT);
|
||||
}
|
||||
break;
|
||||
case 2: // light pact
|
||||
Talk(EMOTE_TWINK_PACT);
|
||||
Talk(SAY_TWINK_PACT);
|
||||
if( Creature* twin = GetSister() )
|
||||
{
|
||||
twin->AI()->Talk(SAY_TWINK_PACT);
|
||||
twin->AI()->DoAction(-3);
|
||||
}
|
||||
me->CastSpell(me, SPELL_LIGHT_SHIELD, true);
|
||||
me->CastSpell(me, SPELL_LIGHT_TWIN_PACT, false);
|
||||
break;
|
||||
case 3: // dark pact
|
||||
if( Creature* twin = GetSister() )
|
||||
{
|
||||
twin->AI()->Talk(EMOTE_TWINK_PACT);
|
||||
twin->AI()->Talk(SAY_TWINK_PACT);
|
||||
Talk(SAY_TWINK_PACT);
|
||||
twin->CastSpell(twin, SPELL_DARK_SHIELD, true);
|
||||
twin->CastSpell(twin, SPELL_DARK_TWIN_PACT, false);
|
||||
DoAction(-3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if( (SpecialMask & 0xF) == 0xF )
|
||||
SpecialMask = 0;
|
||||
events.RepeatEvent(45000);
|
||||
events.DelayEventsToMax(15000, 1); // no touch of light/darkness during special abilities!
|
||||
}
|
||||
break;
|
||||
case EVENT_REMOVE_DUAL_WIELD:
|
||||
me->SetCanDualWield(false);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
myDoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*pKiller*/)
|
||||
{
|
||||
DoAction(-1);
|
||||
Talk(SAY_DEATH);
|
||||
if( pInstance )
|
||||
{
|
||||
pInstance->SetData(TYPE_VALKYR, DONE);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POWERING_UP);
|
||||
}
|
||||
if( Creature* twin = GetSister() )
|
||||
if( twin->IsAlive() )
|
||||
{
|
||||
twin->SetHealth(1);
|
||||
Unit::Kill(twin, twin);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* s)
|
||||
{
|
||||
summons.Summon(s);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* s)
|
||||
{
|
||||
summons.Despawn(s);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
int32 id = urand(0,1) ? SAY_KILL_PLAYER_1 : SAY_KILL_PLAYER_2;
|
||||
Talk(id);
|
||||
if( Creature* twin = GetSister() )
|
||||
twin->AI()->Talk(id);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
if( pInstance )
|
||||
pInstance->SetData(TYPE_FAILED, 0);
|
||||
}
|
||||
};
|
||||
|
||||
class boss_eydis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_eydis() : CreatureScript("boss_eydis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_eydisAI(pCreature);
|
||||
}
|
||||
|
||||
struct boss_eydisAI : public boss_twin_valkyrAI
|
||||
{
|
||||
boss_eydisAI(Creature* pCreature) : boss_twin_valkyrAI(pCreature)
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_AURASTATE, 1<<(19-1));
|
||||
SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_OFFHAND_2, EQUIP_RANGED_2);
|
||||
if( Creature* c = me->SummonCreature(NPC_DARK_ESSENCE, Locs[LOC_DARKESS_1]) )
|
||||
boss_twin_valkyrAI::JustSummoned(c);
|
||||
if( Creature* c = me->SummonCreature(NPC_DARK_ESSENCE, Locs[LOC_DARKESS_2]) )
|
||||
boss_twin_valkyrAI::JustSummoned(c);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* s) {}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_fjola : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_fjola() : CreatureScript("boss_fjola") {}
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_fjolaAI(pCreature);
|
||||
}
|
||||
|
||||
struct boss_fjolaAI : public boss_twin_valkyrAI
|
||||
{
|
||||
boss_fjolaAI(Creature* pCreature) : boss_twin_valkyrAI(pCreature)
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_AURASTATE, 1<<(22-1));
|
||||
SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_OFFHAND_1, EQUIP_RANGED_1);
|
||||
if( Creature* c = me->SummonCreature(NPC_LIGHT_ESSENCE, Locs[LOC_LIGHTESS_1]) )
|
||||
boss_twin_valkyrAI::JustSummoned(c);
|
||||
if( Creature* c = me->SummonCreature(NPC_LIGHT_ESSENCE, Locs[LOC_LIGHTESS_2]) )
|
||||
boss_twin_valkyrAI::JustSummoned(c);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* s) {}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_essence_of_twin : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_essence_of_twin() : CreatureScript("npc_essence_of_twin") { }
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
switch( creature->GetEntry() )
|
||||
{
|
||||
case NPC_LIGHT_ESSENCE:
|
||||
{
|
||||
uint32 essenceId = 0;
|
||||
uint32 effect2Id = 0;
|
||||
uint32 empoweredId = 0;
|
||||
uint32 touchId1 = 0;
|
||||
uint32 touchId2 = 0;
|
||||
switch( creature->GetMap()->GetDifficulty() )
|
||||
{
|
||||
case 0:
|
||||
essenceId = 65684;
|
||||
empoweredId = 65724;
|
||||
touchId1 = 65950;
|
||||
touchId2 = 66001;
|
||||
effect2Id = 65827;
|
||||
break;
|
||||
case 1:
|
||||
essenceId = 67176;
|
||||
empoweredId = 67213;
|
||||
touchId1 = 67296;
|
||||
touchId2 = 67281;
|
||||
effect2Id = 67179;
|
||||
break;
|
||||
case 2:
|
||||
essenceId = 67177;
|
||||
empoweredId = 67214;
|
||||
touchId1 = 67297;
|
||||
touchId2 = 67282;
|
||||
effect2Id = 67180;
|
||||
break;
|
||||
case 3:
|
||||
essenceId = 67178;
|
||||
empoweredId = 67215;
|
||||
touchId1 = 67298;
|
||||
touchId2 = 67283;
|
||||
effect2Id = 67181;
|
||||
break;
|
||||
}
|
||||
player->RemoveAura(essenceId);
|
||||
player->RemoveAura(effect2Id);
|
||||
player->RemoveAura(touchId1);
|
||||
//player->RemoveAura(touchId2); // dont remove black touch here - only white can have black touch - so white changing to white - so no change of color
|
||||
//player->RemoveAura(empoweredId); // apply new empowered?
|
||||
player->CastSpell(player, SPELL_LIGHT_ESSENCE, true);
|
||||
}
|
||||
break;
|
||||
case NPC_DARK_ESSENCE:
|
||||
{
|
||||
uint32 essenceId = 0;
|
||||
uint32 effect2Id = 0;
|
||||
uint32 empoweredId = 0;
|
||||
uint32 touchId1 = 0;
|
||||
uint32 touchId2 = 0;
|
||||
switch( creature->GetMap()->GetDifficulty() )
|
||||
{
|
||||
case 0:
|
||||
essenceId = 65686;
|
||||
empoweredId = 65748;
|
||||
touchId1 = 65950;
|
||||
touchId2 = 66001;
|
||||
effect2Id = 65811;
|
||||
break;
|
||||
case 1:
|
||||
essenceId = 67222;
|
||||
empoweredId = 67216;
|
||||
touchId1 = 67296;
|
||||
touchId2 = 67281;
|
||||
effect2Id = 67511;
|
||||
break;
|
||||
case 2:
|
||||
essenceId = 67223;
|
||||
empoweredId = 67217;
|
||||
touchId1 = 67297;
|
||||
touchId2 = 67282;
|
||||
effect2Id = 67512;
|
||||
break;
|
||||
case 3:
|
||||
essenceId = 67224;
|
||||
empoweredId = 67218;
|
||||
touchId1 = 67298;
|
||||
touchId2 = 67283;
|
||||
effect2Id = 67513;
|
||||
break;
|
||||
}
|
||||
player->RemoveAura(essenceId);
|
||||
player->RemoveAura(effect2Id);
|
||||
//player->RemoveAura(touchId1); // dont remove white touch here - only black can have white touch - so black changing to black - so no change of color
|
||||
player->RemoveAura(touchId2);
|
||||
//player->RemoveAura(empoweredId); // apply new empowered?
|
||||
player->CastSpell(player, SPELL_DARK_ESSENCE, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class npc_concentrated_ball : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_concentrated_ball() : CreatureScript("npc_concentrated_ball") { }
|
||||
|
||||
CreatureAI* GetAI(Creature *pCreature) const
|
||||
{
|
||||
return new npc_concentrated_ballAI(pCreature);
|
||||
}
|
||||
|
||||
struct npc_concentrated_ballAI : public NullCreatureAI
|
||||
{
|
||||
npc_concentrated_ballAI(Creature *pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->CastSpell(me, 100101, true); // custom periodic dummy spell
|
||||
despawning = false;
|
||||
}
|
||||
|
||||
bool despawning;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == 1)
|
||||
despawning = true;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if( type != POINT_MOTION_TYPE || id != 0 )
|
||||
return;
|
||||
|
||||
if( urand(0,2) )
|
||||
me->DespawnOrUnsummon(0);
|
||||
}
|
||||
|
||||
void MoveToNextPoint()
|
||||
{
|
||||
float angle = rand_norm()*2*M_PI;
|
||||
me->GetMotionMaster()->MovePoint(0, Locs[LOC_CENTER].GetPositionX()+cos(angle)*47.0f, Locs[LOC_CENTER].GetPositionY()+sin(angle)*47.0f, me->GetPositionZ());
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if( despawning )
|
||||
return;
|
||||
|
||||
if( me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE )
|
||||
MoveToNextPoint();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_valkyr_essence : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_valkyr_essence() : SpellScriptLoader("spell_valkyr_essence") { }
|
||||
|
||||
class spell_valkyr_essence_auraAuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_valkyr_essence_auraAuraScript)
|
||||
|
||||
void HandleAfterEffectAbsorb(AuraEffect * /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount)
|
||||
{
|
||||
uint16 count = absorbAmount/1000;
|
||||
if( !count || !GetOwner() )
|
||||
return;
|
||||
|
||||
if( const SpellInfo* se = GetAura()->GetSpellInfo() )
|
||||
if( Unit* owner = GetOwner()->ToUnit() )
|
||||
{
|
||||
uint32 auraId = 0;
|
||||
uint32 empoweredId = 0;
|
||||
switch( se->Id )
|
||||
{
|
||||
case 65686:
|
||||
auraId = 67590;
|
||||
empoweredId = 65748;
|
||||
break;
|
||||
case 65684:
|
||||
auraId = 67590;
|
||||
empoweredId = 65724;
|
||||
break;
|
||||
case 67222:
|
||||
auraId = 67602;
|
||||
empoweredId = 65748;
|
||||
break;
|
||||
case 67176:
|
||||
auraId = 67602;
|
||||
empoweredId = 65724;
|
||||
break;
|
||||
case 67223:
|
||||
auraId = 67603;
|
||||
empoweredId = 65748;
|
||||
break;
|
||||
case 67177:
|
||||
auraId = 67603;
|
||||
empoweredId = 65724;
|
||||
break;
|
||||
case 67224:
|
||||
auraId = 67604;
|
||||
empoweredId = 65748;
|
||||
break;
|
||||
case 67178:
|
||||
auraId = 67604;
|
||||
empoweredId = 65724;
|
||||
break;
|
||||
}
|
||||
if( !owner->HasAura(auraId) )
|
||||
{
|
||||
owner->CastSpell(owner, SPELL_POWERING_UP, true);
|
||||
if( --count == 0 )
|
||||
return;
|
||||
}
|
||||
if( Aura* aur = owner->GetAura(auraId) )
|
||||
{
|
||||
if( aur->GetStackAmount()+count < 100 )
|
||||
{
|
||||
aur->ModStackAmount(count);
|
||||
|
||||
if (roll_chance_i(30)) // 30% chance to gain extra speed for collecting
|
||||
owner->CastSpell(owner, SPELL_SURGE_OF_SPEED, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
owner->CastSpell(owner, empoweredId, true);
|
||||
aur->Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectAbsorb += AuraEffectAbsorbFn(spell_valkyr_essence_auraAuraScript::HandleAfterEffectAbsorb, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_valkyr_essence_auraAuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_valkyr_touch : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_valkyr_touch() : SpellScriptLoader("spell_valkyr_touch") { }
|
||||
|
||||
class spell_valkyr_touchAuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_valkyr_touchAuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const * aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit* caster = GetCaster();
|
||||
if( !caster )
|
||||
return;
|
||||
if( caster->GetMap()->GetId() == 649 )
|
||||
{
|
||||
uint32 excludedID = GetSpellInfo()->ExcludeTargetAuraSpell;
|
||||
Map::PlayerList const &pl = caster->GetMap()->GetPlayers();
|
||||
for( Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr )
|
||||
if( Player* plr = itr->GetSource() )
|
||||
if( plr->IsAlive() && !plr->HasAura(excludedID) && !plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION) )
|
||||
{
|
||||
uint32 absorb=0;
|
||||
uint32 resist=0;
|
||||
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
|
||||
int32 dmg = urand(2925,3075)*(caster->GetMap()->GetDifficulty()-1);
|
||||
if (caster->CanApplyResilience())
|
||||
Unit::ApplyResilience(plr, NULL, &dmg, false, CR_CRIT_TAKEN_SPELL);
|
||||
uint32 damage = dmg;
|
||||
Unit::CalcAbsorbResist(caster, plr, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, GetSpellInfo());
|
||||
Unit::DealDamageMods(plr,damage,&absorb);
|
||||
int32 overkill = damage - plr->GetHealth();
|
||||
if (overkill < 0)
|
||||
overkill = 0;
|
||||
SpellPeriodicAuraLogInfo pInfo(aurEff, damage, overkill, absorb, resist, 0.0f, false);
|
||||
plr->SendPeriodicAuraLog(&pInfo);
|
||||
Unit::DealDamage(caster, plr, damage, 0, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_valkyr_touchAuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_valkyr_touchAuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_valkyr_ball_periodic_dummy : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_valkyr_ball_periodic_dummy() : SpellScriptLoader("spell_valkyr_ball_periodic_dummy") { }
|
||||
|
||||
class spell_valkyr_ball_periodic_dummyAuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_valkyr_ball_periodic_dummyAuraScript)
|
||||
|
||||
void HandleEffectPeriodic(AuraEffect const * aurEff)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
if (target->GetDisplayId() != 11686)
|
||||
if (Creature* me = target->ToCreature())
|
||||
if (Player* p = me->SelectNearestPlayer(2.75f))
|
||||
if (me->GetExactDist2d(p) <= 2.75f)
|
||||
{
|
||||
me->AI()->DoAction(1); // despawning = true;
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->CastSpell((Unit*)NULL, me->GetEntry()==NPC_CONCENTRATED_LIGHT ? SPELL_UNLEASHED_LIGHT : SPELL_UNLEASHED_DARK, false);
|
||||
me->SetDisplayId(11686);
|
||||
me->DespawnOrUnsummon(1500);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_valkyr_ball_periodic_dummyAuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript *GetAuraScript() const
|
||||
{
|
||||
return new spell_valkyr_ball_periodic_dummyAuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_twin_valkyr()
|
||||
{
|
||||
new boss_fjola();
|
||||
new boss_eydis();
|
||||
new npc_essence_of_twin();
|
||||
new npc_concentrated_ball();
|
||||
new spell_valkyr_essence();
|
||||
new spell_valkyr_touch();
|
||||
new spell_valkyr_ball_periodic_dummy();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "trial_of_the_crusader.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum MenuTexts
|
||||
{
|
||||
MSG_TESTED = 724001,
|
||||
MSG_NEXT_STAGE = 724002,
|
||||
MSG_CRUSADERS = 724003,
|
||||
MSG_ANUBARAK = 724005,
|
||||
};
|
||||
|
||||
class npc_announcer_toc10 : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_announcer_toc10() : CreatureScript("npc_announcer_toc10") { }
|
||||
|
||||
bool OnGossipHello(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if( !pCreature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP) )
|
||||
return true;
|
||||
|
||||
InstanceScript* pInstance = pCreature->GetInstanceScript();
|
||||
if( !pInstance )
|
||||
return true;
|
||||
|
||||
uint32 gossipTextId = 0;
|
||||
switch( pInstance->GetData(TYPE_INSTANCE_PROGRESS) )
|
||||
{
|
||||
case INSTANCE_PROGRESS_INITIAL:
|
||||
gossipTextId = MSG_TESTED;
|
||||
break;
|
||||
case INSTANCE_PROGRESS_INTRO_DONE:
|
||||
case INSTANCE_PROGRESS_BEASTS_DEAD:
|
||||
case INSTANCE_PROGRESS_FACTION_CHAMPIONS_DEAD:
|
||||
case INSTANCE_PROGRESS_VALKYR_DEAD:
|
||||
gossipTextId = MSG_NEXT_STAGE;
|
||||
break;
|
||||
case INSTANCE_PROGRESS_JARAXXUS_DEAD:
|
||||
gossipTextId = MSG_CRUSADERS;
|
||||
break;
|
||||
case INSTANCE_PROGRESS_DONE:
|
||||
pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "We are ready!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1337);
|
||||
pPlayer->SEND_GOSSIP_MENU(gossipTextId, pCreature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 /*sender*/, uint32 uiAction)
|
||||
{
|
||||
if( !pCreature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP) )
|
||||
return true;
|
||||
|
||||
InstanceScript* pInstance = pCreature->GetInstanceScript();
|
||||
if( !pInstance )
|
||||
return true;
|
||||
|
||||
if( uiAction == GOSSIP_ACTION_INFO_DEF+1337 )
|
||||
{
|
||||
pInstance->SetData(TYPE_ANNOUNCER_GOSSIP_SELECT, 0);
|
||||
pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_trial_of_the_crusader()
|
||||
{
|
||||
new npc_announcer_toc10();
|
||||
}
|
||||
@@ -1,384 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_CRUSADER_H
|
||||
#define DEF_CRUSADER_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_NONE = 0,
|
||||
TYPE_INSTANCE_PROGRESS,
|
||||
TYPE_ANNOUNCER_GOSSIP_SELECT,
|
||||
TYPE_FAILED,
|
||||
|
||||
TYPE_GORMOK,
|
||||
TYPE_JORMUNGAR,
|
||||
TYPE_DREADSCALE,
|
||||
TYPE_ACIDMAW,
|
||||
TYPE_ICEHOWL,
|
||||
TYPE_JARAXXUS,
|
||||
TYPE_FACTION_CHAMPIONS,
|
||||
TYPE_FACTION_CHAMPIONS_PLAYER_DIED,
|
||||
TYPE_VALKYR,
|
||||
TYPE_ANUBARAK,
|
||||
|
||||
TYPE_FACTION_CHAMPIONS_START,
|
||||
TYPE_NORTHREND_BEASTS_ALL,
|
||||
};
|
||||
|
||||
enum Progress
|
||||
{
|
||||
INSTANCE_PROGRESS_INITIAL = 0,
|
||||
INSTANCE_PROGRESS_INTRO_DONE,
|
||||
INSTANCE_PROGRESS_BEASTS_DEAD,
|
||||
INSTANCE_PROGRESS_JARAXXUS_INTRO_DONE,
|
||||
INSTANCE_PROGRESS_JARAXXUS_DEAD,
|
||||
INSTANCE_PROGRESS_FACTION_CHAMPIONS_DEAD = 6,
|
||||
INSTANCE_PROGRESS_VALKYR_DEAD = 8,
|
||||
INSTANCE_PROGRESS_DONE = 10,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CHECK_PLAYERS = 1,
|
||||
EVENT_OPEN_GATE,
|
||||
EVENT_CLOSE_GATE,
|
||||
|
||||
EVENT_SCENE_001,
|
||||
EVENT_SCENE_002,
|
||||
EVENT_SCENE_003,
|
||||
EVENT_SCENE_004,
|
||||
EVENT_SUMMON_GORMOK,
|
||||
EVENT_GORMOK_ATTACK,
|
||||
EVENT_SCENE_005,
|
||||
EVENT_SCENE_005_2,
|
||||
EVENT_SUMMON_ACIDMAW_AND_DREADSCALE,
|
||||
EVENT_ACIDMAW_AND_DREADSCALE_ATTACK,
|
||||
EVENT_SCENE_006,
|
||||
EVENT_SUMMON_ICEHOWL,
|
||||
EVENT_ICEHOWL_ATTACK,
|
||||
EVENT_SCENE_BEASTS_DONE,
|
||||
EVENT_NORTHREND_BEASTS_ENRAGE,
|
||||
|
||||
EVENT_SCENE_101,
|
||||
EVENT_SCENE_102,
|
||||
EVENT_SCENE_103,
|
||||
EVENT_SCENE_104,
|
||||
EVENT_SUMMON_JARAXXUS,
|
||||
EVENT_SCENE_105,
|
||||
EVENT_SCENE_106,
|
||||
EVENT_SCENE_107,
|
||||
EVENT_SCENE_108,
|
||||
EVENT_SCENE_109,
|
||||
EVENT_JARAXXUS_ATTACK,
|
||||
EVENT_SCENE_110,
|
||||
EVENT_SCENE_111,
|
||||
EVENT_SCENE_112,
|
||||
EVENT_SCENE_113,
|
||||
|
||||
EVENT_SCENE_201,
|
||||
EVENT_SCENE_202,
|
||||
EVENT_SCENE_203,
|
||||
EVENT_SCENE_204,
|
||||
EVENT_SCENE_205,
|
||||
EVENT_SUMMON_CHAMPIONS,
|
||||
EVENT_CHAMPIONS_ATTACK,
|
||||
EVENT_SCENE_FACTION_CHAMPIONS_DEAD,
|
||||
|
||||
EVENT_SCENE_301,
|
||||
EVENT_SCENE_302,
|
||||
EVENT_SCENE_303,
|
||||
EVENT_SCENE_304,
|
||||
EVENT_VALKYRIES_ATTACK,
|
||||
EVENT_SCENE_VALKYR_DEAD,
|
||||
|
||||
EVENT_SCENE_401,
|
||||
EVENT_SCENE_402,
|
||||
EVENT_SCENE_403,
|
||||
EVENT_SCENE_404,
|
||||
EVENT_SCENE_405,
|
||||
EVENT_SCENE_406,
|
||||
EVENT_SCENE_406_2,
|
||||
EVENT_SCENE_407,
|
||||
EVENT_SCENE_408,
|
||||
EVENT_SCENE_409,
|
||||
EVENT_SCENE_410,
|
||||
EVENT_SCENE_501,
|
||||
EVENT_SCENE_502,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_BARRENT = 34816,
|
||||
NPC_TIRION = 34996,
|
||||
NPC_GARROSH = 34995,
|
||||
NPC_THRALL = 34994,
|
||||
NPC_VARIAN = 34990,
|
||||
NPC_PROUDMOORE = 34992,
|
||||
NPC_ARGENT_MAGE = 36097,
|
||||
|
||||
NPC_FIZZLEBANG = 35458,
|
||||
NPC_LICH_KING = 35877,
|
||||
|
||||
NPC_GORMOK = 34796,
|
||||
NPC_DREADSCALE = 34799,
|
||||
NPC_ACIDMAW = 35144,
|
||||
NPC_ICEHOWL = 34797,
|
||||
NPC_JARAXXUS = 34780,
|
||||
|
||||
NPC_PURPLE_GROUND = 35651,
|
||||
NPC_WORLD_TRIGGER = 18721,
|
||||
|
||||
NPC_ALLIANCE_DEATH_KNIGHT = 34461,
|
||||
NPC_ALLIANCE_DRUID_BALANCE = 34460,
|
||||
NPC_ALLIANCE_DRUID_RESTORATION = 34469,
|
||||
NPC_ALLIANCE_HUNTER = 34467,
|
||||
NPC_ALLIANCE_MAGE = 34468,
|
||||
NPC_ALLIANCE_PALADIN_HOLY = 34465,
|
||||
NPC_ALLIANCE_PALADIN_RETRIBUTION = 34471,
|
||||
NPC_ALLIANCE_PRIEST_DISCIPLINE = 34466,
|
||||
NPC_ALLIANCE_PRIEST_SHADOW = 34473,
|
||||
NPC_ALLIANCE_ROGUE = 34472,
|
||||
NPC_ALLIANCE_SHAMAN_ENHANCEMENT = 34463,
|
||||
NPC_ALLIANCE_SHAMAN_RESTORATION = 34470,
|
||||
NPC_ALLIANCE_WARLOCK = 34474,
|
||||
NPC_ALLIANCE_WARRIOR = 34475,
|
||||
|
||||
NPC_HORDE_DEATH_KNIGHT = 34458,
|
||||
NPC_HORDE_DRUID_BALANCE = 34451,
|
||||
NPC_HORDE_DRUID_RESTORATION = 34459,
|
||||
NPC_HORDE_HUNTER = 34448,
|
||||
NPC_HORDE_MAGE = 34449,
|
||||
NPC_HORDE_PALADIN_HOLY = 34445,
|
||||
NPC_HORDE_PALADIN_RETRIBUTION = 34456,
|
||||
NPC_HORDE_PRIEST_DISCIPLINE = 34447,
|
||||
NPC_HORDE_PRIEST_SHADOW = 34441,
|
||||
NPC_HORDE_ROGUE = 34454,
|
||||
NPC_HORDE_SHAMAN_ENHANCEMENT = 34455,
|
||||
NPC_HORDE_SHAMAN_RESTORATION = 34444,
|
||||
NPC_HORDE_WARLOCK = 34450,
|
||||
NPC_HORDE_WARRIOR = 34453,
|
||||
|
||||
NPC_LIGHTBANE = 34497,
|
||||
NPC_DARKBANE = 34496,
|
||||
|
||||
NPC_ANUBARAK = 34564,
|
||||
};
|
||||
|
||||
enum GOs
|
||||
{
|
||||
GO_ARGENT_COLISEUM_FLOOR = 195527,
|
||||
GO_MAIN_GATE_DOOR = 195647,
|
||||
GO_WEB_DOOR = 195485,
|
||||
GO_EAST_PORTCULLIS = 195648,
|
||||
GO_SOUTH_PORTCULLIS = 195649,
|
||||
GO_NORTH_PORTCULLIS = 195650,
|
||||
|
||||
GO_CRUSADERS_CACHE_10 = 195631,
|
||||
GO_CRUSADERS_CACHE_25 = 195632,
|
||||
GO_CRUSADERS_CACHE_10_H = 195633,
|
||||
GO_CRUSADERS_CACHE_25_H = 195635,
|
||||
|
||||
// Tribute Chest (heroic)
|
||||
GO_TRIBUTE_CHEST_10H_25 = 195668, // 10man 01-24 attempts
|
||||
GO_TRIBUTE_CHEST_10H_45 = 195667, // 10man 25-44 attempts
|
||||
GO_TRIBUTE_CHEST_10H_50 = 195666, // 10man 45-49 attempts
|
||||
GO_TRIBUTE_CHEST_10H_99 = 195665, // 10man 50 attempts
|
||||
GO_TRIBUTE_CHEST_25H_25 = 195672, // 25man 01-24 attempts
|
||||
GO_TRIBUTE_CHEST_25H_45 = 195671, // 25man 25-44 attempts
|
||||
GO_TRIBUTE_CHEST_25H_50 = 195670, // 25man 45-49 attempts
|
||||
GO_TRIBUTE_CHEST_25H_99 = 195669, // 25man 50 attempts
|
||||
};
|
||||
|
||||
enum eTexts
|
||||
{
|
||||
// Highlord Tirion Fordring - 34996
|
||||
SAY_STAGE_0_01 = 0,
|
||||
SAY_STAGE_0_02 = 1,
|
||||
SAY_STAGE_0_04 = 2,
|
||||
SAY_STAGE_0_05 = 3,
|
||||
SAY_STAGE_0_06 = 4,
|
||||
SAY_STAGE_0_WIPE = 5,
|
||||
SAY_STAGE_1_01 = 6,
|
||||
SAY_STAGE_1_07 = 7,
|
||||
SAY_STAGE_1_08 = 8,
|
||||
SAY_STAGE_1_11 = 9,
|
||||
SAY_STAGE_2_01 = 10,
|
||||
SAY_STAGE_2_03 = 11,
|
||||
SAY_STAGE_2_06 = 12,
|
||||
SAY_STAGE_3_01 = 13,
|
||||
SAY_STAGE_3_02 = 14,
|
||||
SAY_STAGE_4_01 = 15,
|
||||
SAY_STAGE_4_03 = 16,
|
||||
|
||||
// Varian Wrynn
|
||||
SAY_STAGE_0_03a = 0,
|
||||
SAY_STAGE_1_10 = 1,
|
||||
SAY_STAGE_2_02a = 2,
|
||||
SAY_STAGE_2_04a = 3,
|
||||
SAY_STAGE_2_05a = 4,
|
||||
SAY_STAGE_3_03a = 5,
|
||||
SAY_VARIAN_KILL_HORDE_PLAYER_1 = 6,
|
||||
|
||||
// Garrosh
|
||||
SAY_STAGE_0_03h = 0,
|
||||
SAY_STAGE_1_09 = 1,
|
||||
SAY_STAGE_2_02h = 2,
|
||||
SAY_STAGE_2_04h = 3,
|
||||
SAY_STAGE_2_05h = 4,
|
||||
SAY_STAGE_3_03h = 5,
|
||||
SAY_GARROSH_KILL_ALLIANCE_PLAYER_1 = 6,
|
||||
|
||||
// Wilfred Fizzlebang
|
||||
SAY_STAGE_1_02 = 0,
|
||||
SAY_STAGE_1_03 = 1,
|
||||
SAY_STAGE_1_04 = 2,
|
||||
SAY_STAGE_1_06 = 3,
|
||||
|
||||
// Lord Jaraxxus
|
||||
SAY_STAGE_1_05 = 0,
|
||||
|
||||
// The Lich King
|
||||
SAY_STAGE_4_02 = 0,
|
||||
SAY_STAGE_4_05 = 1,
|
||||
SAY_STAGE_4_04 = 2,
|
||||
|
||||
// Highlord Tirion Fordring - 36095
|
||||
SAY_STAGE_4_06 = 17,
|
||||
SAY_STAGE_4_07 = 18,
|
||||
};
|
||||
|
||||
const Position Locs[] =
|
||||
{
|
||||
{563.8f, 216.1f, 395.1f, 3*M_PI/2}, // 0
|
||||
{563.93f, 178.37f, 394.49f, 3*M_PI/2}, // 1
|
||||
{575.74f, 171.5f, 394.75f, 3*M_PI/2}, // 2
|
||||
{549.93f, 171.5f, 394.75f, 3*M_PI/2}, // 3
|
||||
{563.672974f, 139.571f, 393.837006f, 3*M_PI/2}, // 4
|
||||
{577.347839f, 210.0f, 395.14f /*+ 6.0f*/, 3*M_PI/2}, // 5
|
||||
{550.955933f, 210.0f, 395.14f /*+ 6.0f*/, 3*M_PI/2}, // 6
|
||||
{573.5f, 180.5f, 395.14f /*+ 6.0f*/, 0}, // 7
|
||||
{553.5f, 180.5f, 395.14f /*+ 6.0f*/, 0}, // 8
|
||||
{585.5f, 170.0f, 395.14f /*+ 6.0f*/, 0}, // 9
|
||||
{545.5f, 170.0f, 395.14f /*+ 6.0f*/, 0}, // 10
|
||||
{563.833008f, 179.244995f, 394.5f, 3*M_PI/2}, // 11
|
||||
{563.547f, 141.613f, 393.908f, 0}, // 12
|
||||
{586.060242f, 117.514809f, 394.314026f, 0}, // 13 - Dark essence 1
|
||||
{541.602112f, 161.879837f, 394.587952f, 0}, // 14 - Dark essence 2
|
||||
{541.021118f, 117.262932f, 395.314819f, 0}, // 15 - Light essence 1
|
||||
{586.200562f, 162.145523f, 394.626129f, 0}, // 16 - Light essence 2
|
||||
{785.90f, 133.42f, 142.612f, M_PI}, // 17
|
||||
{665.04f, 139.25f, 142.2f, 0.0f}, // 18
|
||||
{664.75f, 135.0f, 142.2f, 0.0f}
|
||||
};
|
||||
|
||||
enum LocNames
|
||||
{
|
||||
LOC_BEHIND_GATE = 0,
|
||||
LOC_GATE_FRONT,
|
||||
LOC_DREADSCALE,
|
||||
LOC_ACIDMAW,
|
||||
LOC_CENTER,
|
||||
LOC_VALKYR_RIGHT,
|
||||
LOC_VALKYR_LEFT,
|
||||
LOC_VALKYR_DEST_RIGHT,
|
||||
LOC_VALKYR_DEST_LEFT,
|
||||
LOC_VALKYR_DEST_2_RIGHT,
|
||||
LOC_VALKYR_DEST_2_LEFT,
|
||||
LOC_ARTHAS_PORTAL,
|
||||
LOC_ARTHAS,
|
||||
LOC_DARKESS_1,
|
||||
LOC_DARKESS_2,
|
||||
LOC_LIGHTESS_1,
|
||||
LOC_LIGHTESS_2,
|
||||
LOC_ANUB,
|
||||
LOC_TIRION_FINAL,
|
||||
LOC_MAGE,
|
||||
};
|
||||
|
||||
const Position FactionChampionLoc[]=
|
||||
{
|
||||
{514.231f, 105.569f, 418.234f, 0}, // 0 - Horde Initial Pos 0
|
||||
{508.334f, 115.377f, 418.234f, 0}, // 1 - Horde Initial Pos 1
|
||||
{506.454f, 126.291f, 418.234f, 0}, // 2 - Horde Initial Pos 2
|
||||
{506.243f, 106.596f, 421.592f, 0}, // 3 - Horde Initial Pos 3
|
||||
{499.885f, 117.717f, 421.557f, 0}, // 4 - Horde Initial Pos 4
|
||||
|
||||
{613.127f, 100.443f, 419.74f, 0}, // 5 - Ally Initial Pos 0
|
||||
{621.126f, 128.042f, 418.231f, 0}, // 6 - Ally Initial Pos 1
|
||||
{618.829f, 113.606f, 418.232f, 0}, // 7 - Ally Initial Pos 2
|
||||
{625.845f, 112.914f, 421.575f, 0}, // 8 - Ally Initial Pos 3
|
||||
{615.566f, 109.653f, 418.234f, 0}, // 9 - Ally Initial Pos 4
|
||||
|
||||
{535.469f, 113.012f, 394.55f, 0}, // 10 - Final Pos 0
|
||||
{526.417f, 137.465f, 394.55f, 0}, // 11 - Final Pos 1
|
||||
{528.108f, 111.057f, 394.55f, 0}, // 12 - Final Pos 2
|
||||
{519.92f, 134.285f, 394.55f, 0}, // 13 - Final Pos 3
|
||||
{533.648f, 119.148f, 394.55f, 0}, // 14 - Final Pos 4
|
||||
{531.399f, 125.63f, 394.55f, 0}, // 15 - Final Pos 5
|
||||
{528.958f, 131.47f, 394.55f, 0}, // 16 - Final Pos 6
|
||||
{526.309f, 116.667f, 394.55f, 0}, // 17 - Final Pos 7
|
||||
{524.238f, 122.411f, 394.55f, 0}, // 18 - Final Pos 8
|
||||
{521.901f, 128.488f, 394.55f, 0}, // 19 - Final Pos 9
|
||||
};
|
||||
|
||||
enum EventSpells
|
||||
{
|
||||
SPELL_WILFRED_PORTAL = 68424,
|
||||
SPELL_JORMUNGAR_ACHIEV = 68523,
|
||||
SPELL_FACTION_CHAMPIONS_KILL_CREDIT = 68184,
|
||||
SPELL_RESILIENCE_WILL_FIX_IT_CREDIT = 68620,
|
||||
SPELL_TRAITOR_KING_10 = 68186,
|
||||
SPELL_TRAITOR_KING_25 = 68515,
|
||||
SPELL_PORTAL_TO_DALARAN = 53142,
|
||||
};
|
||||
|
||||
enum eAchievementCriteria
|
||||
{
|
||||
ACHIEV_CRITERIA_UPPER_BACK_PAIN_10_N = 11779,
|
||||
ACHIEV_CRITERIA_UPPER_BACK_PAIN_10_H = 11802,
|
||||
ACHIEV_CRITERIA_UPPER_BACK_PAIN_25_N = 11780,
|
||||
ACHIEV_CRITERIA_UPPER_BACK_PAIN_25_H = 11801,
|
||||
ACHIEV_CRITERIA_THREE_SIXTY_PAIN_SPIKE_10_N = 11838,
|
||||
ACHIEV_CRITERIA_THREE_SIXTY_PAIN_SPIKE_10_H = 11861,
|
||||
ACHIEV_CRITERIA_THREE_SIXTY_PAIN_SPIKE_25_N = 11839,
|
||||
ACHIEV_CRITERIA_THREE_SIXTY_PAIN_SPIKE_25_H = 11862,
|
||||
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_SKILL_10_PLAYER = 12344,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_SKILL_25_PLAYER = 12338,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_MAD_SKILL_10_PLAYER = 12347,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_MAD_SKILL_25_PLAYER = 12341,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_INSANITY_10_PLAYER = 12349,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_INSANITY_25_PLAYER = 12343,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_IMMORTALITY_HORDE = 12358,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_IMMORTALITY_ALLIANCE = 12359,
|
||||
ACHIEV_CRITERIA_A_TRIBUTE_TO_DEDICATED_INSANITY = 12360,
|
||||
ACHIEV_CRITERIA_REALM_FIRST_GRAND_CRUSADER = 12350,
|
||||
};
|
||||
|
||||
|
||||
enum euiWorldStates
|
||||
{
|
||||
UPDATE_STATE_UI_SHOW = 4390,
|
||||
UPDATE_STATE_UI_COUNT = 4389,
|
||||
};
|
||||
|
||||
const uint32 dIIc = 405;
|
||||
const uint32 dedicatedInsanityItems[405] = {
|
||||
47658, 47659, 47660, 47661, 47662, 47664, 47665, 47666, 47667, 47668, 47670, 47671, 47672, 47673, 47674, 47675, 47677, 47678, 47681, 47682, 47684, 47685, 47686, 47687, 47688, 47689, 47690, 47691, 47692, 47693,
|
||||
47694, 47695, 47696, 47697, 47698, 47699, 47701, 47702, 47704, 47705, 47706, 47707, 47708, 47709, 47710, 47712, 47713, 47714, 47715, 47716, 47729, 47730, 47731, 47732, 47733, 47734, 47735, 47753, 47754, 47755,
|
||||
47756, 47757, 47768, 47769, 47770, 47771, 47772, 47778, 47779, 47780, 47781, 47782, 47803, 47804, 47805, 47806, 47807, 47915, 47916, 47917, 47918, 47919, 47920, 47921, 47922, 47923, 47924, 47925, 47926, 47927,
|
||||
47928, 47929, 47930, 47931, 47932, 47933, 47934, 47935, 47937, 47938, 47939, 47940, 47941, 47942, 47943, 47944, 47945, 47946, 47947, 47948, 47949, 47950, 47951, 47952, 47953, 47954, 47955, 47956, 47957, 47958,
|
||||
47959, 47960, 47961, 47962, 47963, 47964, 47965, 47966, 47967, 47968, 47969, 47970, 47971, 47972, 47973, 47974, 47975, 47976, 47977, 47978, 47979, 47983, 47984, 47985, 47986, 47987, 47988, 47989, 47990, 47991,
|
||||
47992, 47993, 47994, 47995, 47996, 47997, 47998, 47999, 48000, 48001, 48002, 48003, 48004, 48005, 48006, 48007, 48008, 48009, 48010, 48011, 48012, 48013, 48014, 48015, 48016, 48017, 48018, 48019, 48020, 48021,
|
||||
48022, 48023, 48024, 48025, 48026, 48027, 48028, 48030, 48032, 48034, 48036, 48038, 48039, 48040, 48041, 48042, 48043, 48044, 48045, 48046, 48047, 48048, 48049, 48050, 48051, 48052, 48053, 48054, 48055, 48056,
|
||||
48062, 48063, 48064, 48065, 48066, 48077, 48078, 48079, 48080, 48081, 48092, 48093, 48094, 48095, 48096, 48133, 48134, 48135, 48136, 48137, 48148, 48149, 48150, 48151, 48152, 48163, 48164, 48165, 48166, 48167,
|
||||
48178, 48179, 48180, 48181, 48182, 48193, 48194, 48195, 48196, 48197, 48208, 48209, 48210, 48211, 48212, 48223, 48224, 48225, 48226, 48227, 48238, 48239, 48240, 48241, 48242, 48255, 48256, 48257, 48258, 48259,
|
||||
48270, 48271, 48272, 48273, 48274, 48285, 48286, 48287, 48288, 48289, 48300, 48301, 48302, 48303, 48304, 48316, 48317, 48318, 48319, 48320, 48331, 48332, 48333, 48334, 48335, 48346, 48347, 48348, 48349, 48350,
|
||||
48361, 48362, 48363, 48364, 48365, 48376, 48377, 48378, 48379, 48380, 48391, 48392, 48393, 48394, 48395, 48430, 48446, 48450, 48452, 48454, 48461, 48462, 48463, 48464, 48465, 48481, 48482, 48483, 48484, 48485,
|
||||
48496, 48497, 48498, 48499, 48500, 48538, 48539, 48540, 48541, 48542, 48553, 48554, 48555, 48556, 48557, 48575, 48576, 48577, 48578, 48579, 48590, 48591, 48592, 48593, 48594, 48607, 48608, 48609, 48610, 48611,
|
||||
48622, 48623, 48624, 48625, 48626, 48637, 48638, 48639, 48640, 48641, 48657, 48658, 48659, 48660, 48661, 48666, 48667, 48668, 48669, 48670, 48671, 48672, 48673, 48674, 48675, 48693, 48695, 48697, 48699, 48701,
|
||||
48703, 48705, 48708, 48709, 48710, 48711, 48712, 48713, 48714, 48722, 48724, 49233, 49234, 49237, 49238 };
|
||||
|
||||
#endif
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "drak_tharon_keep.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BELLOWING_ROAR = 22686,
|
||||
SPELL_GRIEVOUS_BITE = 48920,
|
||||
SPELL_MANGLING_SLASH = 48873,
|
||||
SPELL_FEARSOME_ROAR = 48849,
|
||||
SPELL_PIERCING_SLASH = 48878,
|
||||
SPELL_RAPTOR_CALL = 59416
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_DRAKKARI_SCYTHECLAW = 26628,
|
||||
NPC_DRAKKARI_GUTRIPPER = 26641,
|
||||
|
||||
SAY_CLAW_EMOTE = 0,
|
||||
|
||||
EVENT_SPELL_BELLOWING_ROAR = 1,
|
||||
EVENT_SPELL_GRIEVOUS_BITE = 2,
|
||||
EVENT_SPELL_MANGLING_SLASH = 3,
|
||||
EVENT_SPELL_FEARSOME_ROAR = 4,
|
||||
EVENT_SPELL_PIERCING_SLASH = 5,
|
||||
EVENT_SPELL_RAPTOR_CALL = 6,
|
||||
EVENT_MENACING_CLAW = 7
|
||||
};
|
||||
|
||||
class boss_dred : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_dred() : CreatureScript("boss_dred") {}
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_dredAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_dredAI : public BossAI
|
||||
{
|
||||
boss_dredAI(Creature* creature) : BossAI(creature, DATA_DRED)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
_raptorCount = 0;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return uint32(_raptorCount >= _raptorCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32)
|
||||
{
|
||||
if (type == me->GetEntry())
|
||||
++_raptorCount;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
_raptorCount = 0;
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWING_ROAR, 33000);
|
||||
events.ScheduleEvent(EVENT_SPELL_GRIEVOUS_BITE, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_MANGLING_SLASH, 18500);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEARSOME_ROAR, urand(10000,20000));
|
||||
events.ScheduleEvent(EVENT_SPELL_PIERCING_SLASH, 17000);
|
||||
if (IsHeroic())
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MENACING_CLAW, 21000);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAPTOR_CALL, urand(20000,25000));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_BELLOWING_ROAR:
|
||||
me->CastSpell(me, SPELL_BELLOWING_ROAR, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_BELLOWING_ROAR, 40000);
|
||||
break;
|
||||
case EVENT_SPELL_GRIEVOUS_BITE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_GRIEVOUS_BITE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_GRIEVOUS_BITE, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_MANGLING_SLASH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MANGLING_SLASH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_MANGLING_SLASH, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_FEARSOME_ROAR:
|
||||
me->CastSpell(me, SPELL_FEARSOME_ROAR, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEARSOME_ROAR, 17000);
|
||||
break;
|
||||
case EVENT_SPELL_PIERCING_SLASH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PIERCING_SLASH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_PIERCING_SLASH, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_RAPTOR_CALL:
|
||||
me->CastSpell(me, SPELL_RAPTOR_CALL, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAPTOR_CALL, 20000);
|
||||
break;
|
||||
case EVENT_MENACING_CLAW:
|
||||
Talk(SAY_CLAW_EMOTE);
|
||||
me->setAttackTimer(BASE_ATTACK, 2000);
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
if (me->GetVictim())
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
if (me->GetVictim())
|
||||
me->AttackerStateUpdate(me->GetVictim());
|
||||
events.ScheduleEvent(EVENT_MENACING_CLAW, 20000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _raptorCount;
|
||||
};
|
||||
};
|
||||
|
||||
class spell_dred_grievious_bite : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_dred_grievious_bite() : SpellScriptLoader("spell_dred_grievious_bite") { }
|
||||
|
||||
class spell_dred_grievious_bite_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_dred_grievious_bite_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Unit* target = GetTarget())
|
||||
if (target->GetHealth() == target->GetMaxHealth())
|
||||
{
|
||||
PreventDefaultAction();
|
||||
SetDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_dred_grievious_bite_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_dred_grievious_bite_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_dred_raptor_call : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_dred_raptor_call() : SpellScriptLoader("spell_dred_raptor_call") { }
|
||||
|
||||
class spell_dred_raptor_call_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_dred_raptor_call_SpellScript);
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->SummonCreature(RAND(NPC_DRAKKARI_GUTRIPPER, NPC_DRAKKARI_SCYTHECLAW), -522.02f, -718.89f, 30.26f, 2.41f);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_dred_raptor_call_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_dred_raptor_call_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_better_off_dred : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_better_off_dred() : AchievementCriteriaScript("achievement_better_off_dred")
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return target->GetAI()->GetData(target->GetEntry());
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_dred()
|
||||
{
|
||||
new boss_dred();
|
||||
new spell_dred_grievious_bite();
|
||||
new spell_dred_raptor_call();
|
||||
new achievement_better_off_dred();
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "drak_tharon_keep.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_SUMMONING_ADDS = 3,
|
||||
SAY_ARCANE_FIELD = 4,
|
||||
EMOTE_SUMMONING_ADDS = 5
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BEAM_CHANNEL = 52106,
|
||||
SPELL_ARCANE_BLAST = 49198,
|
||||
SPELL_ARCANE_FIELD = 47346,
|
||||
SPELL_SUMMON_FETID_TROLL_CORPSE = 49103,
|
||||
SPELL_SUMMON_HULKING_CORPSE = 49104,
|
||||
SPELL_SUMMON_RISEN_SHADOWCASTER = 49105,
|
||||
SPELL_SUMMON_CRYSTAL_HANDLER = 49179,
|
||||
SPELL_DESPAWN_CRYSTAL_HANDLER = 51403,
|
||||
|
||||
SPELL_SUMMON_MINIONS = 59910,
|
||||
SPELL_COPY_OF_SUMMON_MINIONS = 59933,
|
||||
SPELL_BLIZZARD = 49034,
|
||||
SPELL_FROSTBOLT = 49037,
|
||||
SPELL_TOUCH_OF_MISERY = 50090
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_CRYSTAL_CHANNEL_TARGET = 26712,
|
||||
NPC_CRYSTAL_HANDLER = 26627,
|
||||
|
||||
EVENT_SUMMON_FETID_TROLL = 1,
|
||||
EVENT_SUMMON_SHADOWCASTER = 2,
|
||||
EVENT_SUMMON_HULKING_CORPSE = 3,
|
||||
EVENT_SUMMON_CRYSTAL_HANDLER = 4,
|
||||
EVENT_CAST_OFFENSIVE_SPELL = 5,
|
||||
EVENT_KILL_TALK = 6,
|
||||
EVENT_CHECK_PHASE = 7,
|
||||
EVENT_SPELL_SUMMON_MINIONS = 8
|
||||
};
|
||||
|
||||
class boss_novos : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_novos() : CreatureScript("boss_novos") { }
|
||||
|
||||
struct boss_novosAI : public BossAI
|
||||
{
|
||||
boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, NOT_STARTED);
|
||||
_crystalCounter = 0;
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
_achievement = true;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return uint32(_achievement);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32)
|
||||
{
|
||||
if (type == me->GetEntry())
|
||||
_achievement = false;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) { }
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::EnterCombat(who);
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 9000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20000);
|
||||
events.ScheduleEvent(EVENT_CHECK_PHASE, 80000);
|
||||
|
||||
me->CastSpell(me, SPELL_ARCANE_BLAST, true);
|
||||
me->CastSpell(me, SPELL_ARCANE_FIELD, true);
|
||||
me->CastSpell(me, SPELL_DESPAWN_CRYSTAL_HANDLER, true);
|
||||
me->SummonCreature(NPC_CRYSTAL_CHANNEL_TARGET, -378.40f, -813.13f, 59.74f, 0.0f);
|
||||
|
||||
me->SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
me->RemoveAllAuras();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
instance->SetBossState(DATA_NOVOS_CRYSTALS, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET && summon->GetEntry() != NPC_CRYSTAL_HANDLER)
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
else if (summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET)
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_FETID_TROLL:
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, NULL, NULL, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3000);
|
||||
break;
|
||||
case EVENT_SUMMON_HULKING_CORPSE:
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, NULL, NULL, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30000);
|
||||
break;
|
||||
case EVENT_SUMMON_SHADOWCASTER:
|
||||
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET))
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, NULL, NULL, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 10000);
|
||||
break;
|
||||
case EVENT_SUMMON_CRYSTAL_HANDLER:
|
||||
if (_crystalCounter++ < 4)
|
||||
{
|
||||
Talk(SAY_SUMMONING_ADDS);
|
||||
Talk(EMOTE_SUMMONING_ADDS);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f))
|
||||
target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, NULL, NULL, me->GetGUID());
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20000);
|
||||
}
|
||||
break;
|
||||
case EVENT_CHECK_PHASE:
|
||||
if (me->HasAura(SPELL_BEAM_CHANNEL))
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CHECK_PHASE, 2000);
|
||||
break;
|
||||
}
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 10000);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
break;
|
||||
case EVENT_CAST_OFFENSIVE_SPELL:
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
me->CastSpell(target, RAND(SPELL_BLIZZARD,SPELL_FROSTBOLT,SPELL_TOUCH_OF_MISERY), false);
|
||||
|
||||
events.ScheduleEvent(EVENT_CAST_OFFENSIVE_SPELL, 500);
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_MINIONS:
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_MINIONS, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 15000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_MINIONS, 500);
|
||||
break;
|
||||
}
|
||||
|
||||
EnterEvadeIfOutOfCombatArea();
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const
|
||||
{
|
||||
return !SelectTargetFromPlayerList(80.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _crystalCounter;
|
||||
bool _achievement;
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_novosAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_novos_despawn_crystal_handler : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_novos_despawn_crystal_handler() : SpellScriptLoader("spell_novos_despawn_crystal_handler") { }
|
||||
|
||||
class spell_novos_despawn_crystal_handler_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_novos_despawn_crystal_handler_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(GetCaster(), SPELL_BEAM_CHANNEL, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_novos_despawn_crystal_handler_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_novos_despawn_crystal_handler_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_novos_crystal_handler_death : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_novos_crystal_handler_death() : SpellScriptLoader("spell_novos_crystal_handler_death") { }
|
||||
|
||||
class spell_novos_crystal_handler_death_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_novos_crystal_handler_death_AuraScript)
|
||||
|
||||
void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetUnitOwner()->InterruptNonMeleeSpells(false);
|
||||
if (GameObject* crystal = GetUnitOwner()->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_DOOR, 5.0f))
|
||||
crystal->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_novos_crystal_handler_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_novos_crystal_handler_death_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_novos_summon_minions : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_novos_summon_minions() : SpellScriptLoader("spell_novos_summon_minions") { }
|
||||
|
||||
class spell_novos_summon_minions_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_novos_summon_minions_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_novos_summon_minions_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_novos_summon_minions_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_oh_novos : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") { }
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
return target && target->GetAI()->GetData(target->GetEntry());
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_novos()
|
||||
{
|
||||
new boss_novos();
|
||||
new spell_novos_despawn_crystal_handler();
|
||||
new spell_novos_crystal_handler_death();
|
||||
new spell_novos_summon_minions();
|
||||
new achievement_oh_novos();
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "drak_tharon_keep.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_FLESH = 2,
|
||||
SAY_SKELETON = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CURSE_OF_LIFE = 49527,
|
||||
SPELL_RAIN_OF_FIRE = 49518,
|
||||
SPELL_SHADOW_VOLLEY = 49528,
|
||||
|
||||
// flesh spells
|
||||
SPELL_EYE_BEAM = 49544,
|
||||
SPELL_LIGHTNING_BREATH = 49537,
|
||||
SPELL_POISON_CLOUD = 49548,
|
||||
|
||||
SPELL_TURN_FLESH = 49356,
|
||||
SPELL_TURN_BONES = 53463,
|
||||
SPELL_GIFT_OF_THARON_JA = 52509,
|
||||
SPELL_DUMMY = 49551,
|
||||
SPELL_FLESH_VISUAL = 52582,
|
||||
SPELL_CLEAR_GIFT = 53242,
|
||||
|
||||
SPELL_ACHIEVEMENT_CHECK = 61863
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_TURN_BONES = 1,
|
||||
|
||||
EVENT_SPELL_CURSE_OF_LIFE = 1,
|
||||
EVENT_SPELL_RAIN_OF_FIRE = 2,
|
||||
EVENT_SPELL_SHADOW_VOLLEY = 3,
|
||||
EVENT_SPELL_EYE_BEAM = 4,
|
||||
EVENT_SPELL_LIGHTNING_BREATH = 5,
|
||||
EVENT_SPELL_POISON_CLOUD = 6,
|
||||
EVENT_SPELL_TURN_FLESH = 7,
|
||||
EVENT_TURN_FLESH_REAL = 9,
|
||||
EVENT_TURN_BONES_REAL = 10,
|
||||
EVENT_KILL_TALK = 11
|
||||
};
|
||||
|
||||
class boss_tharon_ja : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_tharon_ja() : CreatureScript("boss_tharon_ja") { }
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_tharon_jaAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_tharon_jaAI : public BossAI
|
||||
{
|
||||
boss_tharon_jaAI(Creature* creature) : BossAI(creature, DATA_THARON_JA)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
me->CastSpell(me, SPELL_CLEAR_GIFT, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::EnterCombat(who);
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 5000);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, urand(14000,18000));
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, urand(8000,10000));
|
||||
events.ScheduleEvent(EVENT_SPELL_TURN_FLESH, 1000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_TURN_BONES && me->IsAlive())
|
||||
{
|
||||
Talk(SAY_SKELETON);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_TURN_BONES_REAL, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
me->CastSpell(me, SPELL_ACHIEVEMENT_CHECK, true);
|
||||
me->CastSpell(me, SPELL_CLEAR_GIFT, true);
|
||||
if (me->GetDisplayId() != me->GetNativeDisplayId())
|
||||
{
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
me->CastSpell(me, SPELL_FLESH_VISUAL, true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_CURSE_OF_LIFE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true))
|
||||
me->CastSpell(target, SPELL_CURSE_OF_LIFE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 13000);
|
||||
break;
|
||||
case EVENT_SPELL_RAIN_OF_FIRE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true))
|
||||
me->CastSpell(target, SPELL_RAIN_OF_FIRE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, 16000);
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_VOLLEY:
|
||||
me->CastSpell(me, SPELL_SHADOW_VOLLEY, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 9000);
|
||||
break;
|
||||
case EVENT_SPELL_TURN_FLESH:
|
||||
if (me->HealthBelowPct(50))
|
||||
{
|
||||
Talk(SAY_FLESH);
|
||||
me->getThreatManager().resetAllAggro();
|
||||
me->CastSpell((Unit*)NULL, SPELL_TURN_FLESH, false);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_TURN_FLESH_REAL, 3000);
|
||||
return;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPELL_TURN_FLESH, 1000);
|
||||
break;
|
||||
case EVENT_TURN_FLESH_REAL:
|
||||
me->CastSpell(me, SPELL_DUMMY, true);
|
||||
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
events.ScheduleEvent(EVENT_SPELL_EYE_BEAM, 11000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LIGHTNING_BREATH, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_CLOUD, 6000);
|
||||
break;
|
||||
case EVENT_SPELL_EYE_BEAM:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.0f, true))
|
||||
me->CastSpell(target, SPELL_EYE_BEAM, false);
|
||||
break;
|
||||
case EVENT_SPELL_LIGHTNING_BREATH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_LIGHTNING_BREATH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_LIGHTNING_BREATH, 8000);
|
||||
break;
|
||||
case EVENT_SPELL_POISON_CLOUD:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.0f, true))
|
||||
me->CastSpell(target, SPELL_POISON_CLOUD, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_CLOUD, 10000);
|
||||
break;
|
||||
case EVENT_TURN_BONES_REAL:
|
||||
me->SetDisplayId(me->GetNativeDisplayId());
|
||||
me->CastSpell(me, SPELL_FLESH_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_CLEAR_GIFT, true);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 1000);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, urand(12000,14000));
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, urand(8000,10000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_tharon_ja_curse_of_life : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tharon_ja_curse_of_life() : SpellScriptLoader("spell_tharon_ja_curse_of_life") { }
|
||||
|
||||
class spell_tharon_ja_curse_of_life_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tharon_ja_curse_of_life_AuraScript);
|
||||
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (GetUnitOwner()->HealthBelowPct(50))
|
||||
{
|
||||
PreventDefaultAction();
|
||||
SetDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_tharon_ja_curse_of_life_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_tharon_ja_curse_of_life_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_tharon_ja_dummy : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tharon_ja_dummy() : SpellScriptLoader("spell_tharon_ja_dummy") { }
|
||||
|
||||
class spell_tharon_ja_dummy_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_tharon_ja_dummy_AuraScript)
|
||||
|
||||
void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_FLESH_VISUAL, true);
|
||||
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_GIFT_OF_THARON_JA, true);
|
||||
GetUnitOwner()->SetDisplayId(GetUnitOwner()->GetNativeDisplayId()+1);
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetUnitOwner()->getThreatManager().resetAllAggro();
|
||||
GetUnitOwner()->GetMotionMaster()->Clear();
|
||||
GetUnitOwner()->CastSpell((Unit*)NULL, SPELL_TURN_BONES, false);
|
||||
GetUnitOwner()->GetAI()->DoAction(ACTION_TURN_BONES);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_tharon_ja_dummy_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_tharon_ja_dummy_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_tharon_ja_dummy_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_tharon_ja_clear_gift_of_tharon_ja : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_tharon_ja_clear_gift_of_tharon_ja() : SpellScriptLoader("spell_tharon_ja_clear_gift_of_tharon_ja") { }
|
||||
|
||||
class spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->RemoveAura(SPELL_GIFT_OF_THARON_JA);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_tharon_ja()
|
||||
{
|
||||
new boss_tharon_ja();
|
||||
new spell_tharon_ja_curse_of_life();
|
||||
new spell_tharon_ja_dummy();
|
||||
new spell_tharon_ja_clear_gift_of_tharon_ja();
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "drak_tharon_keep.h"
|
||||
#include "SpellAuras.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_CONSUME = 2,
|
||||
SAY_EXPLODE = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SUMMON_INVADER_A = 49456,
|
||||
SPELL_SUMMON_INVADER_B = 49457,
|
||||
SPELL_SUMMON_INVADER_C = 49458,
|
||||
|
||||
SPELL_INFECTED_WOUND = 49637,
|
||||
SPELL_CRUSH = 49639,
|
||||
SPELL_CONSUME = 49380,
|
||||
SPELL_CORPSE_EXPLODE = 49555,
|
||||
|
||||
SPELL_CORPSE_EXPLODE_DAMAGE = 49618,
|
||||
SPELL_CONSUME_AURA = 49381,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_INFECTED_WOUND = 1,
|
||||
EVENT_SPELL_CRUSH = 2,
|
||||
EVENT_SPELL_CONSUME = 3,
|
||||
EVENT_SPELL_CORPSE_EXPLODE = 4,
|
||||
EVENT_SPAWN_INVADERS = 5,
|
||||
EVENT_KILL_TALK = 6
|
||||
};
|
||||
|
||||
class boss_trollgore : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_trollgore() : CreatureScript("boss_trollgore") { }
|
||||
|
||||
struct boss_trollgoreAI : public BossAI
|
||||
{
|
||||
boss_trollgoreAI(Creature* creature) : BossAI(creature, DATA_TROLLGORE)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
events2.Reset();
|
||||
events2.ScheduleEvent(EVENT_SPAWN_INVADERS, 30000);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SPELL_INFECTED_WOUND, urand(6000,10000));
|
||||
events.ScheduleEvent(EVENT_SPELL_CRUSH, urand(3000,5000));
|
||||
events.ScheduleEvent(EVENT_SPELL_CONSUME, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CORPSE_EXPLODE, 35000);
|
||||
events.ScheduleEvent(EVENT_SPAWN_INVADERS, 20000, 30000);
|
||||
|
||||
me->setActive(true);
|
||||
instance->SetBossState(DATA_TROLLGORE, IN_PROGRESS);
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_KILL);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPAWN_INVADERS:
|
||||
me->CastSpell(me, SPELL_SUMMON_INVADER_A, true);
|
||||
me->CastSpell(me, SPELL_SUMMON_INVADER_B, true);
|
||||
me->CastSpell(me, SPELL_SUMMON_INVADER_C, true);
|
||||
events2.ScheduleEvent(EVENT_SPAWN_INVADERS, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_INFECTED_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_INFECTED_WOUND, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_INFECTED_WOUND, urand(25000,35000));
|
||||
break;
|
||||
case EVENT_SPELL_CRUSH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CRUSH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CRUSH, urand(10000,15000));
|
||||
break;
|
||||
case EVENT_SPELL_CONSUME:
|
||||
Talk(SAY_CONSUME);
|
||||
me->CastSpell(me, SPELL_CONSUME, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CONSUME, 15000);
|
||||
break;
|
||||
case EVENT_SPELL_CORPSE_EXPLODE:
|
||||
Talk(SAY_EXPLODE);
|
||||
me->CastSpell(me, SPELL_CORPSE_EXPLODE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CORPSE_EXPLODE, urand(15000,19000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
EnterEvadeIfOutOfCombatArea();
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const
|
||||
{
|
||||
return me->GetHomePosition().GetExactDist2d(me) > 60.0f;
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events2;
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature *creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_trollgoreAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_trollgore_consume : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_trollgore_consume() : SpellScriptLoader("spell_trollgore_consume") { }
|
||||
|
||||
class spell_trollgore_consume_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_trollgore_consume_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(GetCaster(), SPELL_CONSUME_AURA, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_trollgore_consume_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_trollgore_consume_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_trollgore_corpse_explode : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_trollgore_corpse_explode() : SpellScriptLoader("spell_trollgore_corpse_explode") { }
|
||||
|
||||
class spell_trollgore_corpse_explode_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_trollgore_corpse_explode_AuraScript);
|
||||
|
||||
void PeriodicTick(AuraEffect const* aurEff)
|
||||
{
|
||||
if (aurEff->GetTickNumber() == 2)
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(GetTarget(), SPELL_CORPSE_EXPLODE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Creature* target = GetTarget()->ToCreature())
|
||||
target->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_trollgore_corpse_explode_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_trollgore_corpse_explode_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_trollgore_corpse_explode_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_trollgore_invader_taunt : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_trollgore_invader_taunt() : SpellScriptLoader("spell_trollgore_invader_taunt") { }
|
||||
|
||||
class spell_trollgore_invader_taunt_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_trollgore_invader_taunt_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_trollgore_invader_taunt_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_trollgore_invader_taunt_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_consumption_junction : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_consumption_junction() : AchievementCriteriaScript("achievement_consumption_junction")
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return target->GetAuraCount(sSpellMgr->GetSpellIdForDifficulty(SPELL_CONSUME_AURA, target)) < 10;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_trollgore()
|
||||
{
|
||||
new boss_trollgore();
|
||||
new spell_trollgore_consume();
|
||||
new spell_trollgore_corpse_explode();
|
||||
new spell_trollgore_invader_taunt();
|
||||
new achievement_consumption_junction();
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_DRAK_THARON_H
|
||||
#define DEF_DRAK_THARON_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_TROLLGORE = 0,
|
||||
DATA_NOVOS = 1,
|
||||
DATA_NOVOS_CRYSTALS = 2,
|
||||
DATA_DRED = 3,
|
||||
DATA_THARON_JA = 4,
|
||||
MAX_ENCOUNTERS = 5
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_KURZEL = 26664,
|
||||
NPC_DRAKKARI_GUARDIAN = 26620,
|
||||
NPC_RISEN_DRAKKARI_WARRIOR = 26635,
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_NOVOS_CRYSTAL_1 = 189299,
|
||||
GO_NOVOS_CRYSTAL_2 = 189300,
|
||||
GO_NOVOS_CRYSTAL_3 = 189301,
|
||||
GO_NOVOS_CRYSTAL_4 = 189302,
|
||||
};
|
||||
|
||||
enum DTKSpells
|
||||
{
|
||||
SPELL_SUMMON_DRAKKARI_SHAMAN = 49958,
|
||||
SPELL_SUMMON_DRAKKARI_GUARDIAN = 49959
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "drak_tharon_keep.h"
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_NOVOS_CRYSTAL_1, DATA_NOVOS_CRYSTALS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ GO_NOVOS_CRYSTAL_2, DATA_NOVOS_CRYSTALS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ GO_NOVOS_CRYSTAL_3, DATA_NOVOS_CRYSTALS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ GO_NOVOS_CRYSTAL_4, DATA_NOVOS_CRYSTALS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
|
||||
};
|
||||
|
||||
class instance_drak_tharon_keep : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_drak_tharon_keep() : InstanceMapScript("instance_drak_tharon_keep", 600) { }
|
||||
|
||||
struct instance_drak_tharon_keep_InstanceScript : public InstanceScript
|
||||
{
|
||||
instance_drak_tharon_keep_InstanceScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NOVOS_CRYSTAL_1:
|
||||
case GO_NOVOS_CRYSTAL_2:
|
||||
case GO_NOVOS_CRYSTAL_3:
|
||||
case GO_NOVOS_CRYSTAL_4:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NOVOS_CRYSTAL_1:
|
||||
case GO_NOVOS_CRYSTAL_2:
|
||||
case GO_NOVOS_CRYSTAL_3:
|
||||
case GO_NOVOS_CRYSTAL_4:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "D K " << GetBossSaveData();
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if( !in )
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'D' && dataHead2 == 'K')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
|
||||
tmpState = NOT_STARTED;
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap *map) const
|
||||
{
|
||||
return new instance_drak_tharon_keep_InstanceScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_dtk_raise_dead : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_dtk_raise_dead() : SpellScriptLoader("spell_dtk_raise_dead") { }
|
||||
|
||||
class spell_dtk_raise_dead_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_dtk_raise_dead_AuraScript)
|
||||
|
||||
bool Load()
|
||||
{
|
||||
return GetUnitOwner()->GetTypeId() == TYPEID_UNIT;
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetUnitOwner()->ToCreature()->DespawnOrUnsummon(1);
|
||||
GetUnitOwner()->SummonCreature(NPC_RISEN_DRAKKARI_WARRIOR, *GetUnitOwner());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_dtk_raise_dead_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_dtk_raise_dead_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_dtk_summon_random_drakkari : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_dtk_summon_random_drakkari() : SpellScriptLoader("spell_dtk_summon_random_drakkari") { }
|
||||
|
||||
class spell_dtk_summon_random_drakkari_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_dtk_summon_random_drakkari_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->CastSpell(GetCaster(), RAND(SPELL_SUMMON_DRAKKARI_SHAMAN, SPELL_SUMMON_DRAKKARI_GUARDIAN), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_dtk_summon_random_drakkari_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_dtk_summon_random_drakkari_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_drak_tharon_keep()
|
||||
{
|
||||
new instance_drak_tharon_keep();
|
||||
new spell_dtk_raise_dead();
|
||||
new spell_dtk_summon_random_drakkari();
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "forge_of_souls.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "PassiveAI.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_SOUL_STORM = 3,
|
||||
SAY_CORRUPT_SOUL = 4,
|
||||
};
|
||||
|
||||
enum eSpells
|
||||
{
|
||||
SPELL_SOULSTORM_CHANNEL_OOC = 69008,
|
||||
|
||||
SPELL_SHADOW_BOLT = 70043,
|
||||
SPELL_FEAR = 68950,
|
||||
SPELL_MAGICS_BANE = 68793,
|
||||
SPELL_CORRUPT_SOUL = 68839,
|
||||
SPELL_CONSUME_SOUL = 68861,
|
||||
//SPELL_CONSUME_SOUL_HEAL = 68858,
|
||||
|
||||
SPELL_TELEPORT = 68988,
|
||||
SPELL_TELEPORT_VISUAL = 52096,
|
||||
|
||||
SPELL_SOULSTORM_VISUAL = 68870,
|
||||
SPELL_SOULSTORM = 68872,
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_SPELL_SHADOW_BOLT = 1,
|
||||
EVENT_SPELL_FEAR,
|
||||
EVENT_SPELL_MAGICS_BANE,
|
||||
EVENT_SPELL_CORRUPT_SOUL,
|
||||
EVENT_START_SOULSTORM,
|
||||
};
|
||||
|
||||
class boss_bronjahm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_bronjahm() : CreatureScript("boss_bronjahm") { }
|
||||
|
||||
struct boss_bronjahmAI : public ScriptedAI
|
||||
{
|
||||
boss_bronjahmAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
me->CastSpell(me, SPELL_SOULSTORM_CHANNEL_OOC, true);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
me->CastSpell(me, SPELL_SOULSTORM_CHANNEL_OOC, true);
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_BRONJAHM, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
me->RemoveAurasDueToSpell(SPELL_SOULSTORM_CHANNEL_OOC);
|
||||
|
||||
DoZoneInCombat();
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_SHADOW_BOLT, 2000);
|
||||
events.RescheduleEvent(EVENT_SPELL_MAGICS_BANE, urand(5000, 10000));
|
||||
events.RescheduleEvent(EVENT_SPELL_CORRUPT_SOUL, urand(14000, 20000));
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_BRONJAHM, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE) && me->HealthBelowPctDamaged(35, damage))
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->CastSpell(me, SPELL_TELEPORT, false);
|
||||
events.CancelEvent(EVENT_SPELL_CORRUPT_SOUL);
|
||||
events.DelayEvents(6000);
|
||||
events.RescheduleEvent(EVENT_SPELL_FEAR, urand(8000, 14000));
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_TELEPORT)
|
||||
{
|
||||
me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
|
||||
events.RescheduleEvent(EVENT_START_SOULSTORM, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
|
||||
if (me->isAttackReady())
|
||||
me->SetFacingToObject(me->GetVictim());
|
||||
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_BOLT:
|
||||
if (!me->IsWithinMeleeRange(me->GetVictim()))
|
||||
me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false);
|
||||
events.RepeatEvent(2000);
|
||||
break;
|
||||
case EVENT_SPELL_FEAR:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f, true))
|
||||
me->CastCustomSpell(SPELL_FEAR, SPELLVALUE_MAX_TARGETS, 1, target, false);
|
||||
events.RepeatEvent(urand(8000, 12000));
|
||||
break;
|
||||
case EVENT_SPELL_MAGICS_BANE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MAGICS_BANE, false);
|
||||
events.RepeatEvent(urand(10000, 15000));
|
||||
break;
|
||||
case EVENT_SPELL_CORRUPT_SOUL:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
{
|
||||
Talk(SAY_CORRUPT_SOUL);
|
||||
me->CastSpell(target, SPELL_CORRUPT_SOUL, false);
|
||||
}
|
||||
events.RepeatEvent(urand(20000, 25000));
|
||||
break;
|
||||
case EVENT_START_SOULSTORM:
|
||||
Talk(SAY_SOUL_STORM);
|
||||
me->CastSpell(me, SPELL_SOULSTORM, false);
|
||||
me->CastSpell(me, SPELL_TELEPORT_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_SOULSTORM_VISUAL, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_BRONJAHM, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_bronjahmAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class npc_fos_corrupted_soul_fragment : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_fos_corrupted_soul_fragment() : CreatureScript("npc_fos_corrupted_soul_fragment") { }
|
||||
|
||||
struct npc_fos_corrupted_soul_fragmentAI : public NullCreatureAI
|
||||
{
|
||||
npc_fos_corrupted_soul_fragmentAI(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 timer;
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
timer = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (pInstance)
|
||||
if (Creature* b = pInstance->instance->GetCreature(pInstance->GetData64(DATA_BRONJAHM)))
|
||||
{
|
||||
if (me->GetExactDist2d(b) <= 2.0f)
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->CastSpell(b, SPELL_CONSUME_SOUL, true);
|
||||
me->DespawnOrUnsummon(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (timer <= diff)
|
||||
{
|
||||
if (!me->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED))
|
||||
me->GetMotionMaster()->MovePoint(0, *b);
|
||||
timer = 1000;
|
||||
}
|
||||
else
|
||||
timer -= diff;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_fos_corrupted_soul_fragmentAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class spell_bronjahm_magic_bane : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_bronjahm_magic_bane() : SpellScriptLoader("spell_bronjahm_magic_bane") { }
|
||||
|
||||
class spell_bronjahm_magic_bane_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_bronjahm_magic_bane_SpellScript);
|
||||
|
||||
void RecalculateDamage()
|
||||
{
|
||||
if (GetHitUnit()->getPowerType() != POWER_MANA)
|
||||
return;
|
||||
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
const int32 maxDamage = caster->GetMap()->GetSpawnMode() == 1 ? 15000 : 10000;
|
||||
int32 newDamage = GetHitDamage();
|
||||
newDamage += GetHitUnit()->GetMaxPower(POWER_MANA)/2;
|
||||
newDamage = std::min<int32>(maxDamage, newDamage);
|
||||
|
||||
SetHitDamage(newDamage);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnHit += SpellHitFn(spell_bronjahm_magic_bane_SpellScript::RecalculateDamage);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_bronjahm_magic_bane_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class spell_bronjahm_soulstorm_channel_ooc : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_bronjahm_soulstorm_channel_ooc() : SpellScriptLoader("spell_bronjahm_soulstorm_channel_ooc") { }
|
||||
|
||||
class spell_bronjahm_soulstorm_channel_ooc_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_bronjahm_soulstorm_channel_ooc_AuraScript);
|
||||
|
||||
void HandlePeriodicTick(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget()->CastSpell(GetTarget(), 68904+(aurEff->GetTickNumber()%4), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_bronjahm_soulstorm_channel_ooc_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_bronjahm_soulstorm_channel_ooc_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class spell_bronjahm_soulstorm_visual : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_bronjahm_soulstorm_visual() : SpellScriptLoader("spell_bronjahm_soulstorm_visual") { }
|
||||
|
||||
class spell_bronjahm_soulstorm_visual_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_bronjahm_soulstorm_visual_AuraScript);
|
||||
|
||||
void HandlePeriodicTick(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
uint32 spellId = 0;
|
||||
switch (aurEff->GetTickNumber()%4)
|
||||
{
|
||||
case 0: spellId = 68886; break;
|
||||
case 1: spellId = 68896; break;
|
||||
case 2: spellId = 68897; break;
|
||||
case 3: spellId = 68898; break;
|
||||
}
|
||||
GetTarget()->CastSpell(GetTarget(), spellId, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_bronjahm_soulstorm_visual_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_bronjahm_soulstorm_visual_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_bronjahm_soulstorm_targeting() : SpellScriptLoader("spell_bronjahm_soulstorm_targeting") { }
|
||||
|
||||
class spell_bronjahm_soulstorm_targeting_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(Trinity::AllWorldObjectsInExactRange(GetCaster(), 10.0f, false));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_bronjahm_soulstorm_targeting_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void AddSC_boss_bronjahm()
|
||||
{
|
||||
new boss_bronjahm();
|
||||
new npc_fos_corrupted_soul_fragment();
|
||||
|
||||
new spell_bronjahm_magic_bane();
|
||||
new spell_bronjahm_soulstorm_channel_ooc();
|
||||
new spell_bronjahm_soulstorm_visual();
|
||||
new spell_bronjahm_soulstorm_targeting();
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "forge_of_souls.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum eTexts
|
||||
{
|
||||
SAY_FACE_AGGRO = 0,
|
||||
SAY_FACE_ANGER_SLAY = 1,
|
||||
SAY_FACE_SORROW_SLAY = 2,
|
||||
SAY_FACE_DESIRE_SLAY = 3,
|
||||
SAY_FACE_DEATH = 4,
|
||||
EMOTE_MIRRORED_SOUL = 5,
|
||||
EMOTE_UNLEASH_SOUL = 6,
|
||||
SAY_FACE_UNLEASH_SOUL = 7,
|
||||
EMOTE_WAILING_SOUL = 8,
|
||||
SAY_FACE_WAILING_SOUL = 9,
|
||||
};
|
||||
|
||||
enum eSpells
|
||||
{
|
||||
SPELL_PHANTOM_BLAST = 68982,
|
||||
SPELL_PHANTOM_BLAST_H = 70322,
|
||||
SPELL_MIRRORED_SOUL = 69051,
|
||||
SPELL_WELL_OF_SOULS = 68820,
|
||||
//SPELL_WELL_OF_SOULS_SUMMON = 68853,
|
||||
//SPELL_WELL_OF_SOULS_PERIODIC = 68854,
|
||||
SPELL_UNLEASHED_SOULS = 68939,
|
||||
|
||||
SPELL_WAILING_SOULS = 68899, // target 1.0,1.0, change model, triggers 68871, cast time 3 secs
|
||||
SPELL_WAILING_SOULS_SCRIPT_EFFECT = 68871, // target 1.0, script effect, instant
|
||||
SPELL_WAILING_SOULS_PERIODIC_DUMMY = 68875, // target 1.0, aura 226, instant
|
||||
SPELL_WAILING_SOULS_PERIODIC_DUMMY_2= 68876, // target 1.0, aura 226, instant
|
||||
SPELL_WAILING_SOULS_TARGETING = 68912, // target 22.15, aura dummy, 50000yd, cast instant, duration 4 secs
|
||||
SPELL_WAILING_SOULS_DMG_N = 68873, // 100yd, 104.0
|
||||
SPELL_WAILING_SOULS_DMG_H = 70324, // 100yd, 104.0
|
||||
};
|
||||
|
||||
enum eEvents
|
||||
{
|
||||
EVENT_SPELL_PHANTOM_BLAST = 1,
|
||||
EVENT_SPELL_MIRRORED_SOUL,
|
||||
EVENT_SPELL_WELL_OF_SOULS,
|
||||
EVENT_SPELL_UNLEASHED_SOULS,
|
||||
EVENT_SPELL_WAILING_SOULS,
|
||||
};
|
||||
|
||||
enum eDisplayIds
|
||||
{
|
||||
DISPLAY_ANGER = 30148,
|
||||
DISPLAY_SORROW = 30149,
|
||||
DISPLAY_DESIRE = 30150,
|
||||
};
|
||||
|
||||
enum eMisc
|
||||
{
|
||||
NPC_CRUCIBLE_OF_SOULS = 37094,
|
||||
QUEST_TEMPERING_THE_BLADE_A = 24476,
|
||||
QUEST_TEMPERING_THE_BLADE_H = 24560,
|
||||
};
|
||||
|
||||
class boss_devourer_of_souls : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_devourer_of_souls() : CreatureScript("boss_devourer_of_souls") { }
|
||||
|
||||
struct boss_devourer_of_soulsAI : public ScriptedAI
|
||||
{
|
||||
boss_devourer_of_soulsAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
bool bAchiev;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
bAchiev = true;
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_DEVOURER, NOT_STARTED);
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const
|
||||
{
|
||||
if (id == 1)
|
||||
return bAchiev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_FACE_AGGRO);
|
||||
DoZoneInCombat();
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_PHANTOM_BLAST, 5000);
|
||||
events.RescheduleEvent(EVENT_SPELL_MIRRORED_SOUL, 9000);
|
||||
events.RescheduleEvent(EVENT_SPELL_WELL_OF_SOULS, urand(6000,8000));
|
||||
events.RescheduleEvent(EVENT_SPELL_UNLEASHED_SOULS, urand(18000,20000));
|
||||
events.RescheduleEvent(EVENT_SPELL_WAILING_SOULS, 65000);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_DEVOURER, IN_PROGRESS);
|
||||
|
||||
// Suport for Quest Tempering the Blade
|
||||
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
||||
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
{
|
||||
Player* player = itr->GetSource();
|
||||
if ((player->GetTeamId() == TEAM_ALLIANCE && player->GetQuestStatus(QUEST_TEMPERING_THE_BLADE_A) == QUEST_STATUS_INCOMPLETE) ||
|
||||
(player->GetTeamId() == TEAM_HORDE && player->GetQuestStatus(QUEST_TEMPERING_THE_BLADE_H) == QUEST_STATUS_INCOMPLETE))
|
||||
{
|
||||
if (!me->FindNearestCreature(NPC_CRUCIBLE_OF_SOULS, 100.0f))
|
||||
me->SummonCreature(NPC_CRUCIBLE_OF_SOULS, 5672.29f, 2520.69f, 713.44f, 0.96f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo *spell)
|
||||
{
|
||||
if (spell->Id == SPELL_PHANTOM_BLAST_H)
|
||||
bAchiev = false;
|
||||
else if (spell->Id == SPELL_WAILING_SOULS_TARGETING)
|
||||
{
|
||||
me->SetOrientation(me->GetAngle(target));
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->StopMovingOnCurrentPos();
|
||||
|
||||
me->SetFacingToObject(target);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->CastSpell(me, SPELL_WAILING_SOULS, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit* target) const { return target->GetPositionZ() > 706.5f; }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (Spell* s = me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
|
||||
if (s->m_spellInfo->Id == SPELL_MIRRORED_SOUL)
|
||||
{
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_PHANTOM_BLAST:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PHANTOM_BLAST, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
default:
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->GetCurrentSpell(CURRENT_GENERIC_SPELL))
|
||||
{
|
||||
me->ClearUnitState(UNIT_STATE_CASTING);
|
||||
DoMeleeAttackIfReady();
|
||||
me->AddUnitState(UNIT_STATE_CASTING);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_PHANTOM_BLAST:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PHANTOM_BLAST, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
case EVENT_SPELL_MIRRORED_SOUL:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 90.0f, true))
|
||||
{
|
||||
me->CastSpell(target, SPELL_MIRRORED_SOUL, false);
|
||||
me->setAttackTimer(BASE_ATTACK, 2500);
|
||||
Talk(EMOTE_MIRRORED_SOUL);
|
||||
}
|
||||
events.RepeatEvent(urand(20000,30000));
|
||||
break;
|
||||
case EVENT_SPELL_WELL_OF_SOULS:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
|
||||
me->CastSpell(target, SPELL_WELL_OF_SOULS, false);
|
||||
events.RepeatEvent(urand(25000,30000));
|
||||
events.DelayEventsToMax(4000, 0);
|
||||
break;
|
||||
case EVENT_SPELL_UNLEASHED_SOULS:
|
||||
me->CastSpell(me, SPELL_UNLEASHED_SOULS, false);
|
||||
Talk(SAY_FACE_UNLEASH_SOUL);
|
||||
Talk(EMOTE_UNLEASH_SOUL);
|
||||
events.RepeatEvent(urand(30000,40000));
|
||||
events.DelayEventsToMax(5000, 0);
|
||||
me->setAttackTimer(BASE_ATTACK, 5500);
|
||||
break;
|
||||
case EVENT_SPELL_WAILING_SOULS:
|
||||
Talk(SAY_FACE_WAILING_SOUL);
|
||||
Talk(EMOTE_WAILING_SOUL);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
me->CastCustomSpell(SPELL_WAILING_SOULS_TARGETING, SPELLVALUE_MAX_TARGETS, 1, target, false);
|
||||
events.RepeatEvent(80000);
|
||||
events.DelayEventsToMax(20000, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_FACE_DEATH);
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_DEVOURER, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
int32 textId = 0;
|
||||
switch (me->GetDisplayId())
|
||||
{
|
||||
case DISPLAY_ANGER:
|
||||
textId = SAY_FACE_ANGER_SLAY;
|
||||
break;
|
||||
case DISPLAY_SORROW:
|
||||
textId = SAY_FACE_SORROW_SLAY;
|
||||
break;
|
||||
case DISPLAY_DESIRE:
|
||||
textId = SAY_FACE_DESIRE_SLAY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (textId)
|
||||
Talk(textId);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (summon->GetEntry() != NPC_CRUCIBLE_OF_SOULS)
|
||||
summons.Summon(summon);
|
||||
|
||||
if (summon->GetEntry() == 36595)
|
||||
if (Player* plr = summon->SelectNearestPlayer(100.0f))
|
||||
{
|
||||
summon->AddThreat(plr, 100000.0f);
|
||||
summon->AI()->AttackStart(plr);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_devourer_of_soulsAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class spell_wailing_souls_periodic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_wailing_souls_periodic() : SpellScriptLoader("spell_wailing_souls_periodic") { }
|
||||
|
||||
class spell_wailing_souls_periodic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_wailing_souls_periodic_AuraScript);
|
||||
|
||||
int8 dir;
|
||||
|
||||
bool Load()
|
||||
{
|
||||
dir = urand(0,1) ? 1 : -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandlePeriodicTick(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (Unit* t = GetTarget())
|
||||
{
|
||||
if (aurEff->GetTickNumber() < 30)
|
||||
{
|
||||
// spinning, casting, etc.
|
||||
float diff = (2*M_PI)/(4*30);
|
||||
float new_o = t->GetOrientation() + diff*dir;
|
||||
if (new_o >= 2*M_PI)
|
||||
new_o -= 2*M_PI;
|
||||
else if (new_o < 0)
|
||||
new_o += 2*M_PI;
|
||||
t->UpdateOrientation(new_o);
|
||||
t->SetFacingTo(new_o);
|
||||
t->CastSpell(t, SPELL_WAILING_SOULS_DMG_N, true);
|
||||
}
|
||||
else if (aurEff->GetTickNumber() == 33)
|
||||
{
|
||||
t->SetControlled(false, UNIT_STATE_ROOT);
|
||||
t->DisableRotate(false);
|
||||
if (t->GetTypeId() == TYPEID_UNIT)
|
||||
t->ToCreature()->SetReactState(REACT_AGGRESSIVE);
|
||||
if (t->GetVictim())
|
||||
{
|
||||
t->SetUInt64Value(UNIT_FIELD_TARGET, t->GetVictim()->GetGUID());
|
||||
t->GetMotionMaster()->MoveChase(t->GetVictim());
|
||||
}
|
||||
}
|
||||
else if (aurEff->GetTickNumber() >= 34)
|
||||
Remove(AURA_REMOVE_BY_EXPIRE);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_wailing_souls_periodic_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_wailing_souls_periodic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void AddSC_boss_devourer_of_souls()
|
||||
{
|
||||
new boss_devourer_of_souls();
|
||||
new spell_wailing_souls_periodic();
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "forge_of_souls.h"
|
||||
#include "SpellScript.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_JAINA_INTRO_1 = 0,
|
||||
SAY_JAINA_INTRO_2 = 1,
|
||||
SAY_JAINA_INTRO_3 = 2,
|
||||
SAY_JAINA_INTRO_4 = 3,
|
||||
SAY_JAINA_INTRO_5 = 4,
|
||||
SAY_JAINA_INTRO_6 = 5,
|
||||
SAY_JAINA_INTRO_7 = 6,
|
||||
SAY_JAINA_INTRO_8 = 7,
|
||||
|
||||
SAY_SYLVANAS_INTRO_1 = 0,
|
||||
SAY_SYLVANAS_INTRO_2 = 1,
|
||||
SAY_SYLVANAS_INTRO_3 = 2,
|
||||
SAY_SYLVANAS_INTRO_4 = 3,
|
||||
SAY_SYLVANAS_INTRO_5 = 4,
|
||||
SAY_SYLVANAS_INTRO_6 = 5,
|
||||
|
||||
SAY_JAINA_OUTRO = 0,
|
||||
SAY_SYLVANAS_OUTRO = 0,
|
||||
};
|
||||
|
||||
class npc_fos_leader : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_fos_leader() : CreatureScript("npc_fos_leader") { }
|
||||
|
||||
struct npc_fos_leaderAI: public ScriptedAI
|
||||
{
|
||||
npc_fos_leaderAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void DoAction(int32 a)
|
||||
{
|
||||
if (a == 1)
|
||||
if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
|
||||
{
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(1, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_1);
|
||||
events.ScheduleEvent(2, 8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(SAY_SYLVANAS_INTRO_1);
|
||||
events.ScheduleEvent(2, 11500);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_2);
|
||||
events.ScheduleEvent(3, 9000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(SAY_SYLVANAS_INTRO_2);
|
||||
events.ScheduleEvent(3, 10500);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_3);
|
||||
events.ScheduleEvent(4, 8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(SAY_SYLVANAS_INTRO_3);
|
||||
events.ScheduleEvent(4, 10500);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_4);
|
||||
events.ScheduleEvent(5, 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(SAY_SYLVANAS_INTRO_4);
|
||||
events.ScheduleEvent(5, 11000);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_5);
|
||||
events.ScheduleEvent(6, 8000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(SAY_SYLVANAS_INTRO_5);
|
||||
events.ScheduleEvent(6, 9500);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_6);
|
||||
events.ScheduleEvent(7, 12000);
|
||||
}
|
||||
else
|
||||
{
|
||||
Talk(SAY_SYLVANAS_INTRO_6);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_7);
|
||||
events.ScheduleEvent(8, 8000);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
events.PopEvent();
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
{
|
||||
Talk(SAY_JAINA_INTRO_8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
if (creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
|
||||
{
|
||||
if (creature->GetEntry() == NPC_JAINA_PART1)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "What would you have of me, my lady?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
else
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "What would you have of me, Banshee Queen?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
}
|
||||
|
||||
player->SEND_GOSSIP_MENU(15207, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
switch(uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
if (creature->AI())
|
||||
creature->AI()->DoAction(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI *GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_fos_leaderAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class npc_fos_leader_second : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_fos_leader_second() : CreatureScript("npc_fos_leader_second") { }
|
||||
|
||||
struct npc_fos_leader_secondAI: public ScriptedAI
|
||||
{
|
||||
npc_fos_leader_secondAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == 1)
|
||||
{
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
if (me->GetEntry() == NPC_JAINA_PART1)
|
||||
Talk(SAY_JAINA_OUTRO);
|
||||
else
|
||||
Talk(SAY_SYLVANAS_OUTRO);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI *GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_fos_leader_secondAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class spell_shield_of_bones : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_shield_of_bones() : SpellScriptLoader("spell_shield_of_bones") { }
|
||||
|
||||
class spell_shield_of_bones_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_shield_of_bones_AuraScript);
|
||||
|
||||
int32 amount;
|
||||
bool fired;
|
||||
|
||||
bool Load()
|
||||
{
|
||||
fired = false;
|
||||
amount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleAfterEffectAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount)
|
||||
{
|
||||
amount += absorbAmount;
|
||||
if (!fired && amount >= GetSpellInfo()->Effects[EFFECT_0].BasePoints+1)
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
fired = true;
|
||||
caster->CastSpell(caster, 69642, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectAbsorb += AuraEffectAbsorbFn(spell_shield_of_bones_AuraScript::HandleAfterEffectAbsorb, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_shield_of_bones_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_forge_of_souls()
|
||||
{
|
||||
new npc_fos_leader();
|
||||
new npc_fos_leader_second();
|
||||
new spell_shield_of_bones();
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_FORGE_OF_SOULS_H
|
||||
#define DEF_FORGE_OF_SOULS_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_BRONJAHM,
|
||||
DATA_DEVOURER,
|
||||
MAX_ENCOUNTER,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_BRONJAHM = 36497,
|
||||
NPC_DEVOURER = 36502,
|
||||
|
||||
NPC_SYLVANAS_PART1 = 37596,
|
||||
NPC_SYLVANAS_PART2 = 38161,
|
||||
NPC_JAINA_PART1 = 37597,
|
||||
NPC_JAINA_PART2 = 38160,
|
||||
NPC_KALIRA = 37583,
|
||||
NPC_ELANDRA = 37774,
|
||||
NPC_LORALEN = 37779,
|
||||
NPC_KORELN = 37582,
|
||||
|
||||
NPC_CHAMPION_1_HORDE = 37584,
|
||||
NPC_CHAMPION_2_HORDE = 37587,
|
||||
NPC_CHAMPION_3_HORDE = 37588,
|
||||
NPC_CHAMPION_1_ALLIANCE = 37496,
|
||||
NPC_CHAMPION_2_ALLIANCE = 37497,
|
||||
};
|
||||
|
||||
// OUTRO:
|
||||
|
||||
struct outroPosition
|
||||
{
|
||||
uint32 entry[2];
|
||||
Position startPosition;
|
||||
uint32 pathId;
|
||||
};
|
||||
|
||||
#define PATH_BEGIN_VALUE 3000100
|
||||
|
||||
const outroPosition outroPositions[] =
|
||||
{
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5590.47f, 2427.79f, 705.935f, 0.802851f }, PATH_BEGIN_VALUE+14 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5593.59f, 2428.34f, 705.935f, 0.977384f }, PATH_BEGIN_VALUE+15 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5600.81f, 2429.31f, 705.935f, 0.890118f }, PATH_BEGIN_VALUE+5 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5600.81f, 2421.12f, 705.935f, 0.890118f }, PATH_BEGIN_VALUE+18 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5601.43f, 2426.53f, 705.935f, 0.890118f }, PATH_BEGIN_VALUE+6 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5601.55f, 2418.36f, 705.935f, 1.15192f }, PATH_BEGIN_VALUE+17 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5598, 2429.14f, 705.935f, 1.0472f }, PATH_BEGIN_VALUE+4 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5594.04f, 2424.87f, 705.935f, 1.15192f }, PATH_BEGIN_VALUE+16 },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 5597.89f, 2421.54f, 705.935f, 0.610865f }, PATH_BEGIN_VALUE+19 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5598.57f, 2434.62f, 705.935f, 1.13446f }, PATH_BEGIN_VALUE+2 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5585.46f, 2417.99f, 705.935f, 1.06465f }, PATH_BEGIN_VALUE+12 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5605.81f, 2428.42f, 705.935f, 0.820305f }, PATH_BEGIN_VALUE+3 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5591.61f, 2412.66f, 705.935f, 0.925025f }, PATH_BEGIN_VALUE+11 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5593.9f, 2410.64f, 705.935f, 0.872665f }, PATH_BEGIN_VALUE+10 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 5586.76f, 2416.73f, 705.935f, 0.942478f }, PATH_BEGIN_VALUE+13 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5592.23f, 2419.14f, 705.935f, 0.855211f }, PATH_BEGIN_VALUE+8 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5594.61f, 2416.87f, 705.935f, 0.907571f }, PATH_BEGIN_VALUE+7 },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 5589.77f, 2421.03f, 705.935f, 0.855211f }, PATH_BEGIN_VALUE+9 },
|
||||
|
||||
{ { NPC_KORELN, NPC_LORALEN }, { 5602.58f, 2435.95f, 705.935f, 0.959931f }, PATH_BEGIN_VALUE+0 },
|
||||
{ { NPC_ELANDRA, NPC_KALIRA }, { 5606.13f, 2433.16f, 705.935f, 0.785398f }, PATH_BEGIN_VALUE+1 },
|
||||
|
||||
{ { 0, 0 }, { 0.0f, 0.0f, 0.0f, 0.0f }, 0 }
|
||||
};
|
||||
|
||||
const Position outroSpawnPoint = {5618.139f, 2451.873f, 705.854f, 0.0f};
|
||||
|
||||
#endif
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "forge_of_souls.h"
|
||||
#include "Player.h"
|
||||
|
||||
class instance_forge_of_souls : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_forge_of_souls() : InstanceMapScript("instance_forge_of_souls", 632) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap *map) const
|
||||
{
|
||||
return new instance_forge_of_souls_InstanceScript(map);
|
||||
}
|
||||
|
||||
struct instance_forge_of_souls_InstanceScript : public InstanceScript
|
||||
{
|
||||
instance_forge_of_souls_InstanceScript(Map* map) : InstanceScript(map) {}
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
TeamId teamIdInInstance;
|
||||
std::string str_data;
|
||||
uint64 NPC_BronjahmGUID;
|
||||
uint64 NPC_DevourerGUID;
|
||||
|
||||
uint64 NPC_LeaderFirstGUID;
|
||||
uint64 NPC_LeaderSecondGUID;
|
||||
uint64 NPC_GuardFirstGUID;
|
||||
uint64 NPC_GuardSecondGUID;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
teamIdInInstance = TEAM_NEUTRAL;
|
||||
NPC_BronjahmGUID = 0;
|
||||
NPC_DevourerGUID = 0;
|
||||
|
||||
NPC_LeaderFirstGUID = 0;
|
||||
NPC_LeaderSecondGUID = 0;
|
||||
NPC_GuardFirstGUID = 0;
|
||||
NPC_GuardSecondGUID = 0;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* /*plr*/)
|
||||
{
|
||||
// this will happen only after crash and loading the instance from db
|
||||
if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE && (!NPC_LeaderSecondGUID || !instance->GetCreature(NPC_LeaderSecondGUID)))
|
||||
{
|
||||
Position pos = {5658.15f, 2502.564f, 708.83f, 0.885207f};
|
||||
instance->SummonCreature(NPC_SYLVANAS_PART2, pos);
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
if (teamIdInInstance == TEAM_NEUTRAL)
|
||||
{
|
||||
Map::PlayerList const &players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
if (Player* player = players.begin()->GetSource())
|
||||
teamIdInInstance = player->GetTeamId();
|
||||
}
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_BRONJAHM:
|
||||
NPC_BronjahmGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_DEVOURER:
|
||||
NPC_DevourerGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_SYLVANAS_PART1:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_JAINA_PART1);
|
||||
NPC_LeaderFirstGUID = creature->GetGUID();
|
||||
|
||||
if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_SYLVANAS_PART2:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_JAINA_PART2);
|
||||
NPC_LeaderSecondGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_LORALEN:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_ELANDRA);
|
||||
if (!NPC_GuardFirstGUID)
|
||||
{
|
||||
NPC_GuardFirstGUID = creature->GetGUID();
|
||||
if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE)
|
||||
creature->SetVisible(false);
|
||||
}
|
||||
break;
|
||||
case NPC_KALIRA:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_KORELN);
|
||||
if (!NPC_GuardSecondGUID)
|
||||
{
|
||||
NPC_GuardSecondGUID = creature->GetGUID();
|
||||
if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE)
|
||||
creature->SetVisible(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleOutro()
|
||||
{
|
||||
if (!NPC_LeaderSecondGUID || !instance->GetCreature(NPC_LeaderSecondGUID))
|
||||
if (Creature* leader = instance->SummonCreature(NPC_SYLVANAS_PART2, outroSpawnPoint))
|
||||
if (Creature* boss = instance->GetCreature(NPC_DevourerGUID))
|
||||
{
|
||||
float angle = boss->GetAngle(leader);
|
||||
leader->GetMotionMaster()->MovePoint(1, boss->GetPositionX()+10.0f*cos(angle), boss->GetPositionY()+10.0f*sin(angle), boss->GetPositionZ());
|
||||
}
|
||||
|
||||
for (int8 i = 0; outroPositions[i].entry[teamIdInInstance] != 0; ++i)
|
||||
if (Creature* summon = instance->SummonCreature(outroPositions[i].entry[teamIdInInstance], outroPositions[i].startPosition))
|
||||
summon->GetMotionMaster()->MovePath(outroPositions[i].pathId, false);
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_BRONJAHM:
|
||||
m_auiEncounter[type] = data;
|
||||
break;
|
||||
case DATA_DEVOURER:
|
||||
m_auiEncounter[type] = data;
|
||||
if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE)
|
||||
HandleOutro();
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_BRONJAHM: return NPC_BronjahmGUID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
|
||||
{
|
||||
switch(criteria_id)
|
||||
{
|
||||
case 12752: // Soul Power
|
||||
if( Creature* c = instance->GetCreature(NPC_BronjahmGUID) )
|
||||
{
|
||||
std::list<Creature*> L;
|
||||
uint8 count = 0;
|
||||
c->GetCreaturesWithEntryInRange(L, 200.0f, 36535); // find all Corrupted Soul Fragment (36535)
|
||||
for( std::list<Creature*>::const_iterator itr = L.begin(); itr != L.end(); ++itr )
|
||||
if( (*itr)->IsAlive() )
|
||||
++count;
|
||||
return (count >= 4);
|
||||
}
|
||||
break;
|
||||
case 12976:
|
||||
if( Creature* c = instance->GetCreature(NPC_DevourerGUID) )
|
||||
return (bool)c->AI()->GetData(1);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "F S " << m_auiEncounter[0] << ' ' << m_auiEncounter[1];
|
||||
str_data = saveStream.str();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return str_data;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1;
|
||||
|
||||
if (dataHead1 == 'F' && dataHead2 == 'S')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_forge_of_souls()
|
||||
{
|
||||
new instance_forge_of_souls();
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptPCH.h"
|
||||
#include "halls_of_reflection.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 50,
|
||||
SAY_SLAY_1 = 51,
|
||||
SAY_SLAY_2 = 52,
|
||||
SAY_DEATH = 53,
|
||||
SAY_IMPENDING_DESPAIR = 54,
|
||||
SAY_DEFILING_HORROR = 55,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_QUIVERING_STRIKE = 72422,
|
||||
SPELL_IMPENDING_DESPAIR = 72426,
|
||||
SPELL_DEFILING_HORROR = 72435,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
EVENT_QUIVERING_STRIKE,
|
||||
EVENT_IMPENDING_DESPAIR,
|
||||
EVENT_DEFILING_HORROR,
|
||||
EVENT_UNROOT,
|
||||
};
|
||||
|
||||
const uint32 hopelessnessId[3][2] = { {72395, 72390}, {72396, 72391}, {72397, 72393} };
|
||||
|
||||
class boss_falric : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_falric() : CreatureScript("boss_falric") { }
|
||||
|
||||
struct boss_falricAI : public ScriptedAI
|
||||
{
|
||||
boss_falricAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint8 uiHopelessnessCount;
|
||||
uint16 startFightTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
startFightTimer = 0;
|
||||
uiHopelessnessCount = 0;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_FALRIC, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
|
||||
events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 5000);
|
||||
events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 11000);
|
||||
events.ScheduleEvent(EVENT_DEFILING_HORROR, 20000);
|
||||
}
|
||||
|
||||
void DoAction(int32 a)
|
||||
{
|
||||
if (a == 1)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
startFightTimer = 8000;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (startFightTimer)
|
||||
{
|
||||
if (startFightTimer <= diff)
|
||||
{
|
||||
startFightTimer = 0;
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
else
|
||||
startFightTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_QUIVERING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_QUIVERING_STRIKE, false);
|
||||
events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 5000);
|
||||
break;
|
||||
case EVENT_IMPENDING_DESPAIR:
|
||||
if (Unit* target = SelectTargetFromPlayerList(45.0f, 0, true))
|
||||
{
|
||||
Talk(SAY_IMPENDING_DESPAIR);
|
||||
me->CastSpell(target, SPELL_IMPENDING_DESPAIR, false);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 12000);
|
||||
break;
|
||||
case EVENT_DEFILING_HORROR:
|
||||
Talk(SAY_DEFILING_HORROR);
|
||||
me->CastSpell((Unit*)NULL, SPELL_DEFILING_HORROR, false);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
events.DelayEventsToMax(5000, 0);
|
||||
events.ScheduleEvent(EVENT_UNROOT, 4000);
|
||||
events.ScheduleEvent(EVENT_DEFILING_HORROR, 20000);
|
||||
break;
|
||||
case EVENT_UNROOT:
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((uiHopelessnessCount == 0 && HealthBelowPct(67)) || (uiHopelessnessCount == 1 && HealthBelowPct(34)) || (uiHopelessnessCount == 2 && HealthBelowPct(11)))
|
||||
{
|
||||
if (uiHopelessnessCount)
|
||||
me->RemoveOwnedAura(hopelessnessId[uiHopelessnessCount-1][DUNGEON_MODE(0, 1)]);
|
||||
me->CastSpell((Unit*)NULL, hopelessnessId[uiHopelessnessCount][DUNGEON_MODE(0, 1)], true);
|
||||
++uiHopelessnessCount;
|
||||
}
|
||||
|
||||
if (!me->HasUnitState(UNIT_STATE_ROOT))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_FALRIC, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(RAND(SAY_SLAY_1, SAY_SLAY_2));
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
if (startFightTimer)
|
||||
Reset();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_falricAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_falric()
|
||||
{
|
||||
new boss_falric();
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptPCH.h"
|
||||
#include "halls_of_reflection.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 60,
|
||||
SAY_SLAY_1 = 61,
|
||||
SAY_SLAY_2 = 62,
|
||||
SAY_DEATH = 63,
|
||||
SAY_CORRUPTED_FLESH_1 = 64,
|
||||
SAY_CORRUPTED_FLESH_2 = 65,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_OBLITERATE = 72360,
|
||||
SPELL_WELL_OF_CORRUPTION = 72362,
|
||||
SPELL_CORRUPTED_FLESH = 72363,
|
||||
SPELL_SHARED_SUFFERING = 72368,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
EVENT_OBLITERATE,
|
||||
EVENT_WELL_OF_CORRUPTION,
|
||||
EVENT_CORRUPTED_FLESH,
|
||||
EVENT_SHARED_SUFFERING,
|
||||
};
|
||||
|
||||
class boss_marwyn : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_marwyn() : CreatureScript("boss_marwyn") { }
|
||||
|
||||
struct boss_marwynAI : public ScriptedAI
|
||||
{
|
||||
boss_marwynAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint16 startFightTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
startFightTimer = 0;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MARWYN, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
|
||||
events.ScheduleEvent(EVENT_OBLITERATE, 15000);
|
||||
events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
|
||||
events.ScheduleEvent(EVENT_SHARED_SUFFERING, 5000);
|
||||
}
|
||||
|
||||
void DoAction(int32 a)
|
||||
{
|
||||
if (a == 1)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
startFightTimer = 8000;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (startFightTimer)
|
||||
{
|
||||
if (startFightTimer <= diff)
|
||||
{
|
||||
startFightTimer = 0;
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
else
|
||||
startFightTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_OBLITERATE:
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_OBLITERATE, false);
|
||||
events.ScheduleEvent(EVENT_OBLITERATE, 15000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_OBLITERATE, 3000);
|
||||
break;
|
||||
case EVENT_WELL_OF_CORRUPTION:
|
||||
if (Unit* target = SelectTargetFromPlayerList(40.0f, 0, true))
|
||||
me->CastSpell(target, SPELL_WELL_OF_CORRUPTION, false);
|
||||
events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
|
||||
break;
|
||||
case EVENT_CORRUPTED_FLESH:
|
||||
Talk(RAND(SAY_CORRUPTED_FLESH_1, SAY_CORRUPTED_FLESH_2));
|
||||
me->CastSpell((Unit*)NULL, SPELL_CORRUPTED_FLESH, false);
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
|
||||
break;
|
||||
case EVENT_SHARED_SUFFERING:
|
||||
if (Unit* target = SelectTargetFromPlayerList(200.0f, 0, true))
|
||||
me->CastSpell(target, SPELL_SHARED_SUFFERING, true);
|
||||
events.ScheduleEvent(EVENT_SHARED_SUFFERING, 15000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MARWYN, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(RAND(SAY_SLAY_1, SAY_SLAY_2));
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
if (startFightTimer)
|
||||
Reset();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_marwynAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_hor_shared_suffering : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_hor_shared_suffering() : SpellScriptLoader("spell_hor_shared_suffering") { }
|
||||
|
||||
class spell_hor_shared_sufferingAuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_hor_shared_sufferingAuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode)
|
||||
{
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL) // dispelled
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Map* map = caster->FindMap())
|
||||
if (Aura* a = aurEff->GetBase())
|
||||
{
|
||||
uint32 count = 0;
|
||||
uint32 ticks = 0;
|
||||
uint32 dmgPerTick = a->GetSpellInfo()->Effects[0].BasePoints;
|
||||
Map::PlayerList const& pl = map->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
|
||||
if (Player* p = itr->GetSource())
|
||||
if (p->IsAlive())
|
||||
++count;
|
||||
ticks = (a->GetDuration() / int32(a->GetSpellInfo()->Effects[0].Amplitude)) + 1;
|
||||
int32 dmg = (ticks*dmgPerTick)/count;
|
||||
caster->CastCustomSpell(GetTarget(), 72373, NULL, &dmg, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_hor_shared_sufferingAuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_hor_shared_sufferingAuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_marwyn()
|
||||
{
|
||||
new boss_marwyn();
|
||||
new spell_hor_shared_suffering();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_HALLS_OF_REFLECTION_H
|
||||
#define DEF_HALLS_OF_REFLECTION_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_INTRO,
|
||||
DATA_FALRIC,
|
||||
DATA_MARWYN,
|
||||
DATA_FROSTSWORN_GENERAL,
|
||||
DATA_LK_INTRO,
|
||||
DATA_LICH_KING,
|
||||
DATA_BATTERED_HILT,
|
||||
MAX_ENCOUNTER,
|
||||
ACTION_SHOW_TRASH,
|
||||
ACTION_SPIRITUAL_REFLECTIONS_COPY,
|
||||
ACTION_SPIRITUAL_REFLECTIONS_ACTIVATE,
|
||||
ACTION_SPIRITUAL_REFLECTIONS_HIDE,
|
||||
ACTION_START_LK_FIGHT,
|
||||
ACTION_STOP_LK_FIGHT,
|
||||
ACTION_DELETE_ICE_WALL,
|
||||
DATA_WAVE_NUMBER,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_FALRIC = 38112,
|
||||
NPC_MARWYN = 38113,
|
||||
NPC_LICH_KING_EVENT = 37226,
|
||||
NPC_LICH_KING_BOSS = 36954,
|
||||
|
||||
NPC_UTHER = 37225,
|
||||
NPC_JAINA_PART1 = 37221,
|
||||
NPC_JAINA_PART2 = 36955,
|
||||
NPC_SYLVANAS_PART1 = 37223,
|
||||
NPC_SYLVANAS_PART2 = 37554,
|
||||
|
||||
NPC_DARK_RANGER_LORALEN = 37779,
|
||||
NPC_ARCHMAGE_ELANDRA = 37774,
|
||||
|
||||
NPC_WAVE_MERCENARY = 38177,
|
||||
NPC_WAVE_FOOTMAN = 38173,
|
||||
NPC_WAVE_RIFLEMAN = 38176,
|
||||
NPC_WAVE_PRIEST = 38175,
|
||||
NPC_WAVE_MAGE = 38172,
|
||||
NPC_PHANTOM_HALLUCINATION = 38567,
|
||||
|
||||
NPC_FROSTSWORN_GENERAL = 36723,
|
||||
NPC_SPIRITUAL_REFLECTION = 37068,
|
||||
NPC_ICE_WALL_TARGET = 37014,
|
||||
NPC_WRATH_OF_THE_LICH_KING_CREDIT = 38211,
|
||||
NPC_HIGH_CAPTAIN_JUSTIN_BARLETT = 30344,
|
||||
NPC_SKY_REAVER_KORM_BLACKSKAR = 30824,
|
||||
NPC_ALTAR_BUNNY = 37704,
|
||||
NPC_QUEL_DELAR = 37158,
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_FROSTMOURNE = 202302,
|
||||
GO_FROSTMOURNE_ALTAR = 202236,
|
||||
GO_FRONT_DOOR = 201976,
|
||||
GO_ARTHAS_DOOR = 197341,
|
||||
GO_CAVE_IN = 201596,
|
||||
GO_DOOR_BEFORE_THRONE = 197342,
|
||||
GO_DOOR_AFTER_THRONE = 197343,
|
||||
GO_ICE_WALL = 201385,
|
||||
GO_THE_SKYBREAKER = 201598,
|
||||
GO_ORGRIMS_HAMMER = 201599,
|
||||
GO_STAIRS_ALLIANCE = 201709,
|
||||
GO_STAIRS_HORDE = 202211,
|
||||
GO_CHEST_NORMAL = 201710,
|
||||
GO_CHEST_HEROIC = 202336,
|
||||
GO_PORTAL_TO_DALARAN = 195682,
|
||||
};
|
||||
|
||||
enum HorWorldStates
|
||||
{
|
||||
WORLD_STATE_HOR_COUNTER = 4884,
|
||||
WORLD_STATE_HOR_WAVE_COUNT = 4882,
|
||||
};
|
||||
|
||||
enum BatteredHiltStatusFlags
|
||||
{
|
||||
BHSF_NONE = 0,
|
||||
BHSF_STARTED = 1,
|
||||
BHSF_THROWN = 2,
|
||||
BHSF_FINISHED = 4,
|
||||
};
|
||||
|
||||
#define NUM_OF_TRASH 34
|
||||
#define MAX_DIST_FROM_CENTER_IN_COMBAT 70.5f
|
||||
#define MAX_DIST_FROM_CENTER_TO_START 40.0f
|
||||
|
||||
enum hYells
|
||||
{
|
||||
SAY_JAINA_INTRO_1 = 1,
|
||||
SAY_JAINA_INTRO_2 = 2,
|
||||
SAY_JAINA_INTRO_3 = 3,
|
||||
SAY_JAINA_INTRO_4 = 4,
|
||||
SAY_UTHER_INTRO_A2_1 = 5,
|
||||
SAY_JAINA_INTRO_5 = 6,
|
||||
SAY_UTHER_INTRO_A2_2 = 7,
|
||||
SAY_JAINA_INTRO_6 = 8,
|
||||
SAY_UTHER_INTRO_A2_3 = 9,
|
||||
SAY_JAINA_INTRO_7 = 10,
|
||||
SAY_UTHER_INTRO_A2_4 = 11,
|
||||
SAY_JAINA_INTRO_8 = 12,
|
||||
SAY_UTHER_INTRO_A2_5 = 13,
|
||||
SAY_JAINA_INTRO_9 = 14,
|
||||
SAY_UTHER_INTRO_A2_6 = 15,
|
||||
SAY_UTHER_INTRO_A2_7 = 16,
|
||||
SAY_JAINA_INTRO_10 = 17,
|
||||
SAY_UTHER_INTRO_A2_8 = 18,
|
||||
SAY_JAINA_INTRO_11 = 19,
|
||||
SAY_UTHER_INTRO_A2_9 = 20,
|
||||
|
||||
SAY_SYLVANAS_INTRO_1 = 21,
|
||||
SAY_SYLVANAS_INTRO_2 = 22,
|
||||
SAY_SYLVANAS_INTRO_3 = 23,
|
||||
SAY_UTHER_INTRO_H2_1 = 24,
|
||||
SAY_SYLVANAS_INTRO_4 = 25,
|
||||
SAY_UTHER_INTRO_H2_2 = 26,
|
||||
SAY_SYLVANAS_INTRO_5 = 27,
|
||||
SAY_UTHER_INTRO_H2_3 = 28,
|
||||
SAY_SYLVANAS_INTRO_6 = 29,
|
||||
SAY_UTHER_INTRO_H2_4 = 30,
|
||||
SAY_SYLVANAS_INTRO_7 = 31,
|
||||
SAY_UTHER_INTRO_H2_5 = 32,
|
||||
SAY_UTHER_INTRO_H2_6 = 33,
|
||||
SAY_SYLVANAS_INTRO_8 = 34,
|
||||
SAY_UTHER_INTRO_H2_7 = 35,
|
||||
|
||||
SAY_LK_INTRO_1 = 36,
|
||||
SAY_LK_INTRO_2 = 37,
|
||||
SAY_LK_INTRO_3 = 38,
|
||||
SAY_FALRIC_INTRO_1 = 39,
|
||||
SAY_MARWYN_INTRO_1 = 40,
|
||||
SAY_FALRIC_INTRO_2 = 41,
|
||||
|
||||
SAY_JAINA_INTRO_END = 42,
|
||||
SAY_SYLVANAS_INTRO_END = 43,
|
||||
|
||||
SAY_FROSTSWORN_GENERAL_AGGRO = 98,
|
||||
SAY_FROSTSWORN_GENERAL_DEATH = 99,
|
||||
|
||||
SAY_LK_AGGRO_HORDE = 100,
|
||||
SAY_LK_AGGRO_ALLY = 101,
|
||||
SAY_SYLVANAS_LEAVE = 102,
|
||||
SAY_JAINA_LEAVE = 103,
|
||||
SAY_LK_IW_1 = 104,
|
||||
SAY_LK_IW_2 = 105,
|
||||
SAY_LK_IW_3 = 106,
|
||||
SAY_LK_IW_4 = 107,
|
||||
SAY_LK_IW_1_SUMMON = 108,
|
||||
SAY_SYLVANAS_IW_1 = 109,
|
||||
SAY_SYLVANAS_IW_2 = 110,
|
||||
SAY_SYLVANAS_IW_3 = 111,
|
||||
SAY_SYLVANAS_IW_4 = 112,
|
||||
SAY_SYLVANAS_OPENING = 113,
|
||||
SAY_SYLVANAS_END = 114,
|
||||
SAY_LK_NOWHERE_TO_RUN = 115,
|
||||
SAY_FIRE_HORDE = 116,
|
||||
SAY_ONBOARD_HORDE = 117,
|
||||
SAY_FINAL_HORDE = 118,
|
||||
SAY_JAINA_IW_1 = 119,
|
||||
SAY_JAINA_IW_2 = 120,
|
||||
SAY_JAINA_IW_3 = 121,
|
||||
SAY_JAINA_IW_4 = 122,
|
||||
SAY_JAINA_OPENING = 123,
|
||||
SAY_JAINA_END = 124,
|
||||
SAY_FIRE_ALLY = 125,
|
||||
SAY_ONBOARD_ALLY = 126,
|
||||
SAY_FINAL_ALLY = 127,
|
||||
SAY_FINAL_ALLY_SECOND = 128,
|
||||
|
||||
SAY_BATTERED_HILT_HALT = 200,
|
||||
SAY_BATTERED_HILT_LEAP = 201,
|
||||
SAY_BATTERED_HILT_REALIZE = 202,
|
||||
SAY_BATTERED_HILT_PREPARE = 203,
|
||||
SAY_BATTERED_HILT_OUTRO1 = 204,
|
||||
SAY_BATTERED_HILT_OUTRO2 = 205,
|
||||
SAY_BATTERED_HILT_OUTRO3 = 206,
|
||||
SAY_BATTERED_HILT_OUTRO4 = 207,
|
||||
};
|
||||
|
||||
enum hMisc
|
||||
{
|
||||
ACTION_START_INTRO,
|
||||
ACTION_SKIP_INTRO,
|
||||
ACTION_START_LK_FIGHT_REAL,
|
||||
ACTION_INFORM_TRASH_DIED,
|
||||
ACTION_CHECK_TRASH_DIED,
|
||||
ACTION_INFORM_WALL_DESTROYED,
|
||||
|
||||
QUEST_DELIVRANCE_FROM_THE_PIT_A2 = 24710,
|
||||
QUEST_DELIVRANCE_FROM_THE_PIT_H2 = 24712,
|
||||
QUEST_WRATH_OF_THE_LICH_KING_A2 = 24500,
|
||||
QUEST_WRATH_OF_THE_LICH_KING_H2 = 24802,
|
||||
ACHIEV_RETREATING_TIMED_EVENT = 22615,
|
||||
|
||||
SPELL_FROSTMOURNE_SPAWN_SOUND = 70667,
|
||||
SPELL_FROSTMOURNE_EQUIP = 72729,
|
||||
SPELL_HOR_START_QUEST_ALLY = 71351,
|
||||
SPELL_HOR_START_QUEST_HORDE = 71542,
|
||||
SPELL_SHADOWMOURNE_VISUAL = 72523,
|
||||
SPELL_ARCANE_CAST_VISUAL = 65633,
|
||||
SPELL_WELL_OF_SOULS_VISUAL = 72630,
|
||||
|
||||
// Frostsworn General
|
||||
EVENT_ACTIVATE_REFLECTIONS = 1,
|
||||
EVENT_THROW_SHIELD = 2,
|
||||
EVENT_BALEFUL_STRIKE = 3,
|
||||
SPELL_THROW_SHIELD = 69222,
|
||||
SPELL_SUMMON_REFLECTIONS_DUMMY = 69223,
|
||||
SPELL_HOR_CLONE = 69828,
|
||||
SPELL_HOR_CLONE_NAME = 69837,
|
||||
SPELL_BALEFUL_STRIKE = 69933,
|
||||
SPELL_SPIRIT_BURST = 69900,
|
||||
SPELL_JAINA_ICE_BARRIER = 69787,
|
||||
SPELL_SYLVANAS_CLOAK_OF_DARKNESS = 70188,
|
||||
SPELL_JAINA_ICE_PRISON = 69708,
|
||||
SPELL_SYLVANAS_DARK_BINDING = 70194,
|
||||
SPELL_REMORSELESS_WINTER = 69780,
|
||||
SPELL_LICH_KING_ZAP_PLAYER = 70653,
|
||||
SPELL_DESTROY_WALL_JAINA = 69784,
|
||||
SPELL_DESTROY_WALL_SYLVANAS = 70224,
|
||||
SPELL_SUMMON_ICE_WALL = 69768,
|
||||
SPELL_FURY_OF_FROSTMOURNE = 70063,
|
||||
SPELL_HARVEST_SOUL = 70070,
|
||||
SPELL_HOR_SUICIDE = 69908,
|
||||
SPELL_SUMMON_RAGING_GHOULS = 69818,
|
||||
SPELL_SUMMON_RISEN_WITCH_DOCTOR = 69836,
|
||||
SPELL_SUMMON_LUMBERING_ABOMINATION = 69835,
|
||||
SPELL_GUNSHIP_CANNON_FIRE_PERIODIC = 70017,
|
||||
SPELL_ACHIEVEMENT_CHECK = 72830,
|
||||
};
|
||||
|
||||
const uint32 allowedCompositions[8][5] =
|
||||
{
|
||||
{NPC_WAVE_MERCENARY, NPC_WAVE_PRIEST, NPC_WAVE_RIFLEMAN, 0, 0},
|
||||
{NPC_WAVE_MAGE, NPC_WAVE_RIFLEMAN, NPC_WAVE_FOOTMAN, 0, 0},
|
||||
{NPC_WAVE_MERCENARY, NPC_WAVE_PRIEST, NPC_WAVE_FOOTMAN, NPC_WAVE_FOOTMAN, 0},
|
||||
{NPC_WAVE_MAGE, NPC_WAVE_PRIEST, NPC_WAVE_FOOTMAN, NPC_WAVE_FOOTMAN, 0},
|
||||
{NPC_WAVE_MERCENARY, NPC_WAVE_MAGE, NPC_WAVE_RIFLEMAN, NPC_WAVE_FOOTMAN, NPC_WAVE_FOOTMAN},
|
||||
{NPC_WAVE_MERCENARY, NPC_WAVE_MAGE, NPC_WAVE_PRIEST, NPC_WAVE_RIFLEMAN, NPC_WAVE_RIFLEMAN},
|
||||
{NPC_WAVE_MERCENARY, NPC_WAVE_MAGE, NPC_WAVE_PRIEST, NPC_WAVE_RIFLEMAN, NPC_WAVE_FOOTMAN},
|
||||
{NPC_WAVE_MERCENARY, NPC_WAVE_MAGE, NPC_WAVE_PRIEST, NPC_WAVE_FOOTMAN, NPC_WAVE_FOOTMAN}
|
||||
};
|
||||
|
||||
const Position CenterPos = {5309.459473f, 2006.478516f, 711.595459f, 0.0f};
|
||||
const Position SpawnPos = {5262.540527f, 1949.693726f, 707.695007f, 0.808736f}; // Jaina/Sylvanas Beginning Position
|
||||
const Position LoralenFollowPos = {5283.234863f, 1990.946777f, 707.695679f, 0.929097f};
|
||||
const Position MoveThronePos = {5306.952148f, 1998.499023f, 709.341431f, 1.277278f}; // Jaina/Sylvanas walks to throne
|
||||
const Position UtherSpawnPos = {5308.310059f, 2003.857178f, 709.341431f, 4.650315f};
|
||||
const Position LichKingSpawnPos = {5362.917480f, 2062.307129f, 707.695374f, 3.945812f};
|
||||
const Position LichKingMoveThronePos = {5312.080566f, 2009.172119f, 709.341431f, 3.973301f}; // Lich King walks to throne
|
||||
const Position LichKingMoveAwayPos = {5400.069824f, 2102.7131689f, 707.69525f, 0.843803f}; // Lich King walks away
|
||||
const Position FalricMovePos = {5284.161133f, 2030.691650f, 709.319336f, 5.489386f};
|
||||
const Position MarwynMovePos = {5335.330078f, 1982.376221f, 709.319580f, 2.339942f};
|
||||
const Position SylvanasFightPos = {5557.508301f, 2263.920654f, 733.011230f, 3.624075f};
|
||||
const Position LeaderEscapePos = {5577.654785f, 2235.347412f, 733.011230f, 2.359576f};
|
||||
const Position ShipMasterSummonPos = {5262.773926f, 1669.980103f, 715.000000f, 0.000000f};
|
||||
const Position WalkCaveInPos = {5267.594238f, 1678.750000f, 784.302856f, 1.041739f};
|
||||
const Position AllyPortalPos = {5205.015625f, 1605.680298f, 806.444458f, 0.884375f};
|
||||
const Position AllyChestPos = {5194.341797f, 1611.271484f, 806.408569f, 0.907936f};
|
||||
const Position HordePortalPos = {5222.733887f, 1568.052124f, 819.590881f, 1.198878f};
|
||||
const Position HordeChestPos = {5215.394531f, 1569.726074f, 819.149048f, 1.151754f};
|
||||
|
||||
#define PATH_WP_COUNT 19
|
||||
const uint8 WP_STOP[6] = {0, 5, 8, 10, 14, 18};
|
||||
|
||||
const Position PathWaypoints[PATH_WP_COUNT] =
|
||||
{
|
||||
{5588.055664f, 2229.327393f, 733.011353f, 5.440755f},
|
||||
{5605.567383f, 2203.448486f, 731.304626f, 5.059827f},
|
||||
{5607.415039f, 2189.225098f, 731.022217f, 4.203760f},
|
||||
{5598.958984f, 2169.660156f, 730.919800f, 4.093812f},
|
||||
{5586.018066f, 2149.685303f, 731.090759f, 4.093815f},
|
||||
{5558.182617f, 2103.950928f, 731.263000f, 4.239113f}, // Leader Ice Wall 1
|
||||
{5534.202637f, 2054.254150f, 731.131165f, 4.360846f},
|
||||
{5526.244629f, 2023.878540f, 732.408264f, 4.419744f},
|
||||
{5513.573242f, 1996.611206f, 735.115723f, 4.239110f}, // Leader Ice Wall 2
|
||||
{5478.590820f, 1938.773315f, 741.926697f, 4.168423f},
|
||||
{5456.632324f, 1902.801025f, 747.220886f, 4.058471f}, // Leader Ice Wall 3
|
||||
{5423.630371f, 1858.672363f, 754.901367f, 4.078105f},
|
||||
{5402.314453f, 1829.705811f, 758.029907f, 3.932807f},
|
||||
{5374.380371f, 1802.807007f, 760.831238f, 3.897464f},
|
||||
{5340.560059f, 1772.791016f, 766.478149f, 3.760019f}, // Leader Ice Wall 4
|
||||
{5318.707031f, 1750.379395f, 771.635132f, 3.944588f},
|
||||
{5297.951660f, 1725.419067f, 778.211548f, 4.121302f},
|
||||
{5279.251953f, 1697.474365f, 785.700256f, 4.152715f},
|
||||
{5262.773926f, 1669.980103f, 784.301697f, 1.015049f}
|
||||
};
|
||||
|
||||
const Position CannonFirePos[2][3] =
|
||||
{
|
||||
{
|
||||
{5231.177734f, 1617.087280f, 813.603755f, 0.990318f},
|
||||
{5222.555664f, 1623.302490f, 813.603755f, 0.868589f},
|
||||
{5203.667480f, 1630.986694f, 813.603755f, 0.790045f}
|
||||
},
|
||||
{
|
||||
{5233.234863f, 1572.758789f, 816.572266f, 1.202728f},
|
||||
{5220.500488f, 1577.656860f, 816.572266f, 1.128118f},
|
||||
{5209.669922f, 1584.753784f, 816.572266f, 0.982819f}
|
||||
}
|
||||
};
|
||||
|
||||
const Position StairsPos[2][3] =
|
||||
{
|
||||
{
|
||||
{5226.36f, 1640.87f, 785.737f, 5.56137f},
|
||||
{5213.76f, 1626.21f, 798.068f, 5.56534f},
|
||||
{0.0f, 0.0f, 0.0f, 0.0f}
|
||||
},
|
||||
{
|
||||
{5233.61f, 1607.48f, 796.5f, 5.77774f},
|
||||
{5223.32f, 1589.24f, 809.0f, 5.76989f},
|
||||
{5243.42f, 1624.8f, 784.361f, 5.76592f}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,373 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "pit_of_saron.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
#include "CreatureGroups.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 14,
|
||||
SAY_SLAY_1 = 15,
|
||||
SAY_DEATH = 17,
|
||||
SAY_FORGE_1 = 18,
|
||||
SAY_FORGE_2 = 19,
|
||||
|
||||
SAY_BOULDER_HIT = 16,
|
||||
EMOTE_DEEP_FREEZE = 23,
|
||||
};
|
||||
|
||||
#define EMOTE_THROW_SARONITE "%s hurls a massive saronite boulder at you!"
|
||||
|
||||
enum MiscData
|
||||
{
|
||||
EQUIP_ID_SWORD = 49345,
|
||||
EQUIP_ID_MACE = 49344,
|
||||
GO_SARONITE_ROCK = 196485,
|
||||
};
|
||||
|
||||
Position const northForgePos = {722.5643f, -234.1615f, 527.182f, 2.16421f};
|
||||
Position const southForgePos = {639.257f, -210.1198f, 529.015f, 0.523599f};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_PERMAFROST = 70326,
|
||||
SPELL_THROW_SARONITE = 68788,
|
||||
SPELL_THUNDERING_STOMP = 68771,
|
||||
|
||||
SPELL_CHILLING_WAVE = 68778,
|
||||
SPELL_DEEP_FREEZE = 70381,
|
||||
};
|
||||
|
||||
#define SPELL_FORGE_BLADE RAID_MODE(68774, 70334)
|
||||
#define SPELL_FORGE_MACE RAID_MODE(68785, 70335)
|
||||
#define SPELL_SARONITE_TRIGGERED RAID_MODE(68789, 70851)
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_THROW_SARONITE = 1,
|
||||
EVENT_JUMP,
|
||||
EVENT_SPELL_CHILLING_WAVE,
|
||||
EVENT_SPELL_DEEP_FREEZE,
|
||||
};
|
||||
|
||||
class boss_garfrost : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_garfrost() : CreatureScript("boss_garfrost") { }
|
||||
|
||||
struct boss_garfrostAI : public ScriptedAI
|
||||
{
|
||||
boss_garfrostAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint8 phase;
|
||||
bool bCanSayBoulderHit;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->RemoveAura(SPELL_PERMAFROST);
|
||||
SetEquipmentSlots(true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
phase = 0;
|
||||
bCanSayBoulderHit = true;
|
||||
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_GARFROST, NOT_STARTED);
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 data)
|
||||
{
|
||||
if (id == 1 && pInstance)
|
||||
pInstance->SetData(DATA_ACHIEV_ELEVEN, 0);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->CastSpell(me, SPELL_PERMAFROST, true);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
events.RescheduleEvent(EVENT_SPELL_THROW_SARONITE, urand(5000,7500));
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_GARFROST, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/)
|
||||
{
|
||||
if (phase == 0 && !HealthAbovePct(66) && !me->HasUnitState(UNIT_STATE_ROOT))
|
||||
{
|
||||
phase = 1;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetTarget(0);
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
events.DelayEvents(8000);
|
||||
me->CastSpell(me, SPELL_THUNDERING_STOMP, false);
|
||||
events.RescheduleEvent(EVENT_JUMP, 1250);
|
||||
return;
|
||||
}
|
||||
|
||||
if (phase == 1 && !HealthAbovePct(33) && !me->HasUnitState(UNIT_STATE_ROOT))
|
||||
{
|
||||
events.CancelEvent(EVENT_SPELL_CHILLING_WAVE);
|
||||
phase = 2;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetTarget(0);
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
events.DelayEvents(8000);
|
||||
me->CastSpell(me, SPELL_THUNDERING_STOMP, false);
|
||||
events.RescheduleEvent(EVENT_JUMP, 1250);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != EFFECT_MOTION_TYPE || id != 0)
|
||||
return;
|
||||
|
||||
if (phase == 1)
|
||||
{
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->CastSpell(me, SPELL_FORGE_BLADE, false);
|
||||
Talk(SAY_FORGE_1);
|
||||
}
|
||||
else if (phase == 2)
|
||||
{
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->RemoveAurasDueToSpell(SPELL_FORGE_BLADE);
|
||||
me->CastSpell(me, SPELL_FORGE_MACE, false);
|
||||
Talk(SAY_FORGE_2);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_SARONITE_TRIGGERED)
|
||||
{
|
||||
if (bCanSayBoulderHit)
|
||||
{
|
||||
bCanSayBoulderHit = false;
|
||||
Talk(SAY_BOULDER_HIT);
|
||||
}
|
||||
}
|
||||
if (spell->Id == SPELL_FORGE_BLADE)
|
||||
{
|
||||
events.RescheduleEvent(EVENT_SPELL_CHILLING_WAVE, 10000);
|
||||
SetEquipmentSlots(false, EQUIP_ID_SWORD);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
if (me->GetVictim())
|
||||
{
|
||||
AttackStart(me->GetVictim());
|
||||
me->SetTarget(me->GetVictim()->GetGUID());
|
||||
}
|
||||
}
|
||||
else if (spell->Id == SPELL_FORGE_MACE)
|
||||
{
|
||||
events.RescheduleEvent(EVENT_SPELL_DEEP_FREEZE, 10000);
|
||||
SetEquipmentSlots(false, EQUIP_ID_MACE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
if (me->GetVictim())
|
||||
{
|
||||
AttackStart(me->GetVictim());
|
||||
me->SetTarget(me->GetVictim()->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetVictim())
|
||||
{
|
||||
float x,y,z;
|
||||
me->GetVictim()->GetPosition(x, y, z);
|
||||
if (x<600.0f || x>770.0f || y<-270.0f || y>-137.0f || z<514.0f || z>550.0f)
|
||||
{
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
EnterEvadeMode();
|
||||
if (CreatureGroup* f = me->GetFormation())
|
||||
{
|
||||
const CreatureGroup::CreatureGroupMemberType& m = f->GetMembers();
|
||||
for (CreatureGroup::CreatureGroupMemberType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->first->IsAlive() && itr->first->IsInCombat() && !itr->first->IsInEvadeMode() && itr->first->IsAIEnabled)
|
||||
itr->first->AI()->EnterEvadeMode();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_THROW_SARONITE:
|
||||
bCanSayBoulderHit = true;
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 140.0f, true))
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, me, NULL, EMOTE_THROW_SARONITE);
|
||||
target->ToPlayer()->GetSession()->SendPacket(&data);
|
||||
me->CastSpell(target, SPELL_THROW_SARONITE, false);
|
||||
}
|
||||
events.RepeatEvent(urand(12500,20000));
|
||||
break;
|
||||
case EVENT_JUMP:
|
||||
me->DisableRotate(true);
|
||||
if (phase == 1)
|
||||
me->GetMotionMaster()->MoveJump(northForgePos.GetPositionX(), northForgePos.GetPositionY(), northForgePos.GetPositionZ(), 25.0f, 15.0f, 0);
|
||||
else if (phase == 2)
|
||||
me->GetMotionMaster()->MoveJump(southForgePos.GetPositionX(), southForgePos.GetPositionY(), southForgePos.GetPositionZ(), 25.0f, 15.0f, 0);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_CHILLING_WAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CHILLING_WAVE, false);
|
||||
events.RepeatEvent(35000);
|
||||
break;
|
||||
case EVENT_SPELL_DEEP_FREEZE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
{
|
||||
Talk(EMOTE_DEEP_FREEZE, target);
|
||||
me->CastSpell(target, SPELL_DEEP_FREEZE, false);
|
||||
}
|
||||
events.RepeatEvent(35000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_GARFROST, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY_1);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_garfrostAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_garfrost_permafrost : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_garfrost_permafrost() : SpellScriptLoader("spell_garfrost_permafrost") { }
|
||||
|
||||
class spell_garfrost_permafrost_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_garfrost_permafrost_SpellScript);
|
||||
|
||||
std::list<WorldObject*> targetList;
|
||||
|
||||
void Unload()
|
||||
{
|
||||
targetList.clear();
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
std::list<GameObject*> blockList;
|
||||
caster->GetGameObjectListWithEntryInGrid(blockList, GO_SARONITE_ROCK, 100.0f);
|
||||
|
||||
if (!blockList.empty())
|
||||
{
|
||||
for (std::list<WorldObject*>::iterator itrU = targets.begin(); itrU != targets.end(); ++itrU)
|
||||
if (WorldObject* target = (*itrU))
|
||||
{
|
||||
bool valid = true;
|
||||
if (!caster->IsWithinMeleeRange(target->ToUnit()))
|
||||
for (std::list<GameObject*>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
|
||||
if (!(*itr)->IsInvisibleDueToDespawn())
|
||||
if ((*itr)->IsInBetween(caster, target, 4.0f))
|
||||
{
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
if (valid)
|
||||
{
|
||||
if (Aura* aur = target->ToUnit()->GetAura(70336))
|
||||
if (aur->GetStackAmount() >= 10 && caster->GetTypeId() == TYPEID_UNIT)
|
||||
caster->ToCreature()->AI()->SetData(1, aur->GetStackAmount());
|
||||
targetList.push_back(*itrU);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
targetList = targets;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
targets = targetList;
|
||||
}
|
||||
|
||||
void FilterTargetsNext(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets = targetList;
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_garfrost_permafrost_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_garfrost_permafrost_SpellScript::FilterTargetsNext, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_garfrost_permafrost_SpellScript::FilterTargetsNext, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_garfrost_permafrost_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_garfrost()
|
||||
{
|
||||
new boss_garfrost();
|
||||
|
||||
new spell_garfrost_permafrost();
|
||||
}
|
||||
@@ -1,531 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "pit_of_saron.h"
|
||||
#include "Vehicle.h"
|
||||
#include "SpellScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 24,
|
||||
SAY_SLAY_1 = 25,
|
||||
SAY_SLAY_2 = 26,
|
||||
SAY_ORDER_STOP = 27,
|
||||
SAY_ORDER_BLOW = 28,
|
||||
SAY_TARGET_1 = 29,
|
||||
SAY_TARGET_2 = 30,
|
||||
SAY_TARGET_3 = 31,
|
||||
EMOTE_KRICK_MINES = 32,
|
||||
EMOTE_ICK_POISON = 33,
|
||||
};
|
||||
|
||||
#define EMOTE_ICK_CHASING "%s is chasing you!"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_TOXIC_WASTE = 69024,
|
||||
SPELL_MIGHTY_KICK = 69021,
|
||||
SPELL_SHADOW_BOLT = 69028,
|
||||
|
||||
SPELL_PURSUIT = 68987,
|
||||
|
||||
SPELL_POISON_NOVA = 68989,
|
||||
|
||||
SPELL_EXPLOSIVE_BARRAGE_KRICK = 69012,
|
||||
SPELL_EXPLOSIVE_BARRAGE_ICK = 69263,
|
||||
SPELL_EXPLOSIVE_BARRAGE_SUMMON = 69015,
|
||||
SPELL_EXPLODING_ORB_VISUAL = 69017,
|
||||
SPELL_AUTO_GROW = 69020,
|
||||
SPELL_HASTY_GROW = 44851,
|
||||
SPELL_EXPLOSIVE_BARRAGE_DAMAGE = 69019,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_TOXIC_WASTE = 1,
|
||||
EVENT_SPELL_MIGHTY_KICK,
|
||||
EVENT_SPELL_SHADOW_BOLT,
|
||||
EVENT_SPECIAL,
|
||||
EVENT_SET_REACT_AGGRESSIVE,
|
||||
};
|
||||
|
||||
class boss_ick : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_ick() : CreatureScript("boss_ick") { }
|
||||
|
||||
struct boss_ickAI : public ScriptedAI
|
||||
{
|
||||
boss_ickAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_ICK, NOT_STARTED);
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit* who) const
|
||||
{
|
||||
return pInstance && pInstance->GetData(DATA_INSTANCE_PROGRESS) >= INSTANCE_PROGRESS_FINISHED_INTRO;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (Creature* k = GetKrick())
|
||||
k->AI()->Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_TOXIC_WASTE, urand(3000,5000));
|
||||
events.RescheduleEvent(EVENT_SPELL_MIGHTY_KICK, urand(10000, 20000));
|
||||
events.RescheduleEvent(EVENT_SPELL_SHADOW_BOLT, 10000);
|
||||
events.RescheduleEvent(EVENT_SPECIAL, 25000);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_ICK, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
if (!target || !spell)
|
||||
return;
|
||||
if (spell->Id == SPELL_PURSUIT && target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
WorldPacket data;
|
||||
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, me, NULL, EMOTE_ICK_CHASING);
|
||||
target->ToPlayer()->GetSession()->SendPacket(&data);
|
||||
|
||||
AttackStart(target);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
events.RescheduleEvent(EVENT_SET_REACT_AGGRESSIVE, 12000);
|
||||
}
|
||||
}
|
||||
|
||||
Creature* GetKrick()
|
||||
{
|
||||
if (Vehicle* v = me->GetVehicleKit())
|
||||
if (Unit* p = v->GetPassenger(0))
|
||||
return p->ToCreature();
|
||||
return (Creature*)NULL;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*doneBy*/, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
if (Creature* krick = GetKrick())
|
||||
{
|
||||
krick->InterruptNonMeleeSpells(true);
|
||||
krick->RemoveAllAuras();
|
||||
Position myPos(*me), exitPos;
|
||||
float ang = me->GetOrientation()+3*M_PI/2;
|
||||
float dist = 3.0f;
|
||||
exitPos.Relocate(myPos.GetPositionX()+dist*cos(ang), myPos.GetPositionY()+dist*sin(ang), 515.0f, M_PI);
|
||||
exitPos.m_positionZ = me->GetMap()->GetHeight(exitPos.GetPositionX(), exitPos.GetPositionY(), exitPos.GetPositionZ());
|
||||
|
||||
if (exitPos.GetPositionZ() < 505.0f || exitPos.GetPositionZ() > 512.0f || !me->IsWithinLOS(exitPos.GetPositionX(), exitPos.GetPositionY(), exitPos.GetPositionZ()))
|
||||
exitPos.Relocate(myPos);
|
||||
|
||||
krick->_ExitVehicle(&exitPos);
|
||||
krick->AI()->DoAction(1);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetVictim())
|
||||
{
|
||||
float x,y,z;
|
||||
me->GetVictim()->GetPosition(x, y, z);
|
||||
if (KrickCenterPos.GetExactDist(x,y,z) > 80.0f || z > KrickCenterPos.GetPositionZ()+20.0f || z < KrickCenterPos.GetPositionZ()-20.0f)
|
||||
{
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
|
||||
return;
|
||||
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_TOXIC_WASTE:
|
||||
if (Creature* k = GetKrick())
|
||||
if (!k->HasUnitState(UNIT_STATE_CASTING))
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
|
||||
{
|
||||
k->CastSpell(target, SPELL_TOXIC_WASTE);
|
||||
events.RepeatEvent(urand(7000,10000));
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(2500);
|
||||
break;
|
||||
case EVENT_SPELL_MIGHTY_KICK:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MIGHTY_KICK, false);
|
||||
events.RepeatEvent(urand(20000,25000));
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_BOLT:
|
||||
if (Creature* k = GetKrick())
|
||||
if (!k->HasUnitState(UNIT_STATE_CASTING))
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.0f, true))
|
||||
{
|
||||
k->CastSpell(target, SPELL_SHADOW_BOLT);
|
||||
events.RepeatEvent(14000);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(2500);
|
||||
break;
|
||||
case EVENT_SET_REACT_AGGRESSIVE:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPECIAL:
|
||||
switch(urand(0,2))
|
||||
{
|
||||
case 0: // Pursuit
|
||||
if (Creature* k = GetKrick())
|
||||
k->AI()->Talk(RAND(SAY_TARGET_1, SAY_TARGET_2, SAY_TARGET_3));
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70.0f, true))
|
||||
me->CastSpell(target, SPELL_PURSUIT, false);
|
||||
break;
|
||||
case 1: // Poison Nova
|
||||
if (Creature* k = GetKrick())
|
||||
{
|
||||
k->AI()->Talk(SAY_ORDER_BLOW);
|
||||
Talk(EMOTE_ICK_POISON);
|
||||
}
|
||||
me->CastSpell(me, SPELL_POISON_NOVA, false);
|
||||
break;
|
||||
case 2: // Explosive Barrage
|
||||
if (Creature* k = GetKrick())
|
||||
{
|
||||
k->AI()->Talk(SAY_ORDER_STOP);
|
||||
k->AI()->Talk(EMOTE_KRICK_MINES);
|
||||
k->InterruptNonMeleeSpells(false);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
k->CastSpell(k, SPELL_EXPLOSIVE_BARRAGE_KRICK, false);
|
||||
me->CastSpell(me, SPELL_EXPLOSIVE_BARRAGE_ICK, false);
|
||||
}
|
||||
events.DelayEvents(20000);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(urand(25000,30000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_ICK, DONE);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
// if during pursuit ick kills his target, set to aggressive again
|
||||
if (who && me->GetVictim() && who->GetGUID() == me->GetVictim()->GetGUID())
|
||||
if (me->GetReactState() == REACT_PASSIVE)
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
if (Creature* k = GetKrick())
|
||||
k->AI()->Talk(RAND(SAY_SLAY_1, SAY_SLAY_2));
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_ickAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class boss_krick : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_krick() : CreatureScript("boss_krick") { }
|
||||
|
||||
struct boss_krickAI : public NullCreatureAI
|
||||
{
|
||||
boss_krickAI(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void DoAction(int32 a)
|
||||
{
|
||||
if (a==1)
|
||||
{
|
||||
me->setActive(true);
|
||||
events.RescheduleEvent(20, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 20:
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_INSTANCE_PROGRESS, INSTANCE_PROGRESS_FINISHED_KRICK_SCENE);
|
||||
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_LEADER_FIRST_GUID)))
|
||||
{
|
||||
c->GetMotionMaster()->Clear();
|
||||
c->UpdatePosition(SBSLeaderStartPos, true);
|
||||
c->StopMovingOnCurrentPos();
|
||||
c->AI()->Reset();
|
||||
}
|
||||
}
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(1, 3000);
|
||||
break;
|
||||
case 1:
|
||||
Talk(SAY_OUTRO_KRICK_1);
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_LEADER_FIRST_GUID)))
|
||||
{
|
||||
float angle = me->GetAngle(c);
|
||||
me->SetFacingTo(angle);
|
||||
float x = me->GetPositionX()+cos(angle)*7.0f;
|
||||
float y = me->GetPositionY()+sin(angle)*7.0f;
|
||||
c->GetMotionMaster()->MovePoint(0, x, y, me->GetPositionZ());
|
||||
}
|
||||
|
||||
for (uint8 i=0; i<2; ++i)
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_GUARD_1_GUID+i)))
|
||||
c->DespawnOrUnsummon();
|
||||
}
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(2, 7000);
|
||||
break;
|
||||
case 2:
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TYRANNUS_EVENT_GUID)))
|
||||
{
|
||||
c->setActive(true);
|
||||
c->UpdatePosition(SBSTyrannusStartPos, true);
|
||||
c->SetHomePosition(SBSTyrannusStartPos);
|
||||
}
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_LEADER_FIRST_GUID)))
|
||||
c->AI()->Talk(c->GetEntry() == NPC_JAINA_PART1 ? SAY_JAINA_KRICK_1 : SAY_SYLVANAS_KRICK_1);
|
||||
}
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(3, 6500);
|
||||
break;
|
||||
case 3:
|
||||
Talk(SAY_OUTRO_KRICK_2);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(4, 17000);
|
||||
break;
|
||||
case 4:
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TYRANNUS_EVENT_GUID)))
|
||||
c->GetMotionMaster()->MovePath(PATH_BEGIN_VALUE+10, false);
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_LEADER_FIRST_GUID)))
|
||||
c->AI()->Talk(c->GetEntry() == NPC_JAINA_PART1 ? SAY_JAINA_KRICK_2 : SAY_SYLVANAS_KRICK_2);
|
||||
}
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(5, 6500);
|
||||
break;
|
||||
case 5:
|
||||
Talk(SAY_OUTRO_KRICK_3);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(6, 6500);
|
||||
break;
|
||||
case 6:
|
||||
if (pInstance)
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TYRANNUS_EVENT_GUID)))
|
||||
{
|
||||
c->SetFacingToObject(me);
|
||||
c->AI()->Talk(SAY_TYRANNUS_KRICK_1);
|
||||
}
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(7, 4000);
|
||||
break;
|
||||
case 7:
|
||||
me->CastSpell(me, 69413, true);
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
me->SetCanFly(true);
|
||||
me->SetDisableGravity(true);
|
||||
me->SendMovementFlagUpdate();
|
||||
me->GetMotionMaster()->MoveTakeoff(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+9.0f, 0.5f * 7.0f);
|
||||
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(8, 2000);
|
||||
break;
|
||||
case 8:
|
||||
Talk(SAY_OUTRO_KRICK_4);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(9, 1500);
|
||||
break;
|
||||
case 9:
|
||||
if (pInstance)
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TYRANNUS_EVENT_GUID)))
|
||||
c->CastSpell(c, 69753, false);
|
||||
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29 | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
|
||||
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
|
||||
me->AddUnitState(UNIT_STATE_DIED);
|
||||
|
||||
me->CastSpell(me, SPELL_KRICK_KILL_CREDIT, true);
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->GetMotionMaster()->MoveFall(0, true);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(10, 5000);
|
||||
break;
|
||||
case 10:
|
||||
if (pInstance)
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TYRANNUS_EVENT_GUID)))
|
||||
c->AI()->Talk(SAY_TYRANNUS_KRICK_2);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(11, 9000);
|
||||
break;
|
||||
case 11:
|
||||
if (pInstance)
|
||||
{
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_TYRANNUS_EVENT_GUID)))
|
||||
c->GetMotionMaster()->MovePoint(1, 809.39f, 74.69f, 541.54f);
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_LEADER_FIRST_GUID)))
|
||||
{
|
||||
c->AI()->Talk(c->GetEntry() == NPC_JAINA_PART1 ? SAY_JAINA_KRICK_3 : SAY_SYLVANAS_KRICK_3);
|
||||
c->GetMotionMaster()->MovePath(PATH_BEGIN_VALUE+11, false);
|
||||
}
|
||||
}
|
||||
me->setActive(false);
|
||||
Unit::Kill(me, me);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_krickAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_krick_explosive_barrage : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_krick_explosive_barrage() : SpellScriptLoader("spell_krick_explosive_barrage") { }
|
||||
|
||||
class spell_krick_explosive_barrage_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_krick_explosive_barrage_AuraScript);
|
||||
|
||||
void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (Unit* caster = GetCaster())
|
||||
if (caster->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
Map::PlayerList const &players = caster->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
if (player->IsWithinDist(caster, 100.0f))
|
||||
caster->CastSpell(player, SPELL_EXPLOSIVE_BARRAGE_SUMMON, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_krick_explosive_barrage_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_krick_explosive_barrage_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_exploding_orb_auto_grow : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_exploding_orb_auto_grow() : SpellScriptLoader("spell_exploding_orb_auto_grow") { }
|
||||
|
||||
class spell_exploding_orb_auto_grow_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_exploding_orb_auto_grow_AuraScript);
|
||||
|
||||
void HandlePeriodicTick(AuraEffect const* aurEff)
|
||||
{
|
||||
if (aurEff->GetTickNumber() >= 16)
|
||||
if (Unit* target = GetTarget())
|
||||
{
|
||||
PreventDefaultAction();
|
||||
target->CastSpell(target, SPELL_EXPLOSIVE_BARRAGE_DAMAGE, false);
|
||||
target->RemoveAurasDueToSpell(SPELL_HASTY_GROW);
|
||||
target->RemoveAurasDueToSpell(SPELL_AUTO_GROW);
|
||||
target->RemoveAurasDueToSpell(SPELL_EXPLODING_ORB_VISUAL);
|
||||
if (target->GetTypeId() == TYPEID_UNIT)
|
||||
target->ToCreature()->DespawnOrUnsummon(2000);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_exploding_orb_auto_grow_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_exploding_orb_auto_grow_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_ick()
|
||||
{
|
||||
new boss_ick();
|
||||
new boss_krick();
|
||||
|
||||
new spell_krick_explosive_barrage();
|
||||
new spell_exploding_orb_auto_grow();
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "pit_of_saron.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 53,
|
||||
SAY_SLAY_1 = 54,
|
||||
SAY_SLAY_2 = 55,
|
||||
SAY_DEATH = 56,
|
||||
SAY_MARK = 57,
|
||||
SAY_SMASH = 58,
|
||||
EMOTE_RIMEFANG_ICEBOLT = 59,
|
||||
EMOTE_SMASH = 60,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_OVERLORDS_BRAND = 69172,
|
||||
SPELL_OVERLORDS_BRAND_HEAL = 69190,
|
||||
SPELL_OVERLORDS_BRAND_DAMAGE = 69189,
|
||||
SPELL_FORCEFUL_SMASH = 69155,
|
||||
SPELL_UNHOLY_POWER = 69167,
|
||||
RIMEFANG_SPELL_ICY_BLAST = 69232,
|
||||
SPELL_MARK_OF_RIMEFANG = 69275,
|
||||
RIMEFANG_SPELL_HOARFROST = 69246,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_FORCEFUL_SMASH = 1,
|
||||
EVENT_SPELL_UNHOLY_POWER,
|
||||
EVENT_SPELL_OVERLORDS_BRAND,
|
||||
EVENT_RIMEFANG_SPELL_ICY_BLAST,
|
||||
EVENT_SPELL_MARK_OF_RIMEFANG,
|
||||
};
|
||||
|
||||
class boss_tyrannus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_tyrannus() : CreatureScript("boss_tyrannus") { }
|
||||
|
||||
struct boss_tyrannusAI : public ScriptedAI
|
||||
{
|
||||
boss_tyrannusAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_RIMEFANG_GUID)))
|
||||
{
|
||||
c->SetCanFly(true);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
if (me->HasReactState(REACT_AGGRESSIVE)) // Reset() called by EnterEvadeMode()
|
||||
{
|
||||
if (!pInstance)
|
||||
return;
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_MARTIN_OR_GORKUN_GUID)))
|
||||
{
|
||||
c->AI()->DoAction(1);
|
||||
c->DespawnOrUnsummon();
|
||||
pInstance->SetData64(DATA_MARTIN_OR_GORKUN_GUID, 0);
|
||||
}
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_RIMEFANG_GUID)))
|
||||
{
|
||||
c->GetMotionMaster()->Clear();
|
||||
c->GetMotionMaster()->MoveIdle();
|
||||
|
||||
c->RemoveAllAuras();
|
||||
c->UpdatePosition(1017.3f, 168.974f, 642.926f, 5.2709f, true);
|
||||
c->StopMovingOnCurrentPos();
|
||||
if (Vehicle* v = c->GetVehicleKit())
|
||||
v->InstallAllAccessories(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == 1)
|
||||
{
|
||||
Position exitPos = {1023.46f, 159.12f, 628.2f, 5.23f};
|
||||
me->RemoveAllAuras();
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_RIMEFANG_GUID)))
|
||||
{
|
||||
c->RemoveAura(46598);
|
||||
c->GetMotionMaster()->Clear();
|
||||
c->GetMotionMaster()->MovePath(PATH_BEGIN_VALUE+18, true);
|
||||
}
|
||||
me->SetHomePosition(exitPos);
|
||||
me->GetMotionMaster()->MoveJump(exitPos, 10.0f, 2.0f);
|
||||
|
||||
// start real fight
|
||||
DoZoneInCombat();
|
||||
me->CastSpell(me, 43979, true);
|
||||
Talk(SAY_AGGRO);
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_SPELL_FORCEFUL_SMASH, urand(14000,16000));
|
||||
events.RescheduleEvent(EVENT_SPELL_OVERLORDS_BRAND, urand(4000,6000));
|
||||
events.RescheduleEvent(EVENT_RIMEFANG_SPELL_ICY_BLAST, 5000);
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_OF_RIMEFANG, 25000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->GetVictim())
|
||||
{
|
||||
float x,y,z;
|
||||
me->GetVictim()->GetPosition(x, y, z);
|
||||
if (TSDistCheckPos.GetExactDist(x,y,z) > 100.0f || z > TSDistCheckPos.GetPositionZ()+20.0f || z < TSDistCheckPos.GetPositionZ()-20.0f)
|
||||
{
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_SPELL_FORCEFUL_SMASH:
|
||||
if (me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_FORCEFUL_SMASH, false);
|
||||
events.PopEvent();
|
||||
events.RescheduleEvent(EVENT_SPELL_UNHOLY_POWER, 1000);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(3000);
|
||||
break;
|
||||
case EVENT_SPELL_UNHOLY_POWER:
|
||||
Talk(SAY_SMASH);
|
||||
Talk(EMOTE_SMASH);
|
||||
me->CastSpell(me, SPELL_UNHOLY_POWER, false);
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_SPELL_FORCEFUL_SMASH, urand(40000, 48000));
|
||||
break;
|
||||
case EVENT_SPELL_OVERLORDS_BRAND:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 95.0f, true))
|
||||
me->CastSpell(target, SPELL_OVERLORDS_BRAND, false);
|
||||
events.RepeatEvent(urand(11000,12000));
|
||||
break;
|
||||
case EVENT_RIMEFANG_SPELL_ICY_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 190.0f, true))
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_RIMEFANG_GUID)))
|
||||
c->CastSpell(target, RIMEFANG_SPELL_ICY_BLAST, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
case EVENT_SPELL_MARK_OF_RIMEFANG:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 190.0f, true))
|
||||
if (Creature* c = pInstance->instance->GetCreature(pInstance->GetData64(DATA_RIMEFANG_GUID)))
|
||||
{
|
||||
Talk(SAY_MARK);
|
||||
c->AI()->Talk(EMOTE_RIMEFANG_ICEBOLT, target);
|
||||
c->CastSpell(target, RIMEFANG_SPELL_HOARFROST, false);
|
||||
}
|
||||
events.RepeatEvent(25000);
|
||||
events.RescheduleEvent(EVENT_RIMEFANG_SPELL_ICY_BLAST, 10000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_TYRANNUS, DONE);
|
||||
if (me->IsSummon())
|
||||
me->ToTempSummon()->SetTempSummonType(TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(RAND(SAY_SLAY_1,SAY_SLAY_2));
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit* who) const
|
||||
{
|
||||
switch (who->GetEntry())
|
||||
{
|
||||
case NPC_MARTIN_VICTUS_2:
|
||||
case NPC_GORKUN_IRONSKULL_2:
|
||||
case NPC_FREED_SLAVE_1_ALLIANCE:
|
||||
case NPC_FREED_SLAVE_2_ALLIANCE:
|
||||
case NPC_FREED_SLAVE_3_ALLIANCE:
|
||||
case NPC_FREED_SLAVE_1_HORDE:
|
||||
case NPC_FREED_SLAVE_2_HORDE:
|
||||
case NPC_FREED_SLAVE_3_HORDE:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_tyrannusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_tyrannus()
|
||||
{
|
||||
new boss_tyrannus();
|
||||
}
|
||||
@@ -1,437 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "pit_of_saron.h"
|
||||
#include "Player.h"
|
||||
|
||||
class instance_pit_of_saron : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_pit_of_saron() : InstanceMapScript("instance_pit_of_saron", 658) { }
|
||||
|
||||
struct instance_pit_of_saron_InstanceScript : public InstanceScript
|
||||
{
|
||||
instance_pit_of_saron_InstanceScript(Map* map) : InstanceScript(map) {}
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
TeamId teamIdInInstance;
|
||||
uint32 InstanceProgress;
|
||||
std::string str_data;
|
||||
|
||||
uint64 NPC_LeaderFirstGUID;
|
||||
uint64 NPC_LeaderSecondGUID;
|
||||
uint64 NPC_TyrannusEventGUID;
|
||||
uint64 NPC_Necrolyte1GUID;
|
||||
uint64 NPC_Necrolyte2GUID;
|
||||
uint64 NPC_GuardFirstGUID;
|
||||
uint64 NPC_GuardSecondGUID;
|
||||
uint64 NPC_SindragosaGUID;
|
||||
|
||||
uint64 NPC_GarfrostGUID;
|
||||
uint64 NPC_MartinOrGorkunGUID;
|
||||
uint64 NPC_RimefangGUID;
|
||||
uint64 NPC_TyrannusGUID;
|
||||
|
||||
uint64 GO_IceWallGUID;
|
||||
|
||||
bool bAchievEleven;
|
||||
bool bAchievDontLookUp;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
teamIdInInstance = TEAM_NEUTRAL;
|
||||
InstanceProgress = INSTANCE_PROGRESS_NONE;
|
||||
|
||||
NPC_LeaderFirstGUID = 0;
|
||||
NPC_LeaderSecondGUID = 0;
|
||||
NPC_TyrannusEventGUID = 0;
|
||||
NPC_Necrolyte1GUID = 0;
|
||||
NPC_Necrolyte2GUID = 0;
|
||||
NPC_GuardFirstGUID = 0;
|
||||
NPC_GuardSecondGUID = 0;
|
||||
NPC_SindragosaGUID = 0;
|
||||
|
||||
NPC_GarfrostGUID = 0;
|
||||
NPC_MartinOrGorkunGUID = 0;
|
||||
NPC_RimefangGUID = 0;
|
||||
NPC_TyrannusGUID = 0;
|
||||
|
||||
GO_IceWallGUID = 0;
|
||||
|
||||
bAchievEleven = true;
|
||||
bAchievDontLookUp = true;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* plr)
|
||||
{
|
||||
instance->LoadGrid(LeaderIntroPos.GetPositionX(), LeaderIntroPos.GetPositionY());
|
||||
}
|
||||
|
||||
uint32 GetCreatureEntry(uint32 /*guidLow*/, CreatureData const* data)
|
||||
{
|
||||
if (teamIdInInstance == TEAM_NEUTRAL)
|
||||
{
|
||||
Map::PlayerList const &players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
if (Player* player = players.begin()->GetSource())
|
||||
teamIdInInstance = player->GetTeamId();
|
||||
}
|
||||
|
||||
uint32 entry = data->id;
|
||||
switch (entry)
|
||||
{
|
||||
case NPC_RESCUED_ALLIANCE_SLAVE:
|
||||
if (teamIdInInstance == TEAM_HORDE)
|
||||
return 0;
|
||||
break;
|
||||
case NPC_RESCUED_HORDE_SLAVE:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
if (teamIdInInstance == TEAM_NEUTRAL)
|
||||
{
|
||||
Map::PlayerList const &players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
if (Player* player = players.begin()->GetSource())
|
||||
teamIdInInstance = player->GetTeamId();
|
||||
}
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_SYLVANAS_PART1:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_JAINA_PART1);
|
||||
NPC_LeaderFirstGUID = creature->GetGUID();
|
||||
|
||||
switch (InstanceProgress)
|
||||
{
|
||||
case INSTANCE_PROGRESS_FINISHED_INTRO:
|
||||
creature->SetPosition(LeaderIntroPos);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_FINISHED_KRICK_SCENE:
|
||||
case INSTANCE_PROGRESS_AFTER_WARN_1:
|
||||
case INSTANCE_PROGRESS_AFTER_WARN_2:
|
||||
case INSTANCE_PROGRESS_AFTER_TUNNEL_WARN:
|
||||
case INSTANCE_PROGRESS_TYRANNUS_INTRO:
|
||||
creature->SetPosition(SBSLeaderEndPos);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NPC_SYLVANAS_PART2:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_JAINA_PART2);
|
||||
NPC_LeaderSecondGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_TYRANNUS_EVENT:
|
||||
if (!NPC_TyrannusEventGUID)
|
||||
{
|
||||
switch (InstanceProgress)
|
||||
{
|
||||
case INSTANCE_PROGRESS_FINISHED_INTRO:
|
||||
creature->SetPosition(SBSTyrannusStartPos);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_FINISHED_KRICK_SCENE:
|
||||
creature->SetPosition(PTSTyrannusWaitPos1);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_AFTER_WARN_1:
|
||||
creature->SetPosition(PTSTyrannusWaitPos2);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_AFTER_WARN_2:
|
||||
creature->SetPosition(PTSTyrannusWaitPos3);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_AFTER_TUNNEL_WARN:
|
||||
case INSTANCE_PROGRESS_TYRANNUS_INTRO:
|
||||
creature->SetPosition(SBSTyrannusStartPos);
|
||||
break;
|
||||
}
|
||||
NPC_TyrannusEventGUID = creature->GetGUID();
|
||||
|
||||
}
|
||||
break;
|
||||
case NPC_LORALEN:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_ELANDRA);
|
||||
if (!NPC_GuardFirstGUID)
|
||||
NPC_GuardFirstGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_KALIRA:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_KORELN);
|
||||
if (!NPC_GuardSecondGUID)
|
||||
NPC_GuardSecondGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HORDE_SLAVE_1:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_ALLIANCE_SLAVE_1);
|
||||
break;
|
||||
case NPC_HORDE_SLAVE_2:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_ALLIANCE_SLAVE_2);
|
||||
break;
|
||||
case NPC_HORDE_SLAVE_3:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_ALLIANCE_SLAVE_3);
|
||||
break;
|
||||
case NPC_HORDE_SLAVE_4:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_ALLIANCE_SLAVE_4);
|
||||
break;
|
||||
case NPC_GORKUN_IRONSKULL_1:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_MARTIN_VICTUS_1);
|
||||
break;
|
||||
case NPC_GARFROST:
|
||||
NPC_GarfrostGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_FREED_SLAVE_1_HORDE:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_FREED_SLAVE_1_ALLIANCE);
|
||||
break;
|
||||
case NPC_FREED_SLAVE_2_HORDE:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_FREED_SLAVE_2_ALLIANCE);
|
||||
break;
|
||||
case NPC_FREED_SLAVE_3_HORDE:
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_FREED_SLAVE_3_ALLIANCE);
|
||||
break;
|
||||
case NPC_GORKUN_IRONSKULL_2:
|
||||
if (NPC_MartinOrGorkunGUID)
|
||||
if (Creature* c = instance->GetCreature(NPC_MartinOrGorkunGUID))
|
||||
{
|
||||
c->AI()->DoAction(1); // despawn summons
|
||||
c->DespawnOrUnsummon();
|
||||
}
|
||||
if (teamIdInInstance == TEAM_ALLIANCE)
|
||||
creature->UpdateEntry(NPC_MARTIN_VICTUS_2);
|
||||
NPC_MartinOrGorkunGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_RIMEFANG:
|
||||
NPC_RimefangGUID = creature->GetGUID();
|
||||
if (m_auiEncounter[2] == DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_TYRANNUS:
|
||||
if (NPC_TyrannusGUID)
|
||||
if (Creature* c = instance->GetCreature(NPC_TyrannusGUID))
|
||||
c->DespawnOrUnsummon();
|
||||
NPC_TyrannusGUID = creature->GetGUID();
|
||||
|
||||
if (m_auiEncounter[2] == DONE)
|
||||
creature->SetVisible(false);
|
||||
break;
|
||||
case NPC_SINDRAGOSA:
|
||||
NPC_SindragosaGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_ICE_WALL:
|
||||
GO_IceWallGUID = go->GetGUID();
|
||||
if (GetData(DATA_GARFROST) == DONE && GetData(DATA_ICK) == DONE)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_INSTANCE_PROGRESS:
|
||||
if (InstanceProgress < data)
|
||||
{
|
||||
InstanceProgress = data;
|
||||
if (InstanceProgress == INSTANCE_PROGRESS_TYRANNUS_INTRO && instance->GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC && bAchievDontLookUp) // achiev Don't Look Up (4525)
|
||||
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 72845);
|
||||
}
|
||||
break;
|
||||
case DATA_GARFROST:
|
||||
m_auiEncounter[0] = data;
|
||||
if (data == DONE)
|
||||
instance->SummonCreature(NPC_GORKUN_IRONSKULL_1, FBSSpawnPos);
|
||||
else // NOT_STARTED, IN_PROGRESS
|
||||
bAchievEleven = true;
|
||||
if (data == DONE && GetData(DATA_ICK) == DONE)
|
||||
if (GameObject* icewall = instance->GetGameObject(GO_IceWallGUID))
|
||||
icewall->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case DATA_ICK:
|
||||
m_auiEncounter[1] = data;
|
||||
if (data == DONE && GetData(DATA_GARFROST) == DONE)
|
||||
if (GameObject* icewall = instance->GetGameObject(GO_IceWallGUID))
|
||||
icewall->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case DATA_TYRANNUS:
|
||||
m_auiEncounter[2] = data;
|
||||
if (data == DONE)
|
||||
instance->SummonCreature(NPC_SYLVANAS_PART2, TSLeaderSpawnPos);
|
||||
break;
|
||||
case DATA_ACHIEV_ELEVEN:
|
||||
bAchievEleven = false;
|
||||
break;
|
||||
case DATA_ACHIEV_DONT_LOOK_UP:
|
||||
bAchievDontLookUp = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE || type == DATA_INSTANCE_PROGRESS)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_NECROLYTE_1_GUID:
|
||||
NPC_Necrolyte1GUID = data;
|
||||
break;
|
||||
case DATA_NECROLYTE_2_GUID:
|
||||
NPC_Necrolyte2GUID = data;
|
||||
break;
|
||||
case DATA_MARTIN_OR_GORKUN_GUID:
|
||||
NPC_MartinOrGorkunGUID = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_INSTANCE_PROGRESS:
|
||||
return InstanceProgress;
|
||||
case DATA_TEAMID_IN_INSTANCE:
|
||||
return teamIdInInstance;
|
||||
case DATA_GARFROST:
|
||||
return m_auiEncounter[0];
|
||||
case DATA_ICK:
|
||||
return m_auiEncounter[1];
|
||||
case DATA_TYRANNUS:
|
||||
return m_auiEncounter[2];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_TYRANNUS_EVENT_GUID:
|
||||
return NPC_TyrannusEventGUID;
|
||||
case DATA_NECROLYTE_1_GUID:
|
||||
return NPC_Necrolyte1GUID;
|
||||
case DATA_NECROLYTE_2_GUID:
|
||||
return NPC_Necrolyte2GUID;
|
||||
case DATA_GUARD_1_GUID:
|
||||
return NPC_GuardFirstGUID;
|
||||
case DATA_GUARD_2_GUID:
|
||||
return NPC_GuardSecondGUID;
|
||||
case DATA_LEADER_FIRST_GUID:
|
||||
return NPC_LeaderFirstGUID;
|
||||
case DATA_GARFROST_GUID:
|
||||
return NPC_GarfrostGUID;
|
||||
case DATA_MARTIN_OR_GORKUN_GUID:
|
||||
return NPC_MartinOrGorkunGUID;
|
||||
case DATA_RIMEFANG_GUID:
|
||||
return NPC_RimefangGUID;
|
||||
case DATA_TYRANNUS_GUID:
|
||||
return NPC_TyrannusGUID;
|
||||
case DATA_LEADER_SECOND_GUID:
|
||||
return NPC_LeaderSecondGUID;
|
||||
case DATA_SINDRAGOSA_GUID:
|
||||
return NPC_SindragosaGUID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
|
||||
{
|
||||
switch(criteria_id)
|
||||
{
|
||||
case 12993: // Doesn't Go to Eleven (4524)
|
||||
return bAchievEleven;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "P S " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' << InstanceProgress;
|
||||
str_data = saveStream.str();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return str_data;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1, data2, data3;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
|
||||
|
||||
if (dataHead1 == 'P' && dataHead2 == 'S')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
m_auiEncounter[2] = data2;
|
||||
InstanceProgress = data3;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_pit_of_saron_InstanceScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_pit_of_saron()
|
||||
{
|
||||
new instance_pit_of_saron();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_PIT_OF_SARON_H
|
||||
#define DEF_PIT_OF_SARON_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_GARFROST,
|
||||
DATA_ICK,
|
||||
DATA_TYRANNUS,
|
||||
MAX_ENCOUNTER,
|
||||
|
||||
DATA_INSTANCE_PROGRESS,
|
||||
DATA_TEAMID_IN_INSTANCE,
|
||||
DATA_TYRANNUS_EVENT_GUID,
|
||||
DATA_NECROLYTE_1_GUID,
|
||||
DATA_NECROLYTE_2_GUID,
|
||||
DATA_GUARD_1_GUID,
|
||||
DATA_GUARD_2_GUID,
|
||||
DATA_LEADER_FIRST_GUID,
|
||||
DATA_GARFROST_GUID,
|
||||
DATA_MARTIN_OR_GORKUN_GUID,
|
||||
DATA_RIMEFANG_GUID,
|
||||
DATA_TYRANNUS_GUID,
|
||||
DATA_LEADER_SECOND_GUID,
|
||||
DATA_SINDRAGOSA_GUID,
|
||||
DATA_ACHIEV_ELEVEN,
|
||||
DATA_ACHIEV_DONT_LOOK_UP,
|
||||
DATA_START_INTRO,
|
||||
};
|
||||
|
||||
enum InstanceProgressConst
|
||||
{
|
||||
INSTANCE_PROGRESS_NONE,
|
||||
INSTANCE_PROGRESS_FINISHED_INTRO,
|
||||
INSTANCE_PROGRESS_FINISHED_KRICK_SCENE,
|
||||
INSTANCE_PROGRESS_AFTER_WARN_1,
|
||||
INSTANCE_PROGRESS_AFTER_WARN_2,
|
||||
INSTANCE_PROGRESS_AFTER_TUNNEL_WARN,
|
||||
INSTANCE_PROGRESS_TYRANNUS_INTRO,
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_GARFROST = 36494,
|
||||
NPC_KRICK = 36477,
|
||||
NPC_ICK = 36476,
|
||||
NPC_TYRANNUS = 36658,
|
||||
NPC_RIMEFANG = 36661,
|
||||
NPC_SINDRAGOSA = 37755,
|
||||
|
||||
NPC_TYRANNUS_EVENT = 36794,
|
||||
NPC_TYRANNUS_VOICE = 36795,
|
||||
NPC_SYLVANAS_PART1 = 36990,
|
||||
NPC_SYLVANAS_PART2 = 38189,
|
||||
NPC_JAINA_PART1 = 36993,
|
||||
NPC_JAINA_PART2 = 38188,
|
||||
|
||||
NPC_KALIRA = 37583,
|
||||
NPC_ELANDRA = 37774,
|
||||
NPC_LORALEN = 37779,
|
||||
NPC_KORELN = 37582,
|
||||
|
||||
NPC_CHAMPION_1_HORDE = 37584,
|
||||
NPC_CHAMPION_2_HORDE = 37587,
|
||||
NPC_CHAMPION_3_HORDE = 37588,
|
||||
NPC_CHAMPION_1_ALLIANCE = 37496,
|
||||
NPC_CHAMPION_2_ALLIANCE = 37497,
|
||||
|
||||
NPC_HORDE_SLAVE_1 = 36770,
|
||||
NPC_HORDE_SLAVE_2 = 36771,
|
||||
NPC_HORDE_SLAVE_3 = 36772,
|
||||
NPC_HORDE_SLAVE_4 = 36773,
|
||||
NPC_ALLIANCE_SLAVE_1 = 36764,
|
||||
NPC_ALLIANCE_SLAVE_2 = 36765,
|
||||
NPC_ALLIANCE_SLAVE_3 = 36766,
|
||||
NPC_ALLIANCE_SLAVE_4 = 36767,
|
||||
|
||||
NPC_RESCUED_ALLIANCE_SLAVE = 36888,
|
||||
NPC_RESCUED_HORDE_SLAVE = 36889,
|
||||
|
||||
NPC_YMIRJAR_DEATHBRINGER = 36892,
|
||||
NPC_YMIRJAR_WRATHBRINGER = 36840,
|
||||
NPC_YMIRJAR_FLAMEBEARER = 36893,
|
||||
|
||||
NPC_FALLEN_WARRIOR = 36841,
|
||||
NPC_WRATHBONE_COLDWRAITH = 36842,
|
||||
|
||||
NPC_MARTIN_VICTUS_1 = 37591,
|
||||
NPC_GORKUN_IRONSKULL_1 = 37592,
|
||||
|
||||
NPC_MARTIN_VICTUS_2 = 37580,
|
||||
NPC_GORKUN_IRONSKULL_2 = 37581,
|
||||
NPC_FREED_SLAVE_1_ALLIANCE = 37576, // mage
|
||||
NPC_FREED_SLAVE_2_ALLIANCE = 37575, // warr
|
||||
NPC_FREED_SLAVE_3_ALLIANCE = 37572, // warr
|
||||
NPC_FREED_SLAVE_1_HORDE = 37579, // mage
|
||||
NPC_FREED_SLAVE_2_HORDE = 37578, // warr
|
||||
NPC_FREED_SLAVE_3_HORDE = 37577, // warr
|
||||
};
|
||||
|
||||
enum GameObjectIds
|
||||
{
|
||||
GO_HOR_PORTCULLIS = 201848,
|
||||
GO_ICE_WALL = 201885,
|
||||
};
|
||||
|
||||
enum eSpells
|
||||
{
|
||||
SPELL_NECROLYTE_CHANNELING = 30540,
|
||||
SPELL_KRICK_KILL_CREDIT = 71308,
|
||||
SPELL_TUNNEL_ICICLE = 69424,
|
||||
SPELL_TELEPORT_JAINA_VISUAL = 70623,
|
||||
SPELL_TELEPORT_JAINA = 70525,
|
||||
SPELL_TELEPORT_SYLVANAS_VISUAL = 70638,
|
||||
SPELL_TELEPORT_SYLVANAS = 70639,
|
||||
SPELL_SINDRAGOSA_FROST_BOMB_POS = 70521,
|
||||
};
|
||||
|
||||
#define PATH_BEGIN_VALUE 3000200
|
||||
|
||||
/************
|
||||
*** INTRO:
|
||||
************/
|
||||
|
||||
enum eIntroTexts
|
||||
{
|
||||
SAY_TYRANNUS_INTRO_1 = 1,
|
||||
SAY_JAINA_INTRO_1 = 2,
|
||||
SAY_SYLVANAS_INTRO_1 = 3,
|
||||
SAY_TYRANNUS_INTRO_2 = 4,
|
||||
SAY_TYRANNUS_INTRO_3 = 5,
|
||||
SAY_JAINA_INTRO_2 = 6,
|
||||
SAY_SYLVANAS_INTRO_2 = 7,
|
||||
SAY_TYRANNUS_INTRO_4 = 8,
|
||||
SAY_JAINA_INTRO_3 = 9,
|
||||
SAY_JAINA_INTRO_4 = 10,
|
||||
SAY_SYLVANAS_INTRO_3 = 11,
|
||||
SAY_JAINA_INTRO_5 = 12,
|
||||
SAY_SYLVANAS_INTRO_4 = 13,
|
||||
};
|
||||
|
||||
const Position PortalPos = {424.46f, 212.16f, 528.8f, 0.0f};
|
||||
const Position LeaderIntroPos = {440.788f, 213.76f, 528.711f, 0.0f};
|
||||
const Position NecrolytePos1 = {506.304f, 211.78f, 528.71f, M_PI};
|
||||
const Position NecrolytePos2 = {506.127f, 231.46f, 528.71f, M_PI};
|
||||
|
||||
struct ChampionPosition
|
||||
{
|
||||
uint32 entry[2];
|
||||
Position endPosition;
|
||||
};
|
||||
|
||||
const ChampionPosition introPositions[] =
|
||||
{
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 452.884f, 209.141f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 450.541f, 212.28f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 449.835f, 206.68f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 446.542f, 209.986f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 447.29f, 213.916f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE }, { 445.794f, 206.057f, 528.84f, 0.0f } },
|
||||
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 446.74f, 228.577f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 449.19f, 226.21f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 447.352f, 222.754f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 443.346f, 192.343f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 446.293f, 195.047f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE }, { 444.035f, 197.67f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 442.69f, 223.525f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 442.967f, 219.535f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 442.526f, 199.361f, 528.84f, 0.0f } },
|
||||
{ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE }, { 442.843f, 203.193f, 528.84f, 0.0f } },
|
||||
|
||||
{ { NPC_LORALEN, NPC_LORALEN }, { 438.505f, 211.54f, 528.71f, 0.0f } },
|
||||
{ { NPC_LORALEN, NPC_KALIRA }, { 438.946f, 215.427f, 528.71f, 0.0f } },
|
||||
|
||||
{ { 0, 0 }, { 0.0f, 0.0f, 0.0f, 0.0f } }
|
||||
};
|
||||
|
||||
/************
|
||||
*** FIRST BOSS SCENE:
|
||||
************/
|
||||
|
||||
enum eFBSTexts
|
||||
{
|
||||
SAY_GENERAL_GARFROST = 21,
|
||||
SAY_TYRANNUS_GARFROST = 20,
|
||||
};
|
||||
|
||||
const Position FBSSpawnPos = {695.685f, -118.825f, 513.877f, 3*M_PI/2};
|
||||
|
||||
struct FBSPosition
|
||||
{
|
||||
uint32 entry;
|
||||
uint32 pathId;
|
||||
};
|
||||
|
||||
const FBSPosition FBSData[] =
|
||||
{
|
||||
{ NPC_HORDE_SLAVE_1, PATH_BEGIN_VALUE+0 },
|
||||
{ NPC_HORDE_SLAVE_1, PATH_BEGIN_VALUE+1 },
|
||||
{ NPC_HORDE_SLAVE_2, PATH_BEGIN_VALUE+2 },
|
||||
{ NPC_HORDE_SLAVE_2, PATH_BEGIN_VALUE+3 },
|
||||
{ NPC_HORDE_SLAVE_2, PATH_BEGIN_VALUE+4 },
|
||||
{ NPC_HORDE_SLAVE_3, PATH_BEGIN_VALUE+5 },
|
||||
{ NPC_HORDE_SLAVE_3, PATH_BEGIN_VALUE+6 },
|
||||
{ NPC_HORDE_SLAVE_4, PATH_BEGIN_VALUE+7 },
|
||||
{ NPC_HORDE_SLAVE_4, PATH_BEGIN_VALUE+8 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/************
|
||||
*** SECOND BOSS SCENE:
|
||||
************/
|
||||
|
||||
const Position KrickCenterPos = {836.65f, 115.08f, 510.0f, 0.0f};
|
||||
const Position SBSTyrannusStartPos = {781.127f, 265.825f, 552.31f, 0.0f};
|
||||
const Position SBSLeaderStartPos = {772.716f, 111.517f, 510.81f, 0.0f};
|
||||
const Position SBSLeaderEndPos = {823.2f, -4.4497f, 509.49f, 0.86f};
|
||||
|
||||
enum eSBSTexts
|
||||
{
|
||||
SAY_OUTRO_KRICK_1 = 35,
|
||||
SAY_JAINA_KRICK_1 = 36,
|
||||
SAY_SYLVANAS_KRICK_1 = 37,
|
||||
SAY_OUTRO_KRICK_2 = 38,
|
||||
SAY_JAINA_KRICK_2 = 39,
|
||||
SAY_SYLVANAS_KRICK_2 = 40,
|
||||
SAY_OUTRO_KRICK_3 = 41,
|
||||
SAY_TYRANNUS_KRICK_1 = 42,
|
||||
SAY_OUTRO_KRICK_4 = 43,
|
||||
SAY_TYRANNUS_KRICK_2 = 44,
|
||||
SAY_JAINA_KRICK_3 = 45,
|
||||
SAY_SYLVANAS_KRICK_3 = 46,
|
||||
};
|
||||
|
||||
/************
|
||||
*** PRE_TYRANNUS SCENES (WAVES OF TRASH):
|
||||
************/
|
||||
|
||||
const Position PTSTyrannusWaitPos1 = {923.45f, 82.65f, 582.44f, 3.59f};
|
||||
const Position PTSTyrannusWaitPos2 = {907.27f, -53.86f, 617.31f, 1.69f};
|
||||
const Position PTSTyrannusWaitPos3 = {1117.93f, -125.16f, 760.34f, 0.10f};
|
||||
|
||||
enum ePTSTexts
|
||||
{
|
||||
SAY_TYRANNUS_AMBUSH_1 = 47,
|
||||
SAY_TYRANNUS_AMBUSH_2 = 48,
|
||||
SAY_TYRANNUS_TRAP_TUNNEL = 49,
|
||||
};
|
||||
|
||||
/************
|
||||
*** TYRANNUS SCENE:
|
||||
************/
|
||||
|
||||
const Position TSSpawnPos = {1069.49f, 88.99f, 631.5f, 2.0f};
|
||||
const Position TSMidPos = {1051.475f, 126.56f, 628.157f, 2.02f};
|
||||
const float TSHeight = 628.157f;
|
||||
const Position TSLeaderSpawnPos = {1064.3761f, 99.10f, 631.0f, 2.1f};
|
||||
const Position TSCenterPos = {990.48f, 165.37f, 628.157f, 5.7f};
|
||||
const Position TSDistCheckPos = {1009.29f, 163.15f, 628.157f, 0.0f};
|
||||
const Position TSSindragosaPos1 = {919.10f, 249.83f, 556.34f, 5.49f};
|
||||
const Position TSSindragosaPos2 = {948.39f, 215.47f, 653.71f, 5.51f};
|
||||
|
||||
struct TSPosition
|
||||
{
|
||||
uint32 entry;
|
||||
float x,y;
|
||||
};
|
||||
|
||||
const TSPosition TSData[] =
|
||||
{
|
||||
{ NPC_FREED_SLAVE_3_HORDE, 1047.8f, 126.01f },
|
||||
{ NPC_FREED_SLAVE_3_HORDE, 1049.21f, 127.10f },
|
||||
{ NPC_FREED_SLAVE_3_HORDE, 1051.68f, 129.02f },
|
||||
{ NPC_FREED_SLAVE_3_HORDE, 1053.24f, 130.23f },
|
||||
{ NPC_FREED_SLAVE_1_HORDE, 1044.82f, 121.30f },
|
||||
{ NPC_FREED_SLAVE_1_HORDE, 1049.33f, 124.01f },
|
||||
{ NPC_FREED_SLAVE_1_HORDE, 1056.79f, 130.86f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1045.56f, 118.46f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1047.75f, 120.85f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1052.93f, 124.156f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1057.35f, 127.95f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1059.18f, 129.86f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1049.865f, 118.735f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1052.32f, 121.827f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1055.38f, 123.99f },
|
||||
{ NPC_FREED_SLAVE_2_HORDE, 1058.723f, 125.98f },
|
||||
{ 0, 0.0f, 0.0f }
|
||||
};
|
||||
|
||||
enum eTSTexts
|
||||
{
|
||||
SAY_PREFIGHT_1 = 50,
|
||||
SAY_GENERAL_HORDE_TRASH = 51,
|
||||
SAY_PREFIGHT_2 = 52,
|
||||
SAY_PREFIGHT_AGGRO = 53,
|
||||
|
||||
SAY_GENERAL_HORDE_OUTRO_1 = 61,
|
||||
SAY_GENERAL_OUTRO_2 = 62,
|
||||
SAY_JAINA_OUTRO_1 = 63,
|
||||
SAY_SYLVANAS_OUTRO_1 = 64,
|
||||
SAY_JAINA_OUTRO_2 = 65,
|
||||
SAY_JAINA_OUTRO_3 = 66,
|
||||
SAY_SYLVANAS_OUTRO_2 = 67,
|
||||
SAY_GENERAL_ALLIANCE_OUTRO_1 = 68,
|
||||
SAY_GENERAL_ALLIANCE_TRASH = 69,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "gundrak.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MOJO_PUDDLE = 55627,
|
||||
SPELL_MOJO_WAVE = 55626,
|
||||
SPELL_FREEZE_ANIM = 52656,
|
||||
SPELL_MIGHTY_BLOW = 54719,
|
||||
|
||||
SPELL_ELEMENTAL_SPAWN_EFFECT = 54888,
|
||||
SPELL_EMERGE = 54850,
|
||||
SPELL_EMERGE_SUMMON = 54851,
|
||||
SPELL_MOJO_VOLLEY = 54849,
|
||||
|
||||
SPELL_SURGE_VISUAL = 54827,
|
||||
SPELL_SURGE = 54801,
|
||||
SPELL_SURGE_DAMAGE = 54819,
|
||||
|
||||
SPELL_FACE_ME = 54991,
|
||||
SPELL_MERGE = 54878,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_LIVING_MOJO = 29830,
|
||||
NPC_DRAKKARI_ELEMENTAL = 29573,
|
||||
|
||||
ACTION_MERGE = 1,
|
||||
ACTION_INFORM = 2,
|
||||
|
||||
POINT_MERGE = 1,
|
||||
SAY_SURGE = 0,
|
||||
EMOTE_ALTAR = 1,
|
||||
|
||||
EVENT_COLOSSUS_MIGHTY_BLOW = 1,
|
||||
EVENT_COLOSSUS_HEALTH_1 = 2,
|
||||
EVENT_COLOSSUS_HEALTH_2 = 3,
|
||||
EVENT_COLOSSUS_START_FIGHT = 4,
|
||||
|
||||
EVENT_ELEMENTAL_HEALTH = 10,
|
||||
EVENT_ELEMENTAL_SURGE = 11,
|
||||
EVENT_ELEMENTAL_VOLLEY = 12,
|
||||
|
||||
EVENT_MOJO_MOJO_WAVE = 20,
|
||||
EVENT_MOJO_MOJO_PUDDLE = 21,
|
||||
};
|
||||
|
||||
static Position mojoPosition[] =
|
||||
{
|
||||
{1663.1f, 743.6f, 143.1f},
|
||||
{1669.97f, 753.7f, 143.1f},
|
||||
{1680.7f, 750.7f, 143.1f},
|
||||
{1680.7f, 737.1f, 143.1f},
|
||||
{1670.4f, 733.5f, 143.1f}
|
||||
};
|
||||
|
||||
class RestoreFight : public BasicEvent
|
||||
{
|
||||
public:
|
||||
RestoreFight(Creature* owner) : _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*execTime*/, uint32 /*diff*/)
|
||||
{
|
||||
_owner->SetReactState(REACT_AGGRESSIVE);
|
||||
_owner->SetInCombatWithZone();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature* _owner;
|
||||
};
|
||||
|
||||
class boss_drakkari_colossus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_drakkari_colossus() : CreatureScript("boss_drakkari_colossus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_drakkari_colossusAI (creature);
|
||||
}
|
||||
struct boss_drakkari_colossusAI : public BossAI
|
||||
{
|
||||
boss_drakkari_colossusAI(Creature* creature) : BossAI(creature, DATA_DRAKKARI_COLOSSUS)
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_INFORM)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
summons.DoAction(ACTION_MERGE);
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_START_FIGHT, 3500);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
for (uint8 i = 0; i < 5; i++)
|
||||
me->SummonCreature(NPC_LIVING_MOJO, mojoPosition[i].GetPositionX(), mojoPosition[i].GetPositionY(), mojoPosition[i].GetPositionZ(), 0, TEMPSUMMON_MANUAL_DESPAWN, 0);
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
BossAI::JustReachedHome();
|
||||
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_MIGHTY_BLOW, 10000);
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_HEALTH_1, 1000);
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_HEALTH_2, 1000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (summon->GetEntry() == NPC_DRAKKARI_ELEMENTAL)
|
||||
{
|
||||
summon->SetRegeneratingHealth(false);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summon->m_Events.AddEvent(new RestoreFight(summon), summon->m_Events.CalculateTime(3000));
|
||||
if (events.GetNextEventTime(EVENT_COLOSSUS_HEALTH_2) == 0)
|
||||
{
|
||||
summon->SetHealth(summon->GetMaxHealth()/2);
|
||||
summon->LowerPlayerDamageReq(summon->GetMaxHealth()/2);
|
||||
summon->AI()->DoAction(ACTION_INFORM);
|
||||
}
|
||||
}
|
||||
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
if (summon->GetEntry() == NPC_DRAKKARI_ELEMENTAL)
|
||||
Unit::Kill(me, me);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
if (summon->GetEntry() == NPC_DRAKKARI_ELEMENTAL)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
|
||||
if (me->GetVictim())
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_COLOSSUS_START_FIGHT:
|
||||
me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
break;
|
||||
case EVENT_COLOSSUS_MIGHTY_BLOW:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MIGHTY_BLOW, false);
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_MIGHTY_BLOW, 10000);
|
||||
break;
|
||||
case EVENT_COLOSSUS_HEALTH_1:
|
||||
if (me->HealthBelowPct(51))
|
||||
{
|
||||
me->CastSpell(me, SPELL_EMERGE, false);
|
||||
me->CastSpell(me, SPELL_EMERGE_SUMMON, true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->GetMotionMaster()->Clear();
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_HEALTH_1, 1000);
|
||||
break;
|
||||
case EVENT_COLOSSUS_HEALTH_2:
|
||||
if (me->HealthBelowPct(21))
|
||||
{
|
||||
me->CastSpell(me, SPELL_EMERGE, false);
|
||||
me->CastSpell(me, SPELL_EMERGE_SUMMON, true);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->GetMotionMaster()->Clear();
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_COLOSSUS_HEALTH_2, 1000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_drakkari_elemental : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_drakkari_elemental() : CreatureScript("boss_drakkari_elemental") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_drakkari_elementalAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_drakkari_elementalAI : public ScriptedAI
|
||||
{
|
||||
boss_drakkari_elementalAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ELEMENTAL_HEALTH, 1000);
|
||||
events.ScheduleEvent(EVENT_ELEMENTAL_SURGE, 7000);
|
||||
events.ScheduleEvent(EVENT_ELEMENTAL_VOLLEY, 0);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_INFORM)
|
||||
events.CancelEvent(EVENT_ELEMENTAL_HEALTH);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->CastSpell(me, SPELL_ELEMENTAL_SPAWN_EFFECT, false);
|
||||
}
|
||||
|
||||
void JustDied(Unit*)
|
||||
{
|
||||
Talk(EMOTE_ALTAR);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_CHARGING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ELEMENTAL_HEALTH:
|
||||
if (me->HealthBelowPct(51))
|
||||
{
|
||||
me->CastSpell(me, SPELL_FACE_ME, true);
|
||||
me->CastSpell(me, SPELL_SURGE_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_MERGE, false);
|
||||
me->DespawnOrUnsummon(2000);
|
||||
events.Reset();
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ELEMENTAL_HEALTH, 1000);
|
||||
break;
|
||||
case EVENT_ELEMENTAL_SURGE:
|
||||
Talk(SAY_SURGE);
|
||||
me->CastSpell(me, SPELL_SURGE_VISUAL, true);
|
||||
me->CastSpell(me->GetVictim(), SPELL_SURGE, false);
|
||||
events.ScheduleEvent(EVENT_ELEMENTAL_SURGE, 15000);
|
||||
break;
|
||||
case EVENT_ELEMENTAL_VOLLEY:
|
||||
me->CastSpell(me, SPELL_MOJO_VOLLEY, true);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_living_mojo : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_living_mojo() : CreatureScript("npc_living_mojo") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_living_mojoAI (pCreature);
|
||||
}
|
||||
|
||||
struct npc_living_mojoAI : public ScriptedAI
|
||||
{
|
||||
npc_living_mojoAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_MOJO_MOJO_PUDDLE, 13000);
|
||||
events.ScheduleEvent(EVENT_MOJO_MOJO_WAVE, 15000);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (me->ToTempSummon())
|
||||
return;
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (me->ToTempSummon())
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER || IS_PLAYER_GUID(who->GetOwnerGUID()))
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummoner())
|
||||
summoner->GetAI()->DoAction(ACTION_INFORM);
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_MERGE)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->MoveCharge(1672.96f, 743.488f, 143.338f, 7.0f, POINT_MERGE);
|
||||
me->DespawnOrUnsummon(1200);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (me->ToTempSummon() || !UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_MOJO_MOJO_PUDDLE:
|
||||
{
|
||||
me->CastSpell(me, SPELL_MOJO_PUDDLE, false);
|
||||
events.ScheduleEvent(EVENT_MOJO_MOJO_PUDDLE, 13000);
|
||||
break;
|
||||
}
|
||||
case EVENT_MOJO_MOJO_WAVE:
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_MOJO_WAVE, false);
|
||||
events.ScheduleEvent(EVENT_MOJO_MOJO_WAVE, 15000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_drakkari_colossus_emerge : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_drakkari_colossus_emerge() : SpellScriptLoader("spell_drakkari_colossus_emerge") { }
|
||||
|
||||
class spell_drakkari_colossus_emerge_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_drakkari_colossus_emerge_SpellScript);
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_FREEZE_ANIM, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_drakkari_colossus_emerge_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_drakkari_colossus_emerge_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_drakkari_colossus_surge : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_drakkari_colossus_surge() : SpellScriptLoader("spell_drakkari_colossus_surge") { }
|
||||
|
||||
class spell_drakkari_colossus_surge_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_drakkari_colossus_surge_SpellScript);
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
GetCaster()->CastSpell(target, SPELL_SURGE_DAMAGE, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_drakkari_colossus_surge_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_drakkari_colossus_surge_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_drakkari_colossus_face_me : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_drakkari_colossus_face_me() : SpellScriptLoader("spell_drakkari_colossus_face_me") { }
|
||||
|
||||
class spell_drakkari_colossus_face_me_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_drakkari_colossus_face_me_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
GetCaster()->SetInFront(target);
|
||||
GetCaster()->SetFacingTo(GetCaster()->GetAngle(target));
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_drakkari_colossus_face_me_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_drakkari_colossus_face_me_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_drakkari_colossus()
|
||||
{
|
||||
new boss_drakkari_colossus();
|
||||
new boss_drakkari_elemental();
|
||||
new npc_living_mojo();
|
||||
new spell_drakkari_colossus_emerge();
|
||||
new spell_drakkari_colossus_surge();
|
||||
new spell_drakkari_colossus_face_me();
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "gundrak.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_ECK_BERSERK = 55816,
|
||||
SPELL_ECK_BITE = 55813,
|
||||
SPELL_ECK_SPIT = 55814,
|
||||
SPELL_ECK_SPRING = 55815,
|
||||
SPELL_ECK_SPRING_INIT = 55837
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
POINT_START = 0,
|
||||
EVENT_ECK_BERSERK = 1,
|
||||
EVENT_ECK_BITE = 2,
|
||||
EVENT_ECK_SPIT = 3,
|
||||
EVENT_ECK_SPRING = 4,
|
||||
EVENT_ECK_HEALTH = 5
|
||||
};
|
||||
|
||||
class boss_eck : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_eck() : CreatureScript("boss_eck") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_eckAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_eckAI : public BossAI
|
||||
{
|
||||
boss_eckAI(Creature* creature) : BossAI(creature, DATA_ECK_THE_FEROCIOUS)
|
||||
{
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
me->GetMotionMaster()->MovePoint(POINT_START, 1638.55f, 919.76f, 104.95f, false);
|
||||
me->SetHomePosition(1642.712f, 934.646f, 107.205f, 0.767f);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == POINT_START)
|
||||
{
|
||||
me->CastSpell(me, SPELL_ECK_SPRING_INIT, true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
BossAI::EnterCombat(who);
|
||||
events.ScheduleEvent(EVENT_ECK_BERSERK, urand(60000, 90000));
|
||||
events.ScheduleEvent(EVENT_ECK_BITE, 5000);
|
||||
events.ScheduleEvent(EVENT_ECK_SPIT, 10000);
|
||||
events.ScheduleEvent(EVENT_ECK_SPRING, 8000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ECK_HEALTH:
|
||||
if (me->HealthBelowPct(21))
|
||||
{
|
||||
events.CancelEvent(EVENT_ECK_BERSERK);
|
||||
me->CastSpell(me, SPELL_ECK_BERSERK, false);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ECK_HEALTH, 1000);
|
||||
break;
|
||||
case EVENT_ECK_BERSERK:
|
||||
me->CastSpell(me, SPELL_ECK_BERSERK, false);
|
||||
events.CancelEvent(EVENT_ECK_HEALTH);
|
||||
break;
|
||||
case EVENT_ECK_BITE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_ECK_BITE, false);
|
||||
events.ScheduleEvent(EVENT_ECK_BITE, urand(8000, 12000));
|
||||
break;
|
||||
case EVENT_ECK_SPIT:
|
||||
me->CastSpell(me->GetVictim(), SPELL_ECK_SPIT, false);
|
||||
events.ScheduleEvent(EVENT_ECK_SPIT, 10000);
|
||||
break;
|
||||
case EVENT_ECK_SPRING:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 30.0f, true))
|
||||
{
|
||||
me->getThreatManager().resetAllAggro();
|
||||
me->AddThreat(target, 500.0f);
|
||||
me->CastSpell(target, SPELL_ECK_SPRING, false);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_ECK_SPRING, urand(5000, 10000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_eck()
|
||||
{
|
||||
new boss_eck();
|
||||
}
|
||||
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "gundrak.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
|
||||
{
|
||||
return GetInstanceAI<boss_gal_darahAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_gal_darahAI : public BossAI
|
||||
{
|
||||
boss_gal_darahAI(Creature* creature) : BossAI(creature, DATA_GAL_DARAH)
|
||||
{
|
||||
}
|
||||
|
||||
uint8 phaseCounter;
|
||||
std::set<uint64> impaledList;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
impaledList.clear();
|
||||
phaseCounter = 0;
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
BossAI::InitializeAI();
|
||||
me->CastSpell(me, SPELL_START_VISUAL, false);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
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)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::EnterCombat(who);
|
||||
|
||||
ScheduleEvents(true);
|
||||
me->RemoveAurasDueToSpell(SPELL_START_VISUAL);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
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
|
||||
{
|
||||
return impaledList.size();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
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()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_galdarah_impaling_charge_SpellScript::HandleApplyAura, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
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()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_galdarah_transform_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "gundrak.h"
|
||||
|
||||
enum eSpells
|
||||
{
|
||||
SPELL_SUMMON_PHANTOM = 55205,
|
||||
SPELL_SUMMON_PHANTOM_TRANSFORM = 55097,
|
||||
SPELL_DETERMINED_STAB = 55104,
|
||||
SPELL_DETERMINED_GORE = 55102,
|
||||
SPELL_GROUND_TREMOR = 55142,
|
||||
SPELL_QUAKE = 55101,
|
||||
SPELL_NUMBING_SHOUT = 55106,
|
||||
SPELL_NUMBING_ROAR = 55100,
|
||||
SPELL_MOJO_FRENZY = 55163,
|
||||
SPELL_TRANSFORMATION = 55098
|
||||
};
|
||||
|
||||
enum eSays
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_TRANSFORM = 3,
|
||||
SAY_QUAKE = 4,
|
||||
EMOTE_TRANSFORM = 5,
|
||||
EMOTE_TRANSFORMED = 6,
|
||||
EMOTE_ALTAR = 7
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_GROUND_TREMOR = 1,
|
||||
EVENT_NUMBLING_SHOUT = 2,
|
||||
EVENT_DETERMINED_STAB = 3,
|
||||
EVENT_TRANSFORMATION = 4,
|
||||
EVENT_KILL_TALK = 5,
|
||||
|
||||
EVENT_PHANTOM = 10
|
||||
};
|
||||
|
||||
class boss_moorabi : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_moorabi() : CreatureScript("boss_moorabi") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_moorabiAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_moorabiAI : public BossAI
|
||||
{
|
||||
boss_moorabiAI(Creature* creature) : BossAI(creature, DATA_MOORABI)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events2;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
events2.Reset();
|
||||
events2.ScheduleEvent(EVENT_PHANTOM, 21000);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::EnterCombat(who);
|
||||
me->CastSpell(me, SPELL_MOJO_FRENZY, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, 18000);
|
||||
events.ScheduleEvent(EVENT_NUMBLING_SHOUT, 10000);
|
||||
events.ScheduleEvent(EVENT_DETERMINED_STAB, 20000);
|
||||
events.ScheduleEvent(EVENT_TRANSFORMATION, 12000);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* caster, const SpellInfo* spellInfo)
|
||||
{
|
||||
if (spellInfo->Id == SPELL_TRANSFORMATION)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_MOJO_FRENZY);
|
||||
events.CancelEvent(EVENT_TRANSFORMATION);
|
||||
Talk(EMOTE_TRANSFORMED);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
Talk(EMOTE_ALTAR);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
events2.Update(diff);
|
||||
if (events2.ExecuteEvent() == EVENT_PHANTOM)
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_PHANTOM, true);
|
||||
events2.ScheduleEvent(EVENT_PHANTOM, urand(20000, 25000));
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_GROUND_TREMOR:
|
||||
if (roll_chance_i(50))
|
||||
Talk(SAY_QUAKE);
|
||||
me->CastSpell(me, me->GetDisplayId() != me->GetNativeDisplayId() ? SPELL_QUAKE : SPELL_GROUND_TREMOR, false);
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, 10000);
|
||||
break;
|
||||
case EVENT_NUMBLING_SHOUT:
|
||||
me->CastSpell(me, me->GetDisplayId() != me->GetNativeDisplayId() ? SPELL_NUMBING_ROAR : SPELL_NUMBING_SHOUT, false);
|
||||
events.ScheduleEvent(EVENT_NUMBLING_SHOUT, 10000);
|
||||
break;
|
||||
case EVENT_DETERMINED_STAB:
|
||||
me->CastSpell(me->GetVictim(), me->GetDisplayId() != me->GetNativeDisplayId() ? SPELL_DETERMINED_GORE : SPELL_DETERMINED_STAB, false);
|
||||
events.ScheduleEvent(EVENT_DETERMINED_STAB, 8000);
|
||||
break;
|
||||
case EVENT_TRANSFORMATION:
|
||||
Talk(EMOTE_TRANSFORM);
|
||||
Talk(SAY_TRANSFORM);
|
||||
me->CastSpell(me, SPELL_TRANSFORMATION, false);
|
||||
me->CastSpell(me,SPELL_SUMMON_PHANTOM_TRANSFORM, true);
|
||||
events.ScheduleEvent(EVENT_TRANSFORMATION, 10000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_moorabi_mojo_frenzy : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_moorabi_mojo_frenzy() : SpellScriptLoader("spell_moorabi_mojo_frenzy") { }
|
||||
|
||||
class spell_moorabi_mojo_frenzy_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_moorabi_mojo_frenzy_AuraScript);
|
||||
|
||||
void HandlePeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
if (GetUnitOwner()->GetMap()->IsHeroic())
|
||||
GetUnitOwner()->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f * (GetUnitOwner()->GetHealthPct()*GetUnitOwner()->GetHealthPct()/10000.0f));
|
||||
else
|
||||
GetUnitOwner()->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f * (GetUnitOwner()->GetHealthPct()/100.0f));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_moorabi_mojo_frenzy_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_moorabi_mojo_frenzy_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_less_rabi : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_less_rabi() : AchievementCriteriaScript("achievement_less_rabi")
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
return target && target->GetDisplayId() == target->GetNativeDisplayId();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_moorabi()
|
||||
{
|
||||
new boss_moorabi();
|
||||
new spell_moorabi_mojo_frenzy();
|
||||
new achievement_less_rabi();
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "gundrak.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISON_NOVA = 55081,
|
||||
SPELL_POWERFULL_BITE = 48287,
|
||||
SPELL_VENOM_BOLT = 54970,
|
||||
|
||||
SPELL_SNAKE_WRAP = 55126
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_SUMMON_SNAKES = 3,
|
||||
SAY_SUMMON_CONSTRICTORS = 4,
|
||||
EMOTE_NOVA = 5,
|
||||
EMOTE_ALTAR = 6
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_SLADRAN_VIPER = 29680,
|
||||
NPC_SLADRAN_CONSTRICTORS = 29713,
|
||||
|
||||
MAX_VIPER = 2,
|
||||
MAX_CONSTRICTOR = 3,
|
||||
MAX_SUMMONS = 5,
|
||||
|
||||
EVENT_POISON_NOVA = 1,
|
||||
EVENT_POWERFULL_BITE = 2,
|
||||
EVENT_VENOM_BOLT = 3,
|
||||
EVENT_CHECK_HEALTH1 = 4,
|
||||
EVENT_CHECK_HEALTH2 = 5,
|
||||
EVENT_SUMMON1 = 6,
|
||||
EVENT_SUMMON2 = 7,
|
||||
EVENT_KILL_TALK = 8
|
||||
};
|
||||
|
||||
const Position SpawnLoc[]=
|
||||
{
|
||||
{1783.81f, 646.637f, 133.948f, 3.71755f},
|
||||
{1775.03f, 606.586f, 134.165f, 1.43117f},
|
||||
{1765.66f, 646.542f, 134.02f, 5.11381f},
|
||||
{1717.39f, 630.041f, 129.282f, 5.96903f},
|
||||
{1716.76f, 635.159f, 129.282f, 0.191986f}
|
||||
};
|
||||
|
||||
class boss_slad_ran : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_slad_ran() : CreatureScript("boss_slad_ran") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_slad_ranAI(creature);
|
||||
}
|
||||
|
||||
struct boss_slad_ranAI : public BossAI
|
||||
{
|
||||
boss_slad_ranAI(Creature* creature) : BossAI(creature, DATA_SLAD_RAN)
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
BossAI::Reset();
|
||||
_achievement = true;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
return uint32(_achievement);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 data, uint32)
|
||||
{
|
||||
if (data == me->GetEntry())
|
||||
_achievement = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::EnterCombat(who);
|
||||
|
||||
events.ScheduleEvent(EVENT_POISON_NOVA, 10000);
|
||||
events.ScheduleEvent(EVENT_POWERFULL_BITE, 3000);
|
||||
events.ScheduleEvent(EVENT_VENOM_BOLT, 15000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH1, 1000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
Talk(EMOTE_ALTAR);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summon->SetInCombatWithZone();
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH1:
|
||||
if (me->HealthBelowPct(70))
|
||||
{
|
||||
Talk(SAY_SUMMON_SNAKES);
|
||||
events.ScheduleEvent(EVENT_SUMMON1, 1000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH1, 1000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH2:
|
||||
if (me->HealthBelowPct(50))
|
||||
{
|
||||
Talk(SAY_SUMMON_CONSTRICTORS);
|
||||
events.ScheduleEvent(EVENT_SUMMON2, 1000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
||||
break;
|
||||
case EVENT_POISON_NOVA:
|
||||
Talk(EMOTE_NOVA);
|
||||
me->CastSpell(me, SPELL_POISON_NOVA, false);
|
||||
events.ScheduleEvent(EVENT_POISON_NOVA, 15000);
|
||||
break;
|
||||
case EVENT_POWERFULL_BITE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_POWERFULL_BITE, false);
|
||||
events.ScheduleEvent(EVENT_POWERFULL_BITE, 10000);
|
||||
break;
|
||||
case EVENT_VENOM_BOLT:
|
||||
me->CastSpell(me->GetVictim(), SPELL_VENOM_BOLT, false);
|
||||
events.ScheduleEvent(EVENT_VENOM_BOLT, 10000);
|
||||
break;
|
||||
case EVENT_SUMMON1:
|
||||
for (uint8 i = MAX_CONSTRICTOR; i < MAX_SUMMONS; ++i)
|
||||
me->SummonCreature(NPC_SLADRAN_VIPER, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_SUMMON1, 8000);
|
||||
break;
|
||||
case EVENT_SUMMON2:
|
||||
for (uint8 i = 0; i < MAX_CONSTRICTOR; ++i)
|
||||
me->SummonCreature(NPC_SLADRAN_CONSTRICTORS, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_SUMMON2, urand(3000, 5000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
bool _achievement;
|
||||
};
|
||||
};
|
||||
|
||||
class spell_sladran_grip_of_sladran : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_sladran_grip_of_sladran() : SpellScriptLoader("spell_sladran_grip_of_sladran") { }
|
||||
|
||||
class spell_sladran_grip_of_sladran_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_sladran_grip_of_sladran_AuraScript);
|
||||
|
||||
void HandlePeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
if (GetStackAmount() >= 5)
|
||||
{
|
||||
SetDuration(0);
|
||||
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_SNAKE_WRAP, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_sladran_grip_of_sladran_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_sladran_grip_of_sladran_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_snakes_whyd_it_have_to_be_snakes : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_snakes_whyd_it_have_to_be_snakes() : AchievementCriteriaScript("achievement_snakes_whyd_it_have_to_be_snakes")
|
||||
{
|
||||
}
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target)
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
return target->GetAI()->GetData(target->GetEntry());
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_slad_ran()
|
||||
{
|
||||
new boss_slad_ran();
|
||||
new spell_sladran_grip_of_sladran();
|
||||
new achievement_snakes_whyd_it_have_to_be_snakes();
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_GUNDRAK_H
|
||||
#define DEF_GUNDRAK_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_SLAD_RAN = 0,
|
||||
DATA_MOORABI = 1,
|
||||
DATA_DRAKKARI_COLOSSUS = 2,
|
||||
DATA_GAL_DARAH = 3,
|
||||
DATA_ECK_THE_FEROCIOUS_INIT = 4,
|
||||
DATA_ECK_THE_FEROCIOUS = 5,
|
||||
MAX_ENCOUNTERS = 6
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_ECK_THE_FEROCIOUS = 29932
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_ALTAR_OF_SLAD_RAN = 192518,
|
||||
GO_STATUE_OF_SLAD_RAN = 192564,
|
||||
GO_ALTAR_OF_DRAKKARI = 192520,
|
||||
GO_STATUE_OF_DRAKKARI = 192567,
|
||||
GO_ALTAR_OF_MOORABI = 192519,
|
||||
GO_STATUE_OF_MOORABI = 192565,
|
||||
GO_STATUE_OF_GAL_DARAH = 192566,
|
||||
|
||||
GO_GUNDRAK_BRIDGE = 193188,
|
||||
GO_GUNDRAK_COLLISION = 192633,
|
||||
|
||||
GO_ECK_DOORS = 192632,
|
||||
GO_ECK_UNDERWATER_GATE = 192569,
|
||||
GO_GAL_DARAH_DOORS0 = 192568,
|
||||
GO_GAL_DARAH_DOORS1 = 193208,
|
||||
GO_GAL_DARAH_DOORS2 = 193209
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "gundrak.h"
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_ECK_DOORS, DATA_MOORABI, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
|
||||
{ GO_ECK_UNDERWATER_GATE, DATA_ECK_THE_FEROCIOUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
|
||||
{ GO_GAL_DARAH_DOORS0, DATA_GAL_DARAH, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ GO_GAL_DARAH_DOORS1, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
|
||||
{ GO_GAL_DARAH_DOORS2, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
|
||||
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
|
||||
};
|
||||
|
||||
class instance_gundrak : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_gundrak() : InstanceMapScript("instance_gundrak", 604) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
|
||||
{
|
||||
return new instance_gundrak_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
struct instance_gundrak_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_gundrak_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
}
|
||||
|
||||
uint64 _sladRanAltarGUID;
|
||||
uint64 _moorabiAltarGUID;
|
||||
uint64 _drakkariAltarGUID;
|
||||
uint64 _bridgeGUIDs[6];
|
||||
uint32 _keysInCount;
|
||||
uint32 _activateTimer;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
|
||||
_sladRanAltarGUID = 0;
|
||||
_moorabiAltarGUID = 0;
|
||||
_drakkariAltarGUID = 0;
|
||||
_keysInCount = 0;
|
||||
_activateTimer = 0;
|
||||
memset(&_bridgeGUIDs, 0, sizeof(_bridgeGUIDs));
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_ALTAR_OF_SLAD_RAN:
|
||||
_sladRanAltarGUID = gameobject->GetGUID();
|
||||
gameobject->SetGoState(GetBossState(DATA_SLAD_RAN) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
break;
|
||||
case GO_ALTAR_OF_DRAKKARI:
|
||||
_drakkariAltarGUID = gameobject->GetGUID();
|
||||
gameobject->SetGoState(GetBossState(DATA_DRAKKARI_COLOSSUS) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
break;
|
||||
case GO_ALTAR_OF_MOORABI:
|
||||
_moorabiAltarGUID = gameobject->GetGUID();
|
||||
gameobject->SetGoState(GetBossState(DATA_MOORABI) == DONE ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
break;
|
||||
case GO_STATUE_OF_SLAD_RAN:
|
||||
_bridgeGUIDs[0] = gameobject->GetGUID();
|
||||
gameobject->SetGoState(_keysInCount == 3 ? GO_STATE_ACTIVE_ALTERNATIVE : (GetBossState(DATA_SLAD_RAN) == DONE ? GO_STATE_READY : GO_STATE_ACTIVE));
|
||||
break;
|
||||
case GO_STATUE_OF_DRAKKARI:
|
||||
_bridgeGUIDs[1] = gameobject->GetGUID();
|
||||
gameobject->SetGoState(_keysInCount == 3 ? GO_STATE_ACTIVE_ALTERNATIVE : (GetBossState(DATA_DRAKKARI_COLOSSUS) == DONE ? GO_STATE_READY : GO_STATE_ACTIVE));
|
||||
break;
|
||||
case GO_STATUE_OF_MOORABI:
|
||||
_bridgeGUIDs[2] = gameobject->GetGUID();
|
||||
gameobject->SetGoState(_keysInCount == 3 ? GO_STATE_ACTIVE_ALTERNATIVE : (GetBossState(DATA_MOORABI) == DONE ? GO_STATE_READY : GO_STATE_ACTIVE));
|
||||
break;
|
||||
case GO_STATUE_OF_GAL_DARAH:
|
||||
_bridgeGUIDs[3] = gameobject->GetGUID();
|
||||
gameobject->SetGoState(_keysInCount == 3 ? GO_STATE_ACTIVE_ALTERNATIVE : GO_STATE_READY);
|
||||
break;
|
||||
case GO_GUNDRAK_COLLISION:
|
||||
_bridgeGUIDs[4] = gameobject->GetGUID();
|
||||
gameobject->SetGoState(_keysInCount == 3 ? GO_STATE_ACTIVE_ALTERNATIVE : GO_STATE_READY);
|
||||
break;
|
||||
case GO_GUNDRAK_BRIDGE:
|
||||
_bridgeGUIDs[5] = gameobject->GetGUID();
|
||||
gameobject->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_ECK_DOORS:
|
||||
case GO_ECK_UNDERWATER_GATE:
|
||||
case GO_GAL_DARAH_DOORS0:
|
||||
case GO_GAL_DARAH_DOORS1:
|
||||
case GO_GAL_DARAH_DOORS2:
|
||||
AddDoor(gameobject, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_ECK_DOORS:
|
||||
case GO_ECK_UNDERWATER_GATE:
|
||||
case GO_GAL_DARAH_DOORS0:
|
||||
case GO_GAL_DARAH_DOORS1:
|
||||
case GO_GAL_DARAH_DOORS2:
|
||||
AddDoor(gameobject, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NPC_ECK_THE_FEROCIOUS:
|
||||
if (GetBossState(DATA_ECK_THE_FEROCIOUS_INIT) != DONE)
|
||||
{
|
||||
SetBossState(DATA_ECK_THE_FEROCIOUS_INIT, NOT_STARTED);
|
||||
SetBossState(DATA_ECK_THE_FEROCIOUS_INIT, DONE);
|
||||
}
|
||||
break;
|
||||
case GO_ALTAR_OF_SLAD_RAN:
|
||||
if (GameObject* statue = instance->GetGameObject(_bridgeGUIDs[0]))
|
||||
statue->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_ALTAR_OF_DRAKKARI:
|
||||
if (GameObject* statue = instance->GetGameObject(_bridgeGUIDs[1]))
|
||||
statue->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_ALTAR_OF_MOORABI:
|
||||
if (GameObject* statue = instance->GetGameObject(_bridgeGUIDs[2]))
|
||||
statue->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
}
|
||||
|
||||
if (type >= GO_ALTAR_OF_SLAD_RAN)
|
||||
{
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (GameObject* statue = instance->GetGameObject(_bridgeGUIDs[i]))
|
||||
if (statue->GetGoState() != GO_STATE_READY)
|
||||
return;
|
||||
_activateTimer = 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state)
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
{
|
||||
if (state == DONE && (type == DATA_SLAD_RAN || type == DATA_MOORABI || type == DATA_DRAKKARI_COLOSSUS))
|
||||
++_keysInCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state != DONE)
|
||||
return true;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SLAD_RAN:
|
||||
if (GameObject* altar = instance->GetGameObject(_sladRanAltarGUID))
|
||||
altar->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case DATA_MOORABI:
|
||||
if (GameObject* altar = instance->GetGameObject(_moorabiAltarGUID))
|
||||
altar->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case DATA_DRAKKARI_COLOSSUS:
|
||||
if (GameObject* altar = instance->GetGameObject(_drakkariAltarGUID))
|
||||
altar->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case DATA_ECK_THE_FEROCIOUS_INIT:
|
||||
{
|
||||
Position pos = {1624.70f, 891.43f, 95.08f, 1.2f};
|
||||
if (instance->IsHeroic())
|
||||
instance->SummonCreature(NPC_ECK_THE_FEROCIOUS, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "G D " << GetBossSaveData();
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'G' && dataHead2 == 'D')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
|
||||
tmpState = NOT_STARTED;
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
if (!_activateTimer)
|
||||
return;
|
||||
|
||||
_activateTimer += diff;
|
||||
if (_activateTimer >= 5000)
|
||||
{
|
||||
_activateTimer = 0;
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
if (GameObject* go = instance->GetGameObject(_bridgeGUIDs[i]))
|
||||
go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_gundrak()
|
||||
{
|
||||
new instance_gundrak();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,494 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "icecrown_citadel.h"
|
||||
|
||||
enum ScriptTexts
|
||||
{
|
||||
SAY_STINKY_DEAD = 0,
|
||||
SAY_AGGRO = 1,
|
||||
EMOTE_GAS_SPORE = 2,
|
||||
EMOTE_WARN_GAS_SPORE = 3,
|
||||
SAY_PUNGENT_BLIGHT = 4,
|
||||
EMOTE_WARN_PUNGENT_BLIGHT = 5,
|
||||
EMOTE_PUNGENT_BLIGHT = 6,
|
||||
SAY_KILL = 7,
|
||||
SAY_BERSERK = 8,
|
||||
SAY_DEATH = 9,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Festergut
|
||||
SPELL_INHALE_BLIGHT = 69165,
|
||||
SPELL_PUNGENT_BLIGHT = 69195,
|
||||
SPELL_GASTRIC_BLOAT = 72219, // 72214 is the proper way (with proc) but atm procs can't have cooldown for creatures
|
||||
SPELL_GASTRIC_EXPLOSION = 72227,
|
||||
SPELL_GAS_SPORE = 69278,
|
||||
SPELL_VILE_GAS = 69240,
|
||||
SPELL_INOCULATED = 69291,
|
||||
SPELL_MALLABLE_GOO_H = 72296,
|
||||
|
||||
// Stinky
|
||||
SPELL_MORTAL_WOUND = 71127,
|
||||
SPELL_DECIMATE = 71123,
|
||||
SPELL_PLAGUE_STENCH = 71805,
|
||||
};
|
||||
|
||||
// Used for HasAura checks
|
||||
#define PUNGENT_BLIGHT_HELPER RAID_MODE<uint32>(69195, 71219, 73031, 73032)
|
||||
#define INOCULATED_HELPER RAID_MODE<uint32>(69291, 72101, 72102, 72103)
|
||||
|
||||
uint32 const gaseousBlight[3] = {69157, 69162, 69164};
|
||||
uint32 const gaseousBlightVisual[3] = {69126, 69152, 69154};
|
||||
|
||||
#define DATA_INOCULATED_STACK 69291
|
||||
|
||||
enum Events
|
||||
{
|
||||
// Festergut
|
||||
EVENT_NONE,
|
||||
EVENT_BERSERK,
|
||||
EVENT_INHALE_BLIGHT,
|
||||
EVENT_VILE_GAS,
|
||||
EVENT_GAS_SPORE,
|
||||
EVENT_GASTRIC_BLOAT,
|
||||
EVENT_FESTERGUT_GOO,
|
||||
|
||||
// Stinky
|
||||
EVENT_DECIMATE,
|
||||
EVENT_MORTAL_WOUND,
|
||||
};
|
||||
|
||||
class boss_festergut : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_festergut() : CreatureScript("boss_festergut") { }
|
||||
|
||||
struct boss_festergutAI : public BossAI
|
||||
{
|
||||
boss_festergutAI(Creature* creature) : BossAI(creature, DATA_FESTERGUT)
|
||||
{
|
||||
_gasDummyGUID = 0;
|
||||
}
|
||||
|
||||
uint64 _gasDummyGUID;
|
||||
uint32 _maxInoculatedStack;
|
||||
uint32 _inhaleCounter;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_maxInoculatedStack = 0;
|
||||
_inhaleCounter = 0;
|
||||
_Reset();
|
||||
events.Reset();
|
||||
if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true))
|
||||
{
|
||||
_gasDummyGUID = gasDummy->GetGUID();
|
||||
for (uint8 i=0; i<3; ++i)
|
||||
gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (!instance->CheckRequiredBosses(DATA_FESTERGUT, who->ToPlayer()))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
|
||||
return;
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_BERSERK, 300000);
|
||||
events.ScheduleEvent(EVENT_INHALE_BLIGHT, urand(25000, 30000));
|
||||
events.ScheduleEvent(EVENT_GAS_SPORE, urand(20000, 25000));
|
||||
events.ScheduleEvent(EVENT_VILE_GAS, urand(30000, 40000), 1);
|
||||
events.ScheduleEvent(EVENT_GASTRIC_BLOAT, urand(12500, 15000));
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000));
|
||||
|
||||
me->setActive(true);
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
if (Creature* gasDummy = me->FindNearestCreature(NPC_GAS_DUMMY, 100.0f, true))
|
||||
_gasDummyGUID = gasDummy->GetGUID();
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->DoAction(ACTION_FESTERGUT_COMBAT);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->DoAction(ACTION_FESTERGUT_DEATH);
|
||||
|
||||
RemoveBlight();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_FESTERGUT, FAIL);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->EnterEvadeMode();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell)
|
||||
{
|
||||
if (spell->Id == PUNGENT_BLIGHT_HELPER)
|
||||
target->RemoveAurasDueToSpell(INOCULATED_HELPER);
|
||||
else if (Player* p = target->ToPlayer())
|
||||
{
|
||||
// Gaseous Blight damage
|
||||
if ((spell->Id == 69159 || spell->Id == 70136 || spell->Id == 69161 || spell->Id == 70139 || spell->Id == 69163 || spell->Id == 70469) && p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_10) == QUEST_STATUS_INCOMPLETE ||
|
||||
(spell->Id == 70135 || spell->Id == 70138 || spell->Id == 70468 || spell->Id == 70137 || spell->Id == 70140 || spell->Id == 70470) && p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_25) == QUEST_STATUS_INCOMPLETE)
|
||||
p->CastSpell(p, SPELL_ORANGE_BLIGHT_RESIDUE, true);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveBlight()
|
||||
{
|
||||
if (Creature* gasDummy = ObjectAccessor::GetCreature(*me, _gasDummyGUID))
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(gaseousBlight[i]);
|
||||
gasDummy->RemoveAurasDueToSpell(gaseousBlightVisual[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK2, true);
|
||||
Talk(SAY_BERSERK);
|
||||
break;
|
||||
case EVENT_INHALE_BLIGHT:
|
||||
RemoveBlight();
|
||||
if (_inhaleCounter == 3)
|
||||
{
|
||||
Talk(EMOTE_WARN_PUNGENT_BLIGHT);
|
||||
Talk(SAY_PUNGENT_BLIGHT);
|
||||
me->CastSpell(me, SPELL_PUNGENT_BLIGHT, false);
|
||||
_inhaleCounter = 0;
|
||||
events.RescheduleEvent(EVENT_GAS_SPORE, urand(20000, 25000));
|
||||
}
|
||||
else
|
||||
{
|
||||
me->CastSpell(me, SPELL_INHALE_BLIGHT, false);
|
||||
// just cast and dont bother with target, conditions will handle it
|
||||
++_inhaleCounter;
|
||||
if (_inhaleCounter < 3)
|
||||
me->CastSpell(me, gaseousBlight[_inhaleCounter], true, NULL, NULL, me->GetGUID());
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_INHALE_BLIGHT, 34000);
|
||||
break;
|
||||
case EVENT_GAS_SPORE:
|
||||
Talk(EMOTE_WARN_GAS_SPORE);
|
||||
Talk(EMOTE_GAS_SPORE);
|
||||
me->CastCustomSpell(SPELL_GAS_SPORE, SPELLVALUE_MAX_TARGETS, RAID_MODE<int32>(2, 3, 2, 3), me);
|
||||
events.ScheduleEvent(EVENT_GAS_SPORE, urand(40000, 45000));
|
||||
events.DelayEventsToMax(20000, 1); // delay EVENT_VILE_GAS
|
||||
break;
|
||||
case EVENT_VILE_GAS:
|
||||
{
|
||||
std::list<Unit*> targets;
|
||||
uint32 minTargets = RAID_MODE<uint32>(3, 8, 3, 8);
|
||||
SelectTargetList(targets, minTargets, SELECT_TARGET_RANDOM, -5.0f, true);
|
||||
float minDist = 0.0f;
|
||||
if (targets.size() >= minTargets)
|
||||
minDist = -5.0f;
|
||||
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, minDist, true))
|
||||
me->CastSpell(target, SPELL_VILE_GAS, false);
|
||||
events.ScheduleEvent(EVENT_VILE_GAS, urand(28000, 35000), 1);
|
||||
break;
|
||||
}
|
||||
case EVENT_GASTRIC_BLOAT:
|
||||
me->CastSpell(me->GetVictim(), SPELL_GASTRIC_BLOAT, false);
|
||||
events.ScheduleEvent(EVENT_GASTRIC_BLOAT, urand(15000, 17500));
|
||||
break;
|
||||
case EVENT_FESTERGUT_GOO:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->CastSpell(target, SPELL_MALLABLE_GOO_H, true);
|
||||
events.ScheduleEvent(EVENT_FESTERGUT_GOO, urand(15000, 20000));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
if (type == DATA_INOCULATED_STACK && data > _maxInoculatedStack)
|
||||
_maxInoculatedStack = data;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
if (type == DATA_INOCULATED_STACK)
|
||||
return _maxInoculatedStack;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<boss_festergutAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_festergut_pungent_blight : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_festergut_pungent_blight() : SpellScriptLoader("spell_festergut_pungent_blight") { }
|
||||
|
||||
class spell_festergut_pungent_blight_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_festergut_pungent_blight_SpellScript);
|
||||
|
||||
bool Load()
|
||||
{
|
||||
return GetCaster()->GetTypeId() == TYPEID_UNIT;
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (caster->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
// Get Inhaled Blight id for our difficulty
|
||||
uint32 blightId = sSpellMgr->GetSpellIdForDifficulty(uint32(GetEffectValue()), caster);
|
||||
|
||||
// ...and remove it
|
||||
caster->RemoveAurasDueToSpell(blightId);
|
||||
caster->ToCreature()->AI()->Talk(EMOTE_PUNGENT_BLIGHT);
|
||||
|
||||
if (InstanceScript* inst = caster->GetInstanceScript())
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*caster, inst->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->DoAction(ACTION_FESTERGUT_GAS);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_festergut_pungent_blight_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_festergut_pungent_blight_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_festergut_blighted_spores : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_festergut_blighted_spores() : SpellScriptLoader("spell_festergut_blighted_spores") { }
|
||||
|
||||
class spell_festergut_blighted_spores_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_festergut_blighted_spores_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_INOCULATED))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExtraEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Aura* a = aurEff->GetBase())
|
||||
if (a->GetDuration() > a->GetMaxDuration()-1000) // this does not stack for different casters and previous is removed by new DoT, prevent it from giving inoculation in such case
|
||||
return;
|
||||
uint32 inoculatedId = sSpellMgr->GetSpellIdForDifficulty(SPELL_INOCULATED, GetTarget());
|
||||
uint8 inoculatedStack = 1;
|
||||
if (Aura* a = GetTarget()->GetAura(inoculatedId))
|
||||
{
|
||||
inoculatedStack += a->GetStackAmount();
|
||||
if (a->GetDuration() > a->GetMaxDuration()-10000) // player may gain only one stack at a time, no matter how many spores explode near him
|
||||
return;
|
||||
}
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_INOCULATED, true);
|
||||
if (InstanceScript* instance = GetTarget()->GetInstanceScript())
|
||||
if (Creature* festergut = ObjectAccessor::GetCreature(*GetTarget(), instance->GetData64(DATA_FESTERGUT)))
|
||||
festergut->AI()->SetData(DATA_INOCULATED_STACK, inoculatedStack);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_festergut_blighted_spores_AuraScript::ExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_festergut_blighted_spores_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_festergut_gastric_bloat : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_festergut_gastric_bloat() : SpellScriptLoader("spell_festergut_gastric_bloat") { }
|
||||
|
||||
class spell_festergut_gastric_bloat_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_festergut_gastric_bloat_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_GASTRIC_EXPLOSION))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Aura const* aura = GetHitUnit()->GetAura(GetSpellInfo()->Id);
|
||||
if (!(aura && aura->GetStackAmount() == 10))
|
||||
return;
|
||||
|
||||
GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Id);
|
||||
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GASTRIC_EXPLOSION, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_festergut_gastric_bloat_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_festergut_gastric_bloat_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class achievement_flu_shot_shortage : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_flu_shot_shortage() : AchievementCriteriaScript("achievement_flu_shot_shortage") { }
|
||||
|
||||
bool OnCheck(Player* /*source*/, Unit* target)
|
||||
{
|
||||
if (target && target->GetTypeId() == TYPEID_UNIT)
|
||||
return target->ToCreature()->AI()->GetData(DATA_INOCULATED_STACK) < 3;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class npc_stinky_icc : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_stinky_icc() : CreatureScript("npc_stinky_icc") { }
|
||||
|
||||
struct npc_stinky_iccAI : public ScriptedAI
|
||||
{
|
||||
npc_stinky_iccAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*target*/)
|
||||
{
|
||||
me->setActive(true);
|
||||
me->CastSpell(me, SPELL_PLAGUE_STENCH, true);
|
||||
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DECIMATE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_DECIMATE, false);
|
||||
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
|
||||
break;
|
||||
case EVENT_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (InstanceScript* _instance = me->GetInstanceScript())
|
||||
if (Creature* festergut = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FESTERGUT)))
|
||||
if (festergut->IsAlive())
|
||||
festergut->AI()->Talk(SAY_STINKY_DEAD);
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<npc_stinky_iccAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_festergut()
|
||||
{
|
||||
new boss_festergut();
|
||||
new spell_festergut_pungent_blight();
|
||||
new spell_festergut_blighted_spores();
|
||||
new spell_festergut_gastric_bloat();
|
||||
new achievement_flu_shot_shortage();
|
||||
|
||||
new npc_stinky_icc();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,701 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "MapManager.h"
|
||||
#include "icecrown_citadel.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
enum ScriptTexts
|
||||
{
|
||||
SAY_ENTER_ZONE = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BONE_STORM = 2,
|
||||
SAY_BONESPIKE = 3,
|
||||
SAY_KILL = 4,
|
||||
SAY_DEATH = 5,
|
||||
SAY_BERSERK = 6,
|
||||
EMOTE_BONE_STORM = 7,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Lord Marrowgar
|
||||
SPELL_BONE_SLICE = 69055,
|
||||
SPELL_BONE_STORM = 69076,
|
||||
SPELL_BONE_SPIKE_GRAVEYARD = 69057,
|
||||
SPELL_COLDFLAME_NORMAL = 69140,
|
||||
SPELL_COLDFLAME_BONE_STORM = 72705,
|
||||
|
||||
// Bone Spike
|
||||
SPELL_IMPALED = 69065,
|
||||
SPELL_RIDE_VEHICLE = 46598,
|
||||
|
||||
// Coldflame
|
||||
SPELL_COLDFLAME_PASSIVE = 69145,
|
||||
SPELL_COLDFLAME_SUMMON = 69147,
|
||||
};
|
||||
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ENABLE_BONE_SLICE = 1,
|
||||
EVENT_SPELL_BONE_SPIKE_GRAVEYARD,
|
||||
EVENT_SPELL_COLDFLAME,
|
||||
EVENT_SPELL_COLDFLAME_BONE_STORM,
|
||||
EVENT_WARN_BONE_STORM,
|
||||
EVENT_BEGIN_BONE_STORM,
|
||||
EVENT_BONE_STORM_MOVE,
|
||||
EVENT_END_BONE_STORM,
|
||||
EVENT_ENRAGE,
|
||||
};
|
||||
|
||||
uint32 const boneSpikeSummonId[3] = {69062, 72669, 72670};
|
||||
|
||||
struct BoneStormMoveTargetSelector : public std::unary_function<Unit*, bool>
|
||||
{
|
||||
public:
|
||||
BoneStormMoveTargetSelector(Creature* source) : _source(source) { }
|
||||
bool operator()(Unit const* target) const
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
if (target->GetExactDist(_source) > 175.0f)
|
||||
return false;
|
||||
|
||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
|
||||
if (target->GetPositionX() > -337.0f)
|
||||
return false;
|
||||
|
||||
return target != _source->GetVictim();
|
||||
}
|
||||
|
||||
private:
|
||||
Creature const* _source;
|
||||
};
|
||||
|
||||
class boss_lord_marrowgar : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_lord_marrowgar() : CreatureScript("boss_lord_marrowgar") { }
|
||||
|
||||
struct boss_lord_marrowgarAI : public BossAI
|
||||
{
|
||||
boss_lord_marrowgarAI(Creature* creature) : BossAI(creature, DATA_LORD_MARROWGAR)
|
||||
{
|
||||
_introDone = false;
|
||||
_boneSlice = false;
|
||||
}
|
||||
|
||||
bool _introDone;
|
||||
bool _boneSlice;
|
||||
uint64 _lastBoneSliceTargets[3];
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
_Reset();
|
||||
events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BONE_SPIKE_GRAVEYARD, urand(10000, 15000));
|
||||
events.ScheduleEvent(EVENT_SPELL_COLDFLAME, 5000);
|
||||
events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000));
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 600000);
|
||||
|
||||
_boneSlice = false;
|
||||
memset(_lastBoneSliceTargets, 0, 3 * sizeof(uint64));
|
||||
|
||||
instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(true));
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
me->setActive(true);
|
||||
DoZoneInCombat();
|
||||
instance->SetBossState(DATA_LORD_MARROWGAR, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spell)
|
||||
{
|
||||
if (target && (spell->Id == 69055 || spell->Id == 70814)) // Bone Slice (Saber Lash)
|
||||
for (uint8 i=0; i<3; ++i)
|
||||
if (!_lastBoneSliceTargets[i])
|
||||
{
|
||||
_lastBoneSliceTargets[i] = target->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetGUID(int32 id) const
|
||||
{
|
||||
if (id >= 0 && id <= 2)
|
||||
return _lastBoneSliceTargets[id];
|
||||
|
||||
return (uint64)0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EVENT_ENABLE_BONE_SLICE:
|
||||
_boneSlice = true;
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_BONE_SPIKE_GRAVEYARD:
|
||||
{
|
||||
bool a = me->HasAura(SPELL_BONE_STORM);
|
||||
if (IsHeroic() || !a)
|
||||
me->CastSpell(me, SPELL_BONE_SPIKE_GRAVEYARD, a);
|
||||
events.RepeatEvent(urand(15000, 20000));
|
||||
}
|
||||
break;
|
||||
case EVENT_SPELL_COLDFLAME:
|
||||
if (!me->HasAura(SPELL_BONE_STORM))
|
||||
me->CastSpell((Unit*)NULL, SPELL_COLDFLAME_NORMAL, false);
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
case EVENT_SPELL_COLDFLAME_BONE_STORM:
|
||||
me->CastSpell(me, SPELL_COLDFLAME_BONE_STORM, false);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_WARN_BONE_STORM:
|
||||
_boneSlice = false;
|
||||
Talk(EMOTE_BONE_STORM);
|
||||
Talk(SAY_BONE_STORM);
|
||||
me->FinishSpell(CURRENT_MELEE_SPELL, false);
|
||||
me->CastSpell(me, SPELL_BONE_STORM, false);
|
||||
me->SetReactState(REACT_PASSIVE); // to prevent chasing another target on UpdateVictim()
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
events.RepeatEvent(urand(90000, 95000));
|
||||
events.ScheduleEvent(EVENT_BEGIN_BONE_STORM, 3050);
|
||||
break;
|
||||
case EVENT_BEGIN_BONE_STORM:
|
||||
{
|
||||
uint32 _boneStormDuration = RAID_MODE<uint32>(20000, 30000, 20000, 30000);
|
||||
if (Aura* pStorm = me->GetAura(SPELL_BONE_STORM))
|
||||
pStorm->SetDuration(int32(_boneStormDuration));
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_BONE_STORM_MOVE, 0);
|
||||
events.ScheduleEvent(EVENT_END_BONE_STORM, _boneStormDuration+1);
|
||||
}
|
||||
break;
|
||||
case EVENT_BONE_STORM_MOVE:
|
||||
{
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
|
||||
{
|
||||
events.RepeatEvent(1);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(5000);
|
||||
Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0, BoneStormMoveTargetSelector(me));
|
||||
if (!unit)
|
||||
{
|
||||
if (unit = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 175.0f, true))
|
||||
if (unit->GetPositionX() > -337.0f)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (unit)
|
||||
me->GetMotionMaster()->MoveCharge(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), 25.0f, 1337);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_END_BONE_STORM:
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoStartMovement(me->GetVictim());
|
||||
events.PopEvent();
|
||||
events.CancelEvent(EVENT_BONE_STORM_MOVE);
|
||||
events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000);
|
||||
if (!IsHeroic())
|
||||
events.RescheduleEvent(EVENT_SPELL_BONE_SPIKE_GRAVEYARD, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
Talk(SAY_BERSERK);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasAura(SPELL_BONE_STORM))
|
||||
return;
|
||||
|
||||
if (_boneSlice && !me->GetCurrentSpell(CURRENT_MELEE_SPELL))
|
||||
DoCastVictim(SPELL_BONE_SLICE);
|
||||
|
||||
if (_boneSlice && me->isAttackReady() && me->GetVictim() && !me->HasUnitState(UNIT_STATE_CASTING) && me->IsWithinMeleeRange(me->GetVictim()))
|
||||
memset(_lastBoneSliceTargets, 0, 3 * sizeof(uint64));
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || id != 1337)
|
||||
return;
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_COLDFLAME_BONE_STORM, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_LORD_MARROWGAR, FAIL);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!_introDone && me->IsAlive() && who->GetTypeId() == TYPEID_PLAYER && me->GetExactDist2dSq(who) <= 10000.0f) // 100*100, moveinlineofsight limited to 60yd anyway
|
||||
{
|
||||
Talk(SAY_ENTER_ZONE);
|
||||
_introDone = true;
|
||||
}
|
||||
|
||||
BossAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
bool CanAIAttack(Unit const* target) const
|
||||
{
|
||||
return target->GetPositionX() < -337.0f; // main gate
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<boss_lord_marrowgarAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_coldflame : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_coldflame() : CreatureScript("npc_coldflame") { }
|
||||
|
||||
struct npc_coldflameAI : public NullCreatureAI
|
||||
{
|
||||
npc_coldflameAI(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/)
|
||||
{
|
||||
events.ScheduleEvent(1, 450);
|
||||
events.ScheduleEvent(2, 12000);
|
||||
me->m_positionZ = 42.5f;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
me->m_positionZ = 42.5f;
|
||||
me->DisableSpline();
|
||||
me->CastSpell(me, SPELL_COLDFLAME_SUMMON, true);
|
||||
float nx = me->GetPositionX()+5.0f*cos(me->GetOrientation());
|
||||
float ny = me->GetPositionY()+5.0f*sin(me->GetOrientation());
|
||||
if (!me->IsWithinLOS(nx, ny, 42.5f))
|
||||
{
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
me->NearTeleportTo(nx, ny, 42.5f, me->GetOrientation());
|
||||
events.RepeatEvent(450);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
events.Reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<npc_coldflameAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_bone_spike : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_bone_spike() : CreatureScript("npc_bone_spike") { }
|
||||
|
||||
struct npc_bone_spikeAI : public NullCreatureAI
|
||||
{
|
||||
npc_bone_spikeAI(Creature* creature) : NullCreatureAI(creature), hasTrappedUnit(false)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool hasTrappedUnit;
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
if (action != -1337)
|
||||
return;
|
||||
|
||||
if (TempSummon* summ = me->ToTempSummon())
|
||||
if (Unit* trapped = summ->GetSummoner())
|
||||
{
|
||||
Position exitPos = {me->GetPositionX(), me->GetPositionY(), 60.0f, me->GetOrientation()};
|
||||
trapped->UpdateAllowedPositionZ(exitPos.GetPositionX(), exitPos.GetPositionY(), exitPos.m_positionZ);
|
||||
exitPos.m_positionZ += 1.0f;
|
||||
if (Unit* vehBase = trapped->GetVehicleBase())
|
||||
vehBase->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, trapped->GetGUID());
|
||||
trapped->_ExitVehicle(&exitPos);
|
||||
trapped->RemoveAurasDueToSpell(SPELL_IMPALED);
|
||||
trapped->GetMotionMaster()->Clear();
|
||||
trapped->UpdatePosition(exitPos, true);
|
||||
trapped->StopMovingOnCurrentPos();
|
||||
trapped->NearTeleportTo(exitPos.GetPositionX(), exitPos.GetPositionY(), exitPos.GetPositionZ(), exitPos.GetOrientation(), false);
|
||||
}
|
||||
|
||||
me->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
DoAction(-1337);
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* summoner)
|
||||
{
|
||||
if (!summoner)
|
||||
return;
|
||||
|
||||
if (Vehicle* v = summoner->GetVehicle())
|
||||
if (Unit* u = v->GetBase())
|
||||
if (u->GetEntry() == NPC_BONE_SPIKE && u->GetTypeId() == TYPEID_UNIT)
|
||||
u->ToCreature()->AI()->DoAction(-1337);
|
||||
|
||||
uint64 petGUID = summoner->GetPetGUID();
|
||||
summoner->SetPetGUID(0);
|
||||
me->CastSpell(summoner, SPELL_IMPALED, true);
|
||||
summoner->CastSpell(me, SPELL_RIDE_VEHICLE, true);
|
||||
//summoner->ClearUnitState(UNIT_STATE_ONVEHICLE);
|
||||
summoner->SetPetGUID(petGUID);
|
||||
summoner->GetMotionMaster()->Clear();
|
||||
summoner->StopMoving();
|
||||
events.ScheduleEvent(1, 8000);
|
||||
hasTrappedUnit = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!hasTrappedUnit || !me->IsAlive())
|
||||
return;
|
||||
|
||||
if (TempSummon* summ = me->ToTempSummon())
|
||||
{
|
||||
if (Unit* trapped = summ->GetSummoner())
|
||||
{
|
||||
if (!trapped->IsOnVehicle(me) || !trapped->IsAlive() || !me->GetInstanceScript() || me->GetInstanceScript()->GetBossState(DATA_LORD_MARROWGAR) != IN_PROGRESS || trapped->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
|
||||
{
|
||||
DoAction(-1337);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
me->DespawnOrUnsummon(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
me->DespawnOrUnsummon(1);
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (events.ExecuteEvent() == 1)
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(DATA_BONED_ACHIEVEMENT, uint32(false));
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<npc_bone_spikeAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_marrowgar_coldflame : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_marrowgar_coldflame() : SpellScriptLoader("spell_marrowgar_coldflame") { }
|
||||
|
||||
class spell_marrowgar_coldflame_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_marrowgar_coldflame_SpellScript);
|
||||
|
||||
void SelectTarget(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.clear();
|
||||
Unit* target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 1, -1.0f, true, -SPELL_IMPALED); // -1.0f as it takes into account object size
|
||||
if (!target)
|
||||
target = GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); // if only tank or noone outside of boss' model
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
targets.push_back(target);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
float angle = caster->GetAngle(GetHitUnit());
|
||||
float dist = caster->GetObjectSize()/2.0f;
|
||||
float z = caster->GetPositionZ()+2.5f;
|
||||
float nx = caster->GetPositionX()+dist*cos(angle);
|
||||
float ny = caster->GetPositionY()+dist*sin(angle);
|
||||
|
||||
if (!caster->IsWithinLOS(nx, ny, z))
|
||||
{
|
||||
nx = caster->GetPositionX()+0.5f*cos(angle);
|
||||
ny = caster->GetPositionY()+0.5f*sin(angle);
|
||||
}
|
||||
|
||||
if (caster->IsWithinLOS(nx, ny, z))
|
||||
{
|
||||
caster->m_orientation = angle;
|
||||
caster->CastSpell(nx, ny, z, uint32(GetEffectValue()), true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_marrowgar_coldflame_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_marrowgar_bone_spike_graveyard() : SpellScriptLoader("spell_marrowgar_bone_spike_graveyard") { }
|
||||
|
||||
class spell_marrowgar_bone_spike_graveyard_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_marrowgar_bone_spike_graveyard_SpellScript);
|
||||
|
||||
void HandleSpikes(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Creature* marrowgar = GetCaster()->ToCreature())
|
||||
{
|
||||
bool didHit = false;
|
||||
CreatureAI* marrowgarAI = marrowgar->AI();
|
||||
uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 3 : 1);
|
||||
|
||||
std::vector<Player*> validPlayers;
|
||||
Map::PlayerList const &pList = marrowgar->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
if (Player* plr = itr->GetSource())
|
||||
if (plr->IsAlive() && !plr->IsGameMaster() && plr->GetExactDist2dSq(marrowgar) < (150.0f * 150.0f) && !plr->HasAura(SPELL_IMPALED))
|
||||
if (!marrowgar->GetVictim() || marrowgar->GetVictim()->GetGUID() != plr->GetGUID())
|
||||
if (plr->GetGUID() != marrowgarAI->GetGUID(0) && plr->GetGUID() != marrowgarAI->GetGUID(1) && plr->GetGUID() != marrowgarAI->GetGUID(2)) // not a bone slice target
|
||||
validPlayers.push_back(plr);
|
||||
|
||||
std::vector<Player*>::iterator begin=validPlayers.begin(), end=validPlayers.end();
|
||||
std::random_shuffle(begin, end);
|
||||
|
||||
for (uint8 i = 0; i < boneSpikeCount && i < validPlayers.size(); ++i)
|
||||
{
|
||||
Unit* target = validPlayers[i];
|
||||
didHit = true;
|
||||
//target->CastCustomSpell(boneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true);
|
||||
target->CastSpell(target, boneSpikeSummonId[i], true);
|
||||
}
|
||||
|
||||
if (didHit)
|
||||
marrowgarAI->Talk(SAY_BONESPIKE);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_bone_spike_graveyard_SpellScript::HandleSpikes, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_marrowgar_bone_spike_graveyard_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_marrowgar_coldflame_bonestorm : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_marrowgar_coldflame_bonestorm() : SpellScriptLoader("spell_marrowgar_coldflame_bonestorm") { }
|
||||
|
||||
class spell_marrowgar_coldflame_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_marrowgar_coldflame_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
Unit* caster = GetCaster();
|
||||
float x = caster->GetPositionX();
|
||||
float y = caster->GetPositionY();
|
||||
float z = caster->GetPositionZ()+2.5f;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
float nx = x+2.5f*cos((M_PI/4)+(i*(M_PI/2)));
|
||||
float ny = y+2.5f*sin((M_PI/4)+(i*(M_PI/2)));
|
||||
if (caster->IsWithinLOS(nx, ny, z))
|
||||
{
|
||||
caster->m_orientation = (M_PI/4)+(i*(M_PI/2));
|
||||
caster->CastSpell(nx, ny, z, uint32(GetEffectValue() + i), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_marrowgar_coldflame_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_marrowgar_bone_storm : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_marrowgar_bone_storm() : SpellScriptLoader("spell_marrowgar_bone_storm") { }
|
||||
|
||||
class spell_marrowgar_bone_storm_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_marrowgar_bone_storm_SpellScript);
|
||||
|
||||
void RecalculateDamage()
|
||||
{
|
||||
float dist = GetHitUnit()->GetExactDist2d(GetCaster());
|
||||
if (dist >= 9.0f) dist -= 9.0f;
|
||||
else dist = 0.0f;
|
||||
SetHitDamage(int32(GetHitDamage() / std::max(sqrtf(dist), 1.0f)));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnHit += SpellHitFn(spell_marrowgar_bone_storm_SpellScript::RecalculateDamage);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_marrowgar_bone_storm_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_marrowgar_bone_slice : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_marrowgar_bone_slice() : SpellScriptLoader("spell_marrowgar_bone_slice") { }
|
||||
|
||||
class spell_marrowgar_bone_slice_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_marrowgar_bone_slice_SpellScript);
|
||||
|
||||
bool Load()
|
||||
{
|
||||
_targetCount = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CountTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
_targetCount = std::min<uint32>(targets.size(), GetSpellInfo()->MaxAffectedTargets);
|
||||
}
|
||||
|
||||
void SplitDamage()
|
||||
{
|
||||
if (!_targetCount)
|
||||
return; // This spell can miss all targets
|
||||
|
||||
SetHitDamage(GetHitDamage() / _targetCount);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_bone_slice_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
OnHit += SpellHitFn(spell_marrowgar_bone_slice_SpellScript::SplitDamage);
|
||||
}
|
||||
|
||||
uint32 _targetCount;
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_marrowgar_bone_slice_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_lord_marrowgar()
|
||||
{
|
||||
new boss_lord_marrowgar();
|
||||
new npc_coldflame();
|
||||
new npc_bone_spike();
|
||||
new spell_marrowgar_coldflame();
|
||||
new spell_marrowgar_coldflame_bonestorm();
|
||||
new spell_marrowgar_bone_spike_graveyard();
|
||||
new spell_marrowgar_bone_storm();
|
||||
new spell_marrowgar_bone_slice();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,961 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "icecrown_citadel.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_PRECIOUS_DIES = 0,
|
||||
SAY_AGGRO = 1,
|
||||
EMOTE_SLIME_SPRAY = 2,
|
||||
SAY_SLIME_SPRAY = 3,
|
||||
EMOTE_UNSTABLE_EXPLOSION = 4,
|
||||
SAY_UNSTABLE_EXPLOSION = 5,
|
||||
SAY_KILL = 6,
|
||||
SAY_BERSERK = 7,
|
||||
SAY_DEATH = 8,
|
||||
EMOTE_MUTATED_INFECTION = 9,
|
||||
|
||||
SAY_ROTFACE_OOZE_FLOOD = 2, // professor
|
||||
|
||||
EMOTE_PRECIOUS_ZOMBIES = 0,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Rotface
|
||||
SPELL_SLIME_SPRAY = 69508, // every 20 seconds
|
||||
SPELL_MUTATED_INFECTION = 69674, // hastens every 1:30
|
||||
|
||||
SPELL_VILE_GAS_H = 69240,
|
||||
|
||||
// Ooze Flood
|
||||
SPELL_OOZE_FLOOD_VISUAL = 69785,
|
||||
SPELL_OOZE_FLOOD_PERIODIC = 69788,
|
||||
|
||||
// Oozes
|
||||
SPELL_LITTLE_OOZE_COMBINE = 69537, // combine 2 Small Oozes
|
||||
SPELL_LARGE_OOZE_COMBINE = 69552, // combine 2 Large Oozes
|
||||
SPELL_LARGE_OOZE_BUFF_COMBINE = 69611, // combine Large and Small Ooze
|
||||
SPELL_OOZE_MERGE = 69889, // 2 Small Oozes summon a Large Ooze
|
||||
SPELL_WEAK_RADIATING_OOZE = 69750, // passive damage aura - small
|
||||
SPELL_RADIATING_OOZE = 69760, // passive damage aura - large
|
||||
SPELL_UNSTABLE_OOZE = 69558, // damage boost and counter for explosion
|
||||
SPELL_GREEN_ABOMINATION_HITTIN__YA_PROC = 70001, // prevents getting hit by infection
|
||||
SPELL_UNSTABLE_OOZE_EXPLOSION = 69839,
|
||||
SPELL_STICKY_OOZE = 69774,
|
||||
SPELL_UNSTABLE_OOZE_EXPLOSION_TRIGGER = 69832,
|
||||
|
||||
// Precious
|
||||
SPELL_MORTAL_WOUND = 71127,
|
||||
SPELL_DECIMATE = 71123,
|
||||
SPELL_AWAKEN_PLAGUED_ZOMBIES = 71159,
|
||||
};
|
||||
|
||||
#define MUTATED_INFECTION RAID_MODE<int32>(69674, 71224, 73022, 73023)
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
// Rotface
|
||||
EVENT_UNROOT,
|
||||
EVENT_SLIME_SPRAY,
|
||||
EVENT_HASTEN_INFECTIONS,
|
||||
EVENT_MUTATED_INFECTION,
|
||||
EVENT_ROTFACE_OOZE_FLOOD,
|
||||
EVENT_ROTFACE_VILE_GAS,
|
||||
|
||||
EVENT_STICKY_OOZE,
|
||||
|
||||
// Precious
|
||||
EVENT_DECIMATE,
|
||||
EVENT_MORTAL_WOUND,
|
||||
EVENT_SUMMON_ZOMBIES,
|
||||
};
|
||||
|
||||
uint32 const oozeFloodSpells[4] = {69782, 69796, 69798, 69801};
|
||||
uint32 getOozeFloodSpellIndex(uint32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 69782: return 0;
|
||||
case 69796: return 1;
|
||||
case 69798: return 2;
|
||||
case 69801: return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct RotfaceHeightCheck
|
||||
{
|
||||
RotfaceHeightCheck() {}
|
||||
|
||||
bool operator()(Creature* stalker) const
|
||||
{
|
||||
return stalker->GetPositionZ() < 365.0f;
|
||||
}
|
||||
};
|
||||
|
||||
class boss_rotface : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_rotface() : CreatureScript("boss_rotface") { }
|
||||
|
||||
struct boss_rotfaceAI : public BossAI
|
||||
{
|
||||
boss_rotfaceAI(Creature* creature) : BossAI(creature, DATA_ROTFACE)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 infectionCooldown;
|
||||
uint64 _oozeFloodDummyGUIDs[4][2];
|
||||
uint8 _oozeFloodStage;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
infectionCooldown = 14000;
|
||||
memset(&_oozeFloodDummyGUIDs, 0, sizeof(_oozeFloodDummyGUIDs));
|
||||
_oozeFloodStage = 0;
|
||||
_Reset();
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
if (!instance->CheckRequiredBosses(DATA_ROTFACE, who->ToPlayer()))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
|
||||
return;
|
||||
}
|
||||
|
||||
// schedule events
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000);
|
||||
events.ScheduleEvent(EVENT_HASTEN_INFECTIONS, 90000);
|
||||
events.ScheduleEvent(EVENT_MUTATED_INFECTION, 14000);
|
||||
events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 8000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000));
|
||||
|
||||
me->setActive(true);
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->DoAction(ACTION_ROTFACE_COMBAT);
|
||||
|
||||
instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(true)); // reset
|
||||
|
||||
// randomize ooze flood
|
||||
_oozeFloodStage = urand(0,3);
|
||||
std::list<Creature*> list;
|
||||
GetCreatureListWithEntryInGrid(list, me, NPC_PUDDLE_STALKER, 60.0f);
|
||||
list.remove_if(RotfaceHeightCheck()); // remove from the list all on the ground
|
||||
for (std::list<Creature*>::const_iterator itr = list.begin(); itr != list.end(); ++itr)
|
||||
{
|
||||
uint32 index = me->GetHomePosition().GetAngle(*itr)/(M_PI/2.0f);
|
||||
if (index>3) index = 3;
|
||||
if (_oozeFloodDummyGUIDs[index][0])
|
||||
_oozeFloodDummyGUIDs[index][1] = (*itr)->GetGUID();
|
||||
else
|
||||
_oozeFloodDummyGUIDs[index][0] = (*itr)->GetGUID();
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(MUTATED_INFECTION);
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->DoAction(ACTION_ROTFACE_DEATH);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(DATA_ROTFACE, FAIL);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (me->IsAlive() && me->IsInCombat() && !me->IsInEvadeMode())
|
||||
summons.Summon(summon);
|
||||
else
|
||||
summon->DespawnOrUnsummon(1);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->AI()->EnterEvadeMode();
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, SpellInfo const* spell)
|
||||
{
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_SLIME_SPRAY:
|
||||
Talk(SAY_SLIME_SPRAY);
|
||||
break;
|
||||
case 69507: // Slime Spray damage
|
||||
case 71213:
|
||||
case 73189:
|
||||
case 73190:
|
||||
if (Player* p = target->ToPlayer())
|
||||
if (p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_10) == QUEST_STATUS_INCOMPLETE || p->GetQuestStatus(QUEST_RESIDUE_RENDEZVOUS_25) == QUEST_STATUS_INCOMPLETE)
|
||||
p->CastSpell(p, SPELL_GREEN_BLIGHT_RESIDUE, true);
|
||||
break;
|
||||
case 69782:
|
||||
case 69796:
|
||||
case 69798:
|
||||
case 69801:
|
||||
{
|
||||
uint32 index = getOozeFloodSpellIndex(spell->Id);
|
||||
if (target->GetGUID() == _oozeFloodDummyGUIDs[index][0] || target->GetGUID() == _oozeFloodDummyGUIDs[index][1])
|
||||
target->CastSpell((Unit*)NULL, spell->Effects[0].CalcValue(), false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_UNROOT:
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(false);
|
||||
break;
|
||||
case EVENT_SLIME_SPRAY:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
|
||||
{
|
||||
if (Creature* c = me->SummonCreature(NPC_OOZE_SPRAY_STALKER, *target, TEMPSUMMON_TIMED_DESPAWN, 8000))
|
||||
{
|
||||
me->SetOrientation(me->GetAngle(c));
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
me->DisableRotate(true);
|
||||
me->SetFacingTo(me->GetAngle(c));
|
||||
me->SendMovementFlagUpdate();
|
||||
Talk(EMOTE_SLIME_SPRAY);
|
||||
me->CastSpell(c, SPELL_SLIME_SPRAY, false);
|
||||
}
|
||||
}
|
||||
events.DelayEvents(1);
|
||||
events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000);
|
||||
events.ScheduleEvent(EVENT_UNROOT, 0);
|
||||
break;
|
||||
case EVENT_HASTEN_INFECTIONS:
|
||||
if (infectionCooldown >= 8000)
|
||||
{
|
||||
infectionCooldown -= 2000;
|
||||
events.ScheduleEvent(EVENT_HASTEN_INFECTIONS, 90000);
|
||||
}
|
||||
break;
|
||||
case EVENT_MUTATED_INFECTION:
|
||||
me->CastCustomSpell(SPELL_MUTATED_INFECTION, SPELLVALUE_MAX_TARGETS, 1, NULL, false);
|
||||
events.ScheduleEvent(EVENT_MUTATED_INFECTION, infectionCooldown);
|
||||
break;
|
||||
case EVENT_ROTFACE_OOZE_FLOOD:
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
{
|
||||
professor->AI()->Talk(SAY_ROTFACE_OOZE_FLOOD);
|
||||
me->CastSpell((Unit*)NULL, oozeFloodSpells[_oozeFloodStage], true);
|
||||
if (++_oozeFloodStage == 4)
|
||||
_oozeFloodStage = 0;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000);
|
||||
break;
|
||||
case EVENT_ROTFACE_VILE_GAS:
|
||||
{
|
||||
std::list<Unit*> targets;
|
||||
uint32 minTargets = RAID_MODE<uint32>(3, 8, 3, 8);
|
||||
SelectTargetList(targets, minTargets, SELECT_TARGET_RANDOM, -5.0f, true);
|
||||
float minDist = 0.0f;
|
||||
if (targets.size() >= minTargets)
|
||||
minDist = -5.0f;
|
||||
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, minDist, true))
|
||||
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE)))
|
||||
professor->CastSpell(target, SPELL_VILE_GAS_H, true); // triggered, to skip LoS check
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ROTFACE_VILE_GAS, urand(15000, 20000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<boss_rotfaceAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_little_ooze : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_little_ooze() : CreatureScript("npc_little_ooze") { }
|
||||
|
||||
struct npc_little_oozeAI : public ScriptedAI
|
||||
{
|
||||
npc_little_oozeAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript())
|
||||
{
|
||||
firstUpdate = true;
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
|
||||
rotface->AI()->JustSummoned(me);
|
||||
}
|
||||
|
||||
bool firstUpdate;
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
|
||||
void IsSummonedBy(Unit* summoner)
|
||||
{
|
||||
if (!summoner)
|
||||
return;
|
||||
|
||||
me->AddThreat(summoner, 500000.0f);
|
||||
AttackStart(summoner);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
|
||||
rotface->AI()->SummonedCreatureDespawn(me);
|
||||
me->DespawnOrUnsummon(0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (firstUpdate)
|
||||
{
|
||||
firstUpdate = false;
|
||||
me->CastSpell(me, SPELL_LITTLE_OOZE_COMBINE, true);
|
||||
me->CastSpell(me, SPELL_WEAK_RADIATING_OOZE, true);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_STICKY_OOZE, 5000);
|
||||
DoResetThreat();
|
||||
me->SetInCombatWithZone();
|
||||
if (TempSummon* ts = me->ToTempSummon())
|
||||
if (Unit* summoner = ts->GetSummoner())
|
||||
{
|
||||
me->AddThreat(summoner, 500000.0f);
|
||||
AttackStart(summoner);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (events.ExecuteEvent() == EVENT_STICKY_OOZE)
|
||||
{
|
||||
me->CastSpell(me->GetVictim(), SPELL_STICKY_OOZE, false);
|
||||
events.ScheduleEvent(EVENT_STICKY_OOZE, 15000);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<npc_little_oozeAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_big_ooze : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_big_ooze() : CreatureScript("npc_big_ooze") { }
|
||||
|
||||
struct npc_big_oozeAI : public ScriptedAI
|
||||
{
|
||||
npc_big_oozeAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript())
|
||||
{
|
||||
firstUpdate = true;
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
|
||||
rotface->AI()->JustSummoned(me);
|
||||
}
|
||||
|
||||
bool firstUpdate;
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/)
|
||||
{
|
||||
if (Player* p = me->SelectNearestPlayer(100.0f))
|
||||
AttackStart(p);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
|
||||
rotface->AI()->SummonedCreatureDespawn(me);
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void DoAction(int32 action)
|
||||
{
|
||||
if (action == EVENT_STICKY_OOZE)
|
||||
events.CancelEvent(EVENT_STICKY_OOZE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (firstUpdate)
|
||||
{
|
||||
firstUpdate = false;
|
||||
me->CastSpell(me, SPELL_LARGE_OOZE_COMBINE, true);
|
||||
me->CastSpell(me, SPELL_LARGE_OOZE_BUFF_COMBINE, true);
|
||||
me->CastSpell(me, SPELL_RADIATING_OOZE, true);
|
||||
me->CastSpell(me, SPELL_UNSTABLE_OOZE, true);
|
||||
me->CastSpell(me, SPELL_GREEN_ABOMINATION_HITTIN__YA_PROC, true);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_STICKY_OOZE, 5000);
|
||||
DoResetThreat();
|
||||
me->SetInCombatWithZone();
|
||||
if (Player* p = me->SelectNearestPlayer(100.0f))
|
||||
AttackStart(p);
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_STICKY_OOZE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_STICKY_OOZE, false);
|
||||
events.ScheduleEvent(EVENT_STICKY_OOZE, 15000);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->IsVisible())
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<npc_big_oozeAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_mutated_infection : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_mutated_infection() : SpellScriptLoader("spell_rotface_mutated_infection") { }
|
||||
|
||||
class spell_rotface_mutated_infection_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_rotface_mutated_infection_SpellScript);
|
||||
|
||||
bool Load()
|
||||
{
|
||||
_target = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
// remove targets with this aura already
|
||||
// tank is not on this list
|
||||
targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
|
||||
targets.remove(GetCaster()->GetVictim());
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
_target = target;
|
||||
}
|
||||
|
||||
void ReplaceTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.clear();
|
||||
if (_target)
|
||||
targets.push_back(_target);
|
||||
}
|
||||
|
||||
void NotifyTargets()
|
||||
{
|
||||
if (Creature* caster = GetCaster()->ToCreature())
|
||||
if (Unit* target = GetHitUnit())
|
||||
caster->AI()->Talk(EMOTE_MUTATED_INFECTION, target);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
AfterHit += SpellHitFn(spell_rotface_mutated_infection_SpellScript::NotifyTargets);
|
||||
}
|
||||
|
||||
WorldObject* _target;
|
||||
};
|
||||
|
||||
class spell_rotface_mutated_infection_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_rotface_mutated_infection_AuraScript);
|
||||
|
||||
void ExtraRemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[2].CalcValue(), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_rotface_mutated_infection_AuraScript::ExtraRemoveEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_rotface_mutated_infection_SpellScript();
|
||||
}
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_rotface_mutated_infection_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_little_ooze_combine : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_little_ooze_combine() : SpellScriptLoader("spell_rotface_little_ooze_combine") { }
|
||||
|
||||
class spell_rotface_little_ooze_combine_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_rotface_little_ooze_combine_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// little targetting little
|
||||
|
||||
if (!GetHitCreature() || !GetHitCreature()->IsAlive())
|
||||
return;
|
||||
|
||||
GetCaster()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE);
|
||||
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE);
|
||||
GetHitCreature()->CastSpell(GetCaster(), SPELL_OOZE_MERGE, true);
|
||||
GetHitCreature()->DespawnOrUnsummon();
|
||||
if (GetCaster()->ToCreature())
|
||||
GetCaster()->ToCreature()->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_rotface_little_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_rotface_little_ooze_combine_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_large_ooze_combine : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_large_ooze_combine() : SpellScriptLoader("spell_rotface_large_ooze_combine") { }
|
||||
|
||||
class spell_rotface_large_ooze_combine_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_rotface_large_ooze_combine_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// large targetting large
|
||||
|
||||
if (!GetHitCreature() || !GetHitCreature()->IsAlive())
|
||||
return;
|
||||
|
||||
uint8 casterStack = 1;
|
||||
uint8 targetStack = 1;
|
||||
Aura* casterAura = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE);
|
||||
if (casterAura)
|
||||
casterStack = casterAura->GetStackAmount();
|
||||
Aura* targetAura = GetHitCreature()->GetAura(SPELL_UNSTABLE_OOZE);
|
||||
if (targetAura)
|
||||
targetStack = targetAura->GetStackAmount();
|
||||
uint8 newStack = casterStack+targetStack;
|
||||
if (newStack > 5)
|
||||
newStack = 5;
|
||||
if (casterAura)
|
||||
casterAura->SetStackAmount(newStack);
|
||||
else
|
||||
{
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE, true);
|
||||
if (Aura* aur = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE))
|
||||
aur->SetStackAmount(newStack);
|
||||
}
|
||||
|
||||
// red color!
|
||||
if (newStack >= 4)
|
||||
GetCaster()->CastSpell(GetCaster(), 69844, true);
|
||||
|
||||
// explode!
|
||||
if (newStack >= 5)
|
||||
{
|
||||
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
|
||||
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE)))
|
||||
if (rotface->IsAlive())
|
||||
{
|
||||
if (GetCaster()->GetTypeId() == TYPEID_UNIT)
|
||||
GetCaster()->ToCreature()->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION);
|
||||
rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION);
|
||||
}
|
||||
|
||||
if (Creature* cre = GetCaster()->ToCreature())
|
||||
cre->AI()->DoAction(EVENT_STICKY_OOZE);
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, GetCaster()->GetGUID());
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false));
|
||||
}
|
||||
|
||||
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
|
||||
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
|
||||
GetHitCreature()->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_rotface_large_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_rotface_large_ooze_combine_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_large_ooze_buff_combine : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_large_ooze_buff_combine() : SpellScriptLoader("spell_rotface_large_ooze_buff_combine") { }
|
||||
|
||||
class spell_rotface_large_ooze_buff_combine_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_rotface_large_ooze_buff_combine_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
// large targetting little
|
||||
|
||||
if (!GetHitCreature() || !GetHitCreature()->IsAlive())
|
||||
return;
|
||||
|
||||
if (Aura* unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE))
|
||||
{
|
||||
uint8 newStack = uint8(unstable->GetStackAmount()+1);
|
||||
unstable->SetStackAmount(newStack);
|
||||
|
||||
// red color!
|
||||
if (newStack >= 4)
|
||||
GetCaster()->CastSpell(GetCaster(), 69844, true);
|
||||
|
||||
// explode!
|
||||
if (newStack >= 5)
|
||||
{
|
||||
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
|
||||
GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE)))
|
||||
if (rotface->IsAlive())
|
||||
{
|
||||
if (GetCaster()->GetTypeId() == TYPEID_UNIT)
|
||||
GetCaster()->ToCreature()->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION);
|
||||
rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION);
|
||||
}
|
||||
|
||||
if (Creature* cre = GetCaster()->ToCreature())
|
||||
cre->AI()->DoAction(EVENT_STICKY_OOZE);
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, GetCaster()->GetGUID());
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false));
|
||||
}
|
||||
}
|
||||
|
||||
GetHitCreature()->RemoveAurasDueToSpell(SPELL_LITTLE_OOZE_COMBINE);
|
||||
GetHitCreature()->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_rotface_large_ooze_buff_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_rotface_large_ooze_buff_combine_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_unstable_ooze_explosion_init : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_unstable_ooze_explosion_init() : SpellScriptLoader("spell_rotface_unstable_ooze_explosion_init") { }
|
||||
|
||||
class spell_rotface_unstable_ooze_explosion_init_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_rotface_unstable_ooze_explosion_init_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_OOZE_EXPLOSION_TRIGGER))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleCast(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitEffect(effIndex);
|
||||
if (!GetHitUnit())
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
GetHitUnit()->GetPosition(x, y, z);
|
||||
Creature* dummy = GetCaster()->SummonCreature(NPC_UNSTABLE_EXPLOSION_STALKER, x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000);
|
||||
GetCaster()->CastSpell(dummy, SPELL_UNSTABLE_OOZE_EXPLOSION_TRIGGER, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_rotface_unstable_ooze_explosion_init_SpellScript::HandleCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_rotface_unstable_ooze_explosion_init_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_unstable_ooze_explosion : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_unstable_ooze_explosion() : SpellScriptLoader("spell_rotface_unstable_ooze_explosion") { }
|
||||
|
||||
class spell_rotface_unstable_ooze_explosion_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_rotface_unstable_ooze_explosion_SpellScript);
|
||||
|
||||
void CheckTarget(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(EFFECT_0);
|
||||
if (!GetExplTargetDest())
|
||||
return;
|
||||
|
||||
uint32 triggered_spell_id = GetSpellInfo()->Effects[effIndex].TriggerSpell;
|
||||
|
||||
float x, y, z;
|
||||
GetExplTargetDest()->GetPosition(x, y, z);
|
||||
// let Rotface handle the cast - caster dies before this executes
|
||||
if (InstanceScript* script = GetCaster()->GetInstanceScript())
|
||||
if (Creature* rotface = script->instance->GetCreature(script->GetData64(DATA_ROTFACE)))
|
||||
rotface->CastSpell(x, y, z, triggered_spell_id, true/*, NULL, NULL, GetCaster()->GetGUID()*/); // caster not available on clientside, no log in such case
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_rotface_unstable_ooze_explosion_SpellScript::CheckTarget, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_rotface_unstable_ooze_explosion_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_rotface_unstable_ooze_explosion_suicide : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_rotface_unstable_ooze_explosion_suicide() : SpellScriptLoader("spell_rotface_unstable_ooze_explosion_suicide") { }
|
||||
|
||||
class spell_rotface_unstable_ooze_explosion_suicide_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_rotface_unstable_ooze_explosion_suicide_AuraScript);
|
||||
|
||||
void DespawnSelf(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
Unit* target = GetTarget();
|
||||
if (target->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
target->SetVisible(false);
|
||||
target->RemoveAllAuras();
|
||||
//target->ToCreature()->DespawnOrUnsummon();
|
||||
target->ToCreature()->DespawnOrUnsummon(60000);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_rotface_unstable_ooze_explosion_suicide_AuraScript::DespawnSelf, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_rotface_unstable_ooze_explosion_suicide_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class npc_precious_icc : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_precious_icc() : CreatureScript("npc_precious_icc") { }
|
||||
|
||||
struct npc_precious_iccAI : public ScriptedAI
|
||||
{
|
||||
npc_precious_iccAI(Creature* creature) : ScriptedAI(creature), summons(me){}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*target*/)
|
||||
{
|
||||
me->setActive(true);
|
||||
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
|
||||
events.ScheduleEvent(EVENT_SUMMON_ZOMBIES, urand(25000, 30000));
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
summon->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (InstanceScript* _instance = me->GetInstanceScript())
|
||||
if (Creature* rotface = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ROTFACE)))
|
||||
if (rotface->IsAlive())
|
||||
rotface->AI()->Talk(SAY_PRECIOUS_DIES);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DECIMATE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_DECIMATE, false);
|
||||
events.ScheduleEvent(EVENT_DECIMATE, urand(20000, 25000));
|
||||
break;
|
||||
case EVENT_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(1500, 2500));
|
||||
break;
|
||||
case EVENT_SUMMON_ZOMBIES:
|
||||
Talk(EMOTE_PRECIOUS_ZOMBIES);
|
||||
for (uint32 i = 0; i < 11; ++i)
|
||||
me->CastSpell(me, SPELL_AWAKEN_PLAGUED_ZOMBIES, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ZOMBIES, urand(20000, 25000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetIcecrownCitadelAI<npc_precious_iccAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_rotface()
|
||||
{
|
||||
new boss_rotface();
|
||||
new npc_little_ooze();
|
||||
new npc_big_ooze();
|
||||
new spell_rotface_mutated_infection();
|
||||
new spell_rotface_little_ooze_combine();
|
||||
new spell_rotface_large_ooze_combine();
|
||||
new spell_rotface_large_ooze_buff_combine();
|
||||
new spell_rotface_unstable_ooze_explosion_init();
|
||||
new spell_rotface_unstable_ooze_explosion();
|
||||
new spell_rotface_unstable_ooze_explosion_suicide();
|
||||
|
||||
new npc_precious_icc();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,608 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef ICECROWN_CITADEL_H_
|
||||
#define ICECROWN_CITADEL_H_
|
||||
|
||||
#include "SpellScript.h"
|
||||
#include "Map.h"
|
||||
#include "Creature.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
#define ICCScriptName "instance_icecrown_citadel"
|
||||
|
||||
uint32 const WeeklyNPCs = 9;
|
||||
uint32 const MaxHeroicAttempts = 25;
|
||||
|
||||
// Defined in boss_valithria_dreamwalker.cpp
|
||||
extern Position const ValithriaSpawnPos;
|
||||
// Defined in boss_sindragosa.cpp
|
||||
extern Position const SindragosaSpawnPos;
|
||||
// Defined in boss_the_lich_king.cpp
|
||||
extern Position const TerenasSpawn;
|
||||
extern Position const TerenasSpawnHeroic;
|
||||
extern Position const SpiritWardenSpawn;
|
||||
|
||||
// Shared spells used by more than one script
|
||||
enum SharedSpells
|
||||
{
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_BERSERK2 = 47008,
|
||||
|
||||
// Deathbound Ward
|
||||
SPELL_STONEFORM = 70733,
|
||||
|
||||
// Residue Rendezvous
|
||||
SPELL_ORANGE_BLIGHT_RESIDUE = 72144,
|
||||
SPELL_GREEN_BLIGHT_RESIDUE = 72145,
|
||||
|
||||
// The Lich King
|
||||
SPELL_ARTHAS_TELEPORTER_CEREMONY = 72915,
|
||||
SPELL_FROSTMOURNE_TELEPORT_VISUAL = 73078,
|
||||
|
||||
// Shadowmourne questline
|
||||
SPELL_UNSATED_CRAVING = 71168,
|
||||
SPELL_SHADOWS_FATE = 71169,
|
||||
|
||||
// Misc
|
||||
SPELL_WEB_BEAM = 69887,
|
||||
SPELL_WEB_BEAM2 = 69986,
|
||||
SPELL_GIANT_INSECT_SWARM = 70475,
|
||||
SPELL_LEAP_TO_A_RANDOM_LOCATION = 70485
|
||||
};
|
||||
|
||||
enum TeleporterSpells
|
||||
{
|
||||
LIGHT_S_HAMMER_TELEPORT = 70781,
|
||||
ORATORY_OF_THE_DAMNED_TELEPORT = 70856,
|
||||
RAMPART_OF_SKULLS_TELEPORT = 70857,
|
||||
DEATHBRINGER_S_RISE_TELEPORT = 70858,
|
||||
UPPER_SPIRE_TELEPORT = 70859,
|
||||
FROZEN_THRONE_TELEPORT = 70860,
|
||||
SINDRAGOSA_S_LAIR_TELEPORT = 70861,
|
||||
};
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
// Encounter States/Boss GUIDs
|
||||
DATA_LORD_MARROWGAR = 0,
|
||||
DATA_LADY_DEATHWHISPER = 1,
|
||||
DATA_ICECROWN_GUNSHIP_BATTLE = 2,
|
||||
DATA_DEATHBRINGER_SAURFANG = 3,
|
||||
DATA_FESTERGUT = 4,
|
||||
DATA_ROTFACE = 5,
|
||||
DATA_PROFESSOR_PUTRICIDE = 6,
|
||||
DATA_BLOOD_PRINCE_COUNCIL = 7,
|
||||
DATA_BLOOD_QUEEN_LANA_THEL = 8,
|
||||
DATA_SISTER_SVALNA = 9,
|
||||
DATA_VALITHRIA_DREAMWALKER = 10,
|
||||
DATA_SINDRAGOSA = 11,
|
||||
DATA_THE_LICH_KING = 12,
|
||||
DATA_SINDRAGOSA_GAUNTLET = 13,
|
||||
DATA_BLOOD_PRINCE_TRASH = 14,
|
||||
MAX_ENCOUNTERS = 15,
|
||||
|
||||
// Additional data
|
||||
DATA_SAURFANG_EVENT_NPC = 13,
|
||||
DATA_BONED_ACHIEVEMENT = 14,
|
||||
DATA_OOZE_DANCE_ACHIEVEMENT = 15,
|
||||
DATA_PUTRICIDE_TABLE = 16,
|
||||
DATA_NAUSEA_ACHIEVEMENT = 17,
|
||||
DATA_ORB_WHISPERER_ACHIEVEMENT = 18,
|
||||
DATA_PRINCE_KELESETH_GUID = 19,
|
||||
DATA_PRINCE_TALDARAM_GUID = 20,
|
||||
DATA_PRINCE_VALANAR_GUID = 21,
|
||||
DATA_BLOOD_PRINCES_CONTROL = 22,
|
||||
DATA_SINDRAGOSA_FROSTWYRMS = 23,
|
||||
DATA_SPINESTALKER = 24,
|
||||
DATA_RIMEFANG = 25,
|
||||
DATA_COLDFLAME_JETS = 26,
|
||||
DATA_TEAMID_IN_INSTANCE = 27,
|
||||
DATA_BLOOD_QUICKENING_STATE = 28,
|
||||
DATA_HEROIC_ATTEMPTS = 29,
|
||||
DATA_CROK_SCOURGEBANE = 30,
|
||||
DATA_CAPTAIN_ARNATH = 31,
|
||||
DATA_CAPTAIN_BRANDON = 32,
|
||||
DATA_CAPTAIN_GRONDEL = 33,
|
||||
DATA_CAPTAIN_RUPERT = 34,
|
||||
DATA_VALITHRIA_TRIGGER = 35,
|
||||
DATA_VALITHRIA_LICH_KING = 36,
|
||||
DATA_HIGHLORD_TIRION_FORDRING = 37,
|
||||
DATA_ARTHAS_PLATFORM = 38,
|
||||
DATA_TERENAS_MENETHIL = 39,
|
||||
DATA_ENEMY_GUNSHIP = 40,
|
||||
|
||||
// pussywizard:
|
||||
DATA_BUFF_AVAILABLE = 251,
|
||||
DATA_WEEKLY_QUEST_ID = 252,
|
||||
// NONE = 253,
|
||||
DATA_PUTRICIDE_TRAP_STATE = 254,
|
||||
DATA_HAS_LIMITED_ATTEMPTS = 255,
|
||||
DATA_LK_HC_AVAILABLE = 256,
|
||||
|
||||
DATA_BPC_TRASH_DIED = 300,
|
||||
};
|
||||
|
||||
enum CreaturesIds
|
||||
{
|
||||
// At Light's Hammer
|
||||
NPC_HIGHLORD_TIRION_FORDRING_LH = 37119,
|
||||
NPC_THE_LICH_KING_LH = 37181,
|
||||
NPC_HIGHLORD_BOLVAR_FORDRAGON_LH = 37183,
|
||||
NPC_KOR_KRON_GENERAL = 37189,
|
||||
NPC_ALLIANCE_COMMANDER = 37190,
|
||||
NPC_TORTUNOK = 37992, // Druid Armor H
|
||||
NPC_ALANA_MOONSTRIKE = 37999, // Druid Armor A
|
||||
NPC_GERARDO_THE_SUAVE = 37993, // Hunter Armor H
|
||||
NPC_TALAN_MOONSTRIKE = 37998, // Hunter Armor A
|
||||
NPC_UVLUS_BANEFIRE = 38284, // Mage Armor H
|
||||
NPC_MALFUS_GRIMFROST = 38283, // Mage Armor A
|
||||
NPC_IKFIRUS_THE_VILE = 37991, // Rogue Armor H
|
||||
NPC_YILI = 37997, // Rogue Armor A
|
||||
NPC_VOL_GUK = 38841, // Shaman Armor H
|
||||
NPC_JEDEBIA = 38840, // Shaman Armor A
|
||||
NPC_HARAGG_THE_UNSEEN = 38181, // Warlock Armor H
|
||||
NPC_NIBY_THE_ALMIGHTY = 38182, // Warlock Armor N
|
||||
NPC_GARROSH_HELLSCREAM = 39372,
|
||||
NPC_KING_VARIAN_WRYNN = 39371,
|
||||
NPC_DEATHBOUND_WARD = 37007,
|
||||
NPC_HIGH_OVERLORD_SAURFANG_DUMMY = 32315,
|
||||
NPC_MURADIN_BRONZEBEARD_DUMMY = 38607,
|
||||
NPC_LADY_JAINA_PROUDMOORE_QUEST = 38606,
|
||||
NPC_MURADIN_BRONZEBEARD_QUEST = 38607,
|
||||
NPC_UTHER_THE_LIGHTBRINGER_QUEST = 38608,
|
||||
NPC_LADY_SYLVANAS_WINDRUNNER_QUEST = 38609,
|
||||
|
||||
// Weekly quests
|
||||
NPC_INFILTRATOR_MINCHAR = 38471,
|
||||
NPC_KOR_KRON_LIEUTENANT = 38491,
|
||||
NPC_SKYBREAKER_LIEUTENANT = 38492,
|
||||
NPC_ROTTING_FROST_GIANT_10 = 38490,
|
||||
NPC_ROTTING_FROST_GIANT_25 = 38494,
|
||||
NPC_ALCHEMIST_ADRIANNA = 38501,
|
||||
NPC_ALRIN_THE_AGILE = 38551,
|
||||
NPC_INFILTRATOR_MINCHAR_BQ = 38558,
|
||||
NPC_BLOOD_QUICKENING_CREDIT_25 = 39123,
|
||||
NPC_MINCHAR_BEAM_STALKER = 38557,
|
||||
NPC_VALITHRIA_DREAMWALKER_QUEST = 38589,
|
||||
|
||||
// Lord Marrowgar
|
||||
NPC_LORD_MARROWGAR = 36612,
|
||||
NPC_COLDFLAME = 36672,
|
||||
NPC_BONE_SPIKE = 36619,
|
||||
|
||||
// Lady Deathwhisper
|
||||
NPC_LADY_DEATHWHISPER = 36855,
|
||||
NPC_CULT_FANATIC = 37890,
|
||||
NPC_DEFORMED_FANATIC = 38135,
|
||||
NPC_REANIMATED_FANATIC = 38009,
|
||||
NPC_CULT_ADHERENT = 37949,
|
||||
NPC_EMPOWERED_ADHERENT = 38136,
|
||||
NPC_REANIMATED_ADHERENT = 38010,
|
||||
NPC_VENGEFUL_SHADE = 38222,
|
||||
|
||||
NPC_DEATHSPEAKER_SERVANT = 36805,
|
||||
NPC_RISEN_DEATHSPEAKER_SERVANT = 36844,
|
||||
|
||||
// Icecrown Gunship Battle
|
||||
NPC_MARTYR_STALKER_IGB_SAURFANG = 38569,
|
||||
NPC_ALLIANCE_GUNSHIP_CANNON = 36838,
|
||||
NPC_HORDE_GUNSHIP_CANNON = 36839,
|
||||
NPC_SKYBREAKER_DECKHAND = 36970,
|
||||
NPC_ORGRIMS_HAMMER_CREW = 36971,
|
||||
NPC_IGB_HIGH_OVERLORD_SAURFANG = 36939,
|
||||
NPC_IGB_MURADIN_BRONZEBEARD = 36948,
|
||||
NPC_THE_SKYBREAKER = 37540,
|
||||
NPC_ORGRIMS_HAMMER = 37215,
|
||||
NPC_GUNSHIP_HULL = 37547,
|
||||
NPC_TELEPORT_PORTAL = 37227,
|
||||
NPC_TELEPORT_EXIT = 37488,
|
||||
NPC_SKYBREAKER_SORCERER = 37116,
|
||||
NPC_SKYBREAKER_RIFLEMAN = 36969,
|
||||
NPC_SKYBREAKER_MORTAR_SOLDIER = 36978,
|
||||
NPC_SKYBREAKER_MARINE = 36950,
|
||||
NPC_SKYBREAKER_SERGEANT = 36961,
|
||||
NPC_KOR_KRON_BATTLE_MAGE = 37117,
|
||||
NPC_KOR_KRON_AXETHROWER = 36968,
|
||||
NPC_KOR_KRON_ROCKETEER = 36982,
|
||||
NPC_KOR_KRON_REAVER = 36957,
|
||||
NPC_KOR_KRON_SERGEANT = 36960,
|
||||
NPC_ZAFOD_BOOMBOX = 37184,
|
||||
NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT = 37182,
|
||||
NPC_SKY_REAVER_KORM_BLACKSCAR = 37833,
|
||||
|
||||
// Deathbringer Saurfang
|
||||
NPC_DEATHBRINGER_SAURFANG = 37813,
|
||||
NPC_BLOOD_BEAST = 38508,
|
||||
NPC_SE_JAINA_PROUDMOORE = 37188, // SE means Saurfang Event
|
||||
NPC_SE_MURADIN_BRONZEBEARD = 37200,
|
||||
NPC_SE_KING_VARIAN_WRYNN = 37879,
|
||||
NPC_SE_HIGH_OVERLORD_SAURFANG = 37187,
|
||||
NPC_SE_KOR_KRON_REAVER = 37920,
|
||||
NPC_SE_SKYBREAKER_MARINE = 37830,
|
||||
NPC_FROST_FREEZE_TRAP = 37744,
|
||||
|
||||
// Festergut
|
||||
NPC_FESTERGUT = 36626,
|
||||
NPC_GAS_DUMMY = 36659,
|
||||
|
||||
// Rotface
|
||||
NPC_ROTFACE = 36627,
|
||||
NPC_OOZE_SPRAY_STALKER = 37986,
|
||||
NPC_PUDDLE_STALKER = 37013,
|
||||
NPC_UNSTABLE_EXPLOSION_STALKER = 38107,
|
||||
|
||||
// Professor Putricide
|
||||
NPC_PROFESSOR_PUTRICIDE = 36678,
|
||||
NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER = 37824,
|
||||
NPC_GROWING_OOZE_PUDDLE = 37690,
|
||||
NPC_GAS_CLOUD = 37562,
|
||||
NPC_VOLATILE_OOZE = 37697,
|
||||
NPC_CHOKING_GAS_BOMB = 38159,
|
||||
NPC_TEAR_GAS_TARGET_STALKER = 38317,
|
||||
NPC_MUTATED_ABOMINATION_10 = 37672,
|
||||
NPC_MUTATED_ABOMINATION_25 = 38285,
|
||||
|
||||
// Blood Prince Council
|
||||
NPC_PRINCE_KELESETH = 37972,
|
||||
NPC_PRINCE_TALDARAM = 37973,
|
||||
NPC_PRINCE_VALANAR = 37970,
|
||||
NPC_BLOOD_ORB_CONTROLLER = 38008,
|
||||
NPC_FLOATING_TRIGGER = 30298,
|
||||
NPC_DARK_NUCLEUS = 38369,
|
||||
NPC_BALL_OF_FLAME = 38332,
|
||||
NPC_BALL_OF_INFERNO_FLAME = 38451,
|
||||
NPC_KINETIC_BOMB_TARGET = 38458,
|
||||
NPC_KINETIC_BOMB = 38454,
|
||||
NPC_SHOCK_VORTEX = 38422,
|
||||
|
||||
// Blood-Queen Lana'thel
|
||||
NPC_BLOOD_QUEEN_LANA_THEL = 37955,
|
||||
|
||||
// Frostwing Halls gauntlet event
|
||||
NPC_CROK_SCOURGEBANE = 37129,
|
||||
NPC_CAPTAIN_ARNATH = 37122,
|
||||
NPC_CAPTAIN_BRANDON = 37123,
|
||||
NPC_CAPTAIN_GRONDEL = 37124,
|
||||
NPC_CAPTAIN_RUPERT = 37125,
|
||||
NPC_CAPTAIN_ARNATH_UNDEAD = 37491,
|
||||
NPC_CAPTAIN_BRANDON_UNDEAD = 37493,
|
||||
NPC_CAPTAIN_GRONDEL_UNDEAD = 37494,
|
||||
NPC_CAPTAIN_RUPERT_UNDEAD = 37495,
|
||||
NPC_YMIRJAR_BATTLE_MAIDEN = 37132,
|
||||
NPC_YMIRJAR_DEATHBRINGER = 38125,
|
||||
NPC_YMIRJAR_FROSTBINDER = 37127,
|
||||
NPC_YMIRJAR_HUNTRESS = 37134,
|
||||
NPC_YMIRJAR_WARLORD = 37133,
|
||||
NPC_SISTER_SVALNA = 37126,
|
||||
NPC_IMPALING_SPEAR = 38248,
|
||||
|
||||
// Valithria Dreamwalker
|
||||
NPC_VALITHRIA_DREAMWALKER = 36789,
|
||||
NPC_GREEN_DRAGON_COMBAT_TRIGGER = 38752,
|
||||
NPC_RISEN_ARCHMAGE = 37868,
|
||||
NPC_BLAZING_SKELETON = 36791,
|
||||
NPC_SUPPRESSER = 37863,
|
||||
NPC_BLISTERING_ZOMBIE = 37934,
|
||||
NPC_GLUTTONOUS_ABOMINATION = 37886,
|
||||
NPC_MANA_VOID = 38068,
|
||||
NPC_COLUMN_OF_FROST = 37918,
|
||||
NPC_ROT_WORM = 37907,
|
||||
NPC_THE_LICH_KING_VALITHRIA = 38153,
|
||||
NPC_DREAM_PORTAL_PRE_EFFECT = 38186,
|
||||
NPC_NIGHTMARE_PORTAL_PRE_EFFECT = 38429,
|
||||
NPC_DREAM_PORTAL = 37945,
|
||||
NPC_NIGHTMARE_PORTAL = 38430,
|
||||
|
||||
// Sindragosa
|
||||
NPC_SINDRAGOSA = 36853,
|
||||
NPC_SPINESTALKER = 37534,
|
||||
NPC_RIMEFANG = 37533,
|
||||
NPC_FROSTWARDEN_HANDLER = 37531,
|
||||
NPC_FROSTWING_WHELP = 37532,
|
||||
NPC_ICY_BLAST = 38223,
|
||||
NPC_FROST_BOMB = 37186,
|
||||
NPC_ICE_TOMB = 36980,
|
||||
|
||||
// Sindragosa Gauntlet
|
||||
NPC_SINDRAGOSA_GAUNTLET = 37503,
|
||||
NPC_NERUBAR_CHAMPION = 37501,
|
||||
NPC_NERUBAR_WEBWEAVER = 37502,
|
||||
NPC_NERUBAR_BROODLING = 37232,
|
||||
NPC_FROSTWARDEN_SORCERESS = 37229,
|
||||
NPC_FROSTWARDEN_WARRIOR = 37228,
|
||||
|
||||
// Putricade Trap
|
||||
NPC_PUTRICADES_TRAP = 38879,
|
||||
NPC_FLASH_EATING_INSECT = 37782,
|
||||
|
||||
// The Lich King
|
||||
NPC_THE_LICH_KING = 36597,
|
||||
NPC_HIGHLORD_TIRION_FORDRING_LK = 38995,
|
||||
NPC_TERENAS_MENETHIL_FROSTMOURNE = 36823,
|
||||
NPC_SPIRIT_WARDEN = 36824,
|
||||
NPC_TERENAS_MENETHIL_FROSTMOURNE_H = 39217,
|
||||
NPC_SHAMBLING_HORROR = 37698,
|
||||
NPC_DRUDGE_GHOUL = 37695,
|
||||
NPC_ICE_SPHERE = 36633,
|
||||
NPC_RAGING_SPIRIT = 36701,
|
||||
NPC_DEFILE = 38757,
|
||||
NPC_SHADOW_TRAP_TRIGGER = 39137,
|
||||
NPC_VALKYR_SHADOWGUARD = 36609,
|
||||
NPC_VILE_SPIRIT = 37799,
|
||||
NPC_WICKED_SPIRIT = 39190,
|
||||
NPC_STRANGULATE_VEHICLE = 36598,
|
||||
NPC_WORLD_TRIGGER = 22515,
|
||||
NPC_WORLD_TRIGGER_INFINITE_AOI = 36171,
|
||||
NPC_SPIRIT_BOMB = 39189,
|
||||
NPC_FROSTMOURNE_TRIGGER = 38584,
|
||||
NPC_TERENAS_MENETHIL_OUTRO = 38579,
|
||||
|
||||
// Generic
|
||||
NPC_INVISIBLE_STALKER = 30298,
|
||||
NPC_SPIRE_FROSTWYRM = 37230,
|
||||
NPC_VENGEFUL_FLESHREAPER = 37038,
|
||||
};
|
||||
|
||||
enum GameObjectsIds
|
||||
{
|
||||
GO_SCOURGE_TRANSPORTER_FIRST = 202242,
|
||||
|
||||
// Traps
|
||||
GO_SPIRIT_ALARM_1 = 201814,
|
||||
GO_SPIRIT_ALARM_2 = 201815,
|
||||
GO_SPIRIT_ALARM_3 = 201816,
|
||||
GO_SPIRIT_ALARM_4 = 201817,
|
||||
GO_GEIST_ALARM_1 = 201888,
|
||||
GO_GEIST_ALARM_2 = 201889,
|
||||
|
||||
// Lord Marrogar
|
||||
GO_DOODAD_ICECROWN_ICEWALL02 = 201910,
|
||||
GO_ICEWALL = 201911,
|
||||
GO_LORD_MARROWGAR_S_ENTRANCE = 201857,
|
||||
|
||||
// Lady Deathwhisper
|
||||
GO_ORATORY_OF_THE_DAMNED_ENTRANCE = 201563,
|
||||
GO_LADY_DEATHWHISPER_ELEVATOR = 202220,
|
||||
|
||||
// Icecrown Gunship Battle - Horde raid
|
||||
GO_ORGRIMS_HAMMER_H = 201812,
|
||||
GO_THE_SKYBREAKER_H = 201811,
|
||||
GO_GUNSHIP_ARMORY_H_10N = 202178,
|
||||
GO_GUNSHIP_ARMORY_H_25N = 202180,
|
||||
GO_GUNSHIP_ARMORY_H_10H = 202177,
|
||||
GO_GUNSHIP_ARMORY_H_25H = 202179,
|
||||
|
||||
// Icecrown Gunship Battle - Alliance raid
|
||||
GO_ORGRIMS_HAMMER_A = 201581,
|
||||
GO_THE_SKYBREAKER_A = 201580,
|
||||
GO_GUNSHIP_ARMORY_A_10N = 201873,
|
||||
GO_GUNSHIP_ARMORY_A_25N = 201874,
|
||||
GO_GUNSHIP_ARMORY_A_10H = 201872,
|
||||
GO_GUNSHIP_ARMORY_A_25H = 201875,
|
||||
|
||||
// Deathbringer Saurfang
|
||||
GO_SAURFANG_S_DOOR = 201825,
|
||||
GO_DEATHBRINGER_S_CACHE_10N = 202239,
|
||||
GO_DEATHBRINGER_S_CACHE_25N = 202240,
|
||||
GO_DEATHBRINGER_S_CACHE_10H = 202238,
|
||||
GO_DEATHBRINGER_S_CACHE_25H = 202241,
|
||||
GO_SCOURGE_TRANSPORTER_SAURFANG = 202244,
|
||||
|
||||
// Professor Putricide
|
||||
GO_ORANGE_PLAGUE_MONSTER_ENTRANCE = 201371,
|
||||
GO_GREEN_PLAGUE_MONSTER_ENTRANCE = 201370,
|
||||
GO_SCIENTIST_AIRLOCK_DOOR_COLLISION = 201612,
|
||||
GO_SCIENTIST_AIRLOCK_DOOR_ORANGE = 201613,
|
||||
GO_SCIENTIST_AIRLOCK_DOOR_GREEN = 201614,
|
||||
GO_DOODAD_ICECROWN_ORANGETUBES02 = 201617,
|
||||
GO_DOODAD_ICECROWN_GREENTUBES02 = 201618,
|
||||
GO_SCIENTIST_ENTRANCE = 201372,
|
||||
GO_DRINK_ME = 201584,
|
||||
GO_PLAGUE_SIGIL = 202182,
|
||||
GO_GAS_RELEASE_VALVE = 201616,
|
||||
GO_OOZE_RELEASE_VALVE = 201615,
|
||||
|
||||
// Blood Prince Council
|
||||
GO_CRIMSON_HALL_DOOR = 201376,
|
||||
GO_BLOOD_ELF_COUNCIL_DOOR = 201378,
|
||||
GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT = 201377,
|
||||
|
||||
// Blood-Queen Lana'thel
|
||||
GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01 = 201746,
|
||||
GO_DOODAD_ICECROWN_GRATE_01 = 201755,
|
||||
GO_BLOODWING_SIGIL = 202183,
|
||||
|
||||
// Valithria Dreamwalker
|
||||
GO_GREEN_DRAGON_BOSS_ENTRANCE = 201375,
|
||||
GO_GREEN_DRAGON_BOSS_EXIT = 201374,
|
||||
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01 = 201380,
|
||||
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02 = 201381,
|
||||
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03 = 201382,
|
||||
GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04 = 201383,
|
||||
GO_CACHE_OF_THE_DREAMWALKER_10N = 201959,
|
||||
GO_CACHE_OF_THE_DREAMWALKER_25N = 202339,
|
||||
GO_CACHE_OF_THE_DREAMWALKER_10H = 202338,
|
||||
GO_CACHE_OF_THE_DREAMWALKER_25H = 202340,
|
||||
|
||||
// Sindragosa
|
||||
GO_SINDRAGOSA_ENTRANCE_DOOR = 201373,
|
||||
GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR = 201369,
|
||||
GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR = 201379,
|
||||
GO_ICE_WALL = 202396,
|
||||
GO_ICE_BLOCK = 201722,
|
||||
GO_SIGIL_OF_THE_FROSTWING = 202181,
|
||||
|
||||
// The Lich King
|
||||
GO_SCOURGE_TRANSPORTER_LK = 202223,
|
||||
GO_ARTHAS_PLATFORM = 202161,
|
||||
GO_ARTHAS_PRECIPICE = 202078,
|
||||
GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188,
|
||||
GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01 = 202189,
|
||||
GO_DOODAD_ICESHARD_STANDING02 = 202141,
|
||||
GO_DOODAD_ICESHARD_STANDING01 = 202142,
|
||||
GO_DOODAD_ICESHARD_STANDING03 = 202143,
|
||||
GO_DOODAD_ICESHARD_STANDING04 = 202144,
|
||||
GO_DOODAD_ICECROWN_SNOWEDGEWARNING01 = 202190,
|
||||
GO_FROZEN_LAVAMAN = 202436,
|
||||
GO_LAVAMAN_PILLARS_CHAINED = 202437,
|
||||
GO_LAVAMAN_PILLARS_UNCHAINED = 202438,
|
||||
};
|
||||
|
||||
enum AchievementCriteriaIds
|
||||
{
|
||||
// Lord Marrowgar
|
||||
CRITERIA_BONED_10N = 12775,
|
||||
CRITERIA_BONED_25N = 12962,
|
||||
CRITERIA_BONED_10H = 13393,
|
||||
CRITERIA_BONED_25H = 13394,
|
||||
|
||||
// Rotface
|
||||
CRITERIA_DANCES_WITH_OOZES_10N = 12984,
|
||||
CRITERIA_DANCES_WITH_OOZES_25N = 12966,
|
||||
CRITERIA_DANCES_WITH_OOZES_10H = 12985,
|
||||
CRITERIA_DANCES_WITH_OOZES_25H = 12983,
|
||||
|
||||
// Professor Putricide
|
||||
CRITERIA_NAUSEA_10N = 12987,
|
||||
CRITERIA_NAUSEA_25N = 12968,
|
||||
CRITERIA_NAUSEA_10H = 12988,
|
||||
CRITERIA_NAUSEA_25H = 12981,
|
||||
|
||||
// Blood Prince Council
|
||||
CRITERIA_ORB_WHISPERER_10N = 13033,
|
||||
CRITERIA_ORB_WHISPERER_25N = 12969,
|
||||
CRITERIA_ORB_WHISPERER_10H = 13034,
|
||||
CRITERIA_ORB_WHISPERER_25H = 13032,
|
||||
|
||||
// Blood-Queen Lana'thel
|
||||
CRITERIA_KILL_LANA_THEL_10M = 13340,
|
||||
CRITERIA_KILL_LANA_THEL_25M = 13360,
|
||||
};
|
||||
|
||||
enum SharedActions
|
||||
{
|
||||
// Icecrown Gunship Battle
|
||||
ACTION_ENEMY_GUNSHIP_TALK = -369390,
|
||||
ACTION_EXIT_SHIP = -369391,
|
||||
|
||||
// Festergut
|
||||
ACTION_FESTERGUT_COMBAT = -366260,
|
||||
ACTION_FESTERGUT_GAS = -366261,
|
||||
ACTION_FESTERGUT_DEATH = -366262,
|
||||
|
||||
// Rotface
|
||||
ACTION_ROTFACE_COMBAT = -366270,
|
||||
ACTION_ROTFACE_OOZE = -366271,
|
||||
ACTION_ROTFACE_DEATH = -366272,
|
||||
ACTION_CHANGE_PHASE = -366780,
|
||||
|
||||
// Blood-Queen Lana'thel
|
||||
ACTION_KILL_MINCHAR = -379550,
|
||||
|
||||
// Frostwing Halls gauntlet event
|
||||
ACTION_VRYKUL_DEATH = 37129,
|
||||
|
||||
// Sindragosa
|
||||
ACTION_START_FROSTWYRM = -368530,
|
||||
|
||||
// The Lich King
|
||||
ACTION_RESTORE_LIGHT = -72262,
|
||||
ACTION_FROSTMOURNE_INTRO = -36823,
|
||||
};
|
||||
|
||||
enum WeekliesICC
|
||||
{
|
||||
QUEST_DEPROGRAMMING_10 = 24869,
|
||||
QUEST_DEPROGRAMMING_25 = 24875,
|
||||
QUEST_SECURING_THE_RAMPARTS_10 = 24870,
|
||||
QUEST_SECURING_THE_RAMPARTS_25 = 24877,
|
||||
QUEST_RESIDUE_RENDEZVOUS_10 = 24873,
|
||||
QUEST_RESIDUE_RENDEZVOUS_25 = 24878,
|
||||
QUEST_BLOOD_QUICKENING_10 = 24874,
|
||||
QUEST_BLOOD_QUICKENING_25 = 24879,
|
||||
QUEST_RESPITE_FOR_A_TORMENTED_SOUL_10 = 24872,
|
||||
QUEST_RESPITE_FOR_A_TORMENTED_SOUL_25 = 24880,
|
||||
};
|
||||
|
||||
enum QuestsICC
|
||||
{
|
||||
QUEST_A_FEAST_OF_SOULS = 24547
|
||||
};
|
||||
|
||||
enum WorldStatesICC
|
||||
{
|
||||
WORLDSTATE_SHOW_TIMER = 4903,
|
||||
WORLDSTATE_EXECUTION_TIME = 4904,
|
||||
WORLDSTATE_SHOW_ATTEMPTS = 4940,
|
||||
WORLDSTATE_ATTEMPTS_REMAINING = 4941,
|
||||
WORLDSTATE_ATTEMPTS_MAX = 4942,
|
||||
};
|
||||
|
||||
enum PutricideEventFlags
|
||||
{
|
||||
PUTRICIDE_EVENT_FLAG_FESTERGUT_VALVE = 1,
|
||||
PUTRICIDE_EVENT_FLAG_ROTFACE_VALVE = 2,
|
||||
PUTRICIDE_EVENT_FLAG_TRAP_INPROGRESS = 4,
|
||||
PUTRICIDE_EVENT_FLAG_TRAP_FINISHED = 8,
|
||||
};
|
||||
|
||||
enum AreaIds
|
||||
{
|
||||
AREA_ICECROWN_CITADEL = 4812,
|
||||
AREA_THE_FROZEN_THRONE = 4859,
|
||||
};
|
||||
|
||||
class spell_trigger_spell_from_caster : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_trigger_spell_from_caster(char const* scriptName, uint32 triggerId) : SpellScriptLoader(scriptName), _triggerId(triggerId) { }
|
||||
|
||||
class spell_trigger_spell_from_caster_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_trigger_spell_from_caster_SpellScript);
|
||||
|
||||
public:
|
||||
spell_trigger_spell_from_caster_SpellScript(uint32 triggerId) : SpellScript(), _triggerId(triggerId) { }
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(_triggerId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleTrigger()
|
||||
{
|
||||
GetCaster()->CastSpell(GetHitUnit(), _triggerId, true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterHit += SpellHitFn(spell_trigger_spell_from_caster_SpellScript::HandleTrigger);
|
||||
}
|
||||
|
||||
uint32 _triggerId;
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_trigger_spell_from_caster_SpellScript(_triggerId);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _triggerId;
|
||||
};
|
||||
|
||||
template<class AI>
|
||||
CreatureAI* GetIcecrownCitadelAI(Creature* creature)
|
||||
{
|
||||
if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
|
||||
if (instance->GetInstanceScript())
|
||||
if (instance->GetScriptId() == sObjectMgr->GetScriptId(ICCScriptName))
|
||||
return new AI(creature);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif // ICECROWN_CITADEL_H_
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY PUSSYWIZARD, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "icecrown_citadel.h"
|
||||
#include "Spell.h"
|
||||
#include "Player.h"
|
||||
|
||||
#define GOSSIP_SENDER_ICC_PORT 631
|
||||
|
||||
class icecrown_citadel_teleport : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
icecrown_citadel_teleport() : GameObjectScript("icecrown_citadel_teleport") { }
|
||||
|
||||
bool OnGossipHello(Player* player, GameObject* go)
|
||||
{
|
||||
if (go->GetEntry() != GO_SCOURGE_TRANSPORTER_FIRST)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Light's Hammer.", GOSSIP_SENDER_ICC_PORT, LIGHT_S_HAMMER_TELEPORT); // M_PI + M_PI/6
|
||||
if (InstanceScript* instance = go->GetInstanceScript())
|
||||
{
|
||||
if (instance->GetBossState(DATA_LORD_MARROWGAR) == DONE && go->GetEntry() != 202245)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); // M_PI + M_PI/6
|
||||
if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE && go->GetEntry() != 202243)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Rampart of Skulls.", GOSSIP_SENDER_ICC_PORT, RAMPART_OF_SKULLS_TELEPORT); // M_PI/6
|
||||
if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE && go->GetEntry() != 202244)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Deathbringer's Rise.", GOSSIP_SENDER_ICC_PORT, DEATHBRINGER_S_RISE_TELEPORT); // M_PI/6
|
||||
if (instance->GetData(DATA_COLDFLAME_JETS) == DONE && go->GetEntry() != 202235)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Upper Spire.", GOSSIP_SENDER_ICC_PORT, UPPER_SPIRE_TELEPORT); // M_PI/6
|
||||
if (instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE && instance->GetBossState(DATA_SINDRAGOSA_GAUNTLET) == DONE && go->GetEntry() != 202246)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Sindragosa's Lair", GOSSIP_SENDER_ICC_PORT, SINDRAGOSA_S_LAIR_TELEPORT); // M_PI*3/2 + M_PI/6
|
||||
}
|
||||
|
||||
player->SEND_GOSSIP_MENU(player->GetGossipTextId(go), go->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 sender, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
SpellInfo const* spell = sSpellMgr->GetSpellInfo(action);
|
||||
if (!spell)
|
||||
return false;
|
||||
|
||||
if (player->IsInCombat())
|
||||
{
|
||||
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_AFFECTING_COMBAT);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sender == GOSSIP_SENDER_ICC_PORT)
|
||||
player->CastSpell(player, spell, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class at_frozen_throne_teleport : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_frozen_throne_teleport() : AreaTriggerScript("at_frozen_throne_teleport") { }
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/)
|
||||
{
|
||||
if (player->IsInCombat())
|
||||
{
|
||||
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(FROZEN_THRONE_TELEPORT))
|
||||
Spell::SendCastResult(player, spell, 0, SPELL_FAILED_AFFECTING_COMBAT);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (InstanceScript* instance = player->GetInstanceScript())
|
||||
if (instance->GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE &&
|
||||
instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE &&
|
||||
instance->GetBossState(DATA_SINDRAGOSA) == DONE &&
|
||||
instance->GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS)
|
||||
player->CastSpell(player, FROZEN_THRONE_TELEPORT, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_icecrown_citadel_teleport()
|
||||
{
|
||||
new icecrown_citadel_teleport();
|
||||
new at_frozen_throne_teleport();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_GREET = 1,
|
||||
SAY_SLAY = 2,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_IMPALE_10 = 28783,
|
||||
SPELL_IMPALE_25 = 56090,
|
||||
SPELL_LOCUST_SWARM_10 = 28785,
|
||||
SPELL_LOCUST_SWARM_25 = 54021,
|
||||
SPELL_SUMMON_CORPSE_SCRABS_5 = 29105,
|
||||
SPELL_SUMMON_CORPSE_SCRABS_10 = 28864,
|
||||
SPELL_BERSERK = 26662,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_IMPALE = 1,
|
||||
EVENT_SPELL_LOCUST_SWARM = 2,
|
||||
EVENT_SPELL_BERSERK = 3,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_CORPSE_SCARAB = 16698,
|
||||
NPC_CRYPT_GUARD = 16573,
|
||||
|
||||
ACHIEV_TIMED_START_EVENT = 9891,
|
||||
};
|
||||
|
||||
class boss_anubrekhan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_anubrekhan() : CreatureScript("boss_anubrekhan") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_anubrekhanAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_anubrekhanAI : public ScriptedAI
|
||||
{
|
||||
boss_anubrekhanAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
sayGreet = false;
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
bool sayGreet;
|
||||
|
||||
void SummonCryptGuards()
|
||||
{
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3308.590f, -3466.29f, 287.16f, M_PI, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
if (IsHeroic())
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, 3308.590f, -3486.29f, 287.16f, M_PI, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SummonCryptGuards();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_ANUB, NOT_STARTED);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_ANUB_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr)
|
||||
{
|
||||
if (me->IsInCombat())
|
||||
cr->SetInCombatWithZone();
|
||||
if (cr->GetEntry() == NPC_CORPSE_SCARAB)
|
||||
{
|
||||
cr->SetReactState(REACT_PASSIVE);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* cr, Unit*)
|
||||
{
|
||||
if (cr->GetEntry() == NPC_CRYPT_GUARD)
|
||||
cr->CastSpell(cr, SPELL_SUMMON_CORPSE_SCRABS_10, true, NULL, NULL, me->GetGUID());
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* cr) { summons.Despawn(cr); }
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
pInstance->SetData(EVENT_ANUB, DONE);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
//Force the player to spawn corpse scarabs via spell
|
||||
victim->CastSpell(victim, SPELL_SUMMON_CORPSE_SCRABS_5, true, NULL, NULL, me->GetGUID());
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->CallForHelp(30.0f); // catch helpers
|
||||
Talk(SAY_AGGRO);
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_ANUB, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_ANUB_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPALE, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LOCUST_SWARM, 70000+urand(0,50000));
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000);
|
||||
|
||||
if (!summons.HasEntry(NPC_CRYPT_GUARD))
|
||||
SummonCryptGuards();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!sayGreet && who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_GREET);
|
||||
sayGreet = true;
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_IMPALE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
me->CastSpell(target, RAID_MODE(SPELL_IMPALE_10, SPELL_IMPALE_25), false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_LOCUST_SWARM:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_LOCUST_SWARM_10, SPELL_LOCUST_SWARM_25), false);
|
||||
Position pos;
|
||||
me->GetNearPosition(pos, 10.0f, rand_norm()*2*M_PI);
|
||||
me->SummonCreature(NPC_CRYPT_GUARD, pos);
|
||||
events.RepeatEvent(90000);
|
||||
break;
|
||||
case EVENT_SPELL_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_anubrekhan()
|
||||
{
|
||||
new boss_anubrekhan();
|
||||
}
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_GREET = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISON_BOLT_VOLLEY_10 = 28796,
|
||||
SPELL_POISON_BOLT_VOLLEY_25 = 54098,
|
||||
SPELL_RAIN_OF_FIRE_10 = 28794,
|
||||
SPELL_RAIN_OF_FIRE_25 = 54099,
|
||||
SPELL_FRENZY_10 = 28798,
|
||||
SPELL_FRENZY_25 = 54100,
|
||||
SPELL_WIDOWS_EMBRACE = 28732,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_POISON_BOLT = 1,
|
||||
EVENT_SPELL_RAIN_OF_FIRE = 2,
|
||||
EVENT_SPELL_FRENZY = 3,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_NAXXRAMAS_WORSHIPPER = 16506,
|
||||
NPC_NAXXRAMAS_FOLLOWER = 16505,
|
||||
};
|
||||
|
||||
class boss_faerlina : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_faerlina() : CreatureScript("boss_faerlina") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_faerlinaAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_faerlinaAI : public ScriptedAI
|
||||
{
|
||||
boss_faerlinaAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
sayGreet = false;
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
bool sayGreet;
|
||||
|
||||
void SummonHelpers()
|
||||
{
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3362.66f, -3620.97f, 261.08f, 4.57276f);
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3344.3f, -3618.31f, 261.08f, 4.69494f);
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3356.71f, -3620.05f, 261.08f, 4.57276f);
|
||||
me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3350.26f, -3619.11f, 261.08f, 4.67748f);
|
||||
|
||||
// Followers
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3347.49f, -3617.59f, 261.0f, 4.49f);
|
||||
me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3359.64f, -3619.16f, 261.0f, 4.56f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SummonHelpers();
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_FAERLINA, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_BOLT, urand(12000,15000));
|
||||
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, urand(6000,18000));
|
||||
events.ScheduleEvent(EVENT_SPELL_FRENZY, urand(60000,80000), 1);
|
||||
events.SetPhase(1);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_FAERLINA, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!sayGreet && who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_GREET);
|
||||
sayGreet = true;
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_FAERLINA, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_POISON_BOLT:
|
||||
if (!me->HasAura(SPELL_WIDOWS_EMBRACE))
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_POISON_BOLT_VOLLEY_10, SPELL_POISON_BOLT_VOLLEY_25), SPELLVALUE_MAX_TARGETS, 3, me, false);
|
||||
events.RepeatEvent(14000);
|
||||
break;
|
||||
case EVENT_SPELL_RAIN_OF_FIRE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
me->CastSpell(target, RAID_MODE(SPELL_RAIN_OF_FIRE_10, SPELL_RAIN_OF_FIRE_25), false);
|
||||
events.RepeatEvent(12000);
|
||||
break;
|
||||
case EVENT_SPELL_FRENZY:
|
||||
me->MonsterTextEmote("%s goes into a frenzy!", 0, true);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25), true);
|
||||
events.RepeatEvent(70000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellInfo *spell)
|
||||
{
|
||||
if (spell->Id == SPELL_WIDOWS_EMBRACE)
|
||||
{
|
||||
me->MonsterTextEmote("%s is affected by Widow's Embrace!", 0, true);
|
||||
if (me->HasAura(RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25)))
|
||||
{
|
||||
me->RemoveAurasDueToSpell(RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25));
|
||||
events.DelayEvents(60000, 1);
|
||||
}
|
||||
else
|
||||
events.DelayEvents(30000, 1);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_FRENZY_REMOVED, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_faerlina()
|
||||
{
|
||||
new boss_faerlina();
|
||||
}
|
||||
@@ -1,398 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "naxxramas.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
// Marks
|
||||
SPELL_MARK_OF_KORTHAZZ = 28832,
|
||||
SPELL_MARK_OF_BLAUMEUX = 28833,
|
||||
SPELL_MARK_OF_RIVENDARE = 28834,
|
||||
SPELL_MARK_OF_ZELIEK = 28835,
|
||||
SPELL_MARK_DAMAGE = 28836,
|
||||
|
||||
// Korth'azz
|
||||
SPELL_KORTHAZZ_METEOR_10 = 28884,
|
||||
SPELL_KORTHAZZ_METEOR_25 = 57467,
|
||||
|
||||
// Blaumeux
|
||||
SPELL_BLAUMEUX_SHADOW_BOLT_10 = 57374,
|
||||
SPELL_BLAUMEUX_SHADOW_BOLT_25 = 57464,
|
||||
SPELL_BLAUMEUX_VOID_ZONE_10 = 28863,
|
||||
SPELL_BLAUMEUX_VOID_ZONE_25 = 57463,
|
||||
SPELL_BLAUMEUX_UNYIELDING_PAIN = 57381,
|
||||
|
||||
// Zeliek
|
||||
SPELL_ZELIEK_HOLY_WRATH_10 = 28883,
|
||||
SPELL_ZELIEK_HOLY_WRATH_25 = 57466,
|
||||
SPELL_ZELIEK_HOLY_BOLT_10 = 57376,
|
||||
SPELL_ZELIEK_HOLY_BOLT_25 = 57465,
|
||||
SPELL_ZELIEK_CONDEMNATION = 57377,
|
||||
|
||||
// Rivendare
|
||||
SPELL_RIVENDARE_UNHOLY_SHADOW_10 = 28882,
|
||||
SPELL_RIVENDARE_UNHOLY_SHADOW_25 = 57369,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_MARK_CAST = 1,
|
||||
EVENT_SPELL_PRIMARY = 2,
|
||||
EVENT_SPELL_SECONDARY = 3,
|
||||
EVENT_SPELL_PUNISH = 4,
|
||||
EVENT_BERSERK = 5,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
// Movement
|
||||
MOVE_PHASE_NONE = 0,
|
||||
MOVE_PHASE_STARTED = 1,
|
||||
MOVE_PHASE_FINISHED = 2,
|
||||
|
||||
// Horseman
|
||||
HORSEMAN_ZELIEK = 0,
|
||||
HORSEMAN_BLAUMEUX = 1,
|
||||
HORSEMAN_RIVENDARE = 2,
|
||||
HORSEMAN_KORTHAZZ = 3,
|
||||
};
|
||||
|
||||
enum FourHorsemen
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_TAUNT = 1,
|
||||
SAY_SPECIAL = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
// MARKS
|
||||
const uint32 TABLE_SPELL_MARK[4] = {SPELL_MARK_OF_ZELIEK, SPELL_MARK_OF_BLAUMEUX, SPELL_MARK_OF_RIVENDARE, SPELL_MARK_OF_KORTHAZZ};
|
||||
|
||||
// SPELL PRIMARY
|
||||
const uint32 TABLE_SPELL_PRIMARY_10[4] = {SPELL_ZELIEK_HOLY_BOLT_10, SPELL_BLAUMEUX_SHADOW_BOLT_10, SPELL_RIVENDARE_UNHOLY_SHADOW_10, SPELL_KORTHAZZ_METEOR_10};
|
||||
const uint32 TABLE_SPELL_PRIMARY_25[4] = {SPELL_ZELIEK_HOLY_BOLT_25, SPELL_BLAUMEUX_SHADOW_BOLT_25, SPELL_RIVENDARE_UNHOLY_SHADOW_25, SPELL_KORTHAZZ_METEOR_25};
|
||||
|
||||
// PUNISH
|
||||
const uint32 TABLE_SPELL_PUNISH[4] = {SPELL_ZELIEK_CONDEMNATION, SPELL_BLAUMEUX_UNYIELDING_PAIN, 0, 0};
|
||||
|
||||
// SPELL SECONDARY
|
||||
const uint32 TABLE_SPELL_SECONDARY_10[4] = {SPELL_ZELIEK_HOLY_WRATH_10, SPELL_BLAUMEUX_VOID_ZONE_10, 0, 0};
|
||||
const uint32 TABLE_SPELL_SECONDARY_25[4] = {SPELL_ZELIEK_HOLY_WRATH_25, SPELL_BLAUMEUX_VOID_ZONE_25, 0, 0};
|
||||
|
||||
|
||||
|
||||
const Position WaypointPositions[12] =
|
||||
{
|
||||
// Thane waypoints
|
||||
{2542.3f, -2984.1f, 241.49f, 5.362f},
|
||||
{2547.6f, -2999.4f, 241.34f, 5.049f},
|
||||
{2542.9f, -3015.0f, 241.35f, 4.654f},
|
||||
// Lady waypoints
|
||||
{2498.3f, -2961.8f, 241.28f, 3.267f},
|
||||
{2487.7f, -2959.2f, 241.28f, 2.890f},
|
||||
{2469.4f, -2947.6f, 241.28f, 2.576f},
|
||||
// Baron waypoints
|
||||
{2553.8f, -2968.4f, 241.33f, 5.757f},
|
||||
{2564.3f, -2972.5f, 241.33f, 5.890f},
|
||||
{2583.9f, -2971.6f, 241.35f, 0.008f},
|
||||
// Sir waypoints
|
||||
{2534.5f, -2921.7f, 241.53f, 1.363f},
|
||||
{2523.5f, -2902.8f, 241.28f, 2.095f},
|
||||
{2517.8f, -2896.6f, 241.28f, 2.315f},
|
||||
};
|
||||
|
||||
class boss_four_horsemen : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_four_horsemen() : CreatureScript("boss_four_horsemen") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_four_horsemenAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_four_horsemenAI : public ScriptedAI
|
||||
{
|
||||
boss_four_horsemenAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_SIR_ZELIEK:
|
||||
horsemanId = HORSEMAN_ZELIEK;
|
||||
break;
|
||||
case NPC_LADY_BLAUMEUX:
|
||||
horsemanId = HORSEMAN_BLAUMEUX;
|
||||
break;
|
||||
case NPC_BARON_RIVENDARE:
|
||||
horsemanId = HORSEMAN_RIVENDARE;
|
||||
break;
|
||||
case NPC_THANE_KORTHAZZ:
|
||||
horsemanId = HORSEMAN_KORTHAZZ;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
uint8 currentWaypoint;
|
||||
uint8 movementPhase;
|
||||
uint8 horsemanId;
|
||||
|
||||
void MoveToCorner()
|
||||
{
|
||||
switch(me->GetEntry())
|
||||
{
|
||||
case NPC_THANE_KORTHAZZ: currentWaypoint = 0; break;
|
||||
case NPC_LADY_BLAUMEUX: currentWaypoint = 3; break;
|
||||
case NPC_BARON_RIVENDARE: currentWaypoint = 6; break;
|
||||
case NPC_SIR_ZELIEK: currentWaypoint = 9; break;
|
||||
}
|
||||
me->GetMotionMaster()->MovePoint(currentWaypoint, WaypointPositions[currentWaypoint]);
|
||||
}
|
||||
|
||||
bool IsInRoom()
|
||||
{
|
||||
if (me->GetExactDist(2535.1f, -2968.7f, 241.3f) > 100.0f)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetPosition(me->GetHomePosition());
|
||||
movementPhase = MOVE_PHASE_NONE;
|
||||
currentWaypoint = 0;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.Reset();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_HORSEMAN, NOT_STARTED);
|
||||
|
||||
// Schedule Events
|
||||
events.RescheduleEvent(EVENT_SPELL_MARK_CAST, 24000);
|
||||
events.RescheduleEvent(EVENT_BERSERK, 100*15000);
|
||||
|
||||
if ((me->GetEntry() != NPC_LADY_BLAUMEUX && me->GetEntry() != NPC_SIR_ZELIEK))
|
||||
events.RescheduleEvent(EVENT_SPELL_PRIMARY, 10000+rand()%5000);
|
||||
else
|
||||
{
|
||||
events.RescheduleEvent(EVENT_SPELL_PUNISH, 5000);
|
||||
events.RescheduleEvent(EVENT_SPELL_SECONDARY, 15000);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
// final waypoint
|
||||
if (id % 3 == 2)
|
||||
{
|
||||
movementPhase = MOVE_PHASE_FINISHED;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK)
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
currentWaypoint = id+1;
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
if (movementPhase == MOVE_PHASE_FINISHED)
|
||||
{
|
||||
if (me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK)
|
||||
me->Attack(who, false);
|
||||
else
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,4))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_HORSEMAN, DONE);
|
||||
if (pInstance->GetData(EVENT_HORSEMAN) == DONE)
|
||||
if (!me->GetMap()->GetPlayers().isEmpty())
|
||||
if (Player* player = me->GetMap()->GetPlayers().getFirst()->GetSource())
|
||||
player->SummonGameObject(RAID_MODE(GO_HORSEMEN_CHEST_10, GO_HORSEMEN_CHEST_25), 2514.8f, -2944.9f, 245.55f, 5.51f, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_HORSEMAN, IN_PROGRESS);
|
||||
|
||||
if (movementPhase == MOVE_PHASE_NONE)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
movementPhase = MOVE_PHASE_STARTED;
|
||||
me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true);
|
||||
MoveToCorner();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (movementPhase == MOVE_PHASE_STARTED && currentWaypoint)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(currentWaypoint, WaypointPositions[currentWaypoint]);
|
||||
currentWaypoint = 0;
|
||||
}
|
||||
|
||||
if (!IsInRoom())
|
||||
return;
|
||||
|
||||
if (movementPhase < MOVE_PHASE_FINISHED || !UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_MARK_CAST:
|
||||
me->CastSpell(me, TABLE_SPELL_MARK[horsemanId], false);
|
||||
events.RepeatEvent((me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK) ? 15000 : 12000);
|
||||
return;
|
||||
case EVENT_BERSERK:
|
||||
Talk(SAY_SPECIAL);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
return;
|
||||
case EVENT_SPELL_PRIMARY:
|
||||
if (!urand(0,10))
|
||||
Talk(SAY_TAUNT);
|
||||
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
|
||||
events.RepeatEvent(15000);
|
||||
return;
|
||||
case EVENT_SPELL_PUNISH:
|
||||
if (!SelectTarget(SELECT_TARGET_NEAREST, 0, 45.0f, true))
|
||||
me->CastSpell(me, TABLE_SPELL_PUNISH[horsemanId], false);
|
||||
events.RepeatEvent(3000);
|
||||
return;
|
||||
case EVENT_SPELL_SECONDARY:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(TABLE_SPELL_SECONDARY_10[horsemanId], TABLE_SPELL_SECONDARY_25[horsemanId]), false);
|
||||
events.RepeatEvent(15000);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((me->GetEntry() == NPC_LADY_BLAUMEUX || me->GetEntry() == NPC_SIR_ZELIEK))
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 45.0f, true))
|
||||
me->CastSpell(target, RAID_MODE(TABLE_SPELL_PRIMARY_10[horsemanId], TABLE_SPELL_PRIMARY_25[horsemanId]), false);
|
||||
}
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_four_horsemen_mark : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_four_horsemen_mark() : SpellScriptLoader("spell_four_horsemen_mark") { }
|
||||
|
||||
class spell_four_horsemen_mark_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_four_horsemen_mark_AuraScript);
|
||||
|
||||
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
int32 damage;
|
||||
switch (GetStackAmount())
|
||||
{
|
||||
case 1:
|
||||
damage = 0;
|
||||
break;
|
||||
case 2:
|
||||
damage = 500;
|
||||
break;
|
||||
case 3:
|
||||
damage = 1000;
|
||||
break;
|
||||
case 4:
|
||||
damage = 1500;
|
||||
break;
|
||||
case 5:
|
||||
damage = 4000;
|
||||
break;
|
||||
case 6:
|
||||
damage = 12000;
|
||||
break;
|
||||
default:
|
||||
damage = 20000 + 1000 * (GetStackAmount() - 7);
|
||||
break;
|
||||
}
|
||||
if (damage)
|
||||
caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_four_horsemen_mark_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_four_horsemen_mark_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_four_horsemen()
|
||||
{
|
||||
new boss_four_horsemen();
|
||||
new spell_four_horsemen_mark();
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MORTAL_WOUND = 25646,
|
||||
SPELL_ENRAGE_10 = 28371,
|
||||
SPELL_ENRAGE_25 = 54427,
|
||||
SPELL_DECIMATE_10 = 28374,
|
||||
SPELL_DECIMATE_25 = 54426,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_INFECTED_WOUND = 29306,
|
||||
SPELL_CHOW_SEARCHER = 28404,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_MORTAL_WOUND = 1,
|
||||
EVENT_SPELL_ENRAGE = 2,
|
||||
EVENT_SPELL_DECIMATE = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
EVENT_SUMMON_ZOMBIE = 5,
|
||||
EVENT_CAN_EAT_ZOMBIE = 6,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_ZOMBIE_CHOW = 16360,
|
||||
};
|
||||
|
||||
const Position zombiePos[3] =
|
||||
{
|
||||
{3267.9f, -3172.1f, 297.42f, 0.94f},
|
||||
{3253.2f, -3132.3f, 297.42f, 0},
|
||||
{3308.3f, -3185.8f, 297.42f, 1.58f},
|
||||
};
|
||||
|
||||
class boss_gluth : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_gluth() : CreatureScript("boss_gluth") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_gluthAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_gluthAI : public ScriptedAI
|
||||
{
|
||||
boss_gluthAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* pInstance;
|
||||
uint64 gazeTarget;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->ApplySpellImmune(29306, IMMUNITY_ID, 29306, true);
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
gazeTarget = 0;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_GLUTH, NOT_STARTED);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if ((!me->GetVictim() || me->GetVictim()->GetEntry() != NPC_ZOMBIE_CHOW) && who->GetEntry() == NPC_ZOMBIE_CHOW && me->IsWithinDistInMap(who, 15))
|
||||
{
|
||||
SetGazeOn(who);
|
||||
me->MonsterTextEmote("%s spots a nearby zombie to devour!", 0, false);
|
||||
}
|
||||
else
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_MORTAL_WOUND, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 30000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DECIMATE, 105000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 8*60000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_ZOMBIE, 10000);
|
||||
events.ScheduleEvent(EVENT_CAN_EAT_ZOMBIE, 1000);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_GLUTH, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
if (summon->GetEntry() == NPC_ZOMBIE_CHOW)
|
||||
summon->AI()->AttackStart(me);
|
||||
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* cr, Unit*) { summons.Despawn(cr); }
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (me->IsAlive() && who->GetEntry() == NPC_ZOMBIE_CHOW)
|
||||
me->ModifyHealth(int32(me->GetMaxHealth()*0.05f));
|
||||
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit*)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_GLUTH, DONE);
|
||||
}
|
||||
|
||||
bool SelectPlayerInRoom()
|
||||
{
|
||||
if (me->IsInCombat())
|
||||
return false;
|
||||
|
||||
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
||||
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
{
|
||||
Player* player = itr->GetSource();
|
||||
if (!player || !player->IsAlive())
|
||||
continue;
|
||||
if (player->GetPositionZ() > 300.0f || me->GetExactDist(player) > 50.0f)
|
||||
continue;
|
||||
|
||||
AttackStart(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictimWithGaze() && !SelectPlayerInRoom())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_ENRAGE:
|
||||
me->MonsterTextEmote("Gluth becomes enraged!", 0, true);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_ENRAGE_10, SPELL_ENRAGE_25), true);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SPELL_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_DECIMATE:
|
||||
me->MonsterTextEmote("Gluth decimates all nearby flesh!", 0, true);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DECIMATE_10, SPELL_DECIMATE_25), false);
|
||||
events.RepeatEvent(105000);
|
||||
break;
|
||||
case EVENT_SUMMON_ZOMBIE:
|
||||
{
|
||||
uint8 rand = urand(0,2);
|
||||
for (int32 i = 0; i < RAID_MODE(1,2); ++i)
|
||||
{
|
||||
me->SummonCreature(NPC_ZOMBIE_CHOW, zombiePos[urand(0,2)]);
|
||||
(rand == 2 ? rand = 0 : rand++);
|
||||
}
|
||||
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
}
|
||||
case EVENT_CAN_EAT_ZOMBIE:
|
||||
events.RepeatEvent(1000);
|
||||
if (me->GetVictim()->GetEntry() == NPC_ZOMBIE_CHOW && me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->CastCustomSpell(SPELL_CHOW_SEARCHER, SPELLVALUE_RADIUS_MOD, 20000, me, true);
|
||||
me->MonsterTextEmote("%s devour all nearby zombies!", 0, false);
|
||||
return; // leave it to skip DoMeleeAttackIfReady
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_gluth_decimate : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gluth_decimate() : SpellScriptLoader("spell_gluth_decimate") { }
|
||||
|
||||
class spell_gluth_decimate_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gluth_decimate_SpellScript);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* unitTarget = GetHitUnit())
|
||||
{
|
||||
int32 damage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5));
|
||||
if (damage <= 0)
|
||||
return;
|
||||
|
||||
if (Creature* cTarget = unitTarget->ToCreature())
|
||||
{
|
||||
cTarget->SetWalk(true);
|
||||
cTarget->GetMotionMaster()->MoveFollow(GetCaster(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
|
||||
cTarget->SetReactState(REACT_PASSIVE);
|
||||
Unit::DealDamage(GetCaster(), cTarget, damage);
|
||||
return;
|
||||
}
|
||||
|
||||
GetCaster()->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, damage, unitTarget);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_gluth_decimate_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_gluth()
|
||||
{
|
||||
new boss_gluth();
|
||||
new spell_gluth_decimate();
|
||||
}
|
||||
|
||||
@@ -1,510 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "CombatAI.h"
|
||||
#include "naxxramas.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_SPEECH = 0,
|
||||
SAY_KILL = 1,
|
||||
SAY_DEATH = 2,
|
||||
SAY_TELEPORT = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_HARVEST_SOUL = 28679,
|
||||
SPELL_SHADOW_BOLT_10 = 29317,
|
||||
SPELL_SHADOW_BOLT_25 = 56405,
|
||||
SPELL_INFORM_LIVING_TRAINEE = 27892,
|
||||
SPELL_INFORM_LIVING_KNIGHT = 27928,
|
||||
SPELL_INFORM_LIVING_RIDER = 27935,
|
||||
SPELL_INFORM_DEAD_TRAINEE = 27915,
|
||||
SPELL_INFORM_DEAD_KNIGHT = 27931,
|
||||
SPELL_INFORM_DEAD_RIDER = 27937,
|
||||
|
||||
SPELL_SHADOW_MARK = 27825
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_LIVING_TRAINEE = 16124,
|
||||
NPC_LIVING_KNIGHT = 16125,
|
||||
NPC_LIVING_RIDER = 16126,
|
||||
NPC_DEAD_TRAINEE = 16127,
|
||||
NPC_DEAD_KNIGHT = 16148,
|
||||
NPC_DEAD_HORSE = 16149,
|
||||
NPC_DEAD_RIDER = 16150,
|
||||
|
||||
ACTION_GATE_OPEN = 1,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SUMMON_ADDS = 1,
|
||||
EVENT_SPELL_HARVEST_SOUL = 2,
|
||||
EVENT_SPELL_SHADOW_BOLT = 3,
|
||||
EVENT_TELEPORT = 4,
|
||||
EVENT_CHECK_HEALTH = 5,
|
||||
EVENT_CHECK_PLAYERS = 6,
|
||||
};
|
||||
|
||||
const uint32 gothikWaves[24][2] =
|
||||
{
|
||||
{NPC_LIVING_TRAINEE, 20000},
|
||||
{NPC_LIVING_TRAINEE, 20000},
|
||||
{NPC_LIVING_TRAINEE, 10000},
|
||||
{NPC_LIVING_KNIGHT, 10000},
|
||||
{NPC_LIVING_TRAINEE, 15000},
|
||||
{NPC_LIVING_KNIGHT, 10000},
|
||||
{NPC_LIVING_TRAINEE, 15000},
|
||||
{NPC_LIVING_TRAINEE, 0},
|
||||
{NPC_LIVING_KNIGHT, 10000},
|
||||
{NPC_LIVING_RIDER, 10000},
|
||||
{NPC_LIVING_TRAINEE, 5000},
|
||||
{NPC_LIVING_KNIGHT, 15000},
|
||||
{NPC_LIVING_RIDER, 0},
|
||||
{NPC_LIVING_TRAINEE, 10000},
|
||||
{NPC_LIVING_KNIGHT, 10000},
|
||||
{NPC_LIVING_TRAINEE, 10000},
|
||||
{NPC_LIVING_RIDER, 5000},
|
||||
{NPC_LIVING_KNIGHT, 5000},
|
||||
{NPC_LIVING_TRAINEE, 20000},
|
||||
{NPC_LIVING_RIDER, 0},
|
||||
{NPC_LIVING_KNIGHT, 0},
|
||||
{NPC_LIVING_TRAINEE, 15000},
|
||||
{NPC_LIVING_TRAINEE, 29000},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
const Position PosSummonLiving[6] =
|
||||
{
|
||||
{2669.7f, -3428.76f, 268.56f, 1.6f},
|
||||
{2692.1f, -3428.76f, 268.56f, 1.6f},
|
||||
{2714.4f, -3428.76f, 268.56f, 1.6f},
|
||||
{2669.7f, -3431.67f, 268.56f, 1.6f},
|
||||
{2692.1f, -3431.67f, 268.56f, 1.6f},
|
||||
{2714.4f, -3431.67f, 268.56f, 1.6f},
|
||||
};
|
||||
|
||||
const Position PosSummonDead[5] =
|
||||
{
|
||||
{2725.1f, -3310.0f, 268.85f, 3.4f},
|
||||
{2699.3f, -3322.8f, 268.60f, 3.3f},
|
||||
{2733.1f, -3348.5f, 268.84f, 3.1f},
|
||||
{2682.8f, -3304.2f, 268.85f, 3.9f},
|
||||
{2664.8f, -3340.7f, 268.23f, 3.7f},
|
||||
};
|
||||
|
||||
const Position PosGroundLivingSide = {2691.2f, -3387.0f, 267.68f, 1.52f};
|
||||
const Position PosGroundDeadSide = {2693.5f, -3334.6f, 267.68f, 4.67f};
|
||||
const Position PosPlatform = {2640.5f, -3360.6f, 285.26f, 0.0f};
|
||||
|
||||
#define POS_Y_GATE -3360.78f
|
||||
#define POS_Y_WEST -3285.0f
|
||||
#define POS_Y_EAST -3434.0f
|
||||
#define POS_X_NORTH 2750.49f
|
||||
#define POS_X_SOUTH 2633.84f
|
||||
#define IN_LIVE_SIDE(who) (who->GetPositionY() < POS_Y_GATE)
|
||||
|
||||
// Predicate function to check that the r efzr unit is NOT on the same side as the source.
|
||||
struct NotOnSameSide : public std::unary_function<Unit *, bool>
|
||||
{
|
||||
bool m_inLiveSide;
|
||||
NotOnSameSide(Unit *pSource) : m_inLiveSide(IN_LIVE_SIDE(pSource)) {}
|
||||
|
||||
bool operator() (const Unit *pTarget)
|
||||
{
|
||||
return (m_inLiveSide != IN_LIVE_SIDE(pTarget));
|
||||
}
|
||||
};
|
||||
|
||||
class boss_gothik : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_gothik() : CreatureScript("boss_gothik") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_gothikAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_gothikAI : public ScriptedAI
|
||||
{
|
||||
boss_gothikAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* pInstance;
|
||||
bool secondPhase;
|
||||
bool gateOpened;
|
||||
uint8 waveCount;
|
||||
|
||||
bool IsInRoom()
|
||||
{
|
||||
if (me->GetPositionX() > 2767 || me->GetPositionX() < 2618 || me->GetPositionY() > -3285 || me->GetPositionY() < -3435)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
secondPhase = false;
|
||||
gateOpened = false;
|
||||
waveCount = 0;
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_GOTHIK, NOT_STARTED);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_ENTER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_EXIT_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_SPEECH);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE);
|
||||
me->NearTeleportTo(PosPlatform.GetPositionX(), PosPlatform.GetPositionY(), PosPlatform.GetPositionZ(), PosPlatform.GetOrientation());
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_ADDS, 30000);
|
||||
events.ScheduleEvent(EVENT_CHECK_PLAYERS, 120000);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_GOTHIK, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_ENTER_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
if (gateOpened)
|
||||
summon->AI()->DoAction(ACTION_GATE_OPEN);
|
||||
|
||||
summons.Summon(summon);
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* cr) { summons.Despawn(cr); }
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_KILL);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_GOTHIK, DONE);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_ENTER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_EXIT_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonHelpers(uint32 entry)
|
||||
{
|
||||
switch(entry)
|
||||
{
|
||||
case NPC_LIVING_TRAINEE:
|
||||
me->SummonCreature(NPC_LIVING_TRAINEE, PosSummonLiving[0].GetPositionX(), PosSummonLiving[0].GetPositionY(), PosSummonLiving[0].GetPositionZ(), PosSummonLiving[0].GetOrientation());
|
||||
me->SummonCreature(NPC_LIVING_TRAINEE, PosSummonLiving[1].GetPositionX(), PosSummonLiving[1].GetPositionY(), PosSummonLiving[1].GetPositionZ(), PosSummonLiving[1].GetOrientation());
|
||||
if (Is25ManRaid())
|
||||
me->SummonCreature(NPC_LIVING_TRAINEE, PosSummonLiving[2].GetPositionX(), PosSummonLiving[2].GetPositionY(), PosSummonLiving[2].GetPositionZ(), PosSummonLiving[2].GetOrientation());
|
||||
break;
|
||||
case NPC_LIVING_KNIGHT:
|
||||
me->SummonCreature(NPC_LIVING_KNIGHT, PosSummonLiving[3].GetPositionX(), PosSummonLiving[3].GetPositionY(), PosSummonLiving[3].GetPositionZ(), PosSummonLiving[3].GetOrientation());
|
||||
if (Is25ManRaid())
|
||||
me->SummonCreature(NPC_LIVING_KNIGHT, PosSummonLiving[5].GetPositionX(), PosSummonLiving[5].GetPositionY(), PosSummonLiving[5].GetPositionZ(), PosSummonLiving[5].GetOrientation());
|
||||
break;
|
||||
case NPC_LIVING_RIDER:
|
||||
me->SummonCreature(NPC_LIVING_RIDER, PosSummonLiving[4].GetPositionX(), PosSummonLiving[4].GetPositionY(), PosSummonLiving[4].GetPositionZ(), PosSummonLiving[4].GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckGroupSplitted()
|
||||
{
|
||||
Map::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
bool checklife = false;
|
||||
bool checkdead = false;
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
Player* player = i->GetSource();
|
||||
if (player->IsAlive() &&
|
||||
player->GetPositionX() <= POS_X_NORTH &&
|
||||
player->GetPositionX() >= POS_X_SOUTH &&
|
||||
player->GetPositionY() <= POS_Y_GATE &&
|
||||
player->GetPositionY() >= POS_Y_EAST)
|
||||
checklife = true;
|
||||
else if (player->IsAlive() &&
|
||||
player->GetPositionX() <= POS_X_NORTH &&
|
||||
player->GetPositionX() >= POS_X_SOUTH &&
|
||||
player->GetPositionY() >= POS_Y_GATE &&
|
||||
player->GetPositionY() <= POS_Y_WEST)
|
||||
checkdead = true;
|
||||
|
||||
if (checklife && checkdead)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SpellHit(Unit *caster, const SpellInfo* spellInfo)
|
||||
{
|
||||
uint8 pos = urand(0,4);
|
||||
switch (spellInfo->Id)
|
||||
{
|
||||
case SPELL_INFORM_LIVING_TRAINEE:
|
||||
me->SummonCreature(NPC_DEAD_TRAINEE, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
|
||||
break;
|
||||
case SPELL_INFORM_LIVING_KNIGHT:
|
||||
me->SummonCreature(NPC_DEAD_KNIGHT, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
|
||||
break;
|
||||
case SPELL_INFORM_LIVING_RIDER:
|
||||
me->SummonCreature(NPC_DEAD_RIDER, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
|
||||
me->SummonCreature(NPC_DEAD_HORSE, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
|
||||
break;
|
||||
}
|
||||
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELL_CAST);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!secondPhase)
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!IsInRoom())
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_SHADOW_BOLT:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SHADOW_BOLT_10, SPELL_SHADOW_BOLT_25), false);
|
||||
events.RepeatEvent(2000);
|
||||
break;
|
||||
case EVENT_SPELL_HARVEST_SOUL:
|
||||
me->CastSpell(me, SPELL_HARVEST_SOUL, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_TELEPORT:
|
||||
me->AttackStop();
|
||||
if (IN_LIVE_SIDE(me))
|
||||
me->NearTeleportTo(PosGroundDeadSide.GetPositionX(), PosGroundDeadSide.GetPositionY(), PosGroundDeadSide.GetPositionZ(), PosGroundDeadSide.GetOrientation());
|
||||
else
|
||||
me->NearTeleportTo(PosGroundLivingSide.GetPositionX(), PosGroundLivingSide.GetPositionY(), PosGroundLivingSide.GetPositionZ(), PosGroundLivingSide.GetOrientation());
|
||||
|
||||
me->getThreatManager().resetAggro(NotOnSameSide(me));
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
|
||||
{
|
||||
me->getThreatManager().addThreat(pTarget, 100.0f);
|
||||
AttackStart(pTarget);
|
||||
}
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(30) && pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
events.CancelEvent(EVENT_TELEPORT);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_SUMMON_ADDS:
|
||||
if (gothikWaves[waveCount][0])
|
||||
{
|
||||
SummonHelpers(gothikWaves[waveCount][0]);
|
||||
events.RepeatEvent(gothikWaves[waveCount][1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
secondPhase = true;
|
||||
Talk(SAY_TELEPORT);
|
||||
me->NearTeleportTo(PosGroundLivingSide.GetPositionX(), PosGroundLivingSide.GetPositionY(), PosGroundLivingSide.GetPositionZ(), PosGroundLivingSide.GetOrientation());
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_DISABLE_MOVE);
|
||||
|
||||
summons.DoAction(ACTION_GATE_OPEN);
|
||||
summons.DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT, 1000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HARVEST_SOUL, urand(5000,15000));
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 20000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
events.PopEvent();
|
||||
}
|
||||
|
||||
waveCount++;
|
||||
break;
|
||||
case EVENT_CHECK_PLAYERS:
|
||||
if (!CheckGroupSplitted())
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_GOTHIK_INNER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
summons.DoAction(ACTION_GATE_OPEN);
|
||||
summons.DoZoneInCombat();
|
||||
gateOpened = true;
|
||||
}
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_boss_gothik_minion : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_boss_gothik_minion() : CreatureScript("npc_boss_gothik_minion") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new npc_boss_gothik_minionAI (pCreature);
|
||||
}
|
||||
|
||||
struct npc_boss_gothik_minionAI : public CombatAI
|
||||
{
|
||||
npc_boss_gothik_minionAI(Creature *c) : CombatAI(c)
|
||||
{
|
||||
livingSide = IN_LIVE_SIDE(me);
|
||||
gateOpened = false;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool livingSide;
|
||||
bool gateOpened;
|
||||
|
||||
bool IsOnSameSide(Unit const* who) const { return livingSide == IN_LIVE_SIDE(who); }
|
||||
bool CanAIAttack(Unit const* target) const { return gateOpened || IsOnSameSide(target); }
|
||||
|
||||
void Reset() { events.Reset(); }
|
||||
void EnterCombat(Unit* who) { me->SetInCombatWithZone(); }
|
||||
void DamageTaken(Unit* attacker, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!attacker || (!gateOpened && !IsOnSameSide(attacker)))
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_GATE_OPEN)
|
||||
gateOpened = true;
|
||||
}
|
||||
|
||||
void JustDied(Unit *)
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
case NPC_LIVING_TRAINEE:
|
||||
me->CastSpell(me, SPELL_INFORM_LIVING_TRAINEE, true);
|
||||
break;
|
||||
case NPC_LIVING_KNIGHT:
|
||||
me->CastSpell(me, SPELL_INFORM_LIVING_KNIGHT, true);
|
||||
break;
|
||||
case NPC_LIVING_RIDER:
|
||||
me->CastSpell(me, SPELL_INFORM_LIVING_RIDER, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_gothik_shadow_bolt_volley : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gothik_shadow_bolt_volley() : SpellScriptLoader("spell_gothik_shadow_bolt_volley") { }
|
||||
|
||||
class spell_gothik_shadow_bolt_volley_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gothik_shadow_bolt_volley_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_SHADOW_MARK));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gothik_shadow_bolt_volley_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_gothik_shadow_bolt_volley_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_gothik()
|
||||
{
|
||||
new boss_gothik();
|
||||
new npc_boss_gothik_minion();
|
||||
new spell_gothik_shadow_bolt_volley();
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_POISON_CLOUD = 28240,
|
||||
SPELL_MUTATING_INJECTION = 28169,
|
||||
SPELL_SLIME_SPRAY_10 = 28157,
|
||||
SPELL_SLIME_SPRAY_25 = 54364,
|
||||
SPELL_POISON_CLOUD_DAMAGE_AURA_10 = 28158,
|
||||
SPELL_POISON_CLOUD_DAMAGE_AURA_25 = 54362,
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
SPELL_BOMBARD_SLIME = 28280, // Spawn slime when hit by slime spray
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_BERSERK = 1,
|
||||
EVENT_SPELL_POISON_CLOUD = 2,
|
||||
EVENT_SPELL_SLIME_SPRAY = 3,
|
||||
EVENT_SPELL_MUTATING_INJECTION = 4,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_FALLOUT_SLIME = 16290,
|
||||
NPC_SEWAGE_SLIME = 16375,
|
||||
};
|
||||
|
||||
class boss_grobbulus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_grobbulus() : CreatureScript("boss_grobbulus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_grobbulusAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_grobbulusAI : public ScriptedAI
|
||||
{
|
||||
boss_grobbulusAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* pInstance;
|
||||
uint32 dropSludgeTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
dropSludgeTimer = 0;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_GROBBULUS, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_CLOUD, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_MUTATING_INJECTION, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SLIME_SPRAY, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, RAID_MODE(12*MINUTE*IN_MILLISECONDS, 9*MINUTE*IN_MILLISECONDS));
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_GROBBULUS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit *target, const SpellInfo* spellInfo)
|
||||
{
|
||||
if (spellInfo->Id == RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25) && target->GetTypeId() == TYPEID_PLAYER)
|
||||
me->SummonCreature(NPC_FALLOUT_SLIME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr)
|
||||
{
|
||||
if (cr->GetEntry() == NPC_FALLOUT_SLIME)
|
||||
cr->SetInCombatWithZone();
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon){ summons.Despawn(summon); }
|
||||
|
||||
void JustDied(Unit*)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_GROBBULUS, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// Some nice visuals
|
||||
dropSludgeTimer += diff;
|
||||
if (!me->IsInCombat() && dropSludgeTimer >= 5000)
|
||||
{
|
||||
if (me->IsWithinDist3d(3178, -3305, 319, 5.0f) && !summons.HasEntry(NPC_SEWAGE_SLIME))
|
||||
me->CastSpell(3128.96f+irand(-20, 20), -3312.96f+irand(-20, 20), 293.25f, SPELL_BOMBARD_SLIME, false);
|
||||
|
||||
dropSludgeTimer = 0;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_POISON_CLOUD:
|
||||
me->CastSpell(me, SPELL_POISON_CLOUD, true);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_SPELL_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_SLIME_SPRAY:
|
||||
me->MonsterTextEmote("Grobbulus sprays slime across the room!", 0, true);
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_SLIME_SPRAY_10, SPELL_SLIME_SPRAY_25), false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_MUTATING_INJECTION:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true, -SPELL_MUTATING_INJECTION))
|
||||
me->CastSpell(target, SPELL_MUTATING_INJECTION, false);
|
||||
|
||||
events.RepeatEvent(8000 + uint32(120 * me->GetHealthPct()));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_grobbulus_poison_cloud : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_grobbulus_poison_cloud() : CreatureScript("boss_grobbulus_poison_cloud") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_grobbulus_poison_cloudAI(pCreature);
|
||||
}
|
||||
|
||||
struct boss_grobbulus_poison_cloudAI : public NullCreatureAI
|
||||
{
|
||||
boss_grobbulus_poison_cloudAI(Creature* pCreature) : NullCreatureAI(pCreature)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 sizeTimer;
|
||||
uint32 auraVisualTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
sizeTimer = 0;
|
||||
auraVisualTimer = 1;
|
||||
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 2.0f);
|
||||
me->setFaction(21); // Grobbulus one
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// this has to be delayed to be visible :/
|
||||
if (auraVisualTimer)
|
||||
{
|
||||
auraVisualTimer += diff;
|
||||
if (auraVisualTimer >= 1000)
|
||||
{
|
||||
me->CastSpell(me, (me->GetMap()->Is25ManRaid() ? SPELL_POISON_CLOUD_DAMAGE_AURA_25 : SPELL_POISON_CLOUD_DAMAGE_AURA_10), true);
|
||||
auraVisualTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sizeTimer += diff;
|
||||
// increase size to 15yd in 60 seconds, 0.00025 is the growth of size in 1ms
|
||||
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 2.0f+(0.00025f*sizeTimer));
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_grobbulus_poison : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_grobbulus_poison() : SpellScriptLoader("spell_grobbulus_poison") { }
|
||||
|
||||
class spell_grobbulus_poison_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_grobbulus_poison_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
std::list<WorldObject*> tmplist;
|
||||
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
if (GetCaster()->IsWithinDist3d((*itr), 0.0f))
|
||||
tmplist.push_back(*itr);
|
||||
|
||||
targets.clear();
|
||||
for( std::list<WorldObject*>::iterator itr = tmplist.begin(); itr != tmplist.end(); ++itr )
|
||||
targets.push_back(*itr);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_grobbulus_poison_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_grobbulus_poison_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_grobbulus()
|
||||
{
|
||||
new boss_grobbulus();
|
||||
new boss_grobbulus_poison_cloud();
|
||||
new spell_grobbulus_poison();
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNT = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SPELL_DISRUPTION = 29310,
|
||||
SPELL_DECREPIT_FEVER_10 = 29998,
|
||||
SPELL_DECREPIT_FEVER_25 = 55011,
|
||||
SPELL_PLAGUE_CLOUD = 29350,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_SPELL_DISRUPTION = 1,
|
||||
EVENT_SPELL_DECEPIT_FEVER = 2,
|
||||
EVENT_ERUPT_SECTION = 3,
|
||||
EVENT_SWITCH_PHASE = 4,
|
||||
EVENT_SAFETY_DANCE = 5,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
PHASE_SLOW_DANCE = 0,
|
||||
PHASE_FAST_DANCE = 1,
|
||||
};
|
||||
|
||||
class boss_heigan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_heigan() : CreatureScript("boss_heigan") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_heiganAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_heiganAI : public ScriptedAI
|
||||
{
|
||||
boss_heiganAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint8 currentPhase;
|
||||
uint8 currentSection;
|
||||
bool moveRight;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
currentPhase = 0;
|
||||
currentSection = 3;
|
||||
moveRight = true;
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_HEIGAN, NOT_STARTED);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_HEIGAN_ENTER_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_HEIGAN, DONE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_HEIGAN, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_HEIGAN_ENTER_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
StartFightPhase(PHASE_SLOW_DANCE);
|
||||
}
|
||||
|
||||
void StartFightPhase(uint8 phase)
|
||||
{
|
||||
currentSection = 3;
|
||||
currentPhase = phase;
|
||||
events.Reset();
|
||||
if (phase == PHASE_SLOW_DANCE)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SPELL_SPELL_DISRUPTION, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_DECEPIT_FEVER, 12000);
|
||||
events.ScheduleEvent(EVENT_ERUPT_SECTION, 10000);
|
||||
events.ScheduleEvent(EVENT_SWITCH_PHASE, 90000);
|
||||
}
|
||||
else // if (phase == PHASE_FAST_DANCE)
|
||||
{
|
||||
me->MonsterTextEmote("%s teleports and begins to channel a spell!", 0, true);
|
||||
// teleport
|
||||
float x, y, z, o;
|
||||
me->GetHomePosition(x, y, z, o);
|
||||
me->NearTeleportTo(x, y, z, o);
|
||||
|
||||
me->CastSpell(me, SPELL_PLAGUE_CLOUD, false);
|
||||
events.ScheduleEvent(EVENT_ERUPT_SECTION, 4000);
|
||||
events.ScheduleEvent(EVENT_SWITCH_PHASE, 45000);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SAFETY_DANCE, 5000);
|
||||
}
|
||||
|
||||
bool IsInRoom(Unit* who)
|
||||
{
|
||||
if (who->GetPositionX() > 2826 || who->GetPositionX() < 2723 || who->GetPositionY() > -3641 || who->GetPositionY() < -3736)
|
||||
{
|
||||
if (who->GetGUID() == me->GetGUID())
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!IsInRoom(me))
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
//if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
// return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_SPELL_DISRUPTION:
|
||||
me->CastSpell(me, SPELL_SPELL_DISRUPTION, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_DECEPIT_FEVER:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DECREPIT_FEVER_10, SPELL_DECREPIT_FEVER_25), false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SWITCH_PHASE:
|
||||
StartFightPhase(currentPhase == PHASE_SLOW_DANCE ? PHASE_FAST_DANCE : PHASE_SLOW_DANCE);
|
||||
// no pop, there is reset in start fight
|
||||
break;
|
||||
case EVENT_ERUPT_SECTION:
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_HEIGAN_ERUPTION, currentSection);
|
||||
if (currentSection == 3)
|
||||
moveRight = false;
|
||||
else if (currentSection == 0)
|
||||
moveRight = true;
|
||||
|
||||
moveRight ? currentSection++ : currentSection--;
|
||||
}
|
||||
|
||||
if (currentPhase == PHASE_SLOW_DANCE && !urand(0,3))
|
||||
Talk(SAY_TAUNT);
|
||||
|
||||
events.RepeatEvent(currentPhase == PHASE_SLOW_DANCE ? 10000 : 4000);
|
||||
break;
|
||||
case EVENT_SAFETY_DANCE:
|
||||
{
|
||||
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
||||
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
{
|
||||
if (IsInRoom(itr->GetSource()) && !itr->GetSource()->IsAlive())
|
||||
{
|
||||
events.PopEvent();
|
||||
pInstance->SetData(DATA_DANCE_FAIL, 0);
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
events.RepeatEvent(5000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_heigan()
|
||||
{
|
||||
new boss_heigan();
|
||||
}
|
||||
@@ -1,621 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_TAUNT = 6,
|
||||
SAY_AGGRO = 7,
|
||||
SAY_SLAY = 8,
|
||||
SAY_DEATH = 9,
|
||||
SAY_CHAIN = 10,
|
||||
SAY_FROST_BLAST = 11,
|
||||
SAY_REQUEST_AID = 12, //start of phase 3
|
||||
SAY_ANSWER_REQUEST = 13, //lich king answer
|
||||
SAY_SUMMON_MINIONS = 14, //start of phase 1
|
||||
SAY_SPECIAL = 15
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_FROST_BOLT_SINGLE_10 = 28478,
|
||||
SPELL_FROST_BOLT_SINGLE_25 = 55802,
|
||||
SPELL_FROST_BOLT_MULTI_10 = 28479,
|
||||
SPELL_FROST_BOLT_MULTI_25 = 55807,
|
||||
SPELL_SHADOW_FISURE = 27810,
|
||||
SPELL_VOID_BLAST = 27812,
|
||||
SPELL_DETONATE_MANA = 27819,
|
||||
SPELL_MANA_DETONATION_DAMAGE = 27820,
|
||||
SPELL_FROST_BLAST = 27808,
|
||||
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
|
||||
SPELL_BERSERK = 28498,
|
||||
|
||||
// Minions
|
||||
SPELL_FRENZY = 28468,
|
||||
SPELL_MORTAL_WOUND = 28467,
|
||||
SPELL_BLOOD_TAP = 28470,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_SOLDIER_OF_THE_FROZEN_WASTES = 16427,
|
||||
NPC_UNSTOPPABLE_ABOMINATION = 16428,
|
||||
NPC_SOUL_WEAVER = 16429,
|
||||
NPC_GUARDIAN_OF_ICECROWN = 16441,
|
||||
|
||||
ACTION_CALL_HELP_ON = 1,
|
||||
ACTION_CALL_HELP_OFF = 2,
|
||||
ACTION_SECOND_PHASE = 3,
|
||||
};
|
||||
|
||||
enum Event
|
||||
{
|
||||
// Kel'Thuzad
|
||||
EVENT_SUMMON_SOLDIER = 1,
|
||||
EVENT_SUMMON_UNSTOPPABLE_ABOMINATION = 2,
|
||||
EVENT_SUMMON_SOUL_WEAVER = 3,
|
||||
EVENT_START_SECOND_PHASE = 4,
|
||||
EVENT_SPELL_FROST_BOLT_SINGLE = 5,
|
||||
EVENT_SPELL_FROST_BOLT_MULTI = 6,
|
||||
EVENT_SPELL_DETONATE_MANA = 7,
|
||||
EVENT_SECOND_PHASE_HEALTH_CHECK = 8,
|
||||
EVENT_THIRD_PHASE_LICH_KING_SAY = 9,
|
||||
EVENT_SPELL_SHADOW_FISSURE = 10,
|
||||
EVENT_SPELL_FROST_BLAST = 11,
|
||||
EVENT_SPELL_CHAINS = 12,
|
||||
EVENT_SUMMON_GUARDIAN_OF_ICECROWN = 13,
|
||||
EVENT_FLOOR_CHANGE = 14,
|
||||
|
||||
// Minions
|
||||
EVENT_MINION_SPELL_FRENZY = 100,
|
||||
EVENT_MINION_SPELL_MORTAL_WOUND = 101,
|
||||
EVENT_MINION_SPELL_BLOOD_TAP = 102,
|
||||
};
|
||||
|
||||
const Position SummonPositions[12] =
|
||||
{
|
||||
// Portals
|
||||
{3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, //LEFT_FAR
|
||||
{3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, //LEFT_MIDDLE
|
||||
{3683.868652f, -5057.281250f, 143.183884f, 5.237086f}, //LEFT_NEAR
|
||||
{3759.355225f, -5174.128418f, 143.802383f, 2.170104f}, //RIGHT_FAR
|
||||
{3700.724365f, -5185.123047f, 143.928024f, 1.309310f}, //RIGHT_MIDDLE
|
||||
{3665.121094f, -5138.679199f, 143.183212f, 0.604023f}, //RIGHT_NEAR
|
||||
|
||||
// Edges
|
||||
//{3754.431396f, -5080.727734f, 142.036316f, 3.736189f}, //LEFT_FAR
|
||||
// {3724.396484f, -5061.330566f, 142.032700f, 4.564785f}, //LEFT_MIDDLE
|
||||
//{3687.158424f, -5076.834473f, 142.017319f, 5.237086f}, //LEFT_NEAR
|
||||
//{3687.571777f, -5126.831055f, 142.017807f, 0.604023f}, //RIGHT_FAR
|
||||
//{3707.990733f, -5151.450195f, 142.032562f, 1.376855f}, //RIGHT_MIDDLE
|
||||
// {3739.500000f, -5141.883989f, 142.014113f, 2.121412f} //RIGHT_NEAR
|
||||
|
||||
// Middle
|
||||
{3769.34f, -5071.80f, 143.2082f, 3.658f},
|
||||
{3729.78f, -5043.56f, 143.3867f, 4.475f},
|
||||
{3682.75f, -5055.26f, 143.1848f, 5.295f},
|
||||
{3752.58f, -5161.82f, 143.2944f, 2.126f},
|
||||
{3702.83f, -5171.70f, 143.4356f, 1.305f},
|
||||
{3665.30f, -5141.55f, 143.1846f, 0.566f}
|
||||
};
|
||||
|
||||
class boss_kelthuzad : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kelthuzad() : CreatureScript("boss_kelthuzad") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_kelthuzadAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_kelthuzadAI : public ScriptedAI
|
||||
{
|
||||
boss_kelthuzadAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* pInstance;
|
||||
|
||||
float NormalizeOrientation(float o)
|
||||
{
|
||||
// Only positive values will be passed
|
||||
return fmod(o, 2.0f * static_cast<float>(M_PI));
|
||||
}
|
||||
|
||||
void SpawnHelpers()
|
||||
{
|
||||
// Ehhh...
|
||||
// in short: 6 rooms, 8 soldiers, 3 abominations and 1 weaver in each room
|
||||
// middle positions in table starts from 6
|
||||
for (uint8 i = 6; i < 12; ++i)
|
||||
for (uint8 j = 0; j < 8; ++j)
|
||||
{
|
||||
float angle = M_PI*2/8*j;
|
||||
me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, SummonPositions[i].GetPositionX()+6*cos(angle), SummonPositions[i].GetPositionY()+6*sin(angle), SummonPositions[i].GetPositionZ()+0.5f, SummonPositions[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
for (uint8 i = 6; i < 12; ++i)
|
||||
for (uint8 j = 1; j < 4; ++j)
|
||||
{
|
||||
float dist = j == 2 ? 0.0f : 8.0f; // second in middle
|
||||
float angle = SummonPositions[i].GetOrientation() + M_PI*2/4*j;
|
||||
NormalizeOrientation(angle);
|
||||
me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, SummonPositions[i].GetPositionX()+dist*cos(angle), SummonPositions[i].GetPositionY()+dist*sin(angle), SummonPositions[i].GetPositionZ()+0.5f, SummonPositions[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
for (uint8 i = 6; i < 12; ++i)
|
||||
for (uint8 j = 0; j < 1; ++j)
|
||||
{
|
||||
float angle = SummonPositions[i].GetOrientation() + M_PI;
|
||||
NormalizeOrientation(angle);
|
||||
me->SummonCreature(NPC_SOUL_WEAVER, SummonPositions[i].GetPositionX()+6*cos(angle), SummonPositions[i].GetPositionY()+6*sin(angle), SummonPositions[i].GetPositionZ()+0.5f, SummonPositions[i].GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_KELTHUZAD, NOT_STARTED);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_FLOOR)))
|
||||
{
|
||||
go->SetPhaseMask(1, true);
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_KELTHUZAD, DONE);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!me->IsInCombat() && who->GetTypeId() == TYPEID_PLAYER && who->IsAlive() && me->GetDistance(who) <= 50.0f)
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
Talk(SAY_SUMMON_MINIONS);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->RemoveAllAttackers();
|
||||
me->SetTarget(0);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
|
||||
// Spawn helpers
|
||||
SpawnHelpers();
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_SOLDIER, 3200);
|
||||
events.ScheduleEvent(EVENT_SUMMON_UNSTOPPABLE_ABOMINATION, 10000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SOUL_WEAVER, 24000);
|
||||
events.ScheduleEvent(EVENT_START_SECOND_PHASE, 228000);
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_KELTHUZAD, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_FLOOR)))
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FLOOR_CHANGE, 15000);
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_FLOOR_CHANGE:
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_FLOOR)))
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FLOOR_CHANGE, 15000);
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
go->SetPhaseMask(2, true);
|
||||
}
|
||||
}
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SUMMON_SOLDIER:
|
||||
if (Creature* cr = me->SummonCreature(NPC_SOLDIER_OF_THE_FROZEN_WASTES, SummonPositions[urand(0,5)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(3200);
|
||||
break;
|
||||
case EVENT_SUMMON_UNSTOPPABLE_ABOMINATION:
|
||||
if (Creature* cr = me->SummonCreature(NPC_UNSTOPPABLE_ABOMINATION, SummonPositions[urand(0,5)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SUMMON_SOUL_WEAVER:
|
||||
if (Creature* cr = me->SummonCreature(NPC_SOUL_WEAVER, SummonPositions[urand(0,5)], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
|
||||
{
|
||||
if (Unit* target = SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
cr->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_START_SECOND_PHASE:
|
||||
// same as pop
|
||||
Talk(SAY_AGGRO);
|
||||
events.Reset();
|
||||
summons.DoAction(ACTION_SECOND_PHASE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.ScheduleEvent(EVENT_SPELL_FROST_BOLT_SINGLE, 2000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FROST_BOLT_MULTI, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DETONATE_MANA, 20000);
|
||||
events.ScheduleEvent(EVENT_SECOND_PHASE_HEALTH_CHECK, 1000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_FISSURE, 25000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FROST_BLAST, 45000);
|
||||
if (Is25ManRaid())
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAINS, 50000);
|
||||
break;
|
||||
case EVENT_SPELL_FROST_BOLT_SINGLE:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_FROST_BOLT_SINGLE_10, SPELL_FROST_BOLT_SINGLE_25), false);
|
||||
events.RepeatEvent(urand(2000, 15000));
|
||||
break;
|
||||
case EVENT_SPELL_FROST_BOLT_MULTI:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FROST_BOLT_MULTI_10, SPELL_FROST_BOLT_MULTI_25), false);
|
||||
events.RepeatEvent(24000);
|
||||
break;
|
||||
case EVENT_SPELL_SHADOW_FISSURE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
|
||||
me->CastSpell(target, SPELL_SHADOW_FISURE, false);
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_SPELL_FROST_BLAST:
|
||||
if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1,0), 0, true))
|
||||
me->CastSpell(target, SPELL_FROST_BLAST, false);
|
||||
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_FROST_BLAST);
|
||||
events.RepeatEvent(45000);
|
||||
break;
|
||||
case EVENT_SPELL_CHAINS:
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true, -SPELL_CHAINS_OF_KELTHUZAD))
|
||||
me->CastSpell(target, SPELL_CHAINS_OF_KELTHUZAD, true);
|
||||
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_CHAIN);
|
||||
events.RepeatEvent(50000);
|
||||
break;
|
||||
case EVENT_SPELL_DETONATE_MANA:
|
||||
{
|
||||
std::vector<Unit*> unitList;
|
||||
ThreatContainer::StorageType const& threatList = me->getThreatManager().getThreatList();
|
||||
for (ThreatContainer::StorageType::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER
|
||||
&& (*itr)->getTarget()->getPowerType() == POWER_MANA
|
||||
&& (*itr)->getTarget()->GetPower(POWER_MANA))
|
||||
unitList.push_back((*itr)->getTarget());
|
||||
}
|
||||
|
||||
if (!unitList.empty())
|
||||
{
|
||||
std::vector<Unit*>::iterator itr = unitList.begin();
|
||||
advance(itr, urand(0, unitList.size()-1));
|
||||
me->CastSpell(*itr, SPELL_DETONATE_MANA, false);
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_SPECIAL);
|
||||
}
|
||||
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
case EVENT_SECOND_PHASE_HEALTH_CHECK:
|
||||
if (me->HealthBelowPct(45))
|
||||
{
|
||||
events.PopEvent();
|
||||
Talk(SAY_REQUEST_AID);
|
||||
events.DelayEvents(5500);
|
||||
events.ScheduleEvent(EVENT_THIRD_PHASE_LICH_KING_SAY, 5000);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_THIRD_PHASE_LICH_KING_SAY:
|
||||
if (pInstance)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_LICH_KING_BOSS)))
|
||||
cr->AI()->Talk(SAY_ANSWER_REQUEST);
|
||||
|
||||
for (uint8 i = 0 ; i < RAID_MODE(2,4); ++i)
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDIAN_OF_ICECROWN, 10000+(i*5000));
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDIAN_OF_ICECROWN:
|
||||
me->MonsterTextEmote("A Guardian of Icecrown enter the fight!", 0, true);
|
||||
if (Creature* cr = me->SummonCreature(NPC_GUARDIAN_OF_ICECROWN, SummonPositions[RAND(0, 1, 3, 4)]))
|
||||
cr->AI()->AttackStart(me->GetVictim());
|
||||
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_kelthuzad_minion : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kelthuzad_minion() : CreatureScript("boss_kelthuzad_minion") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_kelthuzad_minionAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_kelthuzad_minionAI : public ScriptedAI
|
||||
{
|
||||
boss_kelthuzad_minionAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool callHelp;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetNoCallAssistance(true);
|
||||
callHelp = true;
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_CALL_HELP_ON)
|
||||
callHelp = true;
|
||||
else if (param == ACTION_CALL_HELP_OFF)
|
||||
callHelp = false;
|
||||
else if (param == ACTION_SECOND_PHASE)
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
me->DespawnOrUnsummon(500);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER && !who->IsPet())
|
||||
return;
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* )
|
||||
{
|
||||
if (me->GetEntry() == NPC_UNSTOPPABLE_ABOMINATION && me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(DATA_ABOMINATION_KILLED, 0);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who)
|
||||
{
|
||||
ScriptedAI::AttackStart(who);
|
||||
if (callHelp)
|
||||
{
|
||||
std::list<Creature*> targets;
|
||||
me->GetCreaturesWithEntryInRange(targets, 15.0f, me->GetEntry());
|
||||
for (std::list<Creature*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetGUID() != me->GetGUID())
|
||||
{
|
||||
(*itr)->ToCreature()->AI()->DoAction(ACTION_CALL_HELP_OFF);
|
||||
(*itr)->ToCreature()->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (me->GetEntry() != NPC_UNSTOPPABLE_ABOMINATION && me->GetEntry() != NPC_GUARDIAN_OF_ICECROWN)
|
||||
me->AddThreat(who, 1000000.0f);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
if (me->GetEntry() == NPC_UNSTOPPABLE_ABOMINATION)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_FRENZY, 1000);
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_MORTAL_WOUND, 5000);
|
||||
}
|
||||
else if (me->GetEntry() == NPC_GUARDIAN_OF_ICECROWN)
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_BLOOD_TAP, 15000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_MINION_SPELL_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_FRENZY:
|
||||
if (me->HealthBelowPct(35))
|
||||
{
|
||||
me->CastSpell(me, SPELL_FRENZY, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_BLOOD_TAP:
|
||||
me->CastSpell(me->GetVictim(), SPELL_BLOOD_TAP, false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_kelthuzad_frost_blast : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_kelthuzad_frost_blast() : SpellScriptLoader("spell_kelthuzad_frost_blast") { }
|
||||
|
||||
class spell_kelthuzad_frost_blast_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_kelthuzad_frost_blast_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster || !caster->ToCreature())
|
||||
return;
|
||||
|
||||
std::list<WorldObject*> tmplist;
|
||||
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
if (!(*itr)->ToUnit()->HasAura(SPELL_FROST_BLAST))
|
||||
tmplist.push_back(*itr);
|
||||
|
||||
targets.clear();
|
||||
for (std::list<WorldObject*>::iterator itr = tmplist.begin(); itr != tmplist.end(); ++itr)
|
||||
targets.push_back(*itr);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kelthuzad_frost_blast_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_kelthuzad_frost_blast_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_kelthuzad_detonate_mana : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { }
|
||||
|
||||
class spell_kelthuzad_detonate_mana_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_kelthuzad_detonate_mana_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_MANA_DETONATION_DAMAGE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleScript(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
Unit* target = GetTarget();
|
||||
if (int32 mana = int32(target->GetMaxPower(POWER_MANA) / 10))
|
||||
{
|
||||
mana = target->ModifyPower(POWER_MANA, -mana);
|
||||
target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, NULL, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kelthuzad_detonate_mana_AuraScript::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_kelthuzad_detonate_mana_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void AddSC_boss_kelthuzad()
|
||||
{
|
||||
new boss_kelthuzad();
|
||||
new boss_kelthuzad_minion();
|
||||
new spell_kelthuzad_frost_blast();
|
||||
new spell_kelthuzad_detonate_mana();
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_NECROTIC_AURA = 55593,
|
||||
SPELL_SUMMON_SPORE = 29234,
|
||||
SPELL_DEATHBLOOM_10 = 29865,
|
||||
SPELL_DEATHBLOOM_25 = 55053,
|
||||
SPELL_INEVITABLE_DOOM_10 = 29204,
|
||||
SPELL_INEVITABLE_DOOM_25 = 55052,
|
||||
SPELL_BERSERK = 26662,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_NECROTIC_AURA = 1,
|
||||
EVENT_SPELL_DEATHBLOOM = 2,
|
||||
EVENT_SPELL_INEVITABLE_DOOM = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_NECROTIC_AURA_APPLIED = 0,
|
||||
SAY_NECROTIC_AURA_REMOVED = 1,
|
||||
SAY_NECROTIC_AURA_FADING = 2,
|
||||
};
|
||||
|
||||
class boss_loatheb : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_loatheb() : CreatureScript("boss_loatheb") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_loathebAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_loathebAI : public ScriptedAI
|
||||
{
|
||||
boss_loathebAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_LOATHEB, NOT_STARTED);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_LOATHEB_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { cr->SetInCombatWithZone(); }
|
||||
|
||||
void SummonedCreatureDies(Creature* cr, Unit*)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_SPORE_KILLED, 0);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_LOATHEB, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_LOATHEB_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_NECROTIC_AURA, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATHBLOOM, 25000);
|
||||
events.ScheduleEvent(EVENT_SPELL_INEVITABLE_DOOM, 120000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 720000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_LOATHEB, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_NECROTIC_AURA:
|
||||
me->CastSpell(me, SPELL_NECROTIC_AURA, true);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_DEATHBLOOM:
|
||||
me->CastSpell(me, SPELL_SUMMON_SPORE, true);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DEATHBLOOM_10, SPELL_DEATHBLOOM_25), false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SPELL_INEVITABLE_DOOM:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_INEVITABLE_DOOM_10, SPELL_INEVITABLE_DOOM_25), false);
|
||||
events.RepeatEvent(events.GetTimer() < 5*MINUTE*IN_MILLISECONDS ? 30000 : 15000);
|
||||
break;
|
||||
case EVENT_SPELL_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_loatheb_necrotic_aura_warning() : SpellScriptLoader("spell_loatheb_necrotic_aura_warning") { }
|
||||
|
||||
class spell_loatheb_necrotic_aura_warning_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_loatheb_necrotic_aura_warning_AuraScript);
|
||||
|
||||
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (target->IsAIEnabled)
|
||||
target->AI()->Talk(SAY_NECROTIC_AURA_APPLIED);
|
||||
}
|
||||
|
||||
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Creature* target = GetTarget()->ToCreature();
|
||||
if (target->IsAIEnabled)
|
||||
target->AI()->Talk(SAY_NECROTIC_AURA_REMOVED);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectApply += AuraEffectApplyFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_loatheb_necrotic_aura_warning_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_loatheb()
|
||||
{
|
||||
new boss_loatheb();
|
||||
new spell_loatheb_necrotic_aura_warning();
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "PassiveAI.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_WEB_WRAP = 28622,
|
||||
SPELL_WEB_SPRAY_10 = 29484,
|
||||
SPELL_WEB_SPRAY_25 = 54125,
|
||||
SPELL_POISON_SHOCK_10 = 28741,
|
||||
SPELL_POISON_SHOCK_25 = 54122,
|
||||
SPELL_NECROTIC_POISON_10 = 54121,
|
||||
SPELL_NECROTIC_POISON_25 = 28776,
|
||||
SPELL_FRENZY_10 = 54123,
|
||||
SPELL_FRENZY_25 = 54124,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_WEB_SPRAY = 1,
|
||||
EVENT_SPELL_POISON_SHOCK = 2,
|
||||
EVENT_SPELL_NECROTIC_POISON = 3,
|
||||
EVENT_WEB_WRAP = 4,
|
||||
EVENT_HEALTH_CHECK = 5,
|
||||
EVENT_SUMMON_SPIDERLINGS = 6,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_WEB_WRAP = 16486,
|
||||
NPC_MAEXXNA_SPIDERLING = 17055,
|
||||
};
|
||||
|
||||
const Position PosWrap[3] =
|
||||
{
|
||||
{3546.796f, -3869.082f, 296.450f},
|
||||
{3531.271f, -3847.424f, 299.450f},
|
||||
{3497.067f, -3843.384f, 302.384f}
|
||||
};
|
||||
|
||||
class boss_maexxna : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_maexxna() : CreatureScript("boss_maexxna") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_maexxnaAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_maexxnaAI : public ScriptedAI
|
||||
{
|
||||
boss_maexxnaAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
bool IsInRoom()
|
||||
{
|
||||
if (me->GetExactDist(3486.6f, -3890.6f, 291.8f) > 100.0f)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_MAEXXNA, NOT_STARTED);
|
||||
if (pInstance->GetData(EVENT_FAERLINA) == DONE)
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_MAEXXNA_GATE)))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_WEB_WRAP, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WEB_SPRAY, 40000);
|
||||
events.ScheduleEvent(EVENT_SPELL_POISON_SHOCK, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_NECROTIC_POISON, 5000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPIDERLINGS, 30000);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_MAEXXNA, IN_PROGRESS);
|
||||
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetData64(DATA_MAEXXNA_GATE)))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_MAEXXNA, DONE);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr)
|
||||
{
|
||||
if (cr->GetEntry() == NPC_MAEXXNA_SPIDERLING)
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
cr->AI()->AttackStart(target);
|
||||
}
|
||||
|
||||
summons.Summon(cr);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!IsInRoom())
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_WEB_SPRAY:
|
||||
me->MonsterTextEmote("%s sprays strands of web everywhere!", 0, true);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_WEB_SPRAY_10, SPELL_WEB_SPRAY_25), true);
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
case EVENT_SPELL_POISON_SHOCK:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_POISON_SHOCK_10, SPELL_POISON_SHOCK_25), false);
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
case EVENT_SPELL_NECROTIC_POISON:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_NECROTIC_POISON_10, SPELL_NECROTIC_POISON_25), false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SUMMON_SPIDERLINGS:
|
||||
me->MonsterTextEmote("Spiderlings appear on the web!", 0, true);
|
||||
for (uint8 i = 0; i < 8; ++i)
|
||||
me->SummonCreature(NPC_MAEXXNA_SPIDERLING, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
case EVENT_HEALTH_CHECK:
|
||||
if (me->GetHealthPct() < 30)
|
||||
{
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FRENZY_10, SPELL_FRENZY_25), true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
case EVENT_WEB_WRAP:
|
||||
me->MonsterTextEmote("%s spins her web into a cocoon!", 0, true);
|
||||
for (uint8 i = 0; i < RAID_MODE(1,2); ++i)
|
||||
if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP))
|
||||
{
|
||||
target->RemoveAura(RAID_MODE(SPELL_WEB_SPRAY_10, SPELL_WEB_SPRAY_25));
|
||||
uint8 pos = urand(0,2);
|
||||
|
||||
target->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20);
|
||||
if (Creature *wrap = me->SummonCreature(NPC_WEB_WRAP, PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000))
|
||||
wrap->AI()->SetGUID(target->GetGUID());
|
||||
}
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class boss_maexxna_webwrap : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_maexxna_webwrap() : CreatureScript("boss_maexxna_webwrap") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_maexxna_webwrapAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_maexxna_webwrapAI : public NullCreatureAI
|
||||
{
|
||||
boss_maexxna_webwrapAI(Creature *c) : NullCreatureAI(c), victimGUID(0) {}
|
||||
|
||||
uint64 victimGUID;
|
||||
void SetGUID(uint64 guid, int32 param)
|
||||
{
|
||||
victimGUID = guid;
|
||||
if (me->m_spells[0] && victimGUID)
|
||||
if (Unit *victim = ObjectAccessor::GetUnit(*me, victimGUID))
|
||||
victim->CastSpell(victim, me->m_spells[0], true, NULL, NULL, me->GetGUID());
|
||||
}
|
||||
|
||||
void JustDied(Unit *killer)
|
||||
{
|
||||
if (me->m_spells[0] && victimGUID)
|
||||
if (Unit *victim = ObjectAccessor::GetUnit(*me, victimGUID))
|
||||
victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_maexxna()
|
||||
{
|
||||
new boss_maexxna();
|
||||
new boss_maexxna_webwrap();
|
||||
}
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SUMMON = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CURSE_OF_THE_PLAGUEBRINGER_10 = 29213,
|
||||
SPELL_CURSE_OF_THE_PLAGUEBRINGER_25 = 54835,
|
||||
SPELL_CRIPPLE_10 = 29212,
|
||||
SPELL_CRIPPLE_25 = 54814,
|
||||
SPELL_SUMMON_PLAGUED_WARRIORS = 29237,
|
||||
SPELL_TELEPORT = 29216,
|
||||
SPELL_BLINK = 29208,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CURSE = 1,
|
||||
EVENT_SPELL_CRIPPLE = 2,
|
||||
EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE = 3,
|
||||
EVENT_MOVE_TO_BALCONY = 4,
|
||||
EVENT_SPELL_BLINK = 5,
|
||||
EVENT_MOVE_TO_GROUND = 6,
|
||||
EVENT_SUMMON_PLAGUED_WARRIOR_REAL = 7,
|
||||
EVENT_BALCONY_SUMMON_ANNOUNCE = 8,
|
||||
EVENT_BALCONY_SUMMON_REAL = 9,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_PLAGUED_WARRIOR = 16984,
|
||||
NPC_PLAGUED_CHAMPION = 16983,
|
||||
NPC_PLAGUED_GUARDIAN = 16981,
|
||||
};
|
||||
|
||||
const Position summoningPosition[5] =
|
||||
{
|
||||
{2728.12f, -3544.43f, 261.91f, 6.04f},
|
||||
{2729.05f, -3544.47f, 261.91f, 5.58f},
|
||||
{2728.24f, -3465.08f, 264.20f, 3.56f},
|
||||
{2704.11f, -3456.81f, 265.53f, 4.51f},
|
||||
{2663.56f, -3464.43f, 262.66f, 5.20f},
|
||||
};
|
||||
|
||||
const Position nothPosition = {2684.94f, -3502.53f, 261.31f, 4.7f};
|
||||
|
||||
class boss_noth : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_noth() : CreatureScript("boss_noth") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_nothAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_nothAI : public ScriptedAI
|
||||
{
|
||||
boss_nothAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 totalPhase;
|
||||
|
||||
void StartGroundPhase()
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_BALCONY, (totalPhase < 2 ? 110000 : (110000 / totalPhase)));
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE, 15000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE, 25000);
|
||||
if (Is25ManRaid())
|
||||
events.ScheduleEvent(EVENT_SPELL_BLINK, 26000);
|
||||
}
|
||||
|
||||
void StartBalconyPhase()
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_BALCONY_SUMMON_ANNOUNCE, 4000);
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_GROUND, 70000);
|
||||
}
|
||||
|
||||
void SummonHelper(uint32 entry, uint32 count)
|
||||
{
|
||||
for (uint8 i = 0; i < count; ++i)
|
||||
me->SummonCreature(entry, summoningPosition[urand(0,4)]);
|
||||
}
|
||||
|
||||
bool IsInRoom()
|
||||
{
|
||||
if (me->GetPositionX() > 2730 || me->GetPositionX() < 2614 || me->GetPositionY() > -3455 || me->GetPositionY() < -3553)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
totalPhase = 0;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_NOTH, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_NOTH, IN_PROGRESS);
|
||||
|
||||
StartGroundPhase();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_NOTH, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!IsInRoom())
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
// GROUND
|
||||
case EVENT_SPELL_CURSE:
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_CURSE_OF_THE_PLAGUEBRINGER_10, SPELL_CURSE_OF_THE_PLAGUEBRINGER_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(3, 10), me, false);
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_SUMMON_PLAGUED_WARRIOR_ANNOUNCE:
|
||||
me->MonsterTextEmote("Noth the Plaguebringer summons forth Skeletal Warriors!", 0, true);
|
||||
Talk(SAY_SUMMON);
|
||||
events.RepeatEvent(25000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PLAGUED_WARRIOR_REAL, 4000);
|
||||
break;
|
||||
case EVENT_SUMMON_PLAGUED_WARRIOR_REAL:
|
||||
me->CastSpell(me, SPELL_SUMMON_PLAGUED_WARRIORS, true);
|
||||
SummonHelper(NPC_PLAGUED_WARRIOR, RAID_MODE(2,3));
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_MOVE_TO_BALCONY:
|
||||
me->MonsterTextEmote("%s teleports to the balcony above!", 0, true);
|
||||
me->CastSpell(me, SPELL_TELEPORT, true);
|
||||
StartBalconyPhase();
|
||||
//events.PopEvent(); events.Reset()!!
|
||||
break;
|
||||
case EVENT_SPELL_BLINK:
|
||||
DoResetThreat();
|
||||
me->MonsterTextEmote("%s blinks away!", 0, true);
|
||||
me->CastSpell(me, RAID_MODE(SPELL_CRIPPLE_10, SPELL_CRIPPLE_25), false);
|
||||
me->CastSpell(me, SPELL_BLINK, true);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
// BALCONY
|
||||
case EVENT_BALCONY_SUMMON_ANNOUNCE:
|
||||
me->MonsterTextEmote("%s raises more skeletons!", 0, true);
|
||||
events.RepeatEvent(25000);
|
||||
events.ScheduleEvent(EVENT_BALCONY_SUMMON_REAL, 4000);
|
||||
break;
|
||||
case EVENT_BALCONY_SUMMON_REAL:
|
||||
me->CastSpell(me, SPELL_SUMMON_PLAGUED_WARRIORS, true); // visual only
|
||||
if (totalPhase == 0)
|
||||
SummonHelper(NPC_PLAGUED_CHAMPION, RAID_MODE(2,4));
|
||||
else if (totalPhase == 1)
|
||||
{
|
||||
SummonHelper(NPC_PLAGUED_CHAMPION, RAID_MODE(1,2));
|
||||
SummonHelper(NPC_PLAGUED_GUARDIAN, RAID_MODE(1,2));
|
||||
}
|
||||
else
|
||||
SummonHelper(NPC_PLAGUED_GUARDIAN, RAID_MODE(2,4));
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_MOVE_TO_GROUND:
|
||||
me->MonsterTextEmote("%s teleports back into the battle!", 0, true);
|
||||
totalPhase++;
|
||||
StartGroundPhase();
|
||||
me->NearTeleportTo(nothPosition.GetPositionX(), nothPosition.GetPositionY(), nothPosition.GetPositionZ(), nothPosition.GetOrientation(), true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasReactState(REACT_AGGRESSIVE))
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_noth()
|
||||
{
|
||||
new boss_noth();
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2,
|
||||
EMOTE_BERSERK = 3,
|
||||
EMOTE_ENRAGE = 4
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_HATEFUL_STRIKE_10 = 41926,
|
||||
SPELL_HATEFUL_STRIKE_25 = 59192,
|
||||
SPELL_FRENZY = 28131,
|
||||
SPELL_BERSERK = 26662,
|
||||
SPELL_SLIME_BOLT = 32309,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HEALTH_CHECK = 1,
|
||||
EVENT_SPELL_HATEFUL_STRIKE = 2,
|
||||
EVENT_SPELL_SLIME_BOLT = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACHIEV_TIMED_START_EVENT = 10286,
|
||||
};
|
||||
|
||||
class boss_patchwerk : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_patchwerk() : CreatureScript("boss_patchwerk") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_patchwerkAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_patchwerkAI : public ScriptedAI
|
||||
{
|
||||
boss_patchwerkAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_PATCHWERK, NOT_STARTED);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_PATCHWERK, DONE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->SetInCombatWithZone();
|
||||
events.ScheduleEvent(EVENT_SPELL_HATEFUL_STRIKE, 1200);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
pInstance->SetData(EVENT_PATCHWERK, IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_HATEFUL_STRIKE:
|
||||
{
|
||||
//Cast Hateful strike on the player with the highest
|
||||
//amount of HP within melee distance, and second threat amount
|
||||
std::list<Unit*> meleeRangeTargets;
|
||||
Unit* finalTarget = NULL;
|
||||
uint8 counter = 0;
|
||||
|
||||
ThreatContainer::StorageType::const_iterator i = me->getThreatManager().getThreatList().begin();
|
||||
for (; i != me->getThreatManager().getThreatList().end(); ++i, ++counter)
|
||||
{
|
||||
// Gather all units with melee range
|
||||
Unit *target = (*i)->getTarget();
|
||||
if (me->IsWithinMeleeRange(target))
|
||||
meleeRangeTargets.push_back(target);
|
||||
|
||||
// and add threat to most hated
|
||||
if (counter < RAID_MODE(2,3))
|
||||
me->AddThreat(target, 500.0f);
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
for (std::list<Unit*>::const_iterator i = meleeRangeTargets.begin(); i != meleeRangeTargets.end(); ++i, ++counter)
|
||||
{
|
||||
// if there is only one target available
|
||||
if (meleeRangeTargets.size() == 1)
|
||||
finalTarget = (*i);
|
||||
else if (counter > 0) // skip first target
|
||||
{
|
||||
if (!finalTarget || (*i)->GetHealth() > finalTarget->GetHealth())
|
||||
finalTarget = (*i);
|
||||
|
||||
// third loop
|
||||
if (counter >= 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (finalTarget)
|
||||
me->CastSpell(finalTarget, RAID_MODE(SPELL_HATEFUL_STRIKE_10, SPELL_HATEFUL_STRIKE_25), false);
|
||||
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
}
|
||||
case EVENT_SPELL_BERSERK:
|
||||
Talk(EMOTE_BERSERK);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.ScheduleEvent(EVENT_SPELL_SLIME_BOLT, 2000);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_SPELL_SLIME_BOLT:
|
||||
me->CastSpell(me, SPELL_SLIME_BOLT, false);
|
||||
events.RepeatEvent(3000);
|
||||
break;
|
||||
case EVENT_HEALTH_CHECK:
|
||||
if (me->GetHealthPct() <= 5)
|
||||
{
|
||||
Talk(EMOTE_ENRAGE);
|
||||
me->CastSpell(me, SPELL_FRENZY, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(1000);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_patchwerk()
|
||||
{
|
||||
new boss_patchwerk();
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
|
||||
enum Sounds
|
||||
{
|
||||
SOUND_AGGRO_1 = 8852,
|
||||
SOUND_AGGRO_2 = 8853,
|
||||
SOUND_AGGRO_3 = 8854,
|
||||
SOUND_SLAY = 8861,
|
||||
SOUND_COMMAND_1 = 8855,
|
||||
SOUND_COMMAND_2 = 8856,
|
||||
SOUND_COMMAND_3 = 8858,
|
||||
SOUND_COMMAND_4 = 8859,
|
||||
SOUND_COMMAND_5 = 8861,
|
||||
SOUND_DEATH = 8860,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_UNBALANCING_STRIKE = 26613,
|
||||
SPELL_DISRUPTING_SHOUT_10 = 29107,
|
||||
SPELL_DISRUPTING_SHOUT_25 = 55543,
|
||||
SPELL_JAGGED_KNIFE = 55550,
|
||||
SPELL_HOPELESS = 29125,
|
||||
|
||||
SPELL_BONE_BARRIER = 29061,
|
||||
SPELL_BLOOD_STRIKE = 61696,
|
||||
};
|
||||
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_UNBALANCING_STRIKE = 1,
|
||||
EVENT_SPELL_DISRUPTING_SHOUT = 2,
|
||||
EVENT_SPELL_JAGGED_KNIFE = 3,
|
||||
EVENT_PLAY_COMMAND = 4,
|
||||
|
||||
EVENT_MINION_BLOOD_STRIKE = 10,
|
||||
EVENT_MINION_BONE_BARRIER = 11,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_DEATH_KNIGHT_UNDERSTUDY = 16803,
|
||||
NPC_RAZUVIOUS = 16061,
|
||||
};
|
||||
|
||||
class boss_razuvious : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_razuvious() : CreatureScript("boss_razuvious") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_razuviousAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_razuviousAI : public ScriptedAI
|
||||
{
|
||||
boss_razuviousAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* pInstance;
|
||||
|
||||
void SpawnHelpers()
|
||||
{
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2782.45f, -3088.03f, 267.685f, 0.75f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2778.56f, -3113.74f, 267.685f, 5.28f);
|
||||
if (Is25ManRaid())
|
||||
{
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2762.23f, -3085.07f, 267.685f, 1.95f);
|
||||
me->SummonCreature(NPC_DEATH_KNIGHT_UNDERSTUDY, 2758.24f, -3110.97f, 267.685f, 3.94f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
summons.DespawnAll();
|
||||
events.Reset();
|
||||
SpawnHelpers();
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_RAZUVIOUS, NOT_STARTED);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
{
|
||||
DoPlaySoundToSet(me, SOUND_SLAY);
|
||||
me->MonsterYell("You should've stayed home!", LANG_UNIVERSAL, 0);
|
||||
}
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32& damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
// Damage done by the controlled Death Knight understudies should also count toward damage done by players
|
||||
if(who && who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_DEATH_KNIGHT_UNDERSTUDY)
|
||||
me->LowerPlayerDamageReq(damage);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoPlaySoundToSet(me, SOUND_DEATH);
|
||||
me->MonsterYell("An honorable... death...", LANG_UNIVERSAL, 0);
|
||||
|
||||
me->CastSpell(me, SPELL_HOPELESS, true);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_RAZUVIOUS, DONE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
switch (urand(0,2))
|
||||
{
|
||||
case 0:
|
||||
DoPlaySoundToSet(me, SOUND_AGGRO_1);
|
||||
me->MonsterYell("Hah hah, I'm just getting warmed up!", LANG_UNIVERSAL, 0);
|
||||
break;
|
||||
case 1:
|
||||
DoPlaySoundToSet(me, SOUND_AGGRO_2);
|
||||
me->MonsterYell("Stand and fight!", LANG_UNIVERSAL, 0);
|
||||
break;
|
||||
case 2:
|
||||
DoPlaySoundToSet(me, SOUND_AGGRO_3);
|
||||
me->MonsterYell("Show me what you've got!", LANG_UNIVERSAL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_UNBALANCING_STRIKE, 30000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTING_SHOUT, 25000);
|
||||
events.ScheduleEvent(EVENT_SPELL_JAGGED_KNIFE, 15000);
|
||||
events.ScheduleEvent(EVENT_PLAY_COMMAND, 40000);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_RAZUVIOUS, IN_PROGRESS);
|
||||
|
||||
summons.DoZoneInCombat();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_UNBALANCING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_UNBALANCING_STRIKE, false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
case EVENT_SPELL_DISRUPTING_SHOUT:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_DISRUPTING_SHOUT_10, SPELL_DISRUPTING_SHOUT_25), false);
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_SPELL_JAGGED_KNIFE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
|
||||
me->CastSpell(target, SPELL_JAGGED_KNIFE, false);
|
||||
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
case EVENT_PLAY_COMMAND:
|
||||
switch (urand(0,2))
|
||||
{
|
||||
case 0:
|
||||
DoPlaySoundToSet(me, SOUND_COMMAND_1);
|
||||
me->MonsterYell("Do as I taught you!", LANG_UNIVERSAL, 0);
|
||||
break;
|
||||
case 1:
|
||||
DoPlaySoundToSet(me, SOUND_COMMAND_2);
|
||||
me->MonsterYell("Show them no mercy!", LANG_UNIVERSAL, 0);
|
||||
break;
|
||||
case 2:
|
||||
DoPlaySoundToSet(me, SOUND_COMMAND_3);
|
||||
me->MonsterYell("You disappoint me, students!", LANG_UNIVERSAL, 0);
|
||||
break;
|
||||
}
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_razuvious_minion : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_razuvious_minion() : CreatureScript("boss_razuvious_minion") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_razuvious_minionAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_razuvious_minionAI : public ScriptedAI
|
||||
{
|
||||
boss_razuvious_minionAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (me->GetInstanceScript())
|
||||
me->GetInstanceScript()->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_RAZUVIOUS, 100.0f))
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
cr->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_MINION_BLOOD_STRIKE, 4000);
|
||||
events.ScheduleEvent(EVENT_MINION_BONE_BARRIER, 9000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING) || me->IsCharmed())
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_MINION_BLOOD_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_BLOOD_STRIKE, false);
|
||||
events.RepeatEvent(8000);
|
||||
break;
|
||||
case EVENT_MINION_BONE_BARRIER:
|
||||
me->CastSpell(me, SPELL_BONE_BARRIER, true);
|
||||
events.RepeatEvent(40000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_razuvious()
|
||||
{
|
||||
new boss_razuvious();
|
||||
new boss_razuvious_minion();
|
||||
}
|
||||
@@ -1,438 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Yells
|
||||
{
|
||||
EMOTE_AIR_PHASE = 0,
|
||||
EMOTE_GROUND_PHASE = 1,
|
||||
EMOTE_BREATH = 2,
|
||||
EMOTE_ENRAGE = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Fight
|
||||
SPELL_FROST_AURA_10 = 28531,
|
||||
SPELL_FROST_AURA_25 = 55799,
|
||||
SPELL_CLEAVE = 19983,
|
||||
SPELL_TAIL_SWEEP_10 = 55697,
|
||||
SPELL_TAIL_SWEEP_25 = 55696,
|
||||
SPELL_SUMMON_BLIZZARD = 28560,
|
||||
SPELL_LIFE_DRAIN_10 = 28542,
|
||||
SPELL_LIFE_DRAIN_25 = 55665,
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
// Ice block
|
||||
SPELL_ICEBOLT_CAST = 28526,
|
||||
SPELL_ICEBOLT_TRIGGER = 28522,
|
||||
SPELL_FROST_MISSILE = 30101,
|
||||
SPELL_FROST_EXPLOSION = 28524,
|
||||
|
||||
// Visuals
|
||||
SPELL_SAPPHIRON_DIES = 29357,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
GO_ICE_BLOCK = 181247,
|
||||
NPC_BLIZZARD = 16474,
|
||||
|
||||
POINT_CENTER = 1,
|
||||
FAKE_POINTER = 1,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
//EVENT_SAPPHIRON_BIRTH = 1,
|
||||
EVENT_BERSERK = 2,
|
||||
EVENT_SPELL_CLEAVE = 3,
|
||||
EVENT_SPELL_TAIL_SWEEP = 4,
|
||||
EVENT_SPELL_LIFE_DRAIN = 5,
|
||||
EVENT_SPELL_BLIZZARD = 6,
|
||||
EVENT_FLIGHT_START = 7,
|
||||
EVENT_FLIGHT_LIFTOFF = 8,
|
||||
EVENT_FLIGHT_ICEBOLT = 9,
|
||||
EVENT_FLIGHT_BREATH = 10,
|
||||
EVENT_FLIGHT_SPELL_EXPLOSION = 11,
|
||||
EVENT_FLIGHT_START_LAND = 12,
|
||||
EVENT_LAND = 13,
|
||||
EVENT_GROUND = 14,
|
||||
EVENT_HUNDRED_CLUB = 15,
|
||||
};
|
||||
|
||||
class boss_sapphiron : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_sapphiron() : CreatureScript("boss_sapphiron") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_sapphironAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_sapphironAI : public ScriptedAI
|
||||
{
|
||||
boss_sapphironAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* pInstance;
|
||||
uint8 iceboltCount;
|
||||
uint32 spawnTimer;
|
||||
std::list<uint64> blockList;
|
||||
uint64 currentTarget;
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
me->SummonGameObject(GO_SAPPHIRON_BIRTH, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, 0, 0, 0, 0, 0);
|
||||
me->SetVisible(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
ScriptedAI::InitializeAI();
|
||||
}
|
||||
|
||||
bool IsInRoom()
|
||||
{
|
||||
if (me->GetExactDist(3523.5f, -5235.3f, 137.6f) > 100.0f)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (me->IsVisible())
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
events.Reset();
|
||||
iceboltCount = 0;
|
||||
spawnTimer = 0;
|
||||
currentTarget = 0;
|
||||
blockList.clear();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_SAPPHIRON, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombatSelfFunction()
|
||||
{
|
||||
Map::PlayerList const &PlList = me->GetMap()->GetPlayers();
|
||||
if (PlList.isEmpty())
|
||||
return;
|
||||
for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
|
||||
{
|
||||
if (Player* player = i->GetSource())
|
||||
{
|
||||
if (player->IsGameMaster())
|
||||
continue;
|
||||
if (player->IsAlive() && me->GetDistance(player) < 80.0f)
|
||||
{
|
||||
me->SetInCombatWith(player);
|
||||
player->SetInCombatWith(me);
|
||||
me->AddThreat(player, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
EnterCombatSelfFunction();
|
||||
me->CastSpell(me, RAID_MODE(SPELL_FROST_AURA_10, SPELL_FROST_AURA_25), true);
|
||||
|
||||
events.ScheduleEvent(EVENT_BERSERK, 15*60000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEAVE, 5000);
|
||||
events.ScheduleEvent(EVENT_SPELL_TAIL_SWEEP, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_LIFE_DRAIN, 17000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BLIZZARD, 21000);
|
||||
events.ScheduleEvent(EVENT_FLIGHT_START, 45000);
|
||||
events.ScheduleEvent(EVENT_HUNDRED_CLUB, 5000);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_SAPPHIRON, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* who)
|
||||
{
|
||||
me->CastSpell(me, SPELL_SAPPHIRON_DIES, true);
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_SAPPHIRON, DONE);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_SAPPHIRON_BIRTH)
|
||||
spawnTimer = 1;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == POINT_CENTER)
|
||||
events.ScheduleEvent(EVENT_FLIGHT_LIFTOFF, 500);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo)
|
||||
{
|
||||
if (spellInfo->Id == SPELL_ICEBOLT_CAST)
|
||||
{
|
||||
me->CastSpell(target, SPELL_ICEBOLT_TRIGGER, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidExplosionTarget(WorldObject* target)
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
|
||||
{
|
||||
if (target->GetGUID() == (*itr))
|
||||
return false;
|
||||
|
||||
if (Unit* block = ObjectAccessor::GetUnit(*me, *itr))
|
||||
{
|
||||
if (block->IsInBetween(me, target, 2.0f) && block->IsWithinDist(target, 10.0f))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (spawnTimer)
|
||||
{
|
||||
spawnTimer += diff;
|
||||
if (spawnTimer >= 21500)
|
||||
{
|
||||
me->SetVisible(true);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
spawnTimer = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsInRoom())
|
||||
return;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_BERSERK:
|
||||
Talk(EMOTE_ENRAGE);
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
return;
|
||||
case EVENT_SPELL_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.RepeatEvent(10000);
|
||||
return;
|
||||
case EVENT_SPELL_TAIL_SWEEP:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_TAIL_SWEEP_10, SPELL_TAIL_SWEEP_25), false);
|
||||
events.RepeatEvent(10000);
|
||||
return;
|
||||
case EVENT_SPELL_LIFE_DRAIN:
|
||||
me->CastCustomSpell(RAID_MODE(SPELL_LIFE_DRAIN_10, SPELL_LIFE_DRAIN_25), SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5), me, false);
|
||||
events.RepeatEvent(24000);
|
||||
return;
|
||||
case EVENT_SPELL_BLIZZARD:
|
||||
{
|
||||
Creature* cr;
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
|
||||
cr = me->SummonCreature(NPC_BLIZZARD, *target, TEMPSUMMON_TIMED_DESPAWN, 16000);
|
||||
else
|
||||
cr = me->SummonCreature(NPC_BLIZZARD, *me, TEMPSUMMON_TIMED_DESPAWN, 16000);
|
||||
|
||||
if (cr)
|
||||
cr->GetMotionMaster()->MoveRandom(40);
|
||||
events.RepeatEvent(RAID_MODE(8000, 6500));
|
||||
return;
|
||||
}
|
||||
case EVENT_FLIGHT_START:
|
||||
if (me->HealthBelowPct(11))
|
||||
{
|
||||
events.PopEvent();
|
||||
return;
|
||||
}
|
||||
events.RepeatEvent(45000);
|
||||
events.DelayEvents(35000);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
float x, y, z, o;
|
||||
me->GetHomePosition(x, y, z, o);
|
||||
me->GetMotionMaster()->MovePoint(POINT_CENTER, x, y, z);
|
||||
return;
|
||||
case EVENT_FLIGHT_LIFTOFF:
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->SendMeleeAttackStop(me->GetVictim());
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
|
||||
me->SetDisableGravity(true);
|
||||
currentTarget = 0;
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, 3000);
|
||||
iceboltCount = RAID_MODE(2, 3);
|
||||
return;
|
||||
case EVENT_FLIGHT_ICEBOLT:
|
||||
{
|
||||
events.PopEvent();
|
||||
if (currentTarget)
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*me, currentTarget))
|
||||
me->SummonGameObject(GO_ICE_BLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
|
||||
std::vector<Unit*> targets;
|
||||
ThreatContainer::StorageType::const_iterator i = me->getThreatManager().getThreatList().begin();
|
||||
for (; i != me->getThreatManager().getThreatList().end(); ++i)
|
||||
if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
bool inList = false;
|
||||
if (!blockList.empty())
|
||||
for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
|
||||
if ((*i)->getTarget()->GetGUID() == *itr)
|
||||
{
|
||||
inList = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!inList)
|
||||
targets.push_back((*i)->getTarget());
|
||||
}
|
||||
|
||||
if (!targets.empty() && iceboltCount)
|
||||
{
|
||||
std::vector<Unit*>::iterator itr = targets.begin();
|
||||
advance(itr, urand(0, targets.size()-1));
|
||||
me->CastSpell(*itr, SPELL_ICEBOLT_CAST, false);
|
||||
blockList.push_back((*itr)->GetGUID());
|
||||
currentTarget = (*itr)->GetGUID();
|
||||
--iceboltCount;
|
||||
events.ScheduleEvent(EVENT_FLIGHT_ICEBOLT, (me->GetExactDist(*itr) / 13.0f)*IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_FLIGHT_BREATH, 1000);
|
||||
return;
|
||||
}
|
||||
case EVENT_FLIGHT_BREATH:
|
||||
currentTarget = 0;
|
||||
Talk(EMOTE_BREATH);
|
||||
me->CastSpell(me, SPELL_FROST_MISSILE, false);
|
||||
events.ScheduleEvent(EVENT_FLIGHT_SPELL_EXPLOSION, 8500);
|
||||
events.PopEvent();
|
||||
return;
|
||||
case EVENT_FLIGHT_SPELL_EXPLOSION:
|
||||
me->CastSpell(me, SPELL_FROST_EXPLOSION, true);
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_FLIGHT_START_LAND, 3000);
|
||||
return;
|
||||
case EVENT_FLIGHT_START_LAND:
|
||||
if (!blockList.empty())
|
||||
for (std::list<uint64>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
|
||||
if (Unit* block = ObjectAccessor::GetUnit(*me, *itr))
|
||||
block->RemoveAurasDueToSpell(SPELL_ICEBOLT_TRIGGER);
|
||||
|
||||
blockList.clear();
|
||||
me->RemoveAllGameObjects();
|
||||
events.ScheduleEvent(EVENT_LAND, 1000);
|
||||
events.PopEvent();
|
||||
return;
|
||||
case EVENT_LAND:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
|
||||
me->SetDisableGravity(false);
|
||||
|
||||
events.PopEvent();
|
||||
events.ScheduleEvent(EVENT_GROUND, 1500);
|
||||
return;
|
||||
case EVENT_GROUND:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetInCombatWithZone();
|
||||
events.PopEvent();
|
||||
return;
|
||||
case EVENT_HUNDRED_CLUB:
|
||||
{
|
||||
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
||||
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
||||
{
|
||||
if (itr->GetSource()->GetResistance(SPELL_SCHOOL_FROST) > 100 && pInstance)
|
||||
{
|
||||
events.PopEvent();
|
||||
pInstance->SetData(DATA_HUNDRED_CLUB, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
events.RepeatEvent(5000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_sapphiron_frost_explosion : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_sapphiron_frost_explosion() : SpellScriptLoader("spell_sapphiron_frost_explosion") { }
|
||||
|
||||
class spell_sapphiron_frost_explosion_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_sapphiron_frost_explosion_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster || !caster->ToCreature())
|
||||
return;
|
||||
|
||||
std::list<WorldObject*> tmplist;
|
||||
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
{
|
||||
if (CAST_AI(boss_sapphiron::boss_sapphironAI, caster->ToCreature()->AI())->IsValidExplosionTarget(*itr))
|
||||
tmplist.push_back(*itr);
|
||||
}
|
||||
|
||||
targets.clear();
|
||||
for (std::list<WorldObject*>::iterator itr = tmplist.begin(); itr != tmplist.end(); ++itr)
|
||||
targets.push_back(*itr);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sapphiron_frost_explosion_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_sapphiron_frost_explosion_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_sapphiron()
|
||||
{
|
||||
new boss_sapphiron();
|
||||
new spell_sapphiron_frost_explosion();
|
||||
}
|
||||
@@ -1,592 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "SpellScript.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
// Stalagg
|
||||
SAY_STAL_AGGRO = 0,
|
||||
SAY_STAL_SLAY = 1,
|
||||
SAY_STAL_DEATH = 2,
|
||||
|
||||
// Feugen
|
||||
SAY_FEUG_AGGRO = 0,
|
||||
SAY_FEUG_SLAY = 1,
|
||||
SAY_FEUG_DEATH = 2,
|
||||
|
||||
// Thaddius
|
||||
SAY_GREET = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_ELECT = 3,
|
||||
SAY_DEATH = 4,
|
||||
SAY_SCREAM = 5
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MAGNETIC_PULL = 28337,
|
||||
SPELL_TESLA_SHOCK = 28099,
|
||||
|
||||
// Stalagg
|
||||
SPELL_POWER_SURGE_10 = 54529,
|
||||
SPELL_POWER_SURGE_25 = 28134,
|
||||
SPELL_STALAGG_CHAIN = 28096,
|
||||
|
||||
// Feugen
|
||||
SPELL_STATIC_FIELD_10 = 28135,
|
||||
SPELL_STATIC_FIELD_25 = 54528,
|
||||
SPELL_FEUGEN_CHAIN = 28111,
|
||||
|
||||
// Thaddius
|
||||
SPELL_POLARITY_SHIFT = 28089,
|
||||
SPELL_BALL_LIGHTNING = 28299,
|
||||
SPELL_CHAIN_LIGHTNING_10 = 28167,
|
||||
SPELL_CHAIN_LIGHTNING_25 = 54531,
|
||||
SPELL_BERSERK = 27680,
|
||||
|
||||
SPELL_THADDIUS_VISUAL_LIGHTNING = 28136,
|
||||
SPELL_THADDIUS_SPAWN_STUN = 28160,
|
||||
|
||||
SPELL_POSITIVE_CHARGE = 28062,
|
||||
SPELL_POSITIVE_CHARGE_STACK = 29659,
|
||||
SPELL_NEGATIVE_CHARGE = 28085,
|
||||
SPELL_NEGATIVE_CHARGE_STACK = 29660,
|
||||
SPELL_POSITIVE_POLARITY = 28059,
|
||||
SPELL_NEGATIVE_POLARITY = 28084,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MINION_SPELL_POWER_SURGE = 1,
|
||||
EVENT_MINION_SPELL_MAGNETIC_PULL = 2,
|
||||
EVENT_MINION_CHECK_DISTANCE = 3,
|
||||
EVENT_MINION_SPELL_STATIC_FIELD = 4,
|
||||
|
||||
EVENT_THADDIUS_START = 10,
|
||||
EVENT_THADDIUS_SPELL_CHAIN_LIGHTNING= 11,
|
||||
EVENT_THADDIUS_SPELL_BERSERK = 12,
|
||||
EVENT_THADDIUS_POLARITY_SHIFT = 13,
|
||||
EVENT_THADDIUS_START_2 = 14,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_MAGNETIC_PULL = 1,
|
||||
ACTION_SUMMON_DIED = 2,
|
||||
ACTION_RESTORE = 3,
|
||||
NPC_TESLA_COIL = 16218, //the coils (emotes "Tesla Coil overloads!")
|
||||
};
|
||||
|
||||
class boss_thaddius : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_thaddius() : CreatureScript("boss_thaddius") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_thaddiusAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_thaddiusAI : public ScriptedAI
|
||||
{
|
||||
boss_thaddiusAI(Creature *c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint32 summonTimer;
|
||||
uint32 reviveTimer;
|
||||
uint32 resetTimer;
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_START_2, 1000);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
if (cr->GetEntry() == NPC_TESLA_COIL)
|
||||
{
|
||||
cr->CastSpell(me, SPELL_TESLA_SHOCK, true); // till smth better is found ;( ZOMG
|
||||
Unit::Kill(cr, cr);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_SUMMON_DIED)
|
||||
{
|
||||
// Hooray, we did it!
|
||||
if (summonTimer)
|
||||
{
|
||||
summonTimer = 0;
|
||||
reviveTimer = 1;
|
||||
//events.ScheduleEvent(EVENT_THADDIUS_START, 12000);
|
||||
return;
|
||||
}
|
||||
|
||||
summonTimer = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
summonTimer = 0;
|
||||
reviveTimer = 0;
|
||||
resetTimer = 1;
|
||||
me->SetPosition(me->GetHomePosition());
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_THADDIUS, NOT_STARTED);
|
||||
|
||||
me->SummonCreature(NPC_STALAGG, 3450.45f, -2931.42f, 312.091f, 5.49779f);
|
||||
me->SummonCreature(NPC_FEUGEN, 3508.14f, -2988.65f, 312.092f, 2.37365f);
|
||||
if (Creature* cr = me->SummonCreature(NPC_TESLA_COIL, 3527.34f, -2951.56f, 318.75f, 0.0f))
|
||||
{
|
||||
cr->RemoveAllAuras();
|
||||
cr->InterruptNonMeleeSpells(true);
|
||||
cr->CastSpell(cr, SPELL_FEUGEN_CHAIN, false);
|
||||
cr->SetDisableGravity(true);
|
||||
}
|
||||
if (Creature* cr = me->SummonCreature(NPC_TESLA_COIL, 3487.04f, -2911.68f, 318.75f, 0.0f))
|
||||
{
|
||||
cr->RemoveAllAuras();
|
||||
cr->InterruptNonMeleeSpells(true);
|
||||
cr->CastSpell(cr, SPELL_STALAGG_CHAIN, false);
|
||||
cr->SetDisableGravity(true);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (!urand(0,3))
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(EVENT_THADDIUS, DONE);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(28059);
|
||||
pInstance->DoRemoveAurasDueToSpellOnPlayers(28084);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
summons.DoZoneInCombat(NPC_FEUGEN);
|
||||
summons.DoZoneInCombat(NPC_STALAGG);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(EVENT_THADDIUS, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (resetTimer)
|
||||
{
|
||||
resetTimer += diff;
|
||||
if (resetTimer > 1000)
|
||||
{
|
||||
resetTimer = 0;
|
||||
me->CastSpell(me, SPELL_THADDIUS_SPAWN_STUN, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (reviveTimer)
|
||||
{
|
||||
reviveTimer += diff;
|
||||
if (reviveTimer >= 12000)
|
||||
{
|
||||
StartEvent();
|
||||
reviveTimer = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
// Revive code!
|
||||
if (summonTimer)
|
||||
{
|
||||
summonTimer += diff;
|
||||
if (summonTimer >= 5000)
|
||||
{
|
||||
summons.DoAction(ACTION_RESTORE);
|
||||
summonTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
//case EVENT_THADDIUS_START:
|
||||
// StartEvent();
|
||||
// events.PopEvent();
|
||||
// break;
|
||||
case EVENT_THADDIUS_START_2:
|
||||
events.PopEvent();
|
||||
Talk(SAY_AGGRO);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->setAttackTimer(BASE_ATTACK, 4000);
|
||||
|
||||
events.ScheduleEvent(EVENT_THADDIUS_SPELL_CHAIN_LIGHTNING, 14000);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_SPELL_BERSERK, 360000);
|
||||
events.ScheduleEvent(EVENT_THADDIUS_POLARITY_SHIFT, 30000);
|
||||
return;
|
||||
case EVENT_THADDIUS_SPELL_BERSERK:
|
||||
me->CastSpell(me, SPELL_BERSERK, true);
|
||||
events.PopEvent();
|
||||
break;
|
||||
case EVENT_THADDIUS_SPELL_CHAIN_LIGHTNING:
|
||||
me->CastSpell(me->GetVictim(), RAID_MODE(SPELL_CHAIN_LIGHTNING_10, SPELL_CHAIN_LIGHTNING_25), false);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_THADDIUS_POLARITY_SHIFT:
|
||||
me->CastSpell(me, SPELL_POLARITY_SHIFT, false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->isAttackReady())
|
||||
{
|
||||
if (!me->IsWithinMeleeRange(me->GetVictim()))
|
||||
me->CastSpell(me->GetVictim(), SPELL_BALL_LIGHTNING, false);
|
||||
else
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class boss_thaddius_summon : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_thaddius_summon() : CreatureScript("boss_thaddius_summon") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_thaddius_summonAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_thaddius_summonAI : public ScriptedAI
|
||||
{
|
||||
boss_thaddius_summonAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
EventMap events;
|
||||
uint32 pullTimer;
|
||||
uint32 visualTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
pullTimer = 0;
|
||||
visualTimer = 1;
|
||||
|
||||
events.Reset();
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
||||
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
ScriptedAI::EnterEvadeMode();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* pWho)
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
if (me->GetEntry() == NPC_STALAGG)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_POWER_SURGE, 10000);
|
||||
Talk(SAY_STAL_AGGRO);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_STATIC_FIELD, 5000);
|
||||
Talk(SAY_FEUG_AGGRO);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_MINION_CHECK_DISTANCE, 5000);
|
||||
|
||||
// This event needs synchronisation, called for stalagg only
|
||||
if (me->GetEntry() == NPC_STALAGG)
|
||||
events.ScheduleEvent(EVENT_MINION_SPELL_MAGNETIC_PULL, 25000);
|
||||
|
||||
if (pInstance)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_THADDIUS_BOSS)))
|
||||
{
|
||||
cr->AI()->AttackStart(pWho);
|
||||
cr->AddThreat(pWho, 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_MAGNETIC_PULL)
|
||||
{
|
||||
pullTimer = 1;
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
}
|
||||
else if (param == ACTION_RESTORE)
|
||||
{
|
||||
if (!me->IsAlive())
|
||||
{
|
||||
me->Respawn();
|
||||
me->SetInCombatWithZone();
|
||||
}
|
||||
else
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* )
|
||||
{
|
||||
Talk(me->GetEntry() == NPC_STALAGG ? SAY_FEUG_DEATH : SAY_STAL_DEATH);
|
||||
if (pInstance)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_THADDIUS_BOSS)))
|
||||
cr->AI()->DoAction(ACTION_SUMMON_DIED);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_IMMORTAL_FAIL, 0);
|
||||
|
||||
if (!urand(0,2))
|
||||
Talk(me->GetEntry() == NPC_STALAGG ? SAY_FEUG_SLAY : SAY_STAL_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (visualTimer)
|
||||
{
|
||||
visualTimer += diff;
|
||||
if (visualTimer >= 3000)
|
||||
{
|
||||
visualTimer = 0;
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
||||
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// Disable AI during pull
|
||||
if (pullTimer)
|
||||
{
|
||||
pullTimer += diff;
|
||||
if (pullTimer >= 3000)
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
pullTimer = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_MINION_SPELL_POWER_SURGE:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_POWER_SURGE_10, SPELL_POWER_SURGE_25), false);
|
||||
events.RepeatEvent(19000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_STATIC_FIELD:
|
||||
me->CastSpell(me, RAID_MODE(SPELL_STATIC_FIELD_10, SPELL_STATIC_FIELD_25), false);
|
||||
events.RepeatEvent(3000);
|
||||
break;
|
||||
case EVENT_MINION_SPELL_MAGNETIC_PULL:
|
||||
events.RepeatEvent(25000);
|
||||
if (pInstance)
|
||||
if (Creature* feugen = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_FEUGEN_BOSS)))
|
||||
{
|
||||
if (!feugen->IsAlive() || !feugen->GetVictim() || !me->GetVictim())
|
||||
return;
|
||||
|
||||
float threatFeugen = feugen->getThreatManager().getThreat(feugen->GetVictim());
|
||||
float threatStalagg = me->getThreatManager().getThreat(me->GetVictim());
|
||||
Unit* tankFeugen = feugen->GetVictim();
|
||||
Unit* tankStalagg = me->GetVictim();
|
||||
|
||||
feugen->getThreatManager().modifyThreatPercent(tankFeugen, -100);
|
||||
feugen->AddThreat(tankStalagg, threatFeugen);
|
||||
feugen->CastSpell(tankStalagg, SPELL_MAGNETIC_PULL, true);
|
||||
feugen->AI()->DoAction(ACTION_MAGNETIC_PULL);
|
||||
|
||||
me->getThreatManager().modifyThreatPercent(tankStalagg, -100);
|
||||
me->AddThreat(tankFeugen, threatStalagg);
|
||||
me->CastSpell(tankFeugen, SPELL_MAGNETIC_PULL, true);
|
||||
DoAction(ACTION_MAGNETIC_PULL);
|
||||
}
|
||||
|
||||
break;
|
||||
case EVENT_MINION_CHECK_DISTANCE:
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_TESLA_COIL, 150.0f))
|
||||
{
|
||||
if (me->GetExactDist(cr) > 60.0f || me->GetExactDist(cr) < 20.0f)
|
||||
{
|
||||
cr->InterruptNonMeleeSpells(true);
|
||||
cr->CastSpell(me->GetVictim(), SPELL_TESLA_SHOCK, true); // dont know real spell
|
||||
events.RepeatEvent(1500);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr->CastSpell(cr, me->GetEntry() == NPC_STALAGG ? SPELL_STALAGG_CHAIN : SPELL_FEUGEN_CHAIN, false);
|
||||
}
|
||||
}
|
||||
|
||||
events.RepeatEvent(5000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_thaddius_pos_neg_charge : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_thaddius_pos_neg_charge() : SpellScriptLoader("spell_thaddius_pos_neg_charge") { }
|
||||
|
||||
class spell_thaddius_pos_neg_charge_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_thaddius_pos_neg_charge_SpellScript);
|
||||
|
||||
void HandleTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
uint8 count = 0;
|
||||
for (std::list<WorldObject*>::iterator ihit = targets.begin(); ihit != targets.end(); ++ihit)
|
||||
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
|
||||
if (Player* target = (*ihit)->ToPlayer())
|
||||
if (target->HasAura(GetTriggeringSpell()->Id))
|
||||
++count;
|
||||
|
||||
if (count)
|
||||
{
|
||||
uint32 spellId = 0;
|
||||
|
||||
if (GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE)
|
||||
spellId = SPELL_POSITIVE_CHARGE_STACK;
|
||||
else // if (GetSpellInfo()->Id == SPELL_NEGATIVE_CHARGE)
|
||||
spellId = SPELL_NEGATIVE_CHARGE_STACK;
|
||||
|
||||
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleDamage(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (!GetTriggeringSpell())
|
||||
return;
|
||||
|
||||
Unit* target = GetHitUnit();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (target->HasAura(GetTriggeringSpell()->Id) || target->GetTypeId() != TYPEID_PLAYER)
|
||||
SetHitDamage(0);
|
||||
else if (target->GetInstanceScript())
|
||||
target->GetInstanceScript()->SetData(DATA_CHARGES_CROSSED, 0);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_thaddius_pos_neg_charge_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_thaddius_polarity_shift : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_thaddius_polarity_shift() : SpellScriptLoader("spell_thaddius_polarity_shift") { }
|
||||
|
||||
class spell_thaddius_polarity_shift_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_thaddius_polarity_shift_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_POLARITY) || !sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_POLARITY))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /* effIndex */)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, NULL, NULL, caster->GetGUID());
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_thaddius_polarity_shift_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_thaddius_polarity_shift_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_thaddius()
|
||||
{
|
||||
new boss_thaddius();
|
||||
new boss_thaddius_summon();
|
||||
|
||||
new spell_thaddius_pos_neg_charge();
|
||||
new spell_thaddius_polarity_shift();
|
||||
}
|
||||
@@ -1,815 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "naxxramas.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "CellImpl.h"
|
||||
#include "PassiveAI.h"
|
||||
|
||||
const float HeiganPos[2] = {2796, -3707};
|
||||
const float HeiganEruptionSlope[3] =
|
||||
{
|
||||
(-3685 - HeiganPos[1]) /(2724 - HeiganPos[0]),
|
||||
(-3647 - HeiganPos[1]) /(2749 - HeiganPos[0]),
|
||||
(-3637 - HeiganPos[1]) /(2771 - HeiganPos[0]),
|
||||
};
|
||||
|
||||
inline uint8 GetEruptionSection(float x, float y)
|
||||
{
|
||||
y -= HeiganPos[1];
|
||||
if (y < 1.0f)
|
||||
return 0;
|
||||
|
||||
x -= HeiganPos[0];
|
||||
if (x > -1.0f)
|
||||
return 3;
|
||||
|
||||
float slope = y/x;
|
||||
for (uint32 i = 0; i < 3; ++i)
|
||||
if (slope > HeiganEruptionSlope[i])
|
||||
return i;
|
||||
return 3;
|
||||
}
|
||||
|
||||
class instance_naxxramas : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_naxxramas() : InstanceMapScript("instance_naxxramas", 533) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
|
||||
{
|
||||
return new instance_naxxramas_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
struct instance_naxxramas_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_naxxramas_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
|
||||
{
|
||||
memset(&Encounters, 0, sizeof(Encounters));
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
HeiganEruption[i].clear();
|
||||
|
||||
// GOs
|
||||
_patchwerkGateGUID = 0;
|
||||
_gluthGateGUID = 0;
|
||||
_nothGateGUID = 0;
|
||||
_heiganGateGUID = 0;
|
||||
_heiganGateExitGUID = 0;
|
||||
_loathebGateGUID = 0;
|
||||
_anubGateGUID = 0;
|
||||
_anubNextGateGUID = 0;
|
||||
_faerlinaGateGUID = 0;
|
||||
_maexxnaGateGUID = 0;
|
||||
_thaddiusGateGUID = 0;
|
||||
_horsemanGateGUID = 0;
|
||||
_kelthuzadfloorGUID = 0;
|
||||
_kelthuzadgateGUID = 0;
|
||||
_sapphironGateGUID = 0;
|
||||
_horsemanPortalGUID = 0;
|
||||
_loathebPortalGUID = 0;
|
||||
_maexxnaPortalGUID = 0;
|
||||
_thaddiusPortalGUID = 0;
|
||||
|
||||
// NPCs
|
||||
_thaddiusGUID = 0;
|
||||
_stalaggGUID = 0;
|
||||
_feugenGUID = 0;
|
||||
_zeliekGUID = 0;
|
||||
_rivendareGUID = 0;
|
||||
_blaumeuxGUID = 0;
|
||||
_korthazzGUID = 0;
|
||||
_sapphironGUID = 0;
|
||||
_kelthuzadGUID = 0;
|
||||
_lichkingGUID = 0;
|
||||
|
||||
// Controls
|
||||
_horsemanKilled = 0;
|
||||
_speakTimer = 0;
|
||||
_horsemanTimer = 0;
|
||||
|
||||
// Achievements
|
||||
abominationsKilled = 0;
|
||||
faerlinaAchievement = true;
|
||||
thaddiusAchievement = true;
|
||||
loathebAchievement = true;
|
||||
sapphironAchievement = true;
|
||||
heiganAchievement = true;
|
||||
immortalAchievement = 1;
|
||||
}
|
||||
|
||||
uint32 Encounters[MAX_ENCOUNTERS];
|
||||
std::set<GameObject*> HeiganEruption[4];
|
||||
|
||||
// GOs
|
||||
uint64 _patchwerkGateGUID;
|
||||
uint64 _gluthGateGUID;
|
||||
uint64 _nothGateGUID;
|
||||
uint64 _heiganGateGUID;
|
||||
uint64 _heiganGateExitGUID;
|
||||
uint64 _loathebGateGUID;
|
||||
uint64 _anubGateGUID;
|
||||
uint64 _anubNextGateGUID;
|
||||
uint64 _faerlinaGateGUID;
|
||||
uint64 _maexxnaGateGUID;
|
||||
uint64 _thaddiusGateGUID;
|
||||
uint64 _gothikEnterGateGUID;
|
||||
uint64 _gothikInnerGateGUID;
|
||||
uint64 _gothikExitGateGUID;
|
||||
uint64 _horsemanGateGUID;
|
||||
uint64 _kelthuzadfloorGUID;
|
||||
uint64 _kelthuzadgateGUID;
|
||||
uint64 _sapphironGateGUID;
|
||||
uint64 _horsemanPortalGUID;
|
||||
uint64 _loathebPortalGUID;
|
||||
uint64 _maexxnaPortalGUID;
|
||||
uint64 _thaddiusPortalGUID;
|
||||
|
||||
// NPCs
|
||||
uint64 _thaddiusGUID;
|
||||
uint64 _stalaggGUID;
|
||||
uint64 _feugenGUID;
|
||||
uint64 _zeliekGUID;
|
||||
uint64 _rivendareGUID;
|
||||
uint64 _blaumeuxGUID;
|
||||
uint64 _korthazzGUID;
|
||||
uint64 _sapphironGUID;
|
||||
uint64 _kelthuzadGUID;
|
||||
uint64 _lichkingGUID;
|
||||
|
||||
// Controls
|
||||
uint8 _horsemanKilled;
|
||||
uint32 _speakTimer;
|
||||
uint32 _horsemanTimer;
|
||||
|
||||
// Achievements
|
||||
uint8 abominationsKilled;
|
||||
bool faerlinaAchievement;
|
||||
bool thaddiusAchievement;
|
||||
bool loathebAchievement;
|
||||
bool sapphironAchievement;
|
||||
bool heiganAchievement;
|
||||
uint32 immortalAchievement;
|
||||
|
||||
void HeiganEruptSections(uint32 section)
|
||||
{
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (i == section)
|
||||
continue;
|
||||
|
||||
for (std::set<GameObject*>::iterator itr = HeiganEruption[i].begin(); itr != HeiganEruption[i].end(); ++itr)
|
||||
{
|
||||
(*itr)->SendCustomAnim((*itr)->GetGoAnimProgress());
|
||||
(*itr)->CastSpell(NULL, SPELL_ERUPTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
if (Encounters[i] == IN_PROGRESS)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch(creature->GetEntry())
|
||||
{
|
||||
case NPC_THADDIUS:
|
||||
_thaddiusGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_STALAGG:
|
||||
_stalaggGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_FEUGEN:
|
||||
_feugenGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_LADY_BLAUMEUX:
|
||||
_blaumeuxGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_SIR_ZELIEK:
|
||||
_zeliekGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_BARON_RIVENDARE:
|
||||
_rivendareGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_THANE_KORTHAZZ:
|
||||
_korthazzGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_SAPPHIRON:
|
||||
_sapphironGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_KELTHUZAD:
|
||||
_kelthuzadGUID = creature->GetGUID();
|
||||
return;
|
||||
case NPC_LICH_KING:
|
||||
_lichkingGUID = creature->GetGUID();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo)
|
||||
{
|
||||
if (pGo->GetGOInfo()->displayId == 6785 || pGo->GetGOInfo()->displayId == 1287)
|
||||
{
|
||||
HeiganEruption[GetEruptionSection(pGo->GetPositionX(), pGo->GetPositionY())].insert(pGo);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case GO_PATCHWERK_GATE:
|
||||
_patchwerkGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_PATCHWERK] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_GLUTH_GATE:
|
||||
_gluthGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_GLUTH] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_NOTH_GATE:
|
||||
_nothGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_NOTH] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_HEIGAN_ENTERANCE_GATE:
|
||||
_heiganGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_HEIGAN] == DONE || Encounters[EVENT_NOTH] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_HEIGAN_EXIT_GATE:
|
||||
_heiganGateExitGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_HEIGAN] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_LOATHEB_GATE:
|
||||
_loathebGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_LOATHEB] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ANUB_GATE:
|
||||
_anubGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_ANUB] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ANUB_NEXT_GATE:
|
||||
_anubNextGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_ANUB] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_FAERLINA_GATE:
|
||||
_faerlinaGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_FAERLINA] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_MAEXXNA_GATE:
|
||||
_maexxnaGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_FAERLINA] == DONE) // faerlina is correct
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_THADDIUS_GATE:
|
||||
_thaddiusGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_GLUTH] == DONE) // gluth is correct
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_GOTHIK_ENTER_GATE:
|
||||
_gothikEnterGateGUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_GOTHIK_INNER_GATE:
|
||||
_gothikInnerGateGUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_GOTHIK_EXIT_GATE:
|
||||
_gothikExitGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_GOTHIK] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_HORSEMAN_GATE:
|
||||
_horsemanGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_GOTHIK] == DONE) // correct
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_KELTHUZAD_FLOOR:
|
||||
_kelthuzadfloorGUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_KELTHUZAD_GATE:
|
||||
_kelthuzadgateGUID = pGo->GetGUID();
|
||||
break;
|
||||
case GO_SAPPHIRON_GATE:
|
||||
_sapphironGateGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_SAPPHIRON] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_DEATHKNIGHT_WING:
|
||||
_loathebPortalGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_LOATHEB] == DONE)
|
||||
pGo->SetPhaseMask(1, true);
|
||||
break;
|
||||
case GO_THADDIUS_PORTAL:
|
||||
_thaddiusPortalGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_THADDIUS] == DONE)
|
||||
pGo->SetPhaseMask(1, true);
|
||||
break;
|
||||
case GO_MAEXXNA_PORTAL:
|
||||
_maexxnaPortalGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_MAEXXNA] == DONE)
|
||||
pGo->SetPhaseMask(1, true);
|
||||
break;
|
||||
case GO_HORSEMAN_PORTAL:
|
||||
_horsemanPortalGUID = pGo->GetGUID();
|
||||
if (Encounters[EVENT_HORSEMAN] == DONE)
|
||||
pGo->SetPhaseMask(1, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* pGo)
|
||||
{
|
||||
if (pGo->GetGOInfo()->displayId == 6785 || pGo->GetGOInfo()->displayId == 1287)
|
||||
{
|
||||
uint32 section = GetEruptionSection(pGo->GetPositionX(), pGo->GetPositionY());
|
||||
HeiganEruption[section].erase(pGo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pGo->GetEntry() == GO_SAPPHIRON_BIRTH)
|
||||
if (Creature* cr = instance->GetCreature(_sapphironGUID))
|
||||
cr->AI()->DoAction(ACTION_SAPPHIRON_BIRTH);
|
||||
}
|
||||
|
||||
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0)
|
||||
{
|
||||
switch(criteria_id)
|
||||
{
|
||||
case 7600: // And They Would All Go Down Together (10 player)
|
||||
case 7601: // And They Would All Go Down Together (25 player)
|
||||
return (_horsemanTimer < 15*IN_MILLISECONDS);
|
||||
case 7614: // Just Can't Get Enough (10 player)
|
||||
case 7615: // Just Can't Get Enough (25 player)
|
||||
return abominationsKilled >= 18;
|
||||
case 7265: // Momma Said Knock You Out (10 player)
|
||||
case 7549: // Momma Said Knock You Out (25 player)
|
||||
return faerlinaAchievement;
|
||||
case 7604: // Shocking! (10 player)
|
||||
case 7605: // Shocking! (25 player)
|
||||
return thaddiusAchievement;
|
||||
case 7612: // Spore Loser (10 player)
|
||||
case 7613: // Spore Loser (25 player)
|
||||
return loathebAchievement;
|
||||
case 7264: // The Safety Dance (10 player)
|
||||
case 7548: // The Safety Dance (25 player)
|
||||
return heiganAchievement;
|
||||
case 7608: // Subtraction (10 player)
|
||||
// The Dedicated few (10 player)
|
||||
case 6802: case 7146: case 7147: case 7148: case 7149:
|
||||
case 7150: case 7151: case 7152: case 7153: case 7154:
|
||||
case 7155: case 7156: case 7157: case 7158:
|
||||
return (instance->GetPlayersCountExceptGMs() < 9);
|
||||
case 7609: // Subtraction (25 player)
|
||||
// The Dedicated few (25 player)
|
||||
case 7159: case 7160: case 7161: case 7162: case 7163:
|
||||
case 7164: case 7165: case 7166: case 7167: case 7168:
|
||||
case 7169: case 7170: case 7171: case 7172:
|
||||
return (instance->GetPlayersCountExceptGMs() < 21);
|
||||
case 7567: // The Hundred Club (10 player)
|
||||
case 7568: // The Hundred Club (25 player)
|
||||
return sapphironAchievement;
|
||||
// The Undying
|
||||
case 7617: case 13237: case 13238: case 13239: case 13240:
|
||||
// The Immortal
|
||||
case 7616: case 13233: case 13234: case 13235: case 13236:
|
||||
{
|
||||
uint8 count = 0;
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
if (Encounters[i] == NOT_STARTED)
|
||||
++count;
|
||||
|
||||
return !count && immortalAchievement;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 data)
|
||||
{
|
||||
// Bosses data
|
||||
switch(id)
|
||||
{
|
||||
case EVENT_PATCHWERK:
|
||||
case EVENT_GROBBULUS:
|
||||
case EVENT_GLUTH:
|
||||
case EVENT_NOTH:
|
||||
case EVENT_ANUB:
|
||||
case EVENT_MAEXXNA:
|
||||
case EVENT_RAZUVIOUS:
|
||||
case EVENT_GOTHIK:
|
||||
// EVENT_HORSEMAN HANDLED BELOW
|
||||
Encounters[id] = data;
|
||||
break;
|
||||
case EVENT_KELTHUZAD:
|
||||
if (data == NOT_STARTED)
|
||||
abominationsKilled = 0;
|
||||
Encounters[id] = data;
|
||||
break;
|
||||
case EVENT_FAERLINA:
|
||||
if (data == NOT_STARTED)
|
||||
faerlinaAchievement = true;
|
||||
Encounters[id] = data;
|
||||
break;
|
||||
case EVENT_THADDIUS:
|
||||
if (data == NOT_STARTED)
|
||||
thaddiusAchievement = true;
|
||||
Encounters[id] = data;
|
||||
break;
|
||||
case EVENT_LOATHEB:
|
||||
if (data == NOT_STARTED)
|
||||
loathebAchievement = true;
|
||||
Encounters[id] = data;
|
||||
break;
|
||||
case EVENT_HEIGAN:
|
||||
if (data == NOT_STARTED)
|
||||
heiganAchievement = true;
|
||||
Encounters[id] = data;
|
||||
break;
|
||||
case DATA_HEIGAN_ERUPTION:
|
||||
HeiganEruptSections(data);
|
||||
return;
|
||||
case EVENT_SAPPHIRON:
|
||||
Encounters[id] = data;
|
||||
if (data == DONE)
|
||||
_speakTimer = 1;
|
||||
else if (data == NOT_STARTED)
|
||||
sapphironAchievement = true;
|
||||
break;
|
||||
case DATA_ABOMINATION_KILLED:
|
||||
abominationsKilled++;
|
||||
return;
|
||||
case DATA_FRENZY_REMOVED:
|
||||
faerlinaAchievement = false;
|
||||
return;
|
||||
case DATA_CHARGES_CROSSED:
|
||||
thaddiusAchievement = false;
|
||||
return;
|
||||
case DATA_SPORE_KILLED:
|
||||
loathebAchievement = false;
|
||||
return;
|
||||
case DATA_HUNDRED_CLUB:
|
||||
sapphironAchievement = false;
|
||||
return;
|
||||
case DATA_DANCE_FAIL:
|
||||
heiganAchievement = false;
|
||||
return;
|
||||
case DATA_IMMORTAL_FAIL:
|
||||
immortalAchievement = 0;
|
||||
SaveToDB();
|
||||
return;
|
||||
}
|
||||
|
||||
// Horseman handling
|
||||
if (id == EVENT_HORSEMAN)
|
||||
{
|
||||
if (data == DONE)
|
||||
{
|
||||
_horsemanTimer++;
|
||||
_horsemanKilled++;
|
||||
if (_horsemanKilled < 4)
|
||||
return;
|
||||
|
||||
// All horsemans are killed
|
||||
if (Creature* cr = instance->GetCreature(_blaumeuxGUID))
|
||||
cr->CastSpell(cr, 59450, true); // credit
|
||||
}
|
||||
|
||||
// respawn
|
||||
else if (data == NOT_STARTED && _horsemanKilled > 0)
|
||||
{
|
||||
Creature* cr;
|
||||
_horsemanKilled = 0;
|
||||
if (cr = instance->GetCreature(_blaumeuxGUID))
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
if (cr = instance->GetCreature(_rivendareGUID))
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
if (cr = instance->GetCreature(_zeliekGUID))
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
if (cr = instance->GetCreature(_korthazzGUID))
|
||||
if (!cr->IsAlive())
|
||||
{
|
||||
cr->SetPosition(cr->GetHomePosition());
|
||||
cr->Respawn();
|
||||
}
|
||||
}
|
||||
else if (data == IN_PROGRESS)
|
||||
{
|
||||
Creature* cr;
|
||||
if (cr = instance->GetCreature(_blaumeuxGUID))
|
||||
cr->SetInCombatWithZone();
|
||||
if (cr = instance->GetCreature(_rivendareGUID))
|
||||
cr->SetInCombatWithZone();
|
||||
if (cr = instance->GetCreature(_zeliekGUID))
|
||||
cr->SetInCombatWithZone();
|
||||
if (cr = instance->GetCreature(_korthazzGUID))
|
||||
cr->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
if (data == NOT_STARTED)
|
||||
_horsemanTimer = 0;
|
||||
|
||||
Encounters[id] = data;
|
||||
}
|
||||
|
||||
// Save instance and open gates
|
||||
if (data == DONE)
|
||||
{
|
||||
SaveToDB();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case EVENT_PATCHWERK:
|
||||
if (GameObject* go = instance->GetGameObject(_patchwerkGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_GLUTH:
|
||||
if (GameObject* go = instance->GetGameObject(_gluthGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_thaddiusGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_NOTH:
|
||||
if (GameObject* go = instance->GetGameObject(_nothGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_heiganGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_HEIGAN:
|
||||
if (GameObject* go = instance->GetGameObject(_heiganGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_heiganGateExitGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_LOATHEB:
|
||||
if (GameObject* go = instance->GetGameObject(_loathebGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_loathebPortalGUID))
|
||||
go->SetPhaseMask(1, true);
|
||||
break;
|
||||
case EVENT_ANUB:
|
||||
if (GameObject* go = instance->GetGameObject(_anubGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_anubNextGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_FAERLINA:
|
||||
if (GameObject* go = instance->GetGameObject(_faerlinaGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_maexxnaGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_MAEXXNA:
|
||||
if (GameObject* go = instance->GetGameObject(_maexxnaGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_maexxnaPortalGUID))
|
||||
go->SetPhaseMask(1, true);
|
||||
break;
|
||||
case EVENT_GOTHIK:
|
||||
if (GameObject* go = instance->GetGameObject(_gothikEnterGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_gothikExitGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
if (GameObject* go = instance->GetGameObject(_horsemanGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_SAPPHIRON:
|
||||
if (GameObject* go = instance->GetGameObject(_sapphironGateGUID))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_THADDIUS:
|
||||
if (GameObject* go = instance->GetGameObject(_thaddiusPortalGUID))
|
||||
go->SetPhaseMask(1, true);
|
||||
break;
|
||||
case EVENT_HORSEMAN:
|
||||
if (GameObject* go = instance->GetGameObject(_horsemanPortalGUID))
|
||||
go->SetPhaseMask(1, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 identifier) const
|
||||
{
|
||||
switch(identifier)
|
||||
{
|
||||
case EVENT_HORSEMAN:
|
||||
return Encounters[identifier];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
if (_speakTimer)
|
||||
{
|
||||
Creature* kel = instance->GetCreature(_kelthuzadGUID);
|
||||
Creature* lich = instance->GetCreature(_lichkingGUID);
|
||||
if (kel && lich)
|
||||
_speakTimer += diff;
|
||||
else
|
||||
return;
|
||||
if (_speakTimer > 20000 && _speakTimer < 30000)
|
||||
{
|
||||
kel->AI()->Talk(SAY_SAPP_DIALOG1);
|
||||
_speakTimer = 30000;
|
||||
}
|
||||
else if (_speakTimer > 45000 && _speakTimer < 50000)
|
||||
{
|
||||
lich->AI()->Talk(SAY_SAPP_DIALOG2_LICH);
|
||||
_speakTimer = 50000;
|
||||
}
|
||||
else if (_speakTimer > 58000 && _speakTimer < 70000)
|
||||
{
|
||||
kel->AI()->Talk(SAY_SAPP_DIALOG3);
|
||||
_speakTimer = 70000;
|
||||
}
|
||||
else if (_speakTimer > 78000 && _speakTimer < 90000)
|
||||
{
|
||||
lich->AI()->Talk(SAY_SAPP_DIALOG4_LICH);
|
||||
_speakTimer = 90000;
|
||||
}
|
||||
else if (_speakTimer > 98000)
|
||||
{
|
||||
kel->AI()->Talk(SAY_SAPP_DIALOG5);
|
||||
_speakTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// And They would all
|
||||
if (_horsemanTimer)
|
||||
_horsemanTimer += diff;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 id) const
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
// GameObjects
|
||||
case DATA_HEIGAN_ENTER_GATE:
|
||||
return _heiganGateGUID;
|
||||
case DATA_LOATHEB_GATE:
|
||||
return _loathebGateGUID;
|
||||
case DATA_ANUB_GATE:
|
||||
return _anubGateGUID;
|
||||
case DATA_MAEXXNA_GATE:
|
||||
return _maexxnaGateGUID;
|
||||
case DATA_GOTHIK_ENTER_GATE:
|
||||
return _gothikEnterGateGUID;
|
||||
case DATA_GOTHIK_INNER_GATE:
|
||||
return _gothikInnerGateGUID;
|
||||
case DATA_GOTHIK_EXIT_GATE:
|
||||
return _gothikExitGateGUID;
|
||||
case DATA_KELTHUZAD_FLOOR:
|
||||
return _kelthuzadfloorGUID;
|
||||
case DATA_KELTHUZAD_GATE:
|
||||
return _kelthuzadgateGUID;
|
||||
|
||||
// NPCs
|
||||
case DATA_THADDIUS_BOSS:
|
||||
return _thaddiusGUID;
|
||||
case DATA_STALAGG_BOSS:
|
||||
return _stalaggGUID;
|
||||
case DATA_FEUGEN_BOSS:
|
||||
return _feugenGUID;
|
||||
case DATA_LICH_KING_BOSS:
|
||||
return _lichkingGUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "N X X " << Encounters[0] << ' ' << Encounters[1] << ' ' << Encounters[2] << ' ' << Encounters[3]
|
||||
<< ' ' << Encounters[4] << ' ' << Encounters[5] << ' ' << Encounters[6] << ' ' << Encounters[7]
|
||||
<< ' ' << Encounters[8] << ' ' << Encounters[9] << ' ' << Encounters[10] << ' ' << Encounters[11]
|
||||
<< ' ' << Encounters[12] << ' ' << Encounters[13] << ' ' << Encounters[14] << ' ' << immortalAchievement;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2, dataHead3;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> dataHead3;
|
||||
|
||||
if (dataHead1 == 'N' && dataHead2 == 'X' && dataHead3 == 'X')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
loadStream >> Encounters[i];
|
||||
if (Encounters[i] == IN_PROGRESS)
|
||||
Encounters[i] = NOT_STARTED;
|
||||
}
|
||||
loadStream >> immortalAchievement;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
class boss_naxxramas_misc : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_naxxramas_misc() : CreatureScript("boss_naxxramas_misc") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_naxxramas_miscAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_naxxramas_miscAI : public NullCreatureAI
|
||||
{
|
||||
boss_naxxramas_miscAI(Creature* c) : NullCreatureAI(c)
|
||||
{
|
||||
timer = 0;
|
||||
}
|
||||
|
||||
uint32 timer;
|
||||
|
||||
void JustDied(Unit* )
|
||||
{
|
||||
if (me->GetEntry() == NPC_MR_BIGGLESWORTH && me->GetInstanceScript())
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(20350/*NPC_KELTHUZAD*/, *me, TEMPSUMMON_TIMED_DESPAWN, 1))
|
||||
{
|
||||
cr->SetDisplayId(11686);
|
||||
cr->AI()->Talk(SAY_CAT_DIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (me->GetEntry() == NPC_NAXXRAMAS_TRIGGER)
|
||||
{
|
||||
timer += diff;
|
||||
if (timer >= 5000)
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(NPC_LIVING_POISON, *me, TEMPSUMMON_TIMED_DESPAWN, 9000))
|
||||
{
|
||||
cr->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
cr->GetMotionMaster()->MovePoint(0, me->GetPositionX()+50*cos(me->GetOrientation()), me->GetPositionY()+50*sin(me->GetOrientation()), me->GetPositionZ(), false);
|
||||
}
|
||||
timer = 0;
|
||||
}
|
||||
}
|
||||
else if (me->GetEntry() == NPC_LIVING_POISON)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 0.5f);
|
||||
Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, target, u_check);
|
||||
me->VisitNearbyObject(1.5f, searcher);
|
||||
if (target)
|
||||
me->CastSpell(me, SPELL_FROGGER_EXPLODE, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_naxxramas()
|
||||
{
|
||||
new instance_naxxramas();
|
||||
new boss_naxxramas_misc();
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_NAXXRAMAS_H
|
||||
#define DEF_NAXXRAMAS_H
|
||||
|
||||
enum NXEncounter
|
||||
{
|
||||
EVENT_PATCHWERK = 0,
|
||||
EVENT_GROBBULUS = 1,
|
||||
EVENT_GLUTH = 2,
|
||||
EVENT_NOTH = 3,
|
||||
EVENT_HEIGAN = 4,
|
||||
EVENT_LOATHEB = 5,
|
||||
EVENT_ANUB = 6,
|
||||
EVENT_FAERLINA = 7,
|
||||
EVENT_MAEXXNA = 8,
|
||||
EVENT_THADDIUS = 9,
|
||||
EVENT_RAZUVIOUS = 10,
|
||||
EVENT_GOTHIK = 11,
|
||||
EVENT_HORSEMAN = 12,
|
||||
EVENT_SAPPHIRON = 13,
|
||||
EVENT_KELTHUZAD = 14,
|
||||
MAX_ENCOUNTERS,
|
||||
};
|
||||
|
||||
enum NXData
|
||||
{
|
||||
DATA_HEIGAN_ERUPTION = 100,
|
||||
DATA_HEIGAN_ENTER_GATE = 101,
|
||||
DATA_LOATHEB_GATE = 102,
|
||||
DATA_ANUB_GATE = 103,
|
||||
DATA_MAEXXNA_GATE = 104,
|
||||
DATA_THADDIUS_BOSS = 105,
|
||||
DATA_STALAGG_BOSS = 106,
|
||||
DATA_FEUGEN_BOSS = 107,
|
||||
DATA_GOTHIK_ENTER_GATE = 108,
|
||||
DATA_GOTHIK_INNER_GATE = 109,
|
||||
DATA_GOTHIK_EXIT_GATE = 110,
|
||||
DATA_LICH_KING_BOSS = 111,
|
||||
DATA_KELTHUZAD_FLOOR = 112,
|
||||
DATA_ABOMINATION_KILLED = 113,
|
||||
DATA_FRENZY_REMOVED = 114,
|
||||
DATA_CHARGES_CROSSED = 115,
|
||||
DATA_SPORE_KILLED = 116,
|
||||
DATA_HUNDRED_CLUB = 117,
|
||||
DATA_DANCE_FAIL = 118,
|
||||
DATA_IMMORTAL_FAIL = 119,
|
||||
DATA_KELTHUZAD_GATE = 120,
|
||||
};
|
||||
|
||||
enum NXGOs
|
||||
{
|
||||
GO_PATCHWERK_GATE = 181123,
|
||||
GO_GLUTH_GATE = 181120,
|
||||
GO_NOTH_GATE = 181201,
|
||||
GO_HEIGAN_ENTERANCE_GATE = 181202,
|
||||
GO_HEIGAN_EXIT_GATE = 181203,
|
||||
GO_LOATHEB_GATE = 181241,
|
||||
GO_ANUB_GATE = 181126,
|
||||
GO_ANUB_NEXT_GATE = 181195,
|
||||
GO_FAERLINA_GATE = 194022,
|
||||
GO_MAEXXNA_GATE = 181209,
|
||||
GO_THADDIUS_GATE = 181121,
|
||||
GO_GOTHIK_ENTER_GATE = 181124,
|
||||
GO_GOTHIK_INNER_GATE = 181170,
|
||||
GO_GOTHIK_EXIT_GATE = 181125,
|
||||
GO_HORSEMAN_GATE = 181119,
|
||||
GO_SAPPHIRON_GATE = 181225,
|
||||
|
||||
GO_HORSEMEN_CHEST_10 = 181366,
|
||||
GO_HORSEMEN_CHEST_25 = 193426,
|
||||
|
||||
GO_SAPPHIRON_BIRTH = 181356,
|
||||
GO_KELTHUZAD_FLOOR = 181444,
|
||||
GO_KELTHUZAD_GATE = 181228,
|
||||
|
||||
GO_DEATHKNIGHT_WING = 181577, //Loatheb portal
|
||||
GO_THADDIUS_PORTAL = 181576, //Thadius portal
|
||||
GO_MAEXXNA_PORTAL = 181575, //Maexxna portal
|
||||
GO_HORSEMAN_PORTAL = 181578, //Four Horseman portal
|
||||
};
|
||||
|
||||
enum NXNPCs
|
||||
{
|
||||
// Thaddius
|
||||
NPC_THADDIUS = 15928,
|
||||
NPC_STALAGG = 15929,
|
||||
NPC_FEUGEN = 15930,
|
||||
|
||||
// Four horseman
|
||||
NPC_BARON_RIVENDARE = 30549,
|
||||
NPC_SIR_ZELIEK = 16063,
|
||||
NPC_LADY_BLAUMEUX = 16065,
|
||||
NPC_THANE_KORTHAZZ = 16064,
|
||||
|
||||
// Sapphiron
|
||||
NPC_SAPPHIRON = 15989,
|
||||
|
||||
// Kel'Thuzad
|
||||
NPC_KELTHUZAD = 15990,
|
||||
NPC_LICH_KING = 16980,
|
||||
|
||||
// Frogger
|
||||
NPC_LIVING_POISON = 16027,
|
||||
NPC_NAXXRAMAS_TRIGGER = 16082,
|
||||
NPC_MR_BIGGLESWORTH = 16998
|
||||
};
|
||||
|
||||
enum NXMisc
|
||||
{
|
||||
// Spells
|
||||
SPELL_ERUPTION = 29371,
|
||||
SPELL_FROGGER_EXPLODE = 28433,
|
||||
|
||||
// Actions
|
||||
ACTION_SAPPHIRON_BIRTH = 1
|
||||
};
|
||||
|
||||
enum NXSays
|
||||
{
|
||||
SAY_SAPP_DIALOG1 = 0,
|
||||
SAY_SAPP_DIALOG2_LICH = 0,
|
||||
SAY_SAPP_DIALOG3 = 2,
|
||||
SAY_SAPP_DIALOG4_LICH = 1,
|
||||
SAY_SAPP_DIALOG5 = 4,
|
||||
SAY_CAT_DIED = 0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user