aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/scripts/Northrend/CMakeLists.txt1
-rw-r--r--src/server/scripts/Northrend/RubySanctum/boss_baltharus_the_warborn.cpp86
-rw-r--r--src/server/scripts/Northrend/RubySanctum/boss_saviana_ragefire.cpp264
-rw-r--r--src/server/scripts/Northrend/RubySanctum/instance_ruby_sanctum.cpp85
-rw-r--r--src/server/scripts/Northrend/RubySanctum/ruby_sanctum.h11
6 files changed, 438 insertions, 11 deletions
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 2bd8bfdacd0..e68f6adef90 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -483,6 +483,7 @@ void AddSC_icecrown_citadel();
void AddSC_instance_ruby_sanctum(); // Ruby Sanctum
void AddSC_ruby_sanctum();
void AddSC_boss_baltharus_the_warborn();
+void AddSC_boss_saviana_ragefire();
void AddSC_dalaran();
void AddSC_borean_tundra();
@@ -1181,6 +1182,7 @@ void AddNorthrendScripts()
AddSC_instance_ruby_sanctum(); // Ruby Sanctum
AddSC_ruby_sanctum();
AddSC_boss_baltharus_the_warborn();
+ AddSC_boss_saviana_ragefire();
AddSC_dalaran();
AddSC_borean_tundra();
diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt
index 68852f5e34b..cd28cf5a506 100644
--- a/src/server/scripts/Northrend/CMakeLists.txt
+++ b/src/server/scripts/Northrend/CMakeLists.txt
@@ -189,6 +189,7 @@ set(scripts_STAT_SRCS
Northrend/RubySanctum/ruby_sanctum.h
Northrend/RubySanctum/ruby_sanctum.cpp
Northrend/RubySanctum/boss_baltharus_the_warborn.cpp
+ Northrend/RubySanctum/boss_saviana_ragefire.cpp
)
message(" -> Prepared: Northrend")
diff --git a/src/server/scripts/Northrend/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/RubySanctum/boss_baltharus_the_warborn.cpp
index bccb5c1bd81..bd9b478a035 100644
--- a/src/server/scripts/Northrend/RubySanctum/boss_baltharus_the_warborn.cpp
+++ b/src/server/scripts/Northrend/RubySanctum/boss_baltharus_the_warborn.cpp
@@ -84,6 +84,7 @@ class boss_baltharus_the_warborn : public CreatureScript
events.SetPhase(PHASE_INTRO);
events.ScheduleEvent(EVENT_OOC_CHANNEL, 0, 0, PHASE_INTRO);
_cloneCount = RAID_MODE<uint8>(1, 2, 2, 2);
+ instance->SetData(DATA_BALTHARUS_SHARED_HEALTH, me->GetMaxHealth());
}
void DoAction(int32 const action)
@@ -157,6 +158,9 @@ class boss_baltharus_the_warborn : public CreatureScript
else if (me->HealthBelowPctDamaged(33, damage) && _cloneCount == 1)
DoAction(ACTION_CLONE);
}
+
+ if (me->GetHealth() - damage > 0)
+ instance->SetData(DATA_BALTHARUS_SHARED_HEALTH, me->GetHealth() - damage);
}
void UpdateAI(uint32 const diff)
@@ -164,6 +168,9 @@ class boss_baltharus_the_warborn : public CreatureScript
if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK))
return;
+ if (!(events.GetPhaseMask() & PHASE_INTRO_MASK))
+ me->SetHealth(instance->GetData(DATA_BALTHARUS_SHARED_HEALTH));
+
events.Update(diff);
if (me->HasUnitState(UNIT_STAT_CASTING) && !(events.GetPhaseMask() & PHASE_INTRO_MASK))
@@ -214,6 +221,84 @@ class boss_baltharus_the_warborn : public CreatureScript
}
};
+class npc_baltarhus_the_warborn_clone : public CreatureScript
+{
+ public:
+ npc_baltarhus_the_warborn_clone() : CreatureScript("npc_baltarhus_the_warborn_clone") { }
+
+ struct npc_baltarhus_the_warborn_cloneAI : public ScriptedAI
+ {
+ npc_baltarhus_the_warborn_cloneAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = (InstanceScript*)creature->GetInstanceScript();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoZoneInCombat();
+ _events.ScheduleEvent(EVENT_CLEAVE, urand(5000, 10000));
+ _events.ScheduleEvent(EVENT_BLADE_TEMPEST, urand(18000, 25000));
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
+ {
+ // Setting DATA_BALTHARUS_SHARED_HEALTH to 0 when killed would bug the boss.
+ if (_instance && me->GetHealth() - damage > 0)
+ _instance->SetData(DATA_BALTHARUS_SHARED_HEALTH, me->GetHealth() - damage);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ // This is here because DamageTaken wont trigger if the damage is deadly.
+ if (_instance)
+ if (Creature* baltarhus = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_BALTHARUS_THE_WARBORN)))
+ killer->Kill(baltarhus);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (_instance)
+ me->SetHealth(_instance->GetData(DATA_BALTHARUS_SHARED_HEALTH));
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CLEAVE:
+ DoCastVictim(SPELL_CLEAVE);
+ _events.ScheduleEvent(EVENT_CLEAVE, 24000);
+ break;
+ case EVENT_BLADE_TEMPEST:
+ DoCastVictim(SPELL_BLADE_TEMPEST);
+ _events.ScheduleEvent(EVENT_BLADE_TEMPEST, 24000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetRubySanctumAI<npc_baltarhus_the_warborn_cloneAI>(creature);
+ }
+};
+
class spell_baltharus_enervating_brand : public SpellScriptLoader
{
public:
@@ -299,6 +384,7 @@ class spell_baltharus_enervating_brand_trigger : public SpellScriptLoader
void AddSC_boss_baltharus_the_warborn()
{
new boss_baltharus_the_warborn();
+ new npc_baltarhus_the_warborn_clone();
new spell_baltharus_enervating_brand();
new spell_baltharus_enervating_brand_trigger();
}
diff --git a/src/server/scripts/Northrend/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/RubySanctum/boss_saviana_ragefire.cpp
new file mode 100644
index 00000000000..3bf34c42c03
--- /dev/null
+++ b/src/server/scripts/Northrend/RubySanctum/boss_saviana_ragefire.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2008-2011 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 "ScriptPCH.h"
+#include "ruby_sanctum.h"
+
+enum Texts
+{
+ SAY_AGGRO = 0, // You will sssuffer for this intrusion! (17528)
+ SAY_CONFLAGRATION = 1, // Burn in the master's flame! (17532)
+ EMOTE_ENRAGED = 2, // %s becomes enraged!
+ SAY_KILL = 3, // Halion will be pleased. (17530) - As it should be.... (17529)
+};
+
+enum Spells
+{
+ SPELL_CONFLAGRATION = 74452,
+ SPELL_FLAME_BEACON = 74453,
+ SPELL_CONFLAGRATION_2 = 74454, // Unknown dummy effect
+ SPELL_ENRAGE = 78722,
+ SPELL_FLAME_BREATH = 74403,
+};
+
+enum Events
+{
+ EVENT_ENRAGE = 1,
+ EVENT_FLIGHT = 2,
+ EVENT_FLAME_BREATH = 3,
+ EVENT_CONFLAGRATION = 4,
+
+ // Event group
+ EVENT_GROUP_LAND_PHASE = 1,
+};
+
+enum MovementPoints
+{
+ POINT_FLIGHT = 1,
+ POINT_LAND = 2,
+};
+
+enum Misc
+{
+ SOUND_ID_DEATH = 17531,
+};
+
+Position const SavianaRagefireFlyPos = {3155.51f, 683.844f, 95.20f, 4.69f};
+Position const SavianaRagefireLandPos = {3151.07f, 636.443f, 79.54f, 4.69f};
+
+class boss_saviana_ragefire : public CreatureScript
+{
+ public:
+ boss_saviana_ragefire() : CreatureScript("boss_saviana_ragefire") { }
+
+ struct boss_saviana_ragefireAI : public BossAI
+ {
+ boss_saviana_ragefireAI(Creature* creature) : BossAI(creature, DATA_SAVIANA_RAGEFIRE)
+ {
+ }
+
+ void Reset()
+ {
+ _Reset();
+ me->SetReactState(REACT_AGGRESSIVE);
+ events.ScheduleEvent(EVENT_ENRAGE, 20000, EVENT_GROUP_LAND_PHASE);
+ events.ScheduleEvent(EVENT_FLAME_BREATH, 30000, EVENT_GROUP_LAND_PHASE);
+ events.ScheduleEvent(EVENT_FLIGHT, 50000);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ _JustDied();
+ me->PlayDirectSound(SOUND_ID_DEATH);
+ }
+
+ void MovementInform(uint32 type, uint32 point)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (point)
+ {
+ case POINT_FLIGHT:
+ events.ScheduleEvent(EVENT_CONFLAGRATION, 1000);
+ Talk(SAY_CONFLAGRATION);
+ break;
+ case POINT_LAND:
+ me->SetFlying(false);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetReactState(REACT_AGGRESSIVE);
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
+ me->GetMotionMaster()->MovementExpired();
+ DoStartMovement(me->getVictim());
+ break;
+ default:
+ break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ _JustReachedHome();
+ me->SetFlying(false);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_KILL);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FLIGHT:
+ {
+ me->SetFlying(true);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MovePoint(POINT_FLIGHT, SavianaRagefireFlyPos);
+ events.ScheduleEvent(EVENT_FLIGHT, 50000);
+ events.DelayEvents(12500, EVENT_GROUP_LAND_PHASE);
+ break;
+ }
+ case EVENT_CONFLAGRATION:
+ DoCast(me, SPELL_CONFLAGRATION, true);
+ break;
+ case EVENT_ENRAGE:
+ DoCast(me, SPELL_ENRAGE);
+ Talk(EMOTE_ENRAGED);
+ events.ScheduleEvent(EVENT_ENRAGE, urand(15000, 20000), EVENT_GROUP_LAND_PHASE);
+ break;
+ case EVENT_FLAME_BREATH:
+ DoCastVictim(SPELL_FLAME_BREATH);
+ events.ScheduleEvent(EVENT_FLAME_BREATH, urand(20000, 30000), EVENT_GROUP_LAND_PHASE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetRubySanctumAI<boss_saviana_ragefireAI>(creature);
+ }
+};
+
+class ConflagrationTargetSelector
+{
+ public:
+ ConflagrationTargetSelector() { }
+
+ bool operator()(Unit* unit)
+ {
+ return unit->GetTypeId() != TYPEID_PLAYER;
+ }
+};
+
+class spell_saviana_conflagration_init : public SpellScriptLoader
+{
+ public:
+ spell_saviana_conflagration_init() : SpellScriptLoader("spell_saviana_conflagration_init") { }
+
+ class spell_saviana_conflagration_init_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_saviana_conflagration_init_SpellScript);
+
+ void FilterTargets(std::list<Unit*>& unitList)
+ {
+ unitList.remove_if(ConflagrationTargetSelector());
+ uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3);
+ if (unitList.size() > maxSize)
+ Trinity::RandomResizeList(unitList, maxSize);
+ }
+
+ void HandleDummy(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_FLAME_BEACON, true);
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_CONFLAGRATION_2, true);
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
+ OnEffect += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_saviana_conflagration_init_SpellScript();
+ }
+};
+
+class spell_saviana_conflagration_throwback : public SpellScriptLoader
+{
+ public:
+ spell_saviana_conflagration_throwback() : SpellScriptLoader("spell_saviana_conflagration_throwback") { }
+
+ class spell_saviana_conflagration_throwback_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_saviana_conflagration_throwback_SpellScript);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
+ GetHitUnit()->GetMotionMaster()->MovePoint(POINT_LAND, SavianaRagefireLandPos);
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_saviana_conflagration_throwback_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_saviana_conflagration_throwback_SpellScript();
+ }
+};
+
+void AddSC_boss_saviana_ragefire()
+{
+ new boss_saviana_ragefire();
+ new spell_saviana_conflagration_init();
+ new spell_saviana_conflagration_throwback();
+}
diff --git a/src/server/scripts/Northrend/RubySanctum/instance_ruby_sanctum.cpp b/src/server/scripts/Northrend/RubySanctum/instance_ruby_sanctum.cpp
index 88f0a0fc217..8d4e1e2ad0c 100644
--- a/src/server/scripts/Northrend/RubySanctum/instance_ruby_sanctum.cpp
+++ b/src/server/scripts/Northrend/RubySanctum/instance_ruby_sanctum.cpp
@@ -38,10 +38,12 @@ class instance_ruby_sanctum : public InstanceMapScript
LoadDoorData(doorData);
BaltharusTheWarbornGUID = 0;
GeneralZarithrianGUID = 0;
- SavinaRagefireGUID = 0;
+ SavianaRagefireGUID = 0;
HalionGUID = 0;
CrystalChannelTargetGUID = 0;
XerestraszaGUID = 0;
+ BaltharusSharedHealth = 0;
+ FlameWallsGUID = 0;
}
void OnCreatureCreate(Creature* creature)
@@ -54,8 +56,8 @@ class instance_ruby_sanctum : public InstanceMapScript
case NPC_GENERAL_ZARITHRIAN:
GeneralZarithrianGUID = creature->GetGUID();
break;
- case NPC_SAVINA_RAGEFIRE:
- SavinaRagefireGUID = creature->GetGUID();
+ case NPC_SAVIANA_RAGEFIRE:
+ SavianaRagefireGUID = creature->GetGUID();
break;
case NPC_HALION:
HalionGUID = creature->GetGUID();
@@ -78,6 +80,9 @@ class instance_ruby_sanctum : public InstanceMapScript
case GO_FIRE_FIELD:
AddDoor(go, true);
break;
+ case GO_FLAME_WALLS:
+ FlameWallsGUID = go->GetGUID();
+ break;
default:
break;
}
@@ -103,8 +108,8 @@ class instance_ruby_sanctum : public InstanceMapScript
return BaltharusTheWarbornGUID;
case DATA_GENERAL_ZARITHRIAN:
return GeneralZarithrianGUID;
- case DATA_SAVINA_RAGEFIRE:
- return SavinaRagefireGUID;
+ case DATA_SAVIANA_RAGEFIRE:
+ return SavianaRagefireGUID;
case DATA_HALION:
return HalionGUID;
case DATA_CRYSTAL_CHANNEL_TARGET:
@@ -118,6 +123,72 @@ class instance_ruby_sanctum : public InstanceMapScript
return 0;
}
+ bool SetBossState(uint32 type, EncounterState state)
+ {
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ switch (type)
+ {
+ case DATA_BALTHARUS_THE_WARBORN:
+ {
+ if (state == DONE && GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE)
+ {
+ // GO_FLAME_WALLS
+ if (GameObject* flameWalls = instance->GetGameObject(FlameWallsGUID))
+ {
+ flameWalls->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ flameWalls->SetGoState(GO_STATE_READY);
+ }
+ if (Creature* zarithrian = instance->GetCreature(GeneralZarithrianGUID))
+ zarithrian->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE)
+ }
+ break;
+ }
+ case DATA_SAVIANA_RAGEFIRE:
+ {
+ if (state == DONE && GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE)
+ {
+ if (GameObject* flameWalls = instance->GetGameObject(FlameWallsGUID))
+ {
+ flameWalls->SetUInt32Value(GAMEOBJECT_LEVEL, 0);
+ flameWalls->SetGoState(GO_STATE_READY);
+ }
+ if (Creature* zarithrian = instance->GetCreature(GeneralZarithrianGUID))
+ zarithrian->RemoveFlag(UNIT_FLAG, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch (type)
+ {
+ case DATA_BALTHARUS_SHARED_HEALTH:
+ BaltharusSharedHealth = data;
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch (type)
+ {
+ case DATA_BALTHARUS_SHARED_HEALTH:
+ return BaltharusSharedHealth;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
@@ -165,10 +236,12 @@ class instance_ruby_sanctum : public InstanceMapScript
protected:
uint64 BaltharusTheWarbornGUID;
uint64 GeneralZarithrianGUID;
- uint64 SavinaRagefireGUID;
+ uint64 SavianaRagefireGUID;
uint64 HalionGUID;
uint64 CrystalChannelTargetGUID;
uint64 XerestraszaGUID;
+ uint64 FlameWallsGUID;
+ uint32 BaltharusSharedHealth;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const
diff --git a/src/server/scripts/Northrend/RubySanctum/ruby_sanctum.h b/src/server/scripts/Northrend/RubySanctum/ruby_sanctum.h
index 60b4c9f3e92..4ece06807cf 100644
--- a/src/server/scripts/Northrend/RubySanctum/ruby_sanctum.h
+++ b/src/server/scripts/Northrend/RubySanctum/ruby_sanctum.h
@@ -30,12 +30,13 @@ enum DataTypes
// Encounter States/Boss GUIDs
DATA_BALTHARUS_THE_WARBORN = 0,
DATA_GENERAL_ZARITHRIAN = 1,
- DATA_SAVINA_RAGEFIRE = 2,
+ DATA_SAVIANA_RAGEFIRE = 2,
DATA_HALION = 3,
// Etc
DATA_XERESTRASZA = 4,
DATA_CRYSTAL_CHANNEL_TARGET = 5,
+ DATA_BALTHARUS_SHARED_HEALTH = 6,
};
enum SharedActions
@@ -57,7 +58,7 @@ enum CreaturesIds
NPC_ZARITHIAN_SPAWN_STALKER = 39794,
// Saviana Ragefire
- NPC_SAVINA_RAGEFIRE = 39747,
+ NPC_SAVIANA_RAGEFIRE = 39747,
// Halion
NPC_HALION = 39863,
@@ -86,9 +87,9 @@ enum GameObjectsIds
enum WorldStatesRS
{
- WORLDSTATE_UNK_1 = 5049,
- WORLDSTATE_UNK_2 = 5050,
- WORLDSTATE_UNK_3 = 5051,
+ WORLDSTATE_UNK_1 = 5049, // Halion corporeality amount - normal phase
+ WORLDSTATE_UNK_2 = 5050, // Halion corporeality amount - twilight phase
+ WORLDSTATE_UNK_3 = 5051, // Halion corporeality toggle show
};
template<class AI>