Scripts/HallsOfOrigination: Added script for Anraphet and the Vault of Lights.

Some bugs might still remain.
Crumbling Ruin spell has a problem with radius handling.
This commit is contained in:
Subv
2013-01-04 18:06:55 -05:00
parent 0f71fd8e23
commit bb1c955c8b
8 changed files with 780 additions and 58 deletions

View File

@@ -115,6 +115,7 @@ set(scripts_STAT_SRCS
Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp
Kalimdor/HallsOfOrigination/boss_anraphet.cpp
)
message(" -> Prepared: Kalimdor")

View File

@@ -0,0 +1,571 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "GridNotifiers.h"
#include "Player.h"
#include "ObjectAccessor.h"
#include "halls_of_origination.h"
enum Texts
{
ANRAPHET_SAY_INTRO = 0,
ANRAPHET_SAY_AGGRO = 1,
ANRAPHET_SAY_OMEGA_STANCE = 2,
ANRAPHET_SAY_KILL = 3,
ANRAPHET_SAY_DEATH = 4,
BRANN_SAY_DOOR_INTRO = 0, // Right, let's go! Just need to input the final entry sequence into the door mechanism... and...
BRANN_SAY_UNLOCK_DOOR = 1, // That did the trick! The control room should be right behind this... oh... wow...
BRANN_SAY_TROGGS = 2, // What? This isn't the control room! There's another entire defense mechanism in place, and the blasted Rock Troggs broke into here somehow. Troggs. Why did it have to be Troggs!
BRANN_SAY_THINK = 3, // Ok, let me think a moment.
BRANN_SAY_MIRRORS = 4, // Mirrors pointing all over the place.
BRANN_SAY_ELEMENTALS = 5, // Four platforms with huge elementals.
BRANN_SAY_GET_IT = 6, // I got it! I saw a tablet that mentioned this chamber. This is the Vault of Lights! Ok, simple enough. I need you adventurers to take out each of the four elementals to trigger the opening sequence for the far door!
BRANN_1_ELEMENTAL_DEAD = 7, // One down!
BRANN_2_ELEMENTAL_DEAD = 8, // Another one down! Just look at those light beams! They seem to be connecting to the far door!
BRANN_3_ELEMENTAL_DEAD = 9, // One more elemental to go! The door is almost open!
BRANN_4_ELEMENTAL_DEAD = 10, // That''s it, you''ve done it! The vault door is opening! Now we can... oh, no!
BRANN_SAY_ANRAPHET_DIED = 11, // We''ve done it! The control room is breached!
BRANN_SAY_MOMENT = 12 // Here we go! Now this should only take a moment...
};
enum Events
{
EVENT_BRANN_MOVE_INTRO = 1,
EVENT_BRANN_UNLOCK_DOOR = 2,
EVENT_BRANN_THINK = 3,
EVENT_BRANN_SET_ORIENTATION_1 = 4,
EVENT_BRANN_SET_ORIENTATION_2 = 5,
EVENT_BRANN_SET_ORIENTATION_3 = 6,
EVENT_BRANN_SAY_ELEMENTALS = 7,
EVENT_BRANN_SAY_GET_IT = 8,
EVENT_BRANN_SET_ORIENTATION_4 = 9,
EVENT_ANRAPHET_APPEAR = 10,
EVENT_ANRAPHET_ACTIVATE = 11,
EVENT_ANRAPHET_DESTROY = 12,
EVENT_ANRAPHET_READY = 13,
EVENT_ANRAPHET_NEMESIS_STRIKE = 14,
EVENT_ANRAPHET_ALPHA_BEAMS = 15,
EVENT_ANRAPHET_OMEGA_STANCE = 16,
EVENT_ANRAPHET_CRUMBLING_RUIN = 17,
EVENT_ANRAPHET_ACTIVATE_OMEGA = 18
};
enum Spells
{
SPELL_DESTRUCTION_PROTOCOL = 77437,
SPELL_ALPHA_BEAMS = 76184,
SPELL_ALPHA_BEAMS_BACK_CAST = 76912,
SPELL_CRUMBLING_RUIN = 75609,
SPELL_NEMESIS_STRIKE = 75604,
SPELL_OMEGA_STANCE_SUMMON = 77106,
SPELL_OMEGA_STANCE = 75622,
SPELL_OMEGA_STANCE_SPIDER_TRIGGER = 77121,
};
enum Phases
{
PHASE_INTRO = 1,
PHASE_COMBAT = 2,
PHASE_MASK_COMBAT = (1 << PHASE_COMBAT),
};
enum Points
{
POINT_ANRAPHET_ACTIVATE = 0,
MAX_BRANN_WAYPOINTS_INTRO = 17
};
Position const AnraphetActivatePos = {-193.656f, 366.689f, 75.91001f, 3.138207f};
Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] =
{
{-429.583f, 367.019f, 89.79282f, 0.0f},
{-409.9531f, 367.0469f, 89.81111f, 0.0f},
{-397.8246f, 366.967f, 86.37722f, 0.0f},
{-383.7813f, 366.8229f, 82.07919f, 0.0f},
{-368.2604f, 366.7448f, 77.0984f, 0.0f},
{-353.6458f, 366.4896f, 75.92504f, 0.0f},
{-309.0608f, 366.7205f, 75.91345f, 0.0f},
{-276.3303f, 367.0f, 75.92413f, 0.0f},
{-246.5104f, 366.6389f, 75.87791f, 0.0f},
{-202.0417f, 366.7517f, 75.92508f, 0.0f},
{-187.6024f, 366.7656f, 76.23077f, 0.0f},
{-155.0938f, 366.783f, 86.45834f, 0.0f},
{-143.5694f, 366.8177f, 89.73354f, 0.0f},
{-128.5608f, 366.8629f, 89.74199f, 0.0f},
{-103.559f, 366.5938f, 89.79725f, 0.0f},
{-71.58507f, 367.0278f, 89.77069f, 0.0f},
{-35.04861f, 366.6563f, 89.77447f, 0.0f},
};
class boss_anraphet : public CreatureScript
{
public:
boss_anraphet() : CreatureScript("boss_anraphet") { }
struct boss_anraphetAI : public BossAI
{
boss_anraphetAI(Creature* creature) : BossAI(creature, DATA_ANRAPHET) { }
void ScheduleCombatEvents()
{
events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 8000, 0, PHASE_COMBAT);
events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 10000, 0, PHASE_COMBAT);
events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 35000, 0, PHASE_COMBAT);
}
void Reset()
{
_Reset();
me->SetWalk(false);
events.SetPhase(PHASE_INTRO);
if (instance->GetData(DATA_DEAD_ELEMENTALS) == 4)
{
// Set to combat automatically, Brann's event won't repeat
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
events.SetPhase(PHASE_COMBAT);
ScheduleCombatEvents();
me->SetHomePosition(AnraphetActivatePos);
}
}
void EnterCombat(Unit* /*who*/)
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
Talk(ANRAPHET_SAY_AGGRO);
_EnterCombat();
}
void JustDied(Unit* /*killer*/)
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
Talk(ANRAPHET_SAY_DEATH);
if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BRANN_0_GUID)))
brann->AI()->DoAction(ACTION_ANRAPHET_DIED);
_JustDied();
}
void KilledUnit(Unit* victim)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(ANRAPHET_SAY_KILL);
}
void JustReachedHome()
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
_JustReachedHome();
instance->SetBossState(DATA_ANRAPHET, FAIL);
}
void DoAction(int32 const action)
{
if (action == ACTION_ANRAPHET_INTRO)
events.ScheduleEvent(EVENT_ANRAPHET_APPEAR, 6000, 0, PHASE_INTRO);
}
void MovementInform(uint32 type, uint32 point)
{
if (type != POINT_MOTION_TYPE)
return;
if (point == POINT_ANRAPHET_ACTIVATE)
{
events.ScheduleEvent(EVENT_ANRAPHET_ACTIVATE, 1500, 0, PHASE_INTRO);
me->SetHomePosition(AnraphetActivatePos);
}
}
void UpdateAI(uint32 const diff)
{
if ((events.GetPhaseMask() & PHASE_MASK_COMBAT) && (!UpdateVictim() || !CheckInRoom()))
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ANRAPHET_APPEAR:
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_ANRAPHET_ACTIVATE, AnraphetActivatePos);
break;
case EVENT_ANRAPHET_ACTIVATE:
me->SetWalk(false);
Talk(ANRAPHET_SAY_INTRO);
events.ScheduleEvent(EVENT_ANRAPHET_DESTROY, 17500, 0, PHASE_INTRO);
return;
case EVENT_ANRAPHET_DESTROY:
DoCastAOE(SPELL_DESTRUCTION_PROTOCOL);
events.ScheduleEvent(EVENT_ANRAPHET_READY, 6000, 0, PHASE_INTRO);
break;
case EVENT_ANRAPHET_READY:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
events.SetPhase(PHASE_COMBAT);
ScheduleCombatEvents();
break;
case EVENT_ANRAPHET_NEMESIS_STRIKE:
DoCastVictim(SPELL_NEMESIS_STRIKE);
events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 21500, 0, PHASE_COMBAT);
break;
case EVENT_ANRAPHET_ALPHA_BEAMS:
DoCast(me, SPELL_ALPHA_BEAMS);
events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 12500, 0, PHASE_COMBAT);
events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, urand(40000, 45000), 0, PHASE_COMBAT);
break;
case EVENT_ANRAPHET_OMEGA_STANCE:
DoCast(me, SPELL_OMEGA_STANCE_SUMMON);
DoCast(me, SPELL_OMEGA_STANCE);
Talk(ANRAPHET_SAY_OMEGA_STANCE);
events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, urand(45000, 50000), 0, PHASE_COMBAT);
events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 13000, 0, PHASE_COMBAT);
break;
case EVENT_ANRAPHET_CRUMBLING_RUIN:
DoCast(me, SPELL_CRUMBLING_RUIN);
break;
}
}
if (events.GetPhaseMask() & PHASE_MASK_COMBAT)
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetHallsOfOriginationAI<boss_anraphetAI>(creature);
}
};
class npc_omega_stance : public CreatureScript
{
public:
npc_omega_stance() : CreatureScript("npc_omega_stance") { }
struct npc_omega_stanceAI : public ScriptedAI
{
npc_omega_stanceAI(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(Unit* /*who*/)
{
DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true);
}
void EnterEvadeMode() { }
};
CreatureAI* GetAI(Creature* creature) const
{
return new npc_omega_stanceAI(creature);
}
};
class npc_alpha_beam : public CreatureScript
{
public:
npc_alpha_beam() : CreatureScript("npc_alpha_beam") { }
struct npc_alpha_beamAI : public ScriptedAI
{
npc_alpha_beamAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void IsSummonedBy(Unit* summoner)
{
if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ANRAPHET_GUID)))
anraphet->CastSpell(me, SPELL_ALPHA_BEAMS_BACK_CAST);
}
void EnterEvadeMode() { } // Never evade
private:
InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetHallsOfOriginationAI<npc_alpha_beamAI>(creature);
}
};
class npc_brann_bronzebeard_anraphet : public CreatureScript
{
public:
npc_brann_bronzebeard_anraphet() : CreatureScript("npc_brann_bronzebeard_anraphet") { }
struct npc_brann_bronzebeard_anraphetAI : public CreatureAI
{
npc_brann_bronzebeard_anraphetAI(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(creature->GetInstanceScript()) { }
void sGossipSelect(Player* /*player*/, uint32 sender, uint32 action)
{
if (_instance->GetBossState(DATA_VAULT_OF_LIGHTS) == DONE)
return;
if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
{
_instance->SetBossState(DATA_VAULT_OF_LIGHTS, IN_PROGRESS);
_currentPoint = 0;
events.Reset();
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->SetWalk(true);
Talk(BRANN_SAY_DOOR_INTRO);
events.ScheduleEvent(EVENT_BRANN_UNLOCK_DOOR, 7500);
}
}
void DoAction(int32 const action)
{
switch (action)
{
case ACTION_ELEMENTAL_DIED:
{
uint32 dead = _instance->GetData(DATA_DEAD_ELEMENTALS);
Talk(BRANN_1_ELEMENTAL_DEAD + dead - 1);
if (dead == 4)
{
_instance->DoCastSpellOnPlayers(SPELL_VAULT_OF_LIGHTS_CREDIT);
if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ANRAPHET_GUID)))
anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO);
}
break;
}
case ACTION_ANRAPHET_DIED:
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1000);
break;
}
}
void UpdateAI(uint32 const diff)
{
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BRANN_MOVE_INTRO:
if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO)
me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]);
break;
case EVENT_BRANN_UNLOCK_DOOR:
Talk(BRANN_SAY_UNLOCK_DOOR);
_instance->SetBossState(DATA_VAULT_OF_LIGHTS, DONE);
_instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_VAULT_OF_LIGHTS_EVENT);
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 3500);
break;
case EVENT_BRANN_THINK:
Talk(BRANN_SAY_THINK);
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_1, 6000);
break;
case EVENT_BRANN_SET_ORIENTATION_1:
me->SetFacingTo(5.445427f);
Talk(BRANN_SAY_MIRRORS);
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_2, 1000);
break;
case EVENT_BRANN_SET_ORIENTATION_2:
me->SetFacingTo(0.6283185f);
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_3, 2500);
break;
case EVENT_BRANN_SET_ORIENTATION_3:
me->SetFacingTo(0.01745329f);
events.ScheduleEvent(EVENT_BRANN_SAY_ELEMENTALS, 200);
break;
case EVENT_BRANN_SAY_ELEMENTALS:
Talk(BRANN_SAY_ELEMENTALS);
events.ScheduleEvent(EVENT_BRANN_SAY_GET_IT, 3500);
break;
case EVENT_BRANN_SAY_GET_IT:
Talk(BRANN_SAY_GET_IT);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
break;
case EVENT_BRANN_SET_ORIENTATION_4:
me->SetFacingTo(3.141593f);
break;
}
}
}
void MovementInform(uint32 movementType, uint32 pointId)
{
if (movementType != POINT_MOTION_TYPE)
return;
_currentPoint = pointId + 1;
uint32 delay = 1;
switch (pointId)
{
case 0:
Talk(BRANN_SAY_TROGGS);
events.ScheduleEvent(EVENT_BRANN_THINK, 15000);
return;
case 1:
Talk(BRANN_SAY_ANRAPHET_DIED);
delay = 1000;
break;
case 14:
Talk(BRANN_SAY_MOMENT);
delay = 2200;
break;
case 16:
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_4, 6000);
return;
default:
break;
}
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay);
}
protected:
EventMap events;
uint32 _currentPoint;
InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetHallsOfOriginationAI<npc_brann_bronzebeard_anraphetAI>(creature);
}
};
class spell_anraphet_alpha_beams : public SpellScriptLoader
{
public:
spell_anraphet_alpha_beams() : SpellScriptLoader("spell_anraphet_alpha_beams") { }
class spell_anraphet_alpha_beams_SpellScript : public SpellScript
{
PrepareSpellScript(spell_anraphet_alpha_beams_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_anraphet_alpha_beams_SpellScript();
}
};
class spell_anraphet_omega_stance_summon : public SpellScriptLoader
{
public:
spell_anraphet_omega_stance_summon() : SpellScriptLoader("spell_anraphet_omega_stance_summon") { }
class spell_anraphet_omega_stance_summon_SpellScript : public SpellScript
{
PrepareSpellScript(spell_anraphet_omega_stance_summon_SpellScript);
void ModDestHeight(SpellEffIndex /*effIndex*/)
{
Position offset = {0.0f, 0.0f, 30.0f, 0.0f};
const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
GetHitDest()->RelocateOffset(offset);
}
void Register()
{
OnEffectLaunch += SpellEffectFn(spell_anraphet_omega_stance_summon_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
}
};
SpellScript* GetSpellScript() const
{
return new spell_anraphet_omega_stance_summon_SpellScript();
}
};
class spell_omega_stance_spider_effect : public SpellScriptLoader
{
public:
spell_omega_stance_spider_effect() : SpellScriptLoader("spell_omega_stance_spider_effect") { }
class spell_omega_stance_spider_effect_SpellScript : public SpellScript
{
PrepareSpellScript(spell_omega_stance_spider_effect_SpellScript);
void SetDestPosition(SpellEffIndex effIndex)
{
// Do our own calculations for the destination position.
/// TODO: Remove this once we find a general rule for WorldObject::MovePosition (this spell shouldn't take the Z change into consideration)
Unit* caster = GetCaster();
float angle = float(rand_norm()) * static_cast<float>(2 * M_PI);
uint32 dist = caster->GetObjectSize() + GetSpellInfo()->Effects[effIndex].CalcRadius(GetCaster()) * (float)rand_norm();
float x = caster->GetPositionX() + dist * std::cos(angle);
float y = caster->GetPositionY() + dist * std::sin(angle);
float z = caster->GetMap()->GetHeight(x, y, caster->GetPositionZ());
const_cast<WorldLocation*>(GetExplTargetDest())->Relocate(x, y, z);
GetHitDest()->Relocate(x, y, z);
}
void Register()
{
OnEffectLaunch += SpellEffectFn(spell_omega_stance_spider_effect_SpellScript::SetDestPosition, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_omega_stance_spider_effect_SpellScript();
}
};
void AddSC_boss_anraphet()
{
new boss_anraphet();
new spell_anraphet_alpha_beams();
new npc_brann_bronzebeard_anraphet();
new npc_alpha_beam();
new spell_anraphet_omega_stance_summon();
new spell_omega_stance_spider_effect();
new npc_omega_stance();
}

View File

@@ -45,7 +45,6 @@ enum Spells
SPELL_RAGING_SMASH = 83650,
SPELL_FLAME_BOLT = 77370,
SPELL_EARTH_SPIKE_WARN = 94974,
SPELL_EARTH_SPIKE_ERUPT = 75339,
SPELL_PTAH_EXPLOSION = 75519,
SPELL_SANDSTORM = 75491,
@@ -91,22 +90,6 @@ protected:
Unit* _owner;
};
class EruptEarthSpike : public BasicEvent
{
public:
EruptEarthSpike(Unit* caster, WorldLocation const target) : _caster(caster), _target(target) { }
bool Execute(uint64 execTime, uint32 /*diff*/)
{
_caster->CastSpell(_target.GetPositionX(), _target.GetPositionY(), _target.GetPositionZ(), SPELL_EARTH_SPIKE_ERUPT, true);
return true;
}
protected:
Unit* _caster;
WorldLocation const _target;
};
class boss_earthrager_ptah : public CreatureScript
{
public:
@@ -315,34 +298,6 @@ class spell_earthrager_ptah_flame_bolt : public SpellScriptLoader
}
};
class spell_earthrager_ptah_earth_spike : public SpellScriptLoader
{
public:
spell_earthrager_ptah_earth_spike() : SpellScriptLoader("spell_earthrager_ptah_earth_spike") { }
class spell_earthrager_ptah_earth_spike_SpellScript : public SpellScript
{
PrepareSpellScript(spell_earthrager_ptah_earth_spike_SpellScript);
void Launch(SpellEffIndex index)
{
PreventHitDefaultEffect(index);
// Erupt the spike in 4 seconds.
GetCaster()->m_Events.AddEvent(new EruptEarthSpike(GetCaster(), *GetExplTargetDest()), GetCaster()->m_Events.CalculateTime(4000));
}
void Register()
{
OnEffectHit += SpellEffectFn(spell_earthrager_ptah_earth_spike_SpellScript::Launch, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE);
}
};
SpellScript* GetSpellScript() const
{
return new spell_earthrager_ptah_earth_spike_SpellScript();
}
};
class spell_earthrager_ptah_explosion : public SpellScriptLoader
{
public:
@@ -387,6 +342,5 @@ void AddSC_boss_earthrager_ptah()
{
new boss_earthrager_ptah();
new spell_earthrager_ptah_flame_bolt();
new spell_earthrager_ptah_earth_spike();
new spell_earthrager_ptah_explosion();
}

View File

@@ -20,13 +20,18 @@
#define HoOScriptName "instance_halls_of_origination"
uint32 const EncounterCount = 7;
uint32 const EncounterCount = 12;
enum Data
{
// Bosses
DATA_TEMPLE_GUARDIAN_ANHUUR,
DATA_EARTHRAGER_PTAH,
DATA_VAULT_OF_LIGHTS,
DATA_FIRE_WARDEN,
DATA_EARTH_WARDEN,
DATA_WATER_WARDEN,
DATA_AIR_WARDEN,
DATA_ANRAPHET,
DATA_ISISET,
DATA_AMMUNAE,
@@ -39,6 +44,11 @@ enum Data
DATA_ANHUUR_RIGHT_BEACON,
DATA_ANHUUR_BRIDGE,
DATA_ANHUUR_DOOR,
// Anraphet
DATA_BRANN_0_GUID,
DATA_DEAD_ELEMENTALS,
DATA_ANRAPHET_GUID,
};
enum Creatures
@@ -52,6 +62,17 @@ enum Creatures
NPC_JEWELED_SCARAB = 40458,
NPC_DUSTBONE_HORROR = 40450,
NPC_QUICKSAND = 40503, // Summoned by a spell not in dbc (75550)
BOSS_ANRAPHET = 39788,
NPC_FIRE_WARDEN = 39800,
NPC_EARTH_WARDEN = 39801,
NPC_WATER_WARDEN = 39802,
NPC_AIR_WARDEN = 39803,
WARDEN_ENTRY_DATA_DELTA = NPC_FIRE_WARDEN - DATA_FIRE_WARDEN,
NPC_BRANN_BRONZEBEARD_0 = 39908,
NPC_OMEGA_STANCE = 41194,
};
enum GameObjects
@@ -61,11 +82,35 @@ enum GameObjects
GO_ANHUURS_DOOR = 202307,
GO_ANHUURS_RIGHT_BEACON = 203136,
GO_ANHUURS_LEFT_BEACON = 203133,
GO_VAULT_OF_LIGHTS_DOOR = 202313,
GO_SUN_MIRROR = 207726,
GO_ANRAPHET_DOOR = 202314,
GO_DOODAD_ULDUM_LIGHTMACHINE_01 = 207375,
GO_DOODAD_ULDUM_LIGHTMACHINE_02 = 207374,
GO_DOODAD_ULDUM_LIGHTMACHINE_03 = 207377,
GO_DOODAD_ULDUM_LIGHTMACHINE_04 = 207376,
GO_DOODAD_ULDUM_LASERBEAMS01 = 207662, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_02
GO_DOODAD_ULDUM_LASERBEAMS_01 = 207663, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_01
GO_DOODAD_ULDUM_LASERBEAMS_02 = 207664, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_04
GO_DOODAD_ULDUM_LASERBEAMS_03 = 207665, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_03
};
enum AreaIds
enum Misc
{
AREA_TOMB_OF_THE_EARTHRAGER = 5610,
ACHIEV_VAULT_OF_LIGHTS_EVENT = 24212, // Faster Than The Speed Of Light
SPELL_VAULT_OF_LIGHTS_CREDIT = 94067, // Not in DBC
};
enum GlobalActions
{
ACTION_ANRAPHET_INTRO,
ACTION_ELEMENTAL_DIED,
ACTION_ANRAPHET_DIED,
ACTION_OMEGA_TRIGGER,
};
template<class AI>

View File

@@ -29,10 +29,19 @@
DoorData const doorData[] =
{
{GO_ANHUURS_DOOR, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_ANHUURS_BRIDGE, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_ELEVATOR_COL01, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
{GO_ANHUURS_DOOR, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_ANHUURS_BRIDGE, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_ELEVATOR_COL01, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_VAULT_OF_LIGHTS_DOOR, DATA_VAULT_OF_LIGHTS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LIGHTMACHINE_02, DATA_EARTH_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LASERBEAMS01, DATA_EARTH_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LIGHTMACHINE_01, DATA_FIRE_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LASERBEAMS_01, DATA_FIRE_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LIGHTMACHINE_03, DATA_WATER_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LASERBEAMS_03, DATA_WATER_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LIGHTMACHINE_04, DATA_AIR_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{GO_DOODAD_ULDUM_LASERBEAMS_02, DATA_AIR_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
};
class instance_halls_of_origination : public InstanceMapScript
@@ -51,6 +60,11 @@ class instance_halls_of_origination : public InstanceMapScript
AnhuursDoorGUID = 0;
AnhuurRightBeaconGUID = 0;
AnhuurLeftBeaconGUID = 0;
BrannBronzebeardGUID = 0;
AnraphetGUID = 0;
AnraphetDoorGUID = 0;
SunMirrorGUID = 0;
_deadElementals = 0;
}
void OnGameObjectCreate(GameObject* go)
@@ -60,6 +74,15 @@ class instance_halls_of_origination : public InstanceMapScript
case GO_ANHUURS_BRIDGE:
AnhuursBridgeGUID = go->GetGUID();
case GO_DOODAD_ULDUM_ELEVATOR_COL01:
case GO_VAULT_OF_LIGHTS_DOOR:
case GO_DOODAD_ULDUM_LIGHTMACHINE_01:
case GO_DOODAD_ULDUM_LIGHTMACHINE_02:
case GO_DOODAD_ULDUM_LIGHTMACHINE_03:
case GO_DOODAD_ULDUM_LIGHTMACHINE_04:
case GO_DOODAD_ULDUM_LASERBEAMS01:
case GO_DOODAD_ULDUM_LASERBEAMS_01:
case GO_DOODAD_ULDUM_LASERBEAMS_02:
case GO_DOODAD_ULDUM_LASERBEAMS_03:
AddDoor(go, true);
break;
case GO_ANHUURS_DOOR:
@@ -72,6 +95,12 @@ class instance_halls_of_origination : public InstanceMapScript
case GO_ANHUURS_LEFT_BEACON:
AnhuurLeftBeaconGUID = go->GetGUID();
break;
case GO_SUN_MIRROR:
SunMirrorGUID = go->GetGUID();
break;
case GO_ANRAPHET_DOOR:
AnraphetDoorGUID = go->GetGUID();
break;
}
}
@@ -82,6 +111,15 @@ class instance_halls_of_origination : public InstanceMapScript
case GO_ANHUURS_BRIDGE:
case GO_DOODAD_ULDUM_ELEVATOR_COL01:
case GO_ANHUURS_DOOR:
case GO_VAULT_OF_LIGHTS_DOOR:
case GO_DOODAD_ULDUM_LIGHTMACHINE_01:
case GO_DOODAD_ULDUM_LIGHTMACHINE_02:
case GO_DOODAD_ULDUM_LIGHTMACHINE_03:
case GO_DOODAD_ULDUM_LIGHTMACHINE_04:
case GO_DOODAD_ULDUM_LASERBEAMS01:
case GO_DOODAD_ULDUM_LASERBEAMS_01:
case GO_DOODAD_ULDUM_LASERBEAMS_02:
case GO_DOODAD_ULDUM_LASERBEAMS_03:
AddDoor(go, false);
break;
}
@@ -94,9 +132,28 @@ class instance_halls_of_origination : public InstanceMapScript
case BOSS_TEMPLE_GUARDIAN_ANHUUR:
TempleGuardianAnhuurGUID = creature->GetGUID();
break;
case NPC_BRANN_BRONZEBEARD_0:
BrannBronzebeardGUID = creature->GetGUID();
break;
case BOSS_ANRAPHET:
AnraphetGUID = creature->GetGUID();
break;
}
}
uint32 GetData(uint32 data) const
{
switch (data)
{
case DATA_DEAD_ELEMENTALS:
return _deadElementals;
default:
break;
}
return 0;
}
uint64 GetData64(uint32 index) const
{
switch (index)
@@ -111,17 +168,55 @@ class instance_halls_of_origination : public InstanceMapScript
return AnhuurRightBeaconGUID;
case DATA_ANHUUR_GUID:
return TempleGuardianAnhuurGUID;
case DATA_BRANN_0_GUID:
return BrannBronzebeardGUID;
case DATA_ANRAPHET_GUID:
return AnraphetGUID;
}
return 0;
}
void IncreaseDeadElementals(uint32 inc)
{
_deadElementals += inc;
if (_deadElementals == 4)
{
if (GameObject* mirror = instance->GetGameObject(SunMirrorGUID))
mirror->SetGoState(GO_STATE_ACTIVE);
if (GameObject* door = instance->GetGameObject(AnraphetDoorGUID))
door->SetGoState(GO_STATE_ACTIVE);
}
}
void OnUnitDeath(Unit* unit)
{
Creature* creature = unit->ToCreature();
if (!creature)
return;
switch (creature->GetEntry())
{
case NPC_FIRE_WARDEN:
case NPC_EARTH_WARDEN:
case NPC_WATER_WARDEN:
case NPC_AIR_WARDEN:
uint32 data = creature->GetEntry() - WARDEN_ENTRY_DATA_DELTA;
SetBossState(data, IN_PROGRESS); // Needs to be set to IN_PROGRESS or else the gameobjects state won't be updated
SetBossState(data, DONE);
IncreaseDeadElementals(1);
if (Creature* brann = instance->GetCreature(BrannBronzebeardGUID))
brann->AI()->DoAction(ACTION_ELEMENTAL_DIED);
break;
}
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << "H O " << GetBossSaveData();
saveStream << "H O " << GetBossSaveData() << _deadElementals;
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
@@ -152,6 +247,9 @@ class instance_halls_of_origination : public InstanceMapScript
tmpState = NOT_STARTED;
SetBossState(i, EncounterState(tmpState));
}
uint32 tmp;
loadStream >> tmp;
IncreaseDeadElementals(tmp);
}
else
OUT_LOAD_INST_DATA_FAIL;
@@ -165,6 +263,11 @@ class instance_halls_of_origination : public InstanceMapScript
uint64 AnhuursDoorGUID;
uint64 AnhuurRightBeaconGUID;
uint64 AnhuurLeftBeaconGUID;
uint64 BrannBronzebeardGUID;
uint64 AnraphetGUID;
uint64 AnraphetDoorGUID;
uint64 SunMirrorGUID;
uint32 _deadElementals;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const