aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDark0r <none@none>2011-01-01 19:13:59 +0100
committerShauren <krzysiek.7.5.4@gmail.com>2011-01-01 19:13:59 +0100
commit81c358d6dc580e10e38666208aca75b512023ecc (patch)
tree9ee55beace573eac339742583b4a1c5518cdbe12 /src
parent957c69de835cc00e1edee7adb407c1e5a6e608f4 (diff)
Scripts/Pit of Saron: Rewrite Pit of Saron instance
Signed-off-by: Shauren <krzysiek.7.5.4@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp389
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp896
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp537
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp364
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp1193
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h59
6 files changed, 1534 insertions, 1904 deletions
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
index 41c3dfe18e2..fd31748ae86 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
@@ -20,195 +20,314 @@
enum Yells
{
- SAY_AGGRO = -1658001,
- SAY_SLAY_1 = -1658002,
- SAY_SLAY_2 = -1658003,
- SAY_DEATH = -1658004,
- SAY_PHASE2 = -1658005,
- SAY_PHASE3 = -1658006,
-
- SAY_TYRANNUS_DEATH = -1659007,
+ SAY_AGGRO = -1658001,
+ SAY_SLAY_1 = -1658002,
+ SAY_SLAY_2 = -1658003,
+ SAY_DEATH = -1658004,
+ SAY_PHASE2 = -1658005,
+ SAY_PHASE3 = -1658006,
+
+ SAY_TYRANNUS_DEATH = -1659007,
};
+enum Spells
+{
+ SPELL_PERMAFROST = 70326,
+ SPELL_THROW_SARONITE = 68788,
+ SPELL_THUNDERING_STOMP = 68771,
+ SPELL_CHILLING_WAVE = 68778,
+ SPELL_DEEP_FREEZE = 70381,
+ SPELL_FORGE_MACE = 68785,
+ SPELL_FORGE_BLADE = 68774,
+};
+
+#define SPELL_PERMAFROST_HELPER RAID_MODE<uint32>(68786, 70336)
+
enum eEvents
{
- EVENT_NONE,
- EVENT_PERMAFROST,
- EVENT_THROW_SARONITE,
- EVENT_CHILLINGWAVE,
- EVENT_DEEPFREEZE,
+ EVENT_THROW_SARONITE = 1,
+ EVENT_CHILLING_WAVE = 2,
+ EVENT_DEEP_FREEZE = 3,
+ EVENT_JUMP = 4,
+ EVENT_FORGING = 5,
+ EVENT_RESUME_ATTACK = 6,
};
-enum Spells
+enum ePhases
{
- SPELL_PERMAFROST = 70326,
- SPELL_PERMAFROST_TRIGGER = 68786, // triggered by PERMAFROST. Used to check aura
- SPELL_THROW_SARONITE = 68788,
- SPELL_THUNDERING_STOMP = 68771,
- SPELL_CHILLING_WAVE = 68778,
- H_SPELL_CHILLING_WAVE = 70333,
- SPELL_DEEP_FREEZE = 70381,
- H_SPELL_DEEP_FREEZE = 72930,
- SPELL_FORGE_MACE = 68785,
- H_SPELL_FORGE_MACE = 70335,
- SPELL_FORGE_BLADE = 68774,
- H_SPELL_FORGE_BLADE = 70334,
+ PHASE_ONE = 1,
+ PHASE_TWO = 2,
+ PHASE_THREE = 3,
+
+ PHASE_ONE_MASK = 1 << PHASE_ONE,
+ PHASE_TWO_MASK = 1 << PHASE_TWO,
+ PHASE_THREE_MASK = 1 << PHASE_THREE,
};
-enum eEnums
+enum eMiscData
{
- EQUIP_ID_SWORD = 49345,
- EQUIP_ID_MACE = 49344,
- ACHIEV_DOESNT_GO_TO_ELEVEN = 4524,
+ EQUIP_ID_SWORD = 49345,
+ EQUIP_ID_MACE = 49344,
+ ACHIEV_DOESNT_GO_TO_ELEVEN = 0,
+ POINT_FORGE = 0,
};
+static const Position northForgePos = {722.5643f, -234.1615f, 527.182f, 2.16421f};
+static const Position southForgePos = {639.257f, -210.1198f, 529.015f, 0.523599f};
+
class boss_garfrost : public CreatureScript
{
-public:
- boss_garfrost() : CreatureScript("boss_garfrost") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_garfrostAI (pCreature);
- }
+ public:
+ boss_garfrost() : CreatureScript("boss_garfrost") { }
- struct boss_garfrostAI : public ScriptedAI
- {
- boss_garfrostAI(Creature *c) : ScriptedAI(c)
+ struct boss_garfrostAI : public BossAI
{
- pInstance = c->GetInstanceScript();
- }
+ boss_garfrostAI(Creature *creature) : BossAI(creature, DATA_GARFROST)
+ {
+ }
- bool phase2;
- bool phase3;
- bool bAchievement;
+ void InitializeAI()
+ {
+ if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(PoSScriptName))
+ me->IsAIEnabled = false;
+ else if (!me->isDead())
+ Reset();
+ }
- InstanceScript* pInstance;
- EventMap events;
+ void Reset()
+ {
+ events.Reset();
+ events.SetPhase(PHASE_ONE);
+ SetEquipmentSlots(true);
+ _permafrostStack = 0;
- void Reset()
- {
- events.Reset();
+ instance->SetBossState(DATA_GARFROST, NOT_STARTED);
+ }
- phase2 = false;
- phase3 = false;
- bAchievement = true;
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoCast(me, SPELL_PERMAFROST);
+ events.ScheduleEvent(EVENT_THROW_SARONITE, 7000);
- if (pInstance)
- pInstance->SetData(DATA_GARFROST_EVENT, NOT_STARTED);
- }
+ instance->SetBossState(DATA_GARFROST, IN_PROGRESS);
+ }
- void EnterCombat(Unit* /*who*/)
- {
- DoScriptText(SAY_AGGRO, me);
- DoCast(me, SPELL_PERMAFROST);
+ void KilledUnit(Unit* victim)
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me);
+ }
- if (pInstance)
- pInstance->SetData(DATA_GARFROST_EVENT, IN_PROGRESS);
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ if (Creature* tyrannus = me->GetCreature(*me, instance->GetData64(DATA_TYRANNUS)))
+ DoScriptText(SAY_TYRANNUS_DEATH, tyrannus);
- events.ScheduleEvent(EVENT_THROW_SARONITE, 45000);
- }
+ instance->SetBossState(DATA_GARFROST, DONE);
+ }
- void DamageTaken(Unit* /*pDoneBy*/, uint32& /*uiDamage*/)
- {
- if (HealthBelowPct(66) && !phase2)
+ void DamageTaken(Unit* /*attacker*/, uint32& /*uiDamage*/)
{
- phase2 = true;
- DoCast(me, SPELL_THUNDERING_STOMP);
- // TODO: should go to a forge
- DoCast(me, SPELL_FORGE_BLADE);
- // TODO: should equip when spell completes
- SetEquipmentSlots(false, EQUIP_ID_SWORD, -1, -1);
- me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
- events.ScheduleEvent(EVENT_CHILLINGWAVE, 10000);
+ if (events.GetPhaseMask() & PHASE_ONE_MASK && !HealthAbovePct(66))
+ {
+ events.SetPhase(PHASE_TWO);
+ events.DelayEvents(8000);
+ DoCast(me, SPELL_THUNDERING_STOMP);
+ events.ScheduleEvent(EVENT_JUMP, 1500);
+ return;
+ }
+
+ if (events.GetPhaseMask() & PHASE_TWO_MASK && !HealthAbovePct(33))
+ {
+ events.SetPhase(PHASE_THREE);
+ events.DelayEvents(8000);
+ DoCast(me, SPELL_THUNDERING_STOMP);
+ events.ScheduleEvent(EVENT_JUMP, 1500);
+ return;
+ }
}
- if (HealthBelowPct(33) && !phase3)
+ void MovementInform(uint32 type, uint32 id)
{
- phase3 = true;
- DoCast(me, SPELL_THUNDERING_STOMP);
- // TODO: should go to a forge
- DoCast(me, SPELL_FORGE_MACE);
- // TODO: should equip when spell completes
- SetEquipmentSlots(false, EQUIP_ID_MACE, -1, -1);
- me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
- events.CancelEvent(EVENT_CHILLINGWAVE); // cast only in phase 2.
- events.ScheduleEvent(EVENT_DEEPFREEZE, 10000);
+ if (type != POINT_MOTION_TYPE || id != POINT_FORGE)
+ return;
+
+ if (events.GetPhaseMask() & PHASE_TWO_MASK)
+ DoCast(me, SPELL_FORGE_BLADE);
+ if (events.GetPhaseMask() & PHASE_THREE_MASK)
+ DoCast(me, SPELL_FORGE_MACE);
+ events.ScheduleEvent(EVENT_RESUME_ATTACK, 5000);
}
- }
- void KilledUnit(Unit * victim)
- {
- if (victim == me)
- return;
+ void SpellHitTarget(Unit* target, const SpellEntry* spell)
+ {
+ if (spell->Id == SPELL_PERMAFROST_HELPER)
+ {
+ if (Aura *aura = target->GetAura(SPELL_PERMAFROST_HELPER))
+ _permafrostStack = std::max<uint32>(_permafrostStack, aura->GetStackAmount());
+ }
+ else if (spell->Id == SPELL_FORGE_BLADE)
+ SetEquipmentSlots(false, EQUIP_ID_SWORD);
+ else if (spell->Id == SPELL_FORGE_MACE)
+ SetEquipmentSlots(false, EQUIP_ID_MACE);
+ }
- DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
- }
+ uint32 GetData(uint32 type)
+ {
+ return _permafrostStack;
+ }
- void JustDied(Unit* /*killer*/)
- {
- DoScriptText(SAY_DEATH, me);
- if (pInstance)
+ void UpdateAI(const uint32 diff)
{
- if (Creature *pTyrannus = me->GetCreature(*me, pInstance->GetData64(DATA_TYRANNUS)))
- DoScriptText(SAY_TYRANNUS_DEATH, pTyrannus);
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_THROW_SARONITE:
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_THROW_SARONITE);
+ events.ScheduleEvent(EVENT_THROW_SARONITE, urand(12500, 20000));
+ break;
+ case EVENT_CHILLING_WAVE:
+ DoCast(me, SPELL_CHILLING_WAVE);
+ events.ScheduleEvent(EVENT_CHILLING_WAVE, 40000, 0, PHASE_TWO);
+ break;
+ case EVENT_DEEP_FREEZE:
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_DEEP_FREEZE);
+ events.ScheduleEvent(EVENT_DEEP_FREEZE, 35000, 0, PHASE_THREE);
+ break;
+ case EVENT_JUMP:
+ me->AttackStop();
+ if (events.GetPhaseMask() & PHASE_TWO_MASK)
+ me->GetMotionMaster()->MoveJump(northForgePos.GetPositionX(), northForgePos.GetPositionY(), northForgePos.GetPositionZ(), 25.0f, 15.0f);
+ else if (events.GetPhaseMask() & PHASE_THREE_MASK)
+ me->GetMotionMaster()->MoveJump(southForgePos.GetPositionX(), southForgePos.GetPositionY(), southForgePos.GetPositionZ(), 25.0f, 15.0f);
+ break;
+ case EVENT_RESUME_ATTACK:
+ if (events.GetPhaseMask() & PHASE_TWO_MASK)
+ events.ScheduleEvent(EVENT_CHILLING_WAVE, 5000, 0, PHASE_TWO);
+ else if (events.GetPhaseMask() & PHASE_THREE_MASK)
+ events.ScheduleEvent(EVENT_DEEP_FREEZE, 10000, 0, PHASE_THREE);
+ AttackStart(me->getVictim());
+ break;
+ default:
+ break;
+ }
+ }
- pInstance->SetData(DATA_GARFROST_EVENT, DONE);
- if (IsHeroic() && bAchievement)
- pInstance->DoCompleteAchievement(ACHIEV_DOESNT_GO_TO_ELEVEN);
+ DoMeleeAttackIfReady();
}
- }
- void SpellHitTarget(Unit* pTarget, const SpellEntry *spell)
+ private:
+ uint32 _permafrostStack;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
{
- if (spell->Id == SPELL_PERMAFROST_TRIGGER && bAchievement)
- {
- if (Aura *pAura = pTarget->GetAura(SPELL_PERMAFROST_TRIGGER))
- if (pAura->GetStackAmount() > 10)
- bAchievement = false;
- }
+ return new boss_garfrostAI(creature);
}
+};
+
+class spell_garfrost_permafrost : public SpellScriptLoader
+{
+ public:
+ spell_garfrost_permafrost() : SpellScriptLoader("spell_garfrost_permafrost") { }
- void UpdateAI(const uint32 diff)
+ class spell_garfrost_permafrost_SpellScript : public SpellScript
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ PrepareSpellScript(spell_garfrost_permafrost_SpellScript);
- events.Update(diff);
+ bool Load()
+ {
+ prevented = false;
+ return true;
+ }
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ void PreventHitByLoS()
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ Unit* caster = GetCaster();
+ //Temporary Line of Sight Check
+ std::list<GameObject*> blockList;
+ caster->GetGameObjectListWithEntryInGrid(blockList, GO_SARONITE_ROCK, 100.0f);
+ if (!blockList.empty())
+ {
+ for (std::list<GameObject*>::const_iterator itr = blockList.begin(); itr != blockList.end(); ++itr)
+ {
+ if ((*itr)->isVisibleForInState(target))
+ {
+ if ((*itr)->IsInBetween(caster, target, 4.0f))
+ {
+ prevented = true;
+ target->ApplySpellImmune(GetSpellInfo()->Id, IMMUNITY_ID, GetSpellInfo()->Id, true);
+ PreventHitDefaultEffect(EFFECT_0);
+ PreventHitDefaultEffect(EFFECT_1);
+ PreventHitDefaultEffect(EFFECT_2);
+ PreventHitDamage();
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
- while (uint32 eventId = events.ExecuteEvent())
+ void RestoreImmunity()
{
- switch(eventId)
+ if (Unit* target = GetHitUnit())
{
- case EVENT_THROW_SARONITE:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_THROW_SARONITE);
- events.RescheduleEvent(EVENT_THROW_SARONITE, 35000);
- return;
- case EVENT_DEEPFREEZE:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_DEEP_FREEZE);
- events.RescheduleEvent(EVENT_DEEPFREEZE, 35000);
- return;
- case EVENT_CHILLINGWAVE:
- DoCastAOE(SPELL_CHILLING_WAVE);
- events.RescheduleEvent(EVENT_CHILLINGWAVE, 40000);
- return;
+ target->ApplySpellImmune(GetSpellInfo()->Id, IMMUNITY_ID, GetSpellInfo()->Id, false);
+ if (prevented)
+ PreventHitAura();
}
}
- DoMeleeAttackIfReady();
- }
- };
+ void Register()
+ {
+ BeforeHit += SpellHitFn(spell_garfrost_permafrost_SpellScript::PreventHitByLoS);
+ AfterHit += SpellHitFn(spell_garfrost_permafrost_SpellScript::RestoreImmunity);
+ }
+ bool prevented;
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_garfrost_permafrost_SpellScript();
+ }
};
+class achievement_doesnt_go_to_eleven : public AchievementCriteriaScript
+{
+ public:
+ achievement_doesnt_go_to_eleven() : AchievementCriteriaScript("achievement_doesnt_go_to_eleven") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ if (target)
+ if (Creature* garfrost = target->ToCreature())
+ if (garfrost->AI()->GetData(ACHIEV_DOESNT_GO_TO_ELEVEN) <= 10)
+ return true;
+
+ return false;
+ }
+};
void AddSC_boss_garfrost()
{
new boss_garfrost();
+ new spell_garfrost_permafrost();
+ new achievement_doesnt_go_to_eleven();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
index 4b64e27e80d..24831c97e9d 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
@@ -17,22 +17,28 @@
#include "ScriptPCH.h"
#include "pit_of_saron.h"
-
-/*
- * SDComment: Spell Explosive barrage is not working.
- */
+#include "Vehicle.h"
enum Spells
{
- SPELL_PURSUED = 68987,
- SPELL_CONFUSION = 69029,
- SPELL_EXPLOSIVE_BARRAGE = 69263,
- SPELL_MIGHTY_KICK = 69021,
- SPELL_POISON_NOVA = 68989,
- H_SPELL_POISON_NOVA = 70434,
- SPELL_SHADOW_BOLT = 69028,
- SPELL_TOXIC_WASTE = 69024,
- H_SPELL_TOXIC_WASTE = 70436,
+ SPELL_MIGHTY_KICK = 69021, //ick's spell
+ SPELL_SHADOW_BOLT = 69028, //krick's spell
+ SPELL_TOXIC_WASTE = 69024, //krick's spell
+ SPELL_EXPLOSIVE_BARRAGE_KRICK = 69012, //special spell 1
+ SPELL_EXPLOSIVE_BARRAGE_ICK = 69263, //special spell 1
+ SPELL_POISON_NOVA = 68989, //special spell 2
+ SPELL_PURSUIT = 68987, //special spell 3
+
+ SPELL_EXPLOSIVE_BARRAGE_SUMMON = 69015,
+ SPELL_EXPLODING_ORB = 69017, //visual on exploding orb
+ SPELL_AUTO_GROW = 69020, //grow effect on exploding orb
+ SPELL_HASTY_GROW = 44851, //need to check growing stacks
+ SPELL_EXPLOSIVE_BARRAGE_DAMAGE = 69019, //damage done by orb while exploding
+
+ SPELL_STRANGULATING = 69413, //krick's selfcast in intro
+ SPELL_SUICIDE = 7,
+ SPELL_KRICK_KILL_CREDIT = 71308,
+ SPELL_NECROMANTIC_POWER = 69753,
};
enum Yells
@@ -69,423 +75,647 @@ enum Yells
enum Events
{
- EVENT_NONE,
- EVENT_PURSUE,
- EVENT_MIGHTY_KICK,
- EVENT_POISON_NOVA,
- EVENT_EXPLOSIVE_BARRAGE,
- EVENT_END_EXPLOSIVE_BARRAGE,
-
- // Krick
- EVENT_SHADOW_BOLT,
- EVENT_TOXIC_WASTE,
+ EVENT_MIGHTY_KICK = 1,
+ EVENT_SHADOW_BOLT = 2,
+ EVENT_TOXIC_WASTE = 3,
+ EVENT_SPECIAL = 4, //special spell selection (one of event 5, 6 or 7)
+ EVENT_PURSUIT = 5,
+ EVENT_POISON_NOVA = 6,
+ EVENT_EXPLOSIVE_BARRAGE = 7,
// Krick OUTRO
- EVENT_OUTRO_1,
- EVENT_OUTRO_2,
- EVENT_OUTRO_3,
- EVENT_OUTRO_4,
- EVENT_OUTRO_5,
- EVENT_OUTRO_6,
- EVENT_OUTRO_7,
- EVENT_OUTRO_8,
- EVENT_OUTRO_9,
- EVENT_OUTRO_10,
- EVENT_OUTRO_11,
- EVENT_OUTRO_12,
- EVENT_OUTRO_END,
+ EVENT_OUTRO_1 = 8,
+ EVENT_OUTRO_2 = 9,
+ EVENT_OUTRO_3 = 10,
+ EVENT_OUTRO_4 = 11,
+ EVENT_OUTRO_5 = 12,
+ EVENT_OUTRO_6 = 13,
+ EVENT_OUTRO_7 = 14,
+ EVENT_OUTRO_8 = 15,
+ EVENT_OUTRO_9 = 16,
+ EVENT_OUTRO_10 = 17,
+ EVENT_OUTRO_11 = 18,
+ EVENT_OUTRO_12 = 19,
+ EVENT_OUTRO_13 = 20,
+ EVENT_OUTRO_END = 21,
};
enum KrickPhase
{
- PHASE_COMBAT,
- PHASE_OUTRO,
+ PHASE_COMBAT = 1,
+ PHASE_OUTRO = 2,
};
enum Actions
{
- ACTION_OUTRO,
+ ACTION_OUTRO = 1,
};
-enum Misc
+enum Points
{
- SEAT_KRICK = 0,
-
- // events GCD. Shall not be 0.
- GCD_1 = 1,
+ POINT_KRICK_INTRO = 364770,
+ POINT_KRICK_DEATH = 364771,
};
-// Krick is the Gnome.
-// Ick is the Mount
-// Common Events are handled/triggered by Ick that "drive" Krick through DoAction.
+static const Position outroPos[7] =
+{
+ {828.9342f, 118.6247f, 509.5190f, 0.0000000f}, // Krick's Outro Position
+ {841.0100f, 196.2450f, 573.9640f, 0.2046099f}, // Scourgelord Tyrannus Outro Position (Tele to...)
+ {777.2274f, 119.5521f, 510.0363f, 6.0562930f}, // Sylvanas / Jaine Outro Spawn Position (NPC_SYLVANAS_PART1)
+ {823.3984f, 114.4907f, 509.4899f, 0.0000000f}, // Sylvanas / Jaine Outro Move Position (1)
+ {835.5887f, 139.4345f, 530.9526f, 0.0000000f}, // Tyrannus Fly down Position (only not blizz one :/)
+ {828.9342f, 118.6247f, 514.5190f, 0.0000000f}, // Krick's Choke Position
+ {828.9342f, 118.6247f, 509.4958f, 0.0000000f}, // Kirck's Death Position
+};
class boss_ick : public CreatureScript
{
-public:
- boss_ick() : CreatureScript("boss_ick") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_ickAI(pCreature);
- }
+ public:
+ boss_ick() : CreatureScript("boss_ick") { }
- struct boss_ickAI : public ScriptedAI
- {
- boss_ickAI(Creature *c) : ScriptedAI(c)
+ struct boss_ickAI : public BossAI
{
- pInstance = c->GetInstanceScript();
- }
+ boss_ickAI(Creature *creature) : BossAI(creature, DATA_ICK), _vehicle(creature->GetVehicleKit())
+ {
+ ASSERT(_vehicle);
+ }
- InstanceScript* pInstance;
+ void InitializeAI()
+ {
+ if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(PoSScriptName))
+ me->IsAIEnabled = false;
+ else if (!me->isDead())
+ Reset();
+ }
- EventMap events;
+ void Reset()
+ {
+ events.Reset();
+ instance->SetBossState(DATA_ICK, NOT_STARTED);
+ }
- void Reset()
- {
- events.Reset();
+ Creature* GetKrick()
+ {
+ return ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRICK));
+ }
- if (pInstance)
- pInstance->SetData(DATA_KRICKANDICK_EVENT, NOT_STARTED);
- }
+ void EnterCombat(Unit * /*who*/)
+ {
+ _vehicle->InstallAllAccessories(me->GetEntry());
- Creature* GetKrick()
- {
- return me->GetCreature(*me, pInstance ? pInstance->GetData64(DATA_KRICK) : 0);
- }
+ if (Creature* krick = GetKrick())
+ DoScriptText(SAY_KRICK_AGGRO, krick);
- void EnterCombat(Unit * /*who*/)
- {
- if (pInstance)
- pInstance->SetData(DATA_KRICKANDICK_EVENT, IN_PROGRESS);
-
- Creature* pKrick = GetKrick();
- if (!pKrick)
- pKrick = me->SummonCreature(CREATURE_KRICK, *me, TEMPSUMMON_MANUAL_DESPAWN);
-
- if (pKrick)
- DoScriptText(SAY_KRICK_AGGRO, pKrick);
-
- events.ScheduleEvent(EVENT_MIGHTY_KICK, 20000, GCD_1);
- events.ScheduleEvent(EVENT_PURSUE, 30000, GCD_1);
- events.ScheduleEvent(EVENT_POISON_NOVA, 30000, GCD_1);
- events.ScheduleEvent(EVENT_EXPLOSIVE_BARRAGE, 35000);
- events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
- events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
- }
+ events.ScheduleEvent(EVENT_MIGHTY_KICK, 20000);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 10000);
+ events.ScheduleEvent(EVENT_SPECIAL, urand(30000, 35000));
- void EnterEvadeMode()
- {
- me->GetMotionMaster()->Clear();
- ScriptedAI::EnterEvadeMode();
- }
+ instance->SetBossState(DATA_ICK, IN_PROGRESS);
+ }
- void JustDied(Unit* /*pKiller*/)
- {
- if (Creature* pKrick = GetKrick())
+ void EnterEvadeMode()
{
- if (pKrick->AI())
- pKrick->AI()->DoAction(ACTION_OUTRO);
+ me->GetMotionMaster()->Clear();
+ ScriptedAI::EnterEvadeMode();
}
- if (pInstance)
- pInstance->SetData(DATA_KRICKANDICK_EVENT, DONE);
- }
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (Creature* krick = GetKrick())
+ {
+ _vehicle->RemoveAllPassengers();
+ if (krick->AI())
+ krick->AI()->DoAction(ACTION_OUTRO);
+ }
- void UpdateAI(const uint32 diff)
- {
- if (!me->isInCombat())
- return;
+ instance->SetBossState(DATA_ICK, DONE);
+ }
- if (!me->getVictim() && me->getThreatManager().isThreatListEmpty())
+ void SetTempThreat(float threat)
{
- EnterEvadeMode();
- return;
+ _tempThreat = threat;
}
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ void _ResetThreat(Unit* target)
+ {
+ DoModifyThreatPercent(target, -100);
+ me->AddThreat(target, _tempThreat);
+ }
- switch(events.ExecuteEvent())
+ void UpdateAI(const uint32 diff)
{
- case EVENT_PURSUE:
- if (Creature* pKrick = GetKrick())
- DoScriptText(RAND(SAY_KRICK_CHASE_1,SAY_KRICK_CHASE_2,SAY_KRICK_CHASE_3), pKrick);
+ if (!me->isInCombat())
+ return;
+
+ if (!me->getVictim() && me->getThreatManager().isThreatListEmpty())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- me->Attack(pTarget,false);
- DoScriptText(SAY_ICK_CHASE_1, me, pTarget);
- DoCast(pTarget, SPELL_PURSUED);
+ case EVENT_TOXIC_WASTE:
+ if (Creature* krick = GetKrick())
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ krick->CastSpell(target, SPELL_TOXIC_WASTE, false);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, urand(7000, 10000));
+ break;
+ case EVENT_SHADOW_BOLT:
+ if (Creature* krick = GetKrick())
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1))
+ krick->CastSpell(target, SPELL_SHADOW_BOLT, false);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
+ return;
+ case EVENT_MIGHTY_KICK:
+ DoCastVictim(SPELL_MIGHTY_KICK);
+ events.ScheduleEvent(EVENT_MIGHTY_KICK, 25000);
+ return;
+ case EVENT_SPECIAL:
+ //select one of these three special events
+ events.ScheduleEvent(RAND(EVENT_EXPLOSIVE_BARRAGE, EVENT_POISON_NOVA, EVENT_PURSUIT), 1000);
+ events.ScheduleEvent(EVENT_SPECIAL, urand(23000, 28000));
+ break;
+ case EVENT_EXPLOSIVE_BARRAGE:
+ if (Creature* krick = GetKrick())
+ {
+ DoScriptText(SAY_KRICK_BARRAGE_1, krick);
+ DoScriptText(SAY_KRICK_BARRAGE_2, krick);
+ krick->CastSpell(krick, SPELL_EXPLOSIVE_BARRAGE_KRICK, true);
+ DoCast(me, SPELL_EXPLOSIVE_BARRAGE_ICK);
+ }
+ events.DelayEvents(20000);
+ break;
+ case EVENT_POISON_NOVA:
+ if (Creature* krick = GetKrick())
+ DoScriptText(SAY_KRICK_POISON_NOVA, krick);
+
+ DoScriptText(SAY_ICK_POISON_NOVA, me);
+ DoCast(me, SPELL_POISON_NOVA);
+ break;
+ case EVENT_PURSUIT:
+ if (Creature* krick = GetKrick())
+ DoScriptText(RAND(SAY_KRICK_CHASE_1, SAY_KRICK_CHASE_2, SAY_KRICK_CHASE_3), krick);
+ DoCast(me, SPELL_PURSUIT);
+ break;
+ default:
+ break;
}
+ }
- DoCast(SPELL_CONFUSION);
- events.ScheduleEvent(EVENT_PURSUE, 30000, GCD_1);
- return;
+ DoMeleeAttackIfReady();
+ }
- case EVENT_MIGHTY_KICK:
- DoCast(me->getVictim(), SPELL_MIGHTY_KICK);
- events.ScheduleEvent(EVENT_MIGHTY_KICK, 25000, GCD_1);
- return;
+ private:
+ Vehicle* _vehicle;
+ float _tempThreat;
+ };
+
+ 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 ScriptedAI
+ {
+ boss_krickAI(Creature* creature) : ScriptedAI(creature), _summons(creature), _instanceScript(creature->GetInstanceScript())
+ {
+ }
+
+ void InitializeAI()
+ {
+ if (!_instanceScript || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(PoSScriptName))
+ me->IsAIEnabled = false;
+ else if (!me->isDead())
+ Reset();
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _phase = PHASE_COMBAT;
+ _outroNpcGUID = 0;
+ _tyrannusGUID = 0;
+
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
- case EVENT_POISON_NOVA:
- if (Creature* pKrick = GetKrick())
- DoScriptText(SAY_KRICK_POISON_NOVA, pKrick);
+ Creature* GetIck()
+ {
+ return ObjectAccessor::GetCreature(*me, _instanceScript->GetData64(DATA_ICK));
+ }
- DoScriptText(SAY_ICK_POISON_NOVA, me);
- DoCastAOE(SPELL_POISON_NOVA);
- events.ScheduleEvent(EVENT_POISON_NOVA, 30000, GCD_1);
+ void KilledUnit(Unit* victim)
+ {
+ if (victim == me)
return;
- case EVENT_TOXIC_WASTE:
- DoCast(me->getVictim(), SPELL_TOXIC_WASTE);
- events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
+ DoScriptText(RAND(SAY_KRICK_SLAY_1, SAY_KRICK_SLAY_2), me);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ _summons.Summon(summon);
+ if (summon->GetEntry() == NPC_EXPLODING_ORB)
+ {
+ summon->CastSpell(summon, SPELL_EXPLODING_ORB, true);
+ summon->CastSpell(summon, SPELL_AUTO_GROW, true);
+ }
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ if (actionId == ACTION_OUTRO)
+ {
+ Creature* tyrannusPtr = ObjectAccessor::GetCreature(*me, _instanceScript->GetData64(DATA_TYRANNUS_EVENT));
+ if (tyrannusPtr)
+ tyrannusPtr->NearTeleportTo(outroPos[1].GetPositionX(), outroPos[1].GetPositionY(), outroPos[1].GetPositionZ(), outroPos[1].GetOrientation());
+ else
+ tyrannusPtr = me->SummonCreature(NPC_TYRANNUS_EVENTS, outroPos[1], TEMPSUMMON_MANUAL_DESPAWN);
+
+ tyrannusPtr->SetFlying(true);
+ me->GetMotionMaster()->MovePoint(POINT_KRICK_INTRO, outroPos[0].GetPositionX(), outroPos[0].GetPositionY(), outroPos[0].GetPositionZ());
+ tyrannusPtr->SetFacingToObject(me);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || id != POINT_KRICK_INTRO)
return;
- case EVENT_SHADOW_BOLT:
- DoCast(me->getVictim(), SPELL_SHADOW_BOLT);
- events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
+ DoScriptText(SAY_KRICK_OUTRO_1, me);
+ _phase = PHASE_OUTRO;
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_OUTRO_1, 1000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (_phase != PHASE_OUTRO)
return;
- case EVENT_EXPLOSIVE_BARRAGE:
- if (Creature *pKrick = GetKrick())
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
{
- DoScriptText(SAY_KRICK_BARRAGE_1, pKrick);
- DoScriptText(SAY_KRICK_BARRAGE_2, pKrick);
+ case EVENT_OUTRO_1:
+ {
+ if (Creature* temp = me->GetCreature(*me, _instanceScript->GetData64(DATA_JAINA_SYLVANAS_1)))
+ temp->ForcedDespawn();
+
+ Creature* jainaOrSylvanas = NULL;
+ if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ jainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1, outroPos[2], TEMPSUMMON_MANUAL_DESPAWN);
+ else
+ jainaOrSylvanas = me->SummonCreature(NPC_SYLVANAS_PART1, outroPos[2], TEMPSUMMON_MANUAL_DESPAWN);
+
+ if (jainaOrSylvanas)
+ {
+ jainaOrSylvanas->GetMotionMaster()->MovePoint(0, outroPos[3]);
+ _outroNpcGUID = jainaOrSylvanas->GetGUID();
+ }
+ _events.ScheduleEvent(EVENT_OUTRO_2, 6000);
+ }
+ case EVENT_OUTRO_2:
+ if (Creature* jainaOrSylvanas = me->GetCreature(*me, _outroNpcGUID))
+ {
+ jainaOrSylvanas->SetFacingToObject(me);
+ me->SetFacingToObject(jainaOrSylvanas);
+ if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_2, jainaOrSylvanas);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_2, jainaOrSylvanas);
+ }
+ _events.ScheduleEvent(EVENT_OUTRO_3, 5000);
+ break;
+ case EVENT_OUTRO_3:
+ DoScriptText(SAY_KRICK_OUTRO_3, me);
+ _events.ScheduleEvent(EVENT_OUTRO_4, 18000);
+ break;
+ case EVENT_OUTRO_4:
+ if (Creature* jainaOrSylvanas = me->GetCreature(*me, _outroNpcGUID))
+ {
+ if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_4, jainaOrSylvanas);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_4, jainaOrSylvanas);
+ }
+ _events.ScheduleEvent(EVENT_OUTRO_5, 5000);
+ break;
+ case EVENT_OUTRO_5:
+ DoScriptText(SAY_KRICK_OUTRO_5, me);
+ _events.ScheduleEvent(EVENT_OUTRO_6, 1000);
+ break;
+ case EVENT_OUTRO_6:
+ if (Creature* tyrannus = me->GetCreature(*me, _instanceScript->GetData64(DATA_TYRANNUS_EVENT)))
+ {
+ tyrannus->SetSpeed(MOVE_FLIGHT, 3.5f, true);
+ tyrannus->GetMotionMaster()->MovePoint(1, outroPos[4]);
+ _tyrannusGUID = tyrannus->GetGUID();
+ }
+ _events.ScheduleEvent(EVENT_OUTRO_7, 5000);
+ break;
+ case EVENT_OUTRO_7:
+ if (Creature* tyrannus = me->GetCreature(*me, _tyrannusGUID))
+ DoScriptText(SAY_TYRANNUS_OUTRO_7, tyrannus);
+ _events.ScheduleEvent(EVENT_OUTRO_8, 5000);
+ break;
+ case EVENT_OUTRO_8:
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ me->GetMotionMaster()->MovePoint(0, outroPos[5]);
+ DoCast(me, SPELL_STRANGULATING);
+ _events.ScheduleEvent(EVENT_OUTRO_9, 2000);
+ break;
+ case EVENT_OUTRO_9:
+ DoScriptText(SAY_KRICK_OUTRO_8, me);
+ // TODO: Tyrannus starts killing Krick.
+ // there shall be some visual spell effect
+ if (Creature* tyrannus = me->GetCreature(*me, _tyrannusGUID))
+ tyrannus->CastSpell(me, SPELL_NECROMANTIC_POWER, true); //not sure if it's the right spell :/
+ _events.ScheduleEvent(EVENT_OUTRO_10, 1000);
+ break;
+ case EVENT_OUTRO_10:
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ me->GetMotionMaster()->MovePoint(0, outroPos[6]);
+ _events.ScheduleEvent(EVENT_OUTRO_11, 2000);
+ break;
+ case EVENT_OUTRO_11:
+ DoCast(me, SPELL_KRICK_KILL_CREDIT); // don't really know if we need it
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+ me->SetHealth(0);
+ _events.ScheduleEvent(EVENT_OUTRO_12, 3000);
+ break;
+ case EVENT_OUTRO_12:
+ if (Creature* tyrannus = me->GetCreature(*me, _tyrannusGUID))
+ DoScriptText(SAY_TYRANNUS_OUTRO_9, tyrannus);
+ _events.ScheduleEvent(EVENT_OUTRO_13, 2000);
+ break;
+ case EVENT_OUTRO_13:
+ if (Creature* jainaOrSylvanas = me->GetCreature(*me, _outroNpcGUID))
+ {
+ if (_instanceScript->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_10, jainaOrSylvanas);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_10, jainaOrSylvanas);
+ }
+ // End of OUTRO. for now...
+ _events.ScheduleEvent(EVENT_OUTRO_END, 2000);
+ break;
+ case EVENT_OUTRO_END:
+ //if (Creature* jainaOrSylvanas = me->GetCreature(*me, npcOutroDialogGUID))
+ // jainaOrSylvanas->DisappearAndDie();
+
+ //Todo: jaina walk and tyrannus fly to next step
+ me->DisappearAndDie();
+ break;
}
+ }
+ }
- DoCastAOE(SPELL_EXPLOSIVE_BARRAGE);
- me->GetMotionMaster()->MoveIdle();
- events.DelayEvents(20000, GCD_1); // 2 sec cast + 18 sec
- events.ScheduleEvent(EVENT_END_EXPLOSIVE_BARRAGE, 20000);
- return;
+ private:
+ InstanceScript* _instanceScript;
+ SummonList _summons;
+ EventMap _events;
- case EVENT_END_EXPLOSIVE_BARRAGE:
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveChase(me->getVictim());
- events.ScheduleEvent(EVENT_EXPLOSIVE_BARRAGE, 25000);
- break;
- }
+ KrickPhase _phase;
+ uint64 _outroNpcGUID;
+ uint64 _tyrannusGUID;
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_krickAI(creature);
}
- };
-
};
-class boss_krick : public CreatureScript
+class spell_krick_explosive_barrage : public SpellScriptLoader
{
-public:
- boss_krick() : CreatureScript("boss_krick") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_krickAI(pCreature);
- }
+ public:
+ spell_krick_explosive_barrage() : SpellScriptLoader("spell_krick_explosive_barrage") { }
- struct boss_krickAI : public ScriptedAI
- {
- boss_krickAI(Creature *c) : ScriptedAI(c)
+ class spell_krick_explosive_barrage_AuraScript : public AuraScript
{
- pInstance = c->GetInstanceScript();
- }
+ PrepareAuraScript(spell_krick_explosive_barrage_AuraScript);
- InstanceScript* pInstance;
- EventMap events;
+ 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, 60.0f)) // don't know correct range
+ caster->CastSpell(player, SPELL_EXPLOSIVE_BARRAGE_SUMMON, true);
+ }
+ }
- KrickPhase phase;
- uint64 uiNpcOutroDialog;
- uint64 uiTyrannus;
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_krick_explosive_barrage_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
- void Reset()
+ AuraScript* GetAuraScript() const
{
- uiNpcOutroDialog = 0;
- uiTyrannus = 0;
- phase = PHASE_COMBAT;
-
- me->SetReactState(REACT_PASSIVE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetVisible(false);
+ return new spell_krick_explosive_barrage_AuraScript();
}
+};
- Creature* GetIck()
- {
- return me->GetCreature(*me, pInstance ? pInstance->GetData64(DATA_ICK) : 0);
- }
+class spell_ick_explosive_barrage : public SpellScriptLoader
+{
+ public:
+ spell_ick_explosive_barrage() : SpellScriptLoader("spell_ick_explosive_barrage") { }
- void KilledUnit(Unit * victim)
+ class spell_ick_explosive_barrage_AuraScript : public AuraScript
{
- if (victim == me)
- return;
+ PrepareAuraScript(spell_ick_explosive_barrage_AuraScript);
- DoScriptText(RAND(SAY_KRICK_SLAY_1,SAY_KRICK_SLAY_2), me);
- }
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (caster->GetTypeId() == TYPEID_UNIT)
+ caster->GetMotionMaster()->MoveIdle();
+ }
+
+ void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (caster->GetTypeId() == TYPEID_UNIT)
+ {
+ caster->GetMotionMaster()->Clear();
+ caster->GetMotionMaster()->MoveChase(caster->getVictim());
+ }
+ }
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_ick_explosive_barrage_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_ick_explosive_barrage_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
- void DamageTaken(Unit * /*pDoneBy*/, uint32 &uiDamage)
+ AuraScript *GetAuraScript() const
{
- // if killed whatever the reason, it breaks the outro
- uiDamage = 0;
+ return new spell_ick_explosive_barrage_AuraScript();
}
+};
+
+class spell_exploding_orb_hasty_grow : public SpellScriptLoader
+{
+ public:
+ spell_exploding_orb_hasty_grow() : SpellScriptLoader("spell_exploding_orb_hasty_grow") { }
- void DoAction(const int32 actionId)
+ class spell_exploding_orb_hasty_grow_AuraScript : public AuraScript
{
- switch(actionId)
+ PrepareAuraScript(spell_exploding_orb_hasty_grow_AuraScript);
+
+ void OnStackChange(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- case ACTION_OUTRO:
+ if (GetStackAmount() == 15)
{
- Position pos;
- if (Creature* pIck = GetIck())
- {
- // TODO: tele on Ick then run some distance.
- pIck->GetNearPosition(pos, 5.0f, 3.14f);
- me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), 0.0f);
- }
- me->SetVisible(true);
-
- Creature* pJainaOrSylvanas = me->GetCreature(*me, pInstance->GetData64(DATA_JAINA_SYLVANAS_1));
- if (pJainaOrSylvanas) {
- Position pos;
- me->GetNearPosition(pos, 5.0f, 0);
- pJainaOrSylvanas->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(),
- pos.GetAngle(me->GetPositionX(), me->GetPositionY()));
- }
- else {
- if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
- pJainaOrSylvanas = me->SummonCreature(NPC_SYLVANAS_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN);
- else
- pJainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN);
- }
-
- if (pJainaOrSylvanas)
- {
- pJainaOrSylvanas->SetOrientation(pJainaOrSylvanas->GetAngle(me->GetPositionX(), me->GetPositionY()));
- me->SetOrientation(me->GetAngle(pJainaOrSylvanas->GetPositionX(), pJainaOrSylvanas->GetPositionY()));
- uiNpcOutroDialog = pJainaOrSylvanas->GetGUID();
- }
-
- phase = PHASE_OUTRO;
- events.Reset();
- events.ScheduleEvent(EVENT_OUTRO_1, 1000);
- break;
+ GetTarget()->CastSpell(GetTarget(), SPELL_EXPLOSIVE_BARRAGE_DAMAGE, false);
+ GetTarget()->RemoveAurasDueToSpell(SPELL_HASTY_GROW);
+ GetTarget()->RemoveAurasDueToSpell(SPELL_AUTO_GROW);
+ GetTarget()->RemoveAurasDueToSpell(SPELL_EXPLODING_ORB);
+ if (Creature* creature = GetTarget()->ToCreature())
+ creature->ForcedDespawn(1000);
}
}
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_exploding_orb_hasty_grow_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_exploding_orb_hasty_grow_AuraScript();
}
+};
+
+class spell_krick_pursuit : public SpellScriptLoader
+{
+ public:
+ spell_krick_pursuit() : SpellScriptLoader("spell_krick_pursuit") { }
- void UpdateAI(const uint32 diff)
+ class spell_krick_pursuit_SpellScript : public SpellScript
{
- if (phase == PHASE_OUTRO)
+ PrepareSpellScript(spell_krick_pursuit_SpellScript);
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- if (!pInstance)
+ if (GetCaster()->GetTypeId() != TYPEID_UNIT)
return;
- events.Update(diff);
- switch(events.ExecuteEvent())
+ Unit* caster = GetCaster();
+ CreatureAI* ickAI = caster->ToCreature()->AI();
+ if (Unit* target = ickAI->SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true))
{
- case EVENT_OUTRO_1:
- {
- DoScriptText(SAY_KRICK_OUTRO_1, me);
- events.ScheduleEvent(EVENT_OUTRO_2, 14000);
- break;
- }
- case EVENT_OUTRO_2:
- {
- Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
- if (pNpcDialog)
- {
- if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
- DoScriptText(SAY_JAYNA_OUTRO_2, pNpcDialog);
- else
- DoScriptText(SAY_SYLVANAS_OUTRO_2, pNpcDialog);
- }
- events.ScheduleEvent(EVENT_OUTRO_3, 8500);
- break;
- }
- case EVENT_OUTRO_3:
- DoScriptText(SAY_KRICK_OUTRO_3, me);
- events.ScheduleEvent(EVENT_OUTRO_4, 12000);
- break;
- case EVENT_OUTRO_4:
- {
- Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
- if (pNpcDialog)
- {
- if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
- DoScriptText(SAY_JAYNA_OUTRO_4, pNpcDialog);
- else
- DoScriptText(SAY_SYLVANAS_OUTRO_4, pNpcDialog);
- }
- events.ScheduleEvent(EVENT_OUTRO_5, 8000);
- break;
- }
- case EVENT_OUTRO_5:
- DoScriptText(SAY_KRICK_OUTRO_5, me);
- events.ScheduleEvent(EVENT_OUTRO_6, 4000);
- break;
- case EVENT_OUTRO_6:
- // TODO spawn Tyrannus at some distance and MovePoint near-by (flying on rimefang)
- // store uiTyrannus
- // Adjust timer so tyrannus has time to come
- uiTyrannus = (pInstance ? pInstance->GetData64(DATA_TYRANNUS) : 0);
- events.ScheduleEvent(EVENT_OUTRO_7, 1);
- break;
- case EVENT_OUTRO_7:
- if (Creature *pTyrannus = me->GetCreature(*me, uiTyrannus))
- DoScriptText(SAY_TYRANNUS_OUTRO_7, pTyrannus);
- events.ScheduleEvent(EVENT_OUTRO_8, 7000);
- break;
- case EVENT_OUTRO_8:
- DoScriptText(SAY_KRICK_OUTRO_8, me);
- // TODO: Tyrannus starts killing Krick.
- // there shall be some visual spell effect
- events.ScheduleEvent(EVENT_OUTRO_9, 6000);
- break;
- case EVENT_OUTRO_9:
- // tyrannus kills krick
- me->SetStandState(UNIT_STAND_STATE_DEAD);
- me->SetHealth(0);
-
- if (Creature *pTyrannus = me->GetCreature(*me, uiTyrannus))
- DoScriptText(SAY_TYRANNUS_OUTRO_9, pTyrannus);
-
- events.ScheduleEvent(EVENT_OUTRO_10, 12000);
- break;
- case EVENT_OUTRO_10:
- {
- Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
- if (pNpcDialog)
- {
- if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
- DoScriptText(SAY_JAYNA_OUTRO_10, pNpcDialog);
- else
- DoScriptText(SAY_SYLVANAS_OUTRO_10, pNpcDialog);
- }
-
- // End of OUTRO. for now...
- events.ScheduleEvent(EVENT_OUTRO_END, 8000);
- break;
- }
- case EVENT_OUTRO_END:
- {
- Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
- if (pNpcDialog)
- pNpcDialog->DisappearAndDie();
-
- me->DisappearAndDie();
- break;
- }
+ DoScriptText(SAY_ICK_CHASE_1, caster, target);
+ caster->AddAura(GetSpellInfo()->Id, target);
+ CAST_AI(boss_ick::boss_ickAI, ickAI)->SetTempThreat(caster->getThreatManager().getThreat(target));
+ caster->AddThreat(target, float(GetEffectValue()));
+ target->AddThreat(caster, float(GetEffectValue()));
}
- return;
}
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_krick_pursuit_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ class spell_krick_pursuit_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_krick_pursuit_AuraScript);
+
+ void HandleExtraEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Creature* creCaster = caster->ToCreature())
+ CAST_AI(boss_ick::boss_ickAI, creCaster->AI())->_ResetThreat(GetTarget());
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_krick_pursuit_AuraScript::HandleExtraEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_krick_pursuit_SpellScript();
}
- };
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_krick_pursuit_AuraScript();
+ }
};
+class spell_krick_pursuit_confusion : public SpellScriptLoader
+{
+ public:
+ spell_krick_pursuit_confusion() : SpellScriptLoader("spell_krick_pursuit_confusion") { }
+
+ class spell_krick_pursuit_confusion_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_krick_pursuit_confusion_AuraScript);
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ GetTarget()->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
+ GetTarget()->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);
+ }
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_krick_pursuit_confusion_AuraScript::OnApply, EFFECT_2, SPELL_AURA_LINKED, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_krick_pursuit_confusion_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_LINKED, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_krick_pursuit_confusion_AuraScript();
+ }
+};
void AddSC_boss_ick()
{
new boss_ick();
new boss_krick();
+ new spell_krick_explosive_barrage();
+ new spell_ick_explosive_barrage();
+ new spell_exploding_orb_hasty_grow();
+ new spell_krick_pursuit();
+ new spell_krick_pursuit_confusion();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index 7c4f93e277c..fd2c5dff9d5 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -18,266 +18,353 @@
#include "ScriptPCH.h"
#include "pit_of_saron.h"
-/*
- * TODO:
- * - Intro/Outro
- * - improve script of Rimefang
- */
-
enum Yells
{
- SAY_AMBUSH_1 = -1658050,
- SAY_AMBUSH_2 = -1658051,
- SAY_GAUNTLET_START = -1658052,
- SAY_INTRO_1 = -1658053,
- SAY_INTRO_2 = -1658054,
-
- SAY_AGGRO = -1658055,
- SAY_SLAY_1 = -1658056,
- SAY_SLAY_2 = -1658057,
- SAY_DEATH = -1658058,
- SAY_MARK_RIMEFANG_1 = -1658059,
- SAY_MARK_RIMEFANG_2 = -1658060,
- SAY_DARK_MIGHT_1 = -1658061,
- SAY_DARK_MIGHT_2 = -1658062,
-
- SAY_GORKUN_OUTRO_1 = -1658063,
- SAY_GORKUN_OUTRO_2 = -1658064,
- SAY_JAYNA_OUTRO_3 = -1658065,
- SAY_SYLVANAS_OUTRO_3 = -1658066,
- SAY_JAYNA_OUTRO_4 = -1658067,
- SAY_SYLVANAS_OUTRO_4 = -1658068,
- SAY_JAYNA_OUTRO_5 = -1658069,
+ SAY_AMBUSH_1 = -1658050,
+ SAY_AMBUSH_2 = -1658051,
+ SAY_GAUNTLET_START = -1658052,
+ SAY_TYRANNUS_INTRO_1 = -1658053,
+ SAY_GORKUN_INTRO_2 = -1658054,
+ SAY_TYRANNUS_INTRO_3 = -1658055,
+
+ SAY_AGGRO = -1658056,
+ SAY_SLAY_1 = -1658057,
+ SAY_SLAY_2 = -1658058,
+ SAY_DEATH = -1658059,
+ SAY_MARK_RIMEFANG_1 = -1658060,
+ SAY_MARK_RIMEFANG_2 = -1658061,
+ SAY_DARK_MIGHT_1 = -1658062,
+ SAY_DARK_MIGHT_2 = -1658063,
+
+ SAY_GORKUN_OUTRO_1 = -1658064,
+ SAY_GORKUN_OUTRO_2 = -1658065,
+ SAY_JAYNA_OUTRO_3 = -1658066,
+ SAY_SYLVANAS_OUTRO_3 = -1658067,
+ SAY_JAYNA_OUTRO_4 = -1658068,
+ SAY_SYLVANAS_OUTRO_4 = -1658069,
+ SAY_JAYNA_OUTRO_5 = -1658070,
};
enum Spells
{
- SPELL_FORCEFUL_SMASH = 69155,
- H_SPELL_FORCEFUL_SMASH = 69627,
- SPELL_OVERLORDS_BRAND = 69172,
- SPELL_OVERLORD_BRAND_DAMAGE = 69189,
- SPELL_OVERLORD_BRAND_HEAL = 69190,
- SPELL_DARK_MIGHT = 69167,
- H_SPELL_DARK_MIGHT = 69629,
- SPELL_HOARFROST = 69246,
- SPELL_MARK_OF_RIMEFANG = 69275,
- SPELL_ICY_BLAST = 69233,
- H_SPELL_ICY_BLAST = 69646,
- SPELL_ICY_BLAST_2 = 69238,
- H_SPELL_ICY_BLAST_2 = 69628,
+ SPELL_OVERLORD_BRAND = 69172,
+ SPELL_OVERLORD_BRAND_HEAL = 69190,
+ SPELL_OVERLORD_BRAND_DAMAGE = 69189,
+ SPELL_FORCEFUL_SMASH = 69155,
+ SPELL_UNHOLY_POWER = 69167,
+ SPELL_MARK_OF_RIMEFANG = 69275,
+ SPELL_HOARFROST = 69246,
+
+ SPELL_ICY_BLAST = 69232,
+ SPELL_ICY_BLAST_AURA = 69238,
+
+ SPELL_EJECT_ALL_PASSENGERS = 50630,
+ SPELL_FULL_HEAL = 43979,
};
enum Events
{
- EVENT_NONE,
- EVENT_FORCEFUL_SMASH,
- EVENT_OVERLORDS_BRAND,
- EVENT_DARK_MIGHT,
+ EVENT_OVERLORD_BRAND = 1,
+ EVENT_FORCEFUL_SMASH = 2,
+ EVENT_UNHOLY_POWER = 3,
+ EVENT_MARK_OF_RIMEFANG = 4,
// Rimefang
- EVENT_MARK_OF_RIMEFANG,
- EVENT_HOARFROST,
- EVENT_ICY_BLAST,
- EVENT_ICY_BLAST_2,
+ EVENT_MOVE_NEXT = 5,
+ EVENT_HOARFROST = 6,
+ EVENT_ICY_BLAST = 7,
+
+ EVENT_INTRO_1 = 8,
+ EVENT_INTRO_2 = 9,
+ EVENT_INTRO_3 = 10,
+ EVENT_COMBAT_START = 11,
};
-enum Misc
+enum Phases
{
- SEAT_TYRANNUS = 0
+ PHASE_NONE = 0,
+ PHASE_INTRO = 1,
+ PHASE_COMBAT = 2,
+ PHASE_OUTRO = 3,
};
-class boss_tyrannus : public CreatureScript
+enum Actions
{
-public:
- boss_tyrannus() : CreatureScript("boss_tyrannus") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_tyrannusAI(pCreature);
- }
+ ACTION_START_INTRO = 1,
+ ACTION_START_RIMEFANG = 2,
+ ACTION_START_OUTRO = 3,
+};
- struct boss_tyrannusAI : public ScriptedAI
- {
- boss_tyrannusAI(Creature *c) : ScriptedAI(c)
- {
- pInstance = c->GetInstanceScript();
- }
+#define GUID_HOARFROST 1
- InstanceScript* pInstance;
- EventMap events;
+static const Position rimefangPos[10] =
+{
+ {1017.299f, 168.9740f, 642.9259f, 0.000000f},
+ {1047.868f, 126.4931f, 665.0453f, 0.000000f},
+ {1069.828f, 138.3837f, 665.0453f, 0.000000f},
+ {1063.042f, 164.5174f, 665.0453f, 0.000000f},
+ {1031.158f, 195.1441f, 665.0453f, 0.000000f},
+ {1019.087f, 197.8038f, 665.0453f, 0.000000f},
+ {967.6233f, 168.9670f, 665.0453f, 0.000000f},
+ {969.1198f, 140.4722f, 665.0453f, 0.000000f},
+ {986.7153f, 141.6424f, 665.0453f, 0.000000f},
+ {1012.601f, 142.4965f, 665.0453f, 0.000000f},
+};
- void Reset()
- {
- events.Reset();
+static const Position miscPos = {1018.376f, 167.2495f, 628.2811f, 0.000000f}; //tyrannus combat start position
- if (pInstance)
- pInstance->SetData(DATA_TYRANNUS_EVENT, NOT_STARTED);
- }
+class boss_tyrannus : public CreatureScript
+{
+ public:
+ boss_tyrannus() : CreatureScript("boss_tyrannus") { }
- Creature* GetRimefang()
+ struct boss_tyrannusAI : public BossAI
{
- return me->GetCreature(*me, pInstance->GetData64(DATA_RIMEFANG));
- }
+ boss_tyrannusAI(Creature* creature) : BossAI(creature, DATA_TYRANNUS)
+ {
+ }
- void EnterCombat(Unit* /*who*/)
- {
- DoScriptText(SAY_AGGRO, me);
- me->ExitVehicle();
+ void InitializeAI()
+ {
+ if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != GetScriptId(PoSScriptName))
+ me->IsAIEnabled = false;
+ else if (!me->isDead())
+ Reset();
+ }
- // restore health if any damage done during intro
- me->SetFullHealth();
+ void Reset()
+ {
+ events.Reset();
+ events.SetPhase(PHASE_NONE);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ instance->SetBossState(DATA_TYRANNUS, NOT_STARTED);
+ }
- if (pInstance)
- pInstance->SetData(DATA_TYRANNUS_EVENT, IN_PROGRESS);
+ Creature* GetRimefang()
+ {
+ return ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RIMEFANG));
+ }
- events.ScheduleEvent(EVENT_FORCEFUL_SMASH, 10000);
- events.ScheduleEvent(EVENT_OVERLORDS_BRAND, 35000);
- events.ScheduleEvent(EVENT_DARK_MIGHT, 40000);
- }
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ }
- void KilledUnit(Unit * /*victim*/)
- {
- DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
- }
+ void AttackStart(Unit* victim)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
- void JustDied(Unit* /*killer*/)
- {
- DoScriptText(SAY_DEATH, me);
+ if (victim && me->Attack(victim, true) && !(events.GetPhaseMask() & (1 << PHASE_INTRO)))
+ me->GetMotionMaster()->MoveChase(victim);
+ }
- if (pInstance)
+ void EnterEvadeMode()
{
- pInstance->SetData(DATA_TYRANNUS_EVENT, DONE);
- if (Creature* pRimefang = GetRimefang())
- pRimefang->ForcedDespawn();
- }
- }
+ instance->SetBossState(DATA_TYRANNUS, FAIL);
+ if (Creature* rimefang = GetRimefang())
+ rimefang->AI()->EnterEvadeMode();
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ me->ForcedDespawn();
+ }
- events.Update(diff);
+ void KilledUnit(Unit * victim)
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2), me);
+ }
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ instance->SetBossState(DATA_TYRANNUS, DONE);
+ }
- while (uint32 eventId = events.ExecuteEvent())
+ void DoAction(const int32 actionId)
{
- switch(eventId)
+ if (actionId == ACTION_START_INTRO)
{
- case EVENT_FORCEFUL_SMASH:
- DoCast(me->getVictim(), SPELL_FORCEFUL_SMASH);
- events.ScheduleEvent(EVENT_FORCEFUL_SMASH, 10000);
- return;
- case EVENT_OVERLORDS_BRAND:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_OVERLORDS_BRAND);
- events.ScheduleEvent(EVENT_OVERLORDS_BRAND, 45000);
- return;
- case EVENT_DARK_MIGHT:
- DoScriptText(SAY_DARK_MIGHT_1, me);
- DoScriptText(SAY_DARK_MIGHT_2, me);
- DoCast(me, SPELL_DARK_MIGHT);
- events.ScheduleEvent(EVENT_DARK_MIGHT, 60000);
- return;
+ DoScriptText(SAY_TYRANNUS_INTRO_1, me);
+ events.SetPhase(PHASE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO_1, 14000, 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO_2, 22000, 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO_3, 34000, 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_COMBAT_START, 36000, 0, PHASE_INTRO);
+ instance->SetBossState(DATA_TYRANNUS, IN_PROGRESS);
}
}
- DoMeleeAttackIfReady();
- }
- };
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() && !(events.GetPhaseMask() & (1 << PHASE_INTRO)))
+ return;
-};
+ events.Update(diff);
-class boss_rimefang : public CreatureScript
-{
-public:
- boss_rimefang() : CreatureScript("boss_rimefang") { }
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_INTRO_1:
+ //DoScriptText(SAY_GORKUN_INTRO_2, pGorkunOrVictus);
+ break;
+ case EVENT_INTRO_2:
+ DoScriptText(SAY_TYRANNUS_INTRO_3, me);
+ break;
+ case EVENT_INTRO_3:
+ me->ExitVehicle();
+ me->GetMotionMaster()->MovePoint(0, miscPos);
+ break;
+ case EVENT_COMBAT_START:
+ if (Creature* rimefang = me->GetCreature(*me, instance->GetData64(DATA_RIMEFANG)))
+ rimefang->AI()->DoAction(ACTION_START_RIMEFANG); //set rimefang also infight
+
+ events.SetPhase(PHASE_COMBAT);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoCast(me, SPELL_FULL_HEAL);
+ me->SetInCombatWithZone();
+ events.ScheduleEvent(EVENT_OVERLORD_BRAND, urand(5000, 7000));
+ events.ScheduleEvent(EVENT_FORCEFUL_SMASH, urand(14000, 16000));
+ events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, urand(25000, 27000));
+ break;
+ case EVENT_OVERLORD_BRAND:
+ if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ DoCast(target, SPELL_OVERLORD_BRAND);
+ events.ScheduleEvent(EVENT_OVERLORD_BRAND, urand(11000, 12000));
+ break;
+ case EVENT_FORCEFUL_SMASH:
+ DoCastVictim(SPELL_FORCEFUL_SMASH);
+ events.ScheduleEvent(EVENT_UNHOLY_POWER, 1000);
+ break;
+ case EVENT_UNHOLY_POWER:
+ DoScriptText(SAY_DARK_MIGHT_1, me);
+ DoScriptText(SAY_DARK_MIGHT_2, me);
+ DoCast(me, SPELL_UNHOLY_POWER);
+ events.ScheduleEvent(EVENT_FORCEFUL_SMASH, urand(40000, 48000));
+ break;
+ case EVENT_MARK_OF_RIMEFANG:
+ DoScriptText(SAY_MARK_RIMEFANG_1, me);
+ DoScriptText(SAY_MARK_RIMEFANG_2, me);
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_MARK_OF_RIMEFANG);
+ events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, urand(24000, 26000));
+ break;
+ }
+ }
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new boss_rimefangAI(pCreature);
- }
+ DoMeleeAttackIfReady();
+ }
+ };
- struct boss_rimefangAI : public ScriptedAI
- {
- boss_rimefangAI(Creature *c) : ScriptedAI(c)
+ CreatureAI* GetAI(Creature* creature) const
{
- pInstance = c->GetInstanceScript();
+ return new boss_tyrannusAI(creature);
}
+};
- InstanceScript* pInstance;
- EventMap events;
+class boss_rimefang : public CreatureScript
+{
+ public:
+ boss_rimefang() : CreatureScript("boss_rimefang") { }
- void Reset()
+ struct boss_rimefangAI : public ScriptedAI
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- me->InterruptSpell(CURRENT_GENERIC_SPELL);
- me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- events.Reset();
- }
+ boss_rimefangAI(Creature* creature) : ScriptedAI(creature), _vehicle(creature->GetVehicleKit())
+ {
+ ASSERT(_vehicle);
+ }
- void EnterCombat(Unit* /*who*/)
- {
- me->InterruptSpell(CURRENT_GENERIC_SPELL);
- me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, 25000);
- events.ScheduleEvent(EVENT_ICY_BLAST, 35000);
- }
+ void Reset()
+ {
+ _events.Reset();
+ _events.SetPhase(PHASE_NONE);
+ _currentWaypoint = 0;
+ _hoarfrostTargetGUID = 0;
+ me->SetFlying(true);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void JustReachedHome()
+ {
+ _vehicle->InstallAllAccessories(me->GetEntry());
+ }
- events.Update(diff);
+ void DoAction(const int32 actionId)
+ {
+ if (actionId == ACTION_START_RIMEFANG)
+ {
+ _events.SetPhase(PHASE_COMBAT);
+ me->SetInCombatWithZone();
+ _events.ScheduleEvent(EVENT_MOVE_NEXT, 500, 0, PHASE_COMBAT);
+ _events.ScheduleEvent(EVENT_ICY_BLAST, 15000, 0, PHASE_COMBAT);
+ }
+ }
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ void SetGUID(const uint64& guid, int32 type)
+ {
+ if (type == GUID_HOARFROST)
+ {
+ _hoarfrostTargetGUID = guid;
+ _events.ScheduleEvent(EVENT_HOARFROST, 1000);
+ }
+ }
- while (uint32 eventId = events.ExecuteEvent())
+ void UpdateAI(const uint32 diff)
{
- switch(eventId)
+ if (!UpdateVictim() && !(_events.GetPhaseMask() & (1 << PHASE_COMBAT)))
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
{
- case EVENT_MARK_OF_RIMEFANG:
- DoScriptText(SAY_MARK_RIMEFANG_1, me);
- DoScriptText(SAY_MARK_RIMEFANG_2, me);
-
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_MARK_OF_RIMEFANG);
- events.ScheduleEvent(EVENT_HOARFROST, 5000);
- return;
- case EVENT_HOARFROST:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_HOARFROST);
- events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, 20000);
- return;
- case EVENT_ICY_BLAST:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_ICY_BLAST);
- events.ScheduleEvent(EVENT_ICY_BLAST_2, 5000);
- return;
- case EVENT_ICY_BLAST_2:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget->getVictim(), SPELL_ICY_BLAST_2);
- events.ScheduleEvent(EVENT_ICY_BLAST, 30000);
- return;
+ switch (eventId)
+ {
+ case EVENT_MOVE_NEXT:
+ if (_currentWaypoint >= 10 || _currentWaypoint == 0)
+ _currentWaypoint = 1;
+ me->GetMotionMaster()->MovePoint(0, rimefangPos[_currentWaypoint]);
+ ++_currentWaypoint;
+ _events.ScheduleEvent(EVENT_MOVE_NEXT, 2000, 0, PHASE_COMBAT);
+ break;
+ case EVENT_ICY_BLAST:
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_ICY_BLAST);
+ _events.ScheduleEvent(EVENT_ICY_BLAST, 15000, 0, PHASE_COMBAT);
+ break;
+ case EVENT_HOARFROST:
+ if (Unit* target = me->GetUnit(*me, _hoarfrostTargetGUID))
+ {
+ DoCast(target, SPELL_HOARFROST);
+ _hoarfrostTargetGUID = 0;
+ }
+ break;
+ default:
+ break;
+ }
}
}
- }
- };
+ private:
+ Vehicle* _vehicle;
+ uint64 _hoarfrostTargetGUID;
+ EventMap _events;
+ uint8 _currentWaypoint;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_rimefangAI(creature);
+ }
};
class player_overlord_brandAI : public PlayerAI
{
public:
- player_overlord_brandAI(Player* pPlayer) : PlayerAI(pPlayer)
+ player_overlord_brandAI(Player* player) : PlayerAI(player)
{
tyrannus = NULL;
}
@@ -291,7 +378,8 @@ class player_overlord_brandAI : public PlayerAI
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/)
{
- me->CastCustomSpell(SPELL_OVERLORD_BRAND_DAMAGE, SPELLVALUE_BASE_POINT0, damage, tyrannus->getVictim(), true, NULL, NULL, tyrannus->GetGUID());
+ if (tyrannus->getVictim())
+ me->CastCustomSpell(SPELL_OVERLORD_BRAND_DAMAGE, SPELLVALUE_BASE_POINT0, damage, tyrannus->getVictim(), true, NULL, NULL, tyrannus->GetGUID());
}
void HealDone(Unit* /*target*/, uint32& addHealth)
@@ -299,7 +387,7 @@ class player_overlord_brandAI : public PlayerAI
me->CastCustomSpell(SPELL_OVERLORD_BRAND_HEAL, SPELLVALUE_BASE_POINT0, int32(addHealth*5.5f), tyrannus, true, NULL, NULL, tyrannus->GetGUID());
}
- void UpdateAI(const uint32 /*diff*/) { }
+ void UpdateAI(const uint32 diff) { }
private:
Creature* tyrannus;
@@ -352,9 +440,64 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
}
};
+class spell_tyrannus_mark_of_rimefang : public SpellScriptLoader
+{
+ public:
+ spell_tyrannus_mark_of_rimefang() : SpellScriptLoader("spell_tyrannus_mark_of_rimefang") { }
+
+ class spell_tyrannus_mark_of_rimefang_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_tyrannus_mark_of_rimefang_AuraScript);
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (!GetCaster() || GetCaster()->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ if (Creature* rimefang = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_RIMEFANG)))
+ rimefang->AI()->SetGUID(GetTarget()->GetGUID(), GUID_HOARFROST);
+ }
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_tyrannus_mark_of_rimefang_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_tyrannus_mark_of_rimefang_AuraScript();
+ }
+};
+
+class at_tyrannus_event_starter : public AreaTriggerScript
+{
+ public:
+ at_tyrannus_event_starter() : AreaTriggerScript("at_tyrannus_event_starter") { }
+
+ bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/)
+ {
+ InstanceScript* instance = player->GetInstanceScript();
+ if (player->isGameMaster() || !instance)
+ return false;
+
+ if (instance->GetBossState(DATA_TYRANNUS) != IN_PROGRESS || instance->GetBossState(DATA_TYRANNUS) != DONE)
+ if (Creature* tyrannus = Unit::GetCreature(*player, instance->GetData64(DATA_TYRANNUS)))
+ {
+ tyrannus->AI()->DoAction(ACTION_START_INTRO);
+ return true;
+ }
+
+ return false;
+ }
+};
+
void AddSC_boss_tyrannus()
{
new boss_tyrannus();
new boss_rimefang();
new spell_tyrannus_overlord_brand();
+ new spell_tyrannus_mark_of_rimefang();
+ new at_tyrannus_event_starter();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
index 12b7e1c97c1..c26a62d69d5 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
@@ -18,223 +18,211 @@
#include "ScriptPCH.h"
#include "pit_of_saron.h"
-#define MAX_ENCOUNTER 3
-
-/* Pit of Saron encounters:
-0- Forgemaster Garfrost
-1- Krick and Ick
-2- Scourgelord Tyrannus
-*/
-
class instance_pit_of_saron : public InstanceMapScript
{
-public:
- instance_pit_of_saron() : InstanceMapScript("instance_pit_of_saron", 658) { }
-
- InstanceScript* GetInstanceScript(InstanceMap* pMap) const
- {
- return new instance_pit_of_saron_InstanceMapScript(pMap);
- }
-
- struct instance_pit_of_saron_InstanceMapScript : public InstanceScript
- {
- instance_pit_of_saron_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {};
-
- uint64 uiKrick;
- uint64 uiIck;
- uint64 uiGarfrost;
- uint64 uiTyrannus;
- uint64 uiRimefang;
-
- uint64 uiJainaOrSylvanas1;
- uint64 uiJainaOrSylvanas2;
-
- uint32 uiTeamInInstance;
- uint32 uiEncounter[MAX_ENCOUNTER];
-
- void Initialize()
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- uiEncounter[i] = NOT_STARTED;
-
- uiGarfrost = 0;
- uiKrick = 0;
- uiIck = 0;
- uiTyrannus = 0;
- }
+ public:
+ instance_pit_of_saron() : InstanceMapScript(PoSScriptName, 658) { }
- bool IsEncounterInProgress() const
+ struct instance_pit_of_saron_InstanceScript : public InstanceScript
{
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (uiEncounter[i] == IN_PROGRESS)
- return true;
-
- return false;
- }
-
- void OnCreatureCreate(Creature* creature)
- {
- Map::PlayerList const &players = instance->GetPlayers();
-
- if (!players.isEmpty())
+ instance_pit_of_saron_InstanceScript(Map* map) : InstanceScript(map)
{
- if (Player* pPlayer = players.begin()->getSource())
- uiTeamInInstance = pPlayer->GetTeam();
+ SetBossNumber(MAX_ENCOUNTER);
+ _garfrostGUID = 0;
+ _krickGUID = 0;
+ _ickGUID = 0;
+ _tyrannusGUID = 0;
+ _rimefangGUID = 0;
+ _jainaOrSylvanas1GUID = 0;
+ _jainaOrSylvanas2GUID = 0;
+ _teamInInstance = 0;
}
- switch(creature->GetEntry())
+ void OnCreatureCreate(Creature* creature, bool /*add*/)
{
- case CREATURE_KRICK:
- uiKrick = creature->GetGUID();
- break;
-
- case CREATURE_ICK:
- uiIck = creature->GetGUID();
- break;
-
- case CREATURE_GARFROST:
- uiGarfrost = creature->GetGUID();
- break;
-
- case CREATURE_TYRANNUS:
- uiTyrannus = creature->GetGUID();
- break;
-
- case CREATURE_RIMEFANG:
- uiRimefang = creature->GetGUID();
- break;
-
- case NPC_SYLVANAS_PART1:
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_JAINA_PART1, ALLIANCE);
- uiJainaOrSylvanas1 = creature->GetGUID();
- break;
- case NPC_SYLVANAS_PART2:
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_JAINA_PART2, ALLIANCE);
- uiJainaOrSylvanas2 = creature->GetGUID();
- break;
- case NPC_KILARA:
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_ELANDRA, ALLIANCE);
- break;
- case NPC_KORALEN:
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_KORLAEN, ALLIANCE);
- break;
- case NPC_CHAMPION_1_HORDE:
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_CHAMPION_1_ALLIANCE, ALLIANCE);
- break;
- case NPC_CHAMPION_2_HORDE:
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
- break;
- case NPC_CHAMPION_3_HORDE: // No 3rd set for Alliance?
- if (uiTeamInInstance == ALLIANCE)
- creature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
- break;
+ if (!_teamInInstance)
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+ if (!players.isEmpty())
+ if (Player* player = players.begin()->getSource())
+ _teamInInstance = player->GetTeam();
+ }
+
+ switch (creature->GetEntry())
+ {
+ case NPC_GARFROST:
+ _garfrostGUID = creature->GetGUID();
+ break;
+ case NPC_KRICK:
+ _krickGUID = creature->GetGUID();
+ break;
+ case NPC_ICK:
+ _ickGUID = creature->GetGUID();
+ break;
+ case NPC_TYRANNUS:
+ _tyrannusGUID = creature->GetGUID();
+ break;
+ case NPC_RIMEFANG:
+ _rimefangGUID = creature->GetGUID();
+ break;
+ case NPC_TYRANNUS_EVENTS:
+ _tyrannusEventGUID = creature->GetGUID();
+ break;
+ case NPC_SYLVANAS_PART1:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_JAINA_PART1, ALLIANCE);
+ _jainaOrSylvanas1GUID = creature->GetGUID();
+ break;
+ case NPC_SYLVANAS_PART2:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_JAINA_PART2, ALLIANCE);
+ _jainaOrSylvanas2GUID = creature->GetGUID();
+ break;
+ case NPC_KILARA:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ELANDRA, ALLIANCE);
+ break;
+ case NPC_KORALEN:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_KORLAEN, ALLIANCE);
+ break;
+ case NPC_CHAMPION_1_HORDE:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_CHAMPION_1_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_CHAMPION_2_HORDE:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_CHAMPION_3_HORDE: // No 3rd set for Alliance?
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_HORDE_SLAVE_1:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ALLIANCE_SLAVE_1, ALLIANCE);
+ break;
+ case NPC_HORDE_SLAVE_2:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ALLIANCE_SLAVE_2, ALLIANCE);
+ break;
+ case NPC_HORDE_SLAVE_3:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ALLIANCE_SLAVE_3, ALLIANCE);
+ break;
+ case NPC_HORDE_SLAVE_4:
+ if (_teamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ALLIANCE_SLAVE_4, ALLIANCE);
+ break;
+ default:
+ break;
+ }
}
- }
- uint64 GetData64(uint32 identifier)
- {
- switch(identifier)
+ uint32 GetData(uint32 type)
{
- case DATA_GARFROST: return uiGarfrost;
- case DATA_KRICK: return uiKrick;
- case DATA_ICK: return uiIck;
- case DATA_TYRANNUS: return uiTyrannus;
- case DATA_RIMEFANG: return uiRimefang;
-
- case DATA_JAINA_SYLVANAS_1: return uiJainaOrSylvanas1;
- case DATA_JAINA_SYLVANAS_2: return uiJainaOrSylvanas2;
+ switch (type)
+ {
+ case DATA_TEAM_IN_INSTANCE:
+ return _teamInInstance;
+ default:
+ break;
+ }
+
+ return 0;
}
- return 0;
- }
-
- void SetData(uint32 type, uint32 data)
- {
- switch(type)
+ uint64 GetData64(uint32 type)
{
- case DATA_GARFROST_EVENT:
- uiEncounter[0] = data;
- break;
- case DATA_TYRANNUS_EVENT:
- uiEncounter[1] = data;
- break;
- case DATA_KRICKANDICK_EVENT:
- uiEncounter[2] = data;
- break;
+ switch (type)
+ {
+ case DATA_GARFROST:
+ return _garfrostGUID;
+ case DATA_KRICK:
+ return _krickGUID;
+ case DATA_ICK:
+ return _ickGUID;
+ case DATA_TYRANNUS:
+ return _tyrannusGUID;
+ case DATA_RIMEFANG:
+ return _rimefangGUID;
+ case DATA_TYRANNUS_EVENT:
+ return _tyrannusEventGUID;
+ case DATA_JAINA_SYLVANAS_1:
+ return _jainaOrSylvanas1GUID;
+ case DATA_JAINA_SYLVANAS_2:
+ return _jainaOrSylvanas2GUID;
+ default:
+ break;
+ }
+
+ return 0;
}
- if (data == DONE)
- SaveToDB();
- }
-
- uint32 GetData(uint32 type)
- {
- switch(type)
+ std::string GetSaveData()
{
- case DATA_GARFROST_EVENT: return uiEncounter[0];
- case DATA_TYRANNUS_EVENT: return uiEncounter[1];
- case DATA_KRICKANDICK_EVENT: return uiEncounter[2];
- }
+ OUT_SAVE_INST_DATA;
- return 0;
- }
-
- std::string GetSaveData()
- {
- OUT_SAVE_INST_DATA;
-
- std::string str_data;
+ std::ostringstream saveStream;
+ saveStream << "P S " << GetBossSaveData();
- std::ostringstream saveStream;
- saveStream << "P S " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2];
-
- str_data = saveStream.str();
-
- OUT_SAVE_INST_DATA_COMPLETE;
- return str_data;
- }
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
- void Load(const char* in)
- {
- if (!in)
+ void Load(const char* in)
{
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2;
+
+ if (dataHead1 == 'P' && dataHead2 == 'S')
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+
+ SetBossState(i, EncounterState(tmpState));
+ }
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
}
- OUT_LOAD_INST_DATA(in);
-
- char dataHead1, dataHead2;
- uint16 data0, data1, data2;
-
- std::istringstream loadStream(in);
- loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
-
- if (dataHead1 == 'P' && dataHead2 == 'S')
- {
- uiEncounter[0] = data0;
- uiEncounter[1] = data1;
- uiEncounter[2] = data2;
+ private:
+ uint64 _garfrostGUID;
+ uint64 _krickGUID;
+ uint64 _ickGUID;
+ uint64 _tyrannusGUID;
+ uint64 _rimefangGUID;
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (uiEncounter[i] == IN_PROGRESS)
- uiEncounter[i] = NOT_STARTED;
+ uint64 _tyrannusEventGUID;
+ uint64 _jainaOrSylvanas1GUID;
+ uint64 _jainaOrSylvanas2GUID;
- } else OUT_LOAD_INST_DATA_FAIL;
+ uint32 _teamInInstance;
+ };
- 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();
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp
index 777f6042830..c5abad82c4b 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.cpp
@@ -18,1134 +18,267 @@
#include "ScriptPCH.h"
#include "pit_of_saron.h"
-/***************************************SPELLS*************************************/
-// Ymirjar Wrathbringer
-#define SPELL_BLIGHT DUNGEON_MODE(69603,70285)
-
-//Ymirjar Skycaller
-#define SPELL_FROSTBLADE 70291
-#define SPELL_GLACIAL_STRIKE 70292
-
-//Ymirjar Flamebearer
-#define SPELL_FIREBALL DUNGEON_MODE(69583,70282)
-#define SPELL_HELLFIRE DUNGEON_MODE(69586,70283)
-#define SPELL_TACTICAL_BLINK 69584
-
-//Ymirjar Deathbringer
-#define SPELL_EMPOWERED_SHADOW_BOLT DUNGEON_MODE(69528,70281)
-#define SPELL_SUMMON_UNDEAD 69516
-
-//Wrathbone Laborer
-#define SPELL_BLINDING_DIRT 70302
-#define SPELL_PUNCTURE_WOUND DUNGEON_MODE(70278,70279)
-#define SPELL_SHOVELLED DUNGEON_MODE(69572,70280)
-
-//Wrathbone Coldwraith
-#define SPELL_FREEZING_CIRCLE DUNGEON_MODE(69574,70276)
-#define SPELL_FROSTBOLT DUNGEON_MODE(69573,70277)
-
-//Stonespine Gargoyle
-#define SPELL_GARGOYLE_STRIKE DUNGEON_MODE(69520,70275)
-#define SPELL_STONEFORM 69575
-
-// Plagueborn Horror
-#define SPELL_BLIGHT_BOMB 69582
-#define SPELL_PUSTULANT_FLESH DUNGEON_MODE(69581,70273)
-#define SPELL_TOXIC_WASTE 70274
-
-//Iceborn Proto-Drake
-#define SPELL_FROST_BREATH DUNGEON_MODE(69527,70272)
-
-//Hungering Ghoul
-#define SPELL_DEVOUR_FLESH 70393
-
-//Fallen Warrior
-#define SPELL_ARCING_SLICE 69579
-#define SPELL_DEMORALIZING_SHOUT 61044
-#define SPELL_SHIELD_BLOCK 69580
-
-//Deathwhisper Torturer
-#define SPELL_BLACK_BRAND 70392
-#define SPELL_CURSE_OF_AGONY 70391
-
-//Deathwhisper Shadowcaster
-#define SPELL_SHADOW_BOLT DUNGEON_MODE(70386,70387)
-
-//Deathwhisper Necrolyte
-#define SPELL_CONVERSION_BEAM DUNGEON_MODE(69578,70269)
-#define SPELL_SHADOW_BOLT_2 DUNGEON_MODE(69577,70270)
-
-//Wrathbone Sorcerer
-#define SPELL_SHADOW_BOLT_3 DUNGEON_MODE(70386,70387)
-
-//Geist Ambusher
-#define SPELL_LEAPING_FACE_MAUL DUNGEON_MODE(69504,70271)
+enum eSpells
+{
+ SPELL_FIREBALL = 69583, //Ymirjar Flamebearer
+ SPELL_HELLFIRE = 69586,
+ SPELL_TACTICAL_BLINK = 69584,
+ SPELL_FROST_BREATH = 69527, //Iceborn Proto-Drake
+ SPELL_BLINDING_DIRT = 70302, //Wrathbone Laborer
+ SPELL_PUNCTURE_WOUND = 70278,
+ SPELL_SHOVELLED = 69572,
+ SPELL_LEAPING_FACE_MAUL = 69504, // Geist Ambusher
+};
-/****************************************EVENTS************************************/
enum eEvents
{
- EVENT_NONE,
-
- // Ymirjar Wrathbringer
- EVENT_BLIGHT,
-
- // Ymirjar Skycaller
- EVENT_FROSTBLADE,
- EVENT_GLACIAL_STRIKE,
-
// Ymirjar Flamebearer
- EVENT_FIREBALL,
- EVENT_HELLFIRE,
- EVENT_TACTICAL_BLINK,
-
- //Ymirjar Deathbringer
- EVENT_EMPOWERED_SHADOW_BOLT,
- EVENT_SUMMON_UNDEAD,
+ EVENT_FIREBALL = 1,
+ EVENT_TACTICAL_BLINK = 2,
//Wrathbone Laborer
- EVENT_BLINDING_DIRT,
- EVENT_PUNCTURE_WOUND,
- EVENT_SHOVELLED,
-
- //Wrathbone Coldwraith
- EVENT_FREEZING_CIRCLE,
- EVENT_FROSTBOLT,
-
- //Stonespine Gargoyle
- EVENT_GARGOYLE_STRIKE,
- EVENT_STONEFORM,
-
- //Plagueborn Horror
- EVENT_BLIGHT_BOMB,
- EVENT_PUSTULANT_FLESH,
- EVENT_TOXIC_WASTE,
-
- //Iceborn Proto-Drake
- EVENT_FROST_BREATH,
-
- //Hungering Ghoul
- EVENT_DEVOUR_FLESH,
-
- //Fallen Warrior
- EVENT_ARCING_SLICE,
- EVENT_DEMORALIZING_SHOUT,
- EVENT_SHIELD_BLOCK,
-
- //Deathwhisper Torturer
- EVENT_BLACK_BRAND,
- EVENT_CURSE_OF_AGONY,
-
- //Deathwhisper Shadowcaster
- EVENT_SHADOW_BOLT,
-
- //Deathwhisper Necrolyte
- EVENT_CONVERSION_BEAM,
- EVENT_SHADOW_BOLT_2,
-
- EVENT_SHADOW_BOLT_3,
-
- //Geist Ambusher
- EVENT_LEAPING_FACE_MAUL,
+ EVENT_BLINDING_DIRT = 3,
+ EVENT_PUNCTURE_WOUND = 4,
+ EVENT_SHOVELLED = 5,
};
-/****************************************AI****************************************/
-
-class mob_ymirjar_wrathbringer : public CreatureScript
+class mob_ymirjar_flamebearer : public CreatureScript
{
-public:
- mob_ymirjar_wrathbringer() : CreatureScript("mob_ymirjar_wrathbringer") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_ymirjar_wrathbringerAI(pCreature);
- }
-
- struct mob_ymirjar_wrathbringerAI : public ScriptedAI
- {
- mob_ymirjar_wrathbringerAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_BLIGHT, 7000);
- }
+ public:
+ mob_ymirjar_flamebearer() : CreatureScript("mob_ymirjar_flamebearer") { }
- void UpdateAI(const uint32 diff)
+ struct mob_ymirjar_flamebearerAI: public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ mob_ymirjar_flamebearerAI(Creature* creature) : ScriptedAI(creature)
{
- switch(eventId)
- {
- case EVENT_BLIGHT:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_BLIGHT);
- events.RescheduleEvent(EVENT_BLIGHT, 8000);
- return;
- }
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_ymirjar_skycaller : public CreatureScript
-{
-public:
- mob_ymirjar_skycaller() : CreatureScript("mob_ymirjar_skycaller") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_ymirjar_skyCallerAI(pCreature);
- }
-
- struct mob_ymirjar_skyCallerAI: public ScriptedAI
- {
- mob_ymirjar_skyCallerAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_FROSTBLADE, 1);
- events.ScheduleEvent(EVENT_GLACIAL_STRIKE, 8000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void Reset()
{
- switch(eventId)
- {
- case EVENT_GLACIAL_STRIKE:
- DoCast(me->getVictim(), SPELL_GLACIAL_STRIKE);
- events.RescheduleEvent(EVENT_GLACIAL_STRIKE, 8000);
- return;
- case EVENT_FROSTBLADE:
- DoCast(me, SPELL_FROSTBLADE);
- events.CancelEvent(EVENT_FROSTBLADE);
- return;
- }
+ _events.Reset();
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_ymirjar_flamebearer : public CreatureScript
-{
-public:
- mob_ymirjar_flamebearer() : CreatureScript("mob_ymirjar_flamebearer") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_ymirjar_flamebearerAI(pCreature);
- }
-
- struct mob_ymirjar_flamebearerAI: public ScriptedAI
- {
- mob_ymirjar_flamebearerAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_FIREBALL, 4000);
- events.ScheduleEvent(EVENT_HELLFIRE, 8000);
- events.ScheduleEvent(EVENT_TACTICAL_BLINK, 15000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void EnterCombat(Unit* /*who*/)
{
- switch(eventId)
- {
- case EVENT_FIREBALL:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_FIREBALL);
- events.RescheduleEvent(EVENT_FIREBALL, 5000);
- return;
- case EVENT_HELLFIRE:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_HELLFIRE);
- events.RescheduleEvent(EVENT_HELLFIRE, 10000);
- return;
- case EVENT_TACTICAL_BLINK:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_TACTICAL_BLINK);
- events.RescheduleEvent(EVENT_TACTICAL_BLINK, 12000);
- return;
- }
+ _events.ScheduleEvent(EVENT_FIREBALL, 4000);
+ _events.ScheduleEvent(EVENT_TACTICAL_BLINK, 15000);
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_ymirjar_deathbringer : public CreatureScript
-{
-public:
- mob_ymirjar_deathbringer() : CreatureScript("mob_ymirjar_deathbringer") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_ymirjar_deathbringerAI(pCreature);
- }
-
- struct mob_ymirjar_deathbringerAI: public ScriptedAI
- {
- mob_ymirjar_deathbringerAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_EMPOWERED_SHADOW_BOLT, 8000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- events.Update(diff);
+ _events.Update(diff);
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch(eventId)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- case EVENT_EMPOWERED_SHADOW_BOLT:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_EMPOWERED_SHADOW_BOLT);
- events.RescheduleEvent(EVENT_EMPOWERED_SHADOW_BOLT, 8000);
- return;
+ switch (eventId)
+ {
+ case EVENT_FIREBALL:
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_FIREBALL);
+ _events.RescheduleEvent(EVENT_FIREBALL, 5000);
+ break;
+ case EVENT_TACTICAL_BLINK:
+ if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_TACTICAL_BLINK);
+ DoCast(me, SPELL_HELLFIRE);
+ _events.RescheduleEvent(EVENT_TACTICAL_BLINK, 12000);
+ break;
+ default:
+ break;
+ }
}
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_wrathbone_laborer : public CreatureScript
-{
-public:
- mob_wrathbone_laborer() : CreatureScript("mob_wrathbone_laborer") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_wrathbone_laborerAI(pCreature);
- }
-
- struct mob_wrathbone_laborerAI: public ScriptedAI
- {
- mob_wrathbone_laborerAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
- void Reset()
- {
- events.Reset();
- }
+ DoMeleeAttackIfReady();
+ }
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_BLINDING_DIRT, 8000);
- events.ScheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
- events.ScheduleEvent(EVENT_SHOVELLED, 5000);
- }
+ private:
+ EventMap _events;
+ };
- void UpdateAI(const uint32 diff)
+ CreatureAI* GetAI(Creature* creature) const
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch(eventId)
- {
- case EVENT_BLINDING_DIRT:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_BLINDING_DIRT);
- events.RescheduleEvent(EVENT_BLINDING_DIRT, 10000);
- return;
- case EVENT_PUNCTURE_WOUND:
- DoCast(me->getVictim(), SPELL_PUNCTURE_WOUND);
- events.RescheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
- return;
- case EVENT_SHOVELLED:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_SHOVELLED);
- events.RescheduleEvent(EVENT_SHOVELLED, 7000);
- return;
- }
- }
-
- DoMeleeAttackIfReady();
+ return new mob_ymirjar_flamebearerAI(creature);
}
- };
-
};
-class mob_wrathbone_coldwraith : public CreatureScript
+class mob_iceborn_protodrake : public CreatureScript
{
-public:
- mob_wrathbone_coldwraith() : CreatureScript("mob_wrathbone_coldwraith") { }
+ public:
+ mob_iceborn_protodrake() : CreatureScript("mob_iceborn_protodrake") { }
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_wrathbone_coldwraithAI(pCreature);
- }
-
- struct mob_wrathbone_coldwraithAI: public ScriptedAI
- {
- mob_wrathbone_coldwraithAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_FREEZING_CIRCLE, 9000);
- events.ScheduleEvent(EVENT_FROSTBOLT, 5000);
- }
-
- void UpdateAI(const uint32 diff)
+ struct mob_iceborn_protodrakeAI: public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ mob_iceborn_protodrakeAI(Creature *creature) : ScriptedAI(creature), _vehicle(creature->GetVehicleKit())
{
- switch(eventId)
- {
- case EVENT_FREEZING_CIRCLE:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_FREEZING_CIRCLE);
- events.RescheduleEvent(EVENT_FREEZING_CIRCLE, 9000);
- return;
- case EVENT_FROSTBOLT:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_FROSTBOLT);
- events.RescheduleEvent(EVENT_FROSTBOLT, 5000);
- return;
- }
+ ASSERT(_vehicle);
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_stonespine_gargoyle : public CreatureScript
-{
-public:
- mob_stonespine_gargoyle() : CreatureScript("mob_stonespine_gargoyle") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_stonespine_gargoyleAI(pCreature);
- }
-
- struct mob_stonespine_gargoyleAI: public ScriptedAI
- {
- mob_stonespine_gargoyleAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_GARGOYLE_STRIKE, 5000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void Reset()
{
- switch(eventId)
- {
- case EVENT_GARGOYLE_STRIKE:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_GARGOYLE_STRIKE);
- events.RescheduleEvent(EVENT_GARGOYLE_STRIKE, 6000);
- return;
- case EVENT_STONEFORM:
- if (HealthBelowPct(10))
- DoCast(me, SPELL_STONEFORM);
- return;
- }
+ _frostBreathCooldown = 5000;
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_plagueborn_horror : public CreatureScript
-{
-public:
- mob_plagueborn_horror() : CreatureScript("mob_plagueborn_horror") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_plagueborn_horrorAI(pCreature);
- }
-
- struct mob_plagueborn_horrorAI: public ScriptedAI
- {
- mob_plagueborn_horrorAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_BLIGHT_BOMB, 999999);
- events.ScheduleEvent(EVENT_PUSTULANT_FLESH, 5000);
- events.ScheduleEvent(EVENT_TOXIC_WASTE, 8000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void EnterCombat(Unit* /*who*/)
{
- switch(eventId)
- {
- case EVENT_BLIGHT_BOMB:
- if (HealthBelowPct(15))
- DoCast(me, SPELL_BLIGHT_BOMB);
- return;
- case EVENT_PUSTULANT_FLESH:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_PUSTULANT_FLESH);
- events.RescheduleEvent(EVENT_PUSTULANT_FLESH, 10000);
- return;
- case EVENT_TOXIC_WASTE:
- DoCast(me, SPELL_TOXIC_WASTE);
- events.RescheduleEvent(EVENT_TOXIC_WASTE, 8000);
- return;
- }
+ _vehicle->RemoveAllPassengers();
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_iceborn_protodrake : public CreatureScript
-{
-public:
- mob_iceborn_protodrake() : CreatureScript("mob_iceborn_protodrake") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_iceborn_protodrakeAI(pCreature);
- }
-
- struct mob_iceborn_protodrakeAI: public ScriptedAI
- {
- mob_iceborn_protodrakeAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_FROST_BREATH, 5000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void UpdateAI(const uint32 diff)
{
- switch(eventId)
+ if (!UpdateVictim())
+ return;
+
+ if (_frostBreathCooldown < diff)
{
- case EVENT_FROST_BREATH:
- DoCast(me->getVictim(), SPELL_FROST_BREATH);
- events.RescheduleEvent(EVENT_FROST_BREATH, 10000);
- return;
+ DoCastVictim(SPELL_FROST_BREATH);
+ _frostBreathCooldown = 10000;
}
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_hungering_ghoul : public CreatureScript
-{
-public:
- mob_hungering_ghoul() : CreatureScript("mob_hungering_ghoul") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_hungering_ghoulAI(pCreature);
- }
-
- struct mob_hungering_ghoulAI: public ScriptedAI
- {
- mob_hungering_ghoulAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
+ else
+ _frostBreathCooldown -= diff;
- void Reset()
- {
- events.Reset();
- }
+ DoMeleeAttackIfReady();
+ }
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_DEVOUR_FLESH, 4000);
- }
+ private:
+ Vehicle* _vehicle;
+ uint32 _frostBreathCooldown;
+ };
- void UpdateAI(const uint32 diff)
+ CreatureAI* GetAI(Creature* creature) const
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch(eventId)
- {
- case EVENT_DEVOUR_FLESH:
- DoCast(me->getVictim(), SPELL_DEVOUR_FLESH);
- events.RescheduleEvent(EVENT_DEVOUR_FLESH, 8000);
- return;
- }
- }
-
- DoMeleeAttackIfReady();
+ return new mob_iceborn_protodrakeAI(creature);
}
- };
-
};
-class mob_fallen_warrior : public CreatureScript
+class mob_wrathbone_laborer : public CreatureScript
{
-public:
- mob_fallen_warrior() : CreatureScript("mob_fallen_warrior") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_fallen_warriorAI(pCreature);
- }
-
- struct mob_fallen_warriorAI: public ScriptedAI
- {
- mob_fallen_warriorAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_ARCING_SLICE, 8000);
- events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, 20000);
- events.ScheduleEvent(EVENT_SHIELD_BLOCK, 8000);
- }
+ public:
+ mob_wrathbone_laborer() : CreatureScript("mob_wrathbone_laborer") { }
- void UpdateAI(const uint32 diff)
+ struct mob_wrathbone_laborerAI: public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ mob_wrathbone_laborerAI(Creature* creature) : ScriptedAI(creature)
{
- switch(eventId)
- {
- case EVENT_ARCING_SLICE:
- DoCast(me->getVictim(), SPELL_ARCING_SLICE);
- events.RescheduleEvent(EVENT_ARCING_SLICE, 10000);
- return;
- case EVENT_DEMORALIZING_SHOUT:
- DoCast(me, SPELL_DEMORALIZING_SHOUT);
- events.RescheduleEvent(EVENT_DEMORALIZING_SHOUT, 20000);
- return;
- case EVENT_SHIELD_BLOCK:
- DoCast(me->getVictim(), SPELL_SHIELD_BLOCK);
- events.RescheduleEvent(EVENT_SHIELD_BLOCK, 8000);
- return;
- }
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_deathwhisper_torturer : public CreatureScript
-{
-public:
- mob_deathwhisper_torturer() : CreatureScript("mob_deathwhisper_torturer") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_deathwhisper_torturerAI(pCreature);
- }
-
- struct mob_deathwhisper_torturerAI: public ScriptedAI
- {
- mob_deathwhisper_torturerAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_BLACK_BRAND, 10000);
- events.ScheduleEvent(EVENT_CURSE_OF_AGONY, 6000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void Reset()
{
- switch(eventId)
- {
- case EVENT_BLACK_BRAND:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_BLACK_BRAND);
- events.RescheduleEvent(EVENT_BLACK_BRAND, 10000);
- return;
- case EVENT_CURSE_OF_AGONY:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_CURSE_OF_AGONY);
- events.RescheduleEvent(EVENT_CURSE_OF_AGONY, 13000);
- return;
- }
+ _events.Reset();
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_deathwhisper_shadowcaster : public CreatureScript
-{
-public:
- mob_deathwhisper_shadowcaster() : CreatureScript("mob_deathwhisper_shadowcaster") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_deathwhisper_shadowcasterAI(pCreature);
- }
-
- struct mob_deathwhisper_shadowcasterAI: public ScriptedAI
- {
- mob_deathwhisper_shadowcasterAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_SHADOW_BOLT, 3000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
+ void EnterCombat(Unit* /*who*/)
{
- switch(eventId)
- {
- case EVENT_SHADOW_BOLT:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_SHADOW_BOLT);
- events.RescheduleEvent(EVENT_SHADOW_BOLT, 5000);
- return;
- }
+ _events.ScheduleEvent(EVENT_BLINDING_DIRT, 8000);
+ _events.ScheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
+ _events.ScheduleEvent(EVENT_SHOVELLED, 5000);
}
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_deathwhisper_necrolyte : public CreatureScript
-{
-public:
- mob_deathwhisper_necrolyte() : CreatureScript("mob_deathwhisper_necrolyte") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_deathwhisper_necrolyteAI(pCreature);
- }
-
- struct mob_deathwhisper_necrolyteAI: public ScriptedAI
- {
- mob_deathwhisper_necrolyteAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_CONVERSION_BEAM, 12000);
- events.ScheduleEvent(EVENT_SHADOW_BOLT_2, 4000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- events.Update(diff);
+ _events.Update(diff);
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch(eventId)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- case EVENT_CONVERSION_BEAM:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_CONVERSION_BEAM);
- events.RescheduleEvent(EVENT_CONVERSION_BEAM, 12000);
- return;
- case EVENT_SHADOW_BOLT_2:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_SHADOW_BOLT_2);
- events.RescheduleEvent(EVENT_SHADOW_BOLT_2, 5000);
- return;
+ switch(eventId)
+ {
+ case EVENT_BLINDING_DIRT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 10.0f, true))
+ DoCast(target, SPELL_BLINDING_DIRT);
+ _events.RescheduleEvent(EVENT_BLINDING_DIRT, 10000);
+ return;
+ case EVENT_PUNCTURE_WOUND:
+ DoCastVictim(SPELL_PUNCTURE_WOUND);
+ _events.RescheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
+ return;
+ case EVENT_SHOVELLED:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -5.0f))
+ DoCast(target, SPELL_SHOVELLED);
+ _events.RescheduleEvent(EVENT_SHOVELLED, 7000);
+ return;
+ }
}
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class mob_wrathbone_sorcerer : public CreatureScript
-{
-public:
- mob_wrathbone_sorcerer() : CreatureScript("mob_wrathbone_sorcerer") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_wrathbone_sorcererAI(pCreature);
- }
-
- struct mob_wrathbone_sorcererAI: public ScriptedAI
- {
- mob_wrathbone_sorcererAI(Creature *c) : ScriptedAI(c)
- {
- }
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
+ DoMeleeAttackIfReady();
+ }
- void EnterCombat(Unit* /*who*/)
- {
- events.ScheduleEvent(EVENT_SHADOW_BOLT_3, 3000);
- }
+ private:
+ EventMap _events;
+ };
- void UpdateAI(const uint32 diff)
+ CreatureAI* GetAI(Creature* creature) const
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch(eventId)
- {
- case EVENT_SHADOW_BOLT_3:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_SHADOW_BOLT_3);
- events.RescheduleEvent(EVENT_SHADOW_BOLT_3, 5000);
- return;
- }
- }
-
- DoMeleeAttackIfReady();
+ return new mob_wrathbone_laborerAI(creature);
}
- };
-
};
class mob_geist_ambusher : public CreatureScript
{
-public:
- mob_geist_ambusher() : CreatureScript("mob_geist_ambusher") { }
-
- CreatureAI* GetAI(Creature* pCreature) const
- {
- return new mob_geist_ambusherAI(pCreature);
- }
-
- struct mob_geist_ambusherAI: public ScriptedAI
- {
- mob_geist_ambusherAI(Creature *c) : ScriptedAI(c)
- {
- }
-
- EventMap events;
-
- void Reset()
- {
- events.Reset();
- }
+ public:
+ mob_geist_ambusher() : CreatureScript("mob_geist_ambusher") { }
- void EnterCombat(Unit* /*who*/)
+ struct mob_geist_ambusherAI: public ScriptedAI
{
- //Only here so when I figure out how to make it cast on an NPC i can do that.
- events.ScheduleEvent(EVENT_LEAPING_FACE_MAUL, 99999);
- }
+ mob_geist_ambusherAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
- void UpdateAI(const uint32 diff)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void Reset()
+ {
+ _leapingFaceMaulCooldown = 9000;
+ }
- events.Update(diff);
+ void MoveInLineOfSight(Unit* who)
+ {
+ if (who->GetTypeId() != TYPEID_PLAYER)
+ return;
- if (me->HasUnitState(UNIT_STAT_CASTING))
- return;
+ if (me->IsWithinDistInMap(who, 30.0f))
+ DoCast(who, SPELL_LEAPING_FACE_MAUL);
+ }
- while (uint32 eventId = events.ExecuteEvent())
+ void UpdateAI(const uint32 diff)
{
- switch(eventId)
+ if (!UpdateVictim())
+ return;
+
+ if (_leapingFaceMaulCooldown < diff)
{
- //Should only be used on NPCs
- case EVENT_LEAPING_FACE_MAUL:
- if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(pTarget, SPELL_LEAPING_FACE_MAUL);
- events.CancelEvent(EVENT_LEAPING_FACE_MAUL);
- return;
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f, true))
+ DoCast(target, SPELL_LEAPING_FACE_MAUL);
+ _leapingFaceMaulCooldown = urand(9000, 14000);
}
+ else
+ _leapingFaceMaulCooldown -= diff;
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
- }
- };
+ private:
+ uint32 _leapingFaceMaulCooldown;
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_geist_ambusherAI(creature);
+ }
};
void AddSC_pit_of_saron()
{
- new mob_ymirjar_wrathbringer();
- new mob_ymirjar_skycaller();
new mob_ymirjar_flamebearer();
- new mob_ymirjar_deathbringer();
new mob_wrathbone_laborer();
- new mob_wrathbone_coldwraith();
- new mob_stonespine_gargoyle();
- new mob_plagueborn_horror();
new mob_iceborn_protodrake();
- new mob_hungering_ghoul();
- new mob_fallen_warrior();
- new mob_deathwhisper_torturer();
- new mob_deathwhisper_shadowcaster();
- new mob_deathwhisper_necrolyte();
- new mob_wrathbone_sorcerer();
new mob_geist_ambusher();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
index 9368d479cd1..d71972d64fa 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
@@ -18,34 +18,32 @@
#ifndef DEF_PIT_OF_SARON_H
#define DEF_PIT_OF_SARON_H
-enum Data
-{
- DATA_GARFROST_EVENT,
- DATA_KRICKANDICK_EVENT,
- DATA_TYRANNUS_EVENT,
- DATA_TEAM_IN_INSTANCE,
-};
+#define PoSScriptName "instance_pit_of_saron"
+#define MAX_ENCOUNTER 3
-enum Data64
+enum DataTypes
{
- DATA_GARFROST,
- DATA_KRICK,
- DATA_ICK,
- DATA_TYRANNUS,
- DATA_RIMEFANG,
+ DATA_GARFROST = 0,
+ DATA_KRICK = 1,
+ DATA_ICK = 2,
+ DATA_TYRANNUS = 3,
+ DATA_RIMEFANG = 4,
- DATA_JAINA_SYLVANAS_1, // GUID of either Jaina or Sylvanas part 1, depending on team, as it's the same spawn.
- DATA_JAINA_SYLVANAS_2, // GUID of either Jaina or Sylvanas part 2, depending on team, as it's the same spawn.
+ DATA_JAINA_SYLVANAS_1 = 5, // GUID of either Jaina or Sylvanas part 1, depending on team, as it's the same spawn.
+ DATA_JAINA_SYLVANAS_2 = 6, // GUID of either Jaina or Sylvanas part 2, depending on team, as it's the same spawn.
+ DATA_TYRANNUS_EVENT = 7,
+ DATA_TEAM_IN_INSTANCE = 8,
};
-enum Creatures
+enum CreatureIds
{
- CREATURE_GARFROST = 36494,
- CREATURE_KRICK = 36477,
- CREATURE_ICK = 36476,
- CREATURE_TYRANNUS = 36658,
- CREATURE_RIMEFANG = 36661,
+ NPC_GARFROST = 36494,
+ NPC_KRICK = 36477,
+ NPC_ICK = 36476,
+ NPC_TYRANNUS = 36658,
+ NPC_RIMEFANG = 36661,
+ NPC_TYRANNUS_EVENTS = 36794,
NPC_SYLVANAS_PART1 = 36990,
NPC_SYLVANAS_PART2 = 38189,
NPC_JAINA_PART1 = 36993,
@@ -59,6 +57,25 @@ enum Creatures
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_FORGEMASTER_STALKER = 36495,
+ NPC_EXPLODING_ORB = 36610,
+ NPC_YMIRJAR_DEATHBRINGER = 36892,
+ NPC_ICY_BLAST = 36731
+};
+
+enum GameObjectIds
+{
+ GO_SARONITE_ROCK = 196485,
};
#endif