Ruby Sanctum:

- Scripted Saviana Ragefire
- Moved Baltharus the Warborn's clone from smartai to cpp (this because they share healthpool with Baltharus the Warborn, witch cant be done with SAI)
This commit is contained in:
kaelima
2011-05-30 14:36:19 +02:00
parent eccbc87f6b
commit c143319b05
9 changed files with 459 additions and 11 deletions

View File

@@ -0,0 +1,3 @@
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=74455;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(13,0,74455,0,18,1,39747,0,0,'', 'Spell 74455 targets only Saviana Ragefire');

View File

@@ -0,0 +1,13 @@
-- Saviana Ragefire
UPDATE `creature_template` SET `InhabitType`=3,`mechanic_immune_mask`=`mechanic_immune_mask`|8388624,`ScriptName`= 'boss_saviana_ragefire' WHERE `entry`=39747;
DELETE FROM `creature_text` WHERE `entry`=39747;
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(39747,0,0, 'You will sssuffer for this intrusion!',14,0,100,0,0,17528, 'Saviana Ragefire'),
(39747,1,0, 'Burn in the master''s flame!',14,0,100,0,0,17532, 'Saviana Ragefire'),
(39747,2,0, '%s becomes enraged!',16,0,100,0,0,0, 'Saviana Ragefire'),
(39747,3,0, 'Halion will be pleased.',14,0,100,0,0,17530, 'Saviana Ragefire'),
(39747,3,1, 'As it should be....',14,0,100,0,0,17529, 'Saviana Ragefire');
-- Baltharus the Warborn Clone
UPDATE `creature_template` SET `AIName`= '',`ScriptName`= 'npc_baltarhus_the_warborn_clone' WHERE `entry`=39899;
DELETE FROM `smart_scripts` WHERE `entryorguid`=39899;

View File

@@ -0,0 +1,5 @@
DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_saviana_conflagration_init';
DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_saviana_conflagration_throwback';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(74452, 'spell_saviana_conflagration_init'),
(74455, 'spell_saviana_conflagration_throwback');

View File

@@ -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();

View File

@@ -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")

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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>