Scripts/BrC: rewrite and finish Rom'Ogg Bonecrusher encounter

This commit is contained in:
Ovahlord
2018-07-24 00:30:11 +02:00
parent b3d0adcccb
commit 4adabd3605
5 changed files with 363 additions and 222 deletions

View File

@@ -0,0 +1,44 @@
-- Template Updates
-- Rom'Ogg Bonecrusher
UPDATE `creature_template` SET `flags_extra`= `flags_extra` | 2048 WHERE `entry` IN (39665, 39666);
-- Quake
UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 40401;
-- Angered Earth
UPDATE `creature_template` SET `DamageModifier`= 8 WHERE `entry`= 50376;
-- Chains of Woe
UPDATE `creature_template` SET `ScriptName`= '' WHERE `entry`= 40447;
UPDATE `creature_template` SET `InhabitType`= 12, `mechanic_immune_mask`= 1 | 2 | 16 | 32 | 256 | 512 | 2048 | 8192 | 65536 | 131072 | 8388608 | 33554432, `flags_extra`= 0x40000000 WHERE `entry` IN (40447, 50379);
-- Template Addons
DELETE FROM `creature_template_addon` WHERE `entry` IN (40401);
INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES
(40401, '75379');
-- Spells
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
('spell_romogg_quake',
'spell_chains_of_woe_1',
'spell_chains_of_woe_4',
'spell_romogg_chains_of_woe_teleport',
'spell_romogg_chains_of_woe_root',
'spell_romogg_chains_of_woe',
'spell_romogg_chains_of_woe_teleport_dest',
'spell_romogg_call_for_help');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(75272, 'spell_romogg_quake'),
(75437, 'spell_romogg_chains_of_woe_teleport'),
(82189, 'spell_romogg_chains_of_woe_root'),
(75539, 'spell_romogg_chains_of_woe'),
(75464, 'spell_romogg_chains_of_woe_teleport_dest'),
(82137, 'spell_romogg_call_for_help');
-- Achievement
DELETE FROM `achievement_criteria_data` WHERE `criteria_id`= 15943;
INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
(15943, 11, 0, 0, 'achievement_crushing_bones_and_cracking_skulls');
DELETE FROM `conditions` WHERE `SourceEntry`= 93454 AND `SourceTypeOrReferenceId`= 13;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES
(13, 2, 93454, 0, 0, 31, 0, 3, 50376, 0, 0, 0, '', 'The Skullcracker - Target Enraged Earth'),
(13, 2, 93454, 0, 1, 31, 0, 3, 40447, 0, 0, 0, '', 'The Skullcracker - Target Chains of Woe');

View File

@@ -613,12 +613,9 @@ class npc_raz_the_crazed : public CreatureScript
void IsSummonedBy(Unit* summoner) override
{
if (summoner->GetEntry() == NPC_ROMOGG_BONECRUSHER)
{
me->SetDisableGravity(true);
DoCast(me, SPELL_SHADOW_PRISON);
_events.ScheduleEvent(EVENT_AGGO_NEARBY_TARGETS, 1000);
}
me->SetDisableGravity(true);
DoCast(me, SPELL_SHADOW_PRISON);
_events.ScheduleEvent(EVENT_AGGO_NEARBY_TARGETS, 1000);
}
void SetData(uint32 id, uint32 data) override
@@ -670,115 +667,6 @@ class npc_raz_the_crazed : public CreatureScript
}
};
/*#####
# npc_chains_of_woe
#####*/
enum ChainsOfWoe
{
SPELL_CHAINS_OF_WOE_1 = 75437,
SPELL_CHAINS_OF_WOE_2 = 75441,
SPELL_CHAINS_OF_WOE_3 = 75464,
SPELL_CHAINS_OF_WOE_4 = 82189,
SPELL_CHAINS_OF_WOE_5 = 82192,
MODEL_INVISIBLE = 38330
};
class npc_chains_of_woe : public CreatureScript
{
public: npc_chains_of_woe() : CreatureScript("npc_chains_of_woe") { }
struct npc_chains_of_woeAI : public ScriptedAI
{
npc_chains_of_woeAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void IsSummonedBy(Unit* /*summoner*/) override
{
me->SetDisplayId(MODEL_INVISIBLE);
DoCast(me, SPELL_CHAINS_OF_WOE_1, true);
DoCast(me, SPELL_CHAINS_OF_WOE_2, true);
}
private:
InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockCavernsAI<npc_chains_of_woeAI>(creature);
}
};
/*#####
# spell_chains_of_woe_1
#####*/
class spell_chains_of_woe_1 : public SpellScriptLoader
{
public: spell_chains_of_woe_1() : SpellScriptLoader("spell_chains_of_woe_1") { }
class spell_chains_of_woe_1_SpellScript : public SpellScript
{
PrepareSpellScript(spell_chains_of_woe_1_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_CHAINS_OF_WOE_1 });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Player* playerTarget = GetHitPlayer())
playerTarget->CastSpell(GetCaster(), SPELL_CHAINS_OF_WOE_3, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_chains_of_woe_1_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_chains_of_woe_1_SpellScript();
}
};
/*#####
# spell_chains_of_woe_4
#####*/
class spell_chains_of_woe_4 : public SpellScriptLoader
{
public: spell_chains_of_woe_4() : SpellScriptLoader("spell_chains_of_woe_4") { }
class spell_chains_of_woe_4_SpellScript : public SpellScript
{
PrepareSpellScript(spell_chains_of_woe_4_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_CHAINS_OF_WOE_4 });
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (Player* playerTarget = GetHitPlayer())
playerTarget->CastSpell(playerTarget, SPELL_CHAINS_OF_WOE_5, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_chains_of_woe_4_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_chains_of_woe_4_SpellScript();
}
};
/*#####
# spell_nether_dragon_essence_1
#####*/
@@ -882,10 +770,7 @@ void AddSC_blackrock_caverns()
new npc_mad_prisoner();
new npc_crazed_mage();
new npc_raz_the_crazed();
new npc_chains_of_woe();
// Spell Scripts
new spell_chains_of_woe_1();
new spell_chains_of_woe_4();
new spell_nether_dragon_essence_1();
new spell_nether_dragon_essence_2();
}

View File

@@ -40,9 +40,17 @@ enum BRCDataTypes
enum BRCCreatureIds
{
// Bosses
BOSS_ROMOGG_BONECRUSHER = 39665,
// Encounter Related
/*Rom'Ogg Bonecrusher*/
NPC_CHAINS_OF_WOE = 40447,
NPC_ANGERED_EARTH = 50376,
NPC_QUAKE = 40401,
NPC_TWILIGHT_FLAME_CALLER = 39708,
NPC_RAZ_THE_CRAZED = 39670,
NPC_ROMOGG_BONECRUSHER = 39665
};
template <class AI, class T>
@@ -51,4 +59,6 @@ inline AI* GetBlackrockCavernsAI(T* obj)
return GetInstanceAI<AI>(obj, BCScriptName);
}
#define RegisterBlackrockCavernsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackrockCavernsAI)
#endif // BLACKROCKCAVERNS_H_

View File

@@ -19,121 +19,306 @@
#include "blackrock_caverns.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "Spell.h"
#include "SpellScript.h"
enum Romogg
enum Texts
{
YELL_AGGRO = 0,
YELL_KILL = 1,
YELL_SKULLCRACKER = 2,
YELL_DEATH = 3,
EMOTE_CALL_FOR_HELP = 4,
EMOTE_SKULLCRACKER = 5,
SPELL_CALL_FOR_HELP = 82137, // Needs Scripting
SPELL_CHAINS_OF_WOE = 75539,
SPELL_QUAKE = 75272,
SPELL_SKULLCRACKER = 75543,
SPELL_WOUNDING_STRIKE = 75571,
EVENT_CHAINS_OF_WOE = 1,
EVENT_QUAKE = 2, // Not yet sure of timing
EVENT_SKULLCRACKER = 3,
EVENT_WOUNDING_STRIKE = 4,
TYPE_RAZ = 1,
DATA_ROMOGG_DEAD = 1
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_CHAINS_OF_WOE = 2,
SAY_DEATH = 3,
SAY_EMOTE_CALL_FOR_HELP = 4,
SAY_ANNOUNCE_SKULLCRACKER = 5
};
Position const SummonPos = { 249.2639f, 949.1614f, 191.7866f, 3.141593f };
enum Spells
{
// Rom'Ogg Bonecrusher
SPELL_CALL_FOR_HELP = 82137,
SPELL_CHAINS_OF_WOE = 75539,
SPELL_QUAKE = 75272,
SPELL_THE_SKULLCRACKER = 75543,
SPELL_WOUNDING_STRIKE = 75571,
class boss_romogg_bonecrusher : public CreatureScript
// Chains of Woe
SPELL_CHAINS_OF_WOE_TELEPORT = 75437,
SPELL_CHAINS_OF_WOE_CHANNELED = 75441,
};
enum Events
{
// Rom'Ogg Bonecrusher
EVENT_CHAINS_OF_WOE = 1,
EVENT_QUAKE,
EVENT_SKULLCRACKER,
EVENT_WOUNDING_STRIKE
};
enum Data
{
DATA_CRUSHING_BONES_AND_CRACKING_SKULLS = 0
};
struct boss_romogg_bonecrusher : public BossAI
{
boss_romogg_bonecrusher(Creature* creature) : BossAI(creature, DATA_ROMOGG_BONECRUSHER)
{
Initialize();
}
void Initialize()
{
_killedElementals = 0;
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
Talk(SAY_DEATH);
}
void Reset() override
{
_Reset();
Initialize();
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
if (who->GetEntry() == NPC_ANGERED_EARTH)
_killedElementals++;
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
Talk(SAY_AGGRO);
Talk(SAY_EMOTE_CALL_FOR_HELP);
DoCast(me, SPELL_CALL_FOR_HELP);
events.ScheduleEvent(EVENT_CHAINS_OF_WOE, 30s);
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 16s);
events.ScheduleEvent(EVENT_QUAKE, 24s);
}
void EnterEvadeMode(EvadeReason why) override
{
_EnterEvadeMode();
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
_DespawnAtEvade();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_CHAINS_OF_WOE)
{
summon->SetReactState(REACT_PASSIVE);
summon->SetDisplayId(summon->GetCreatureTemplate()->Modelid2);
summon->CastSpell(summon, SPELL_CHAINS_OF_WOE_TELEPORT);
summon->CastSpell(summon, SPELL_CHAINS_OF_WOE_CHANNELED);
if (summon->IsAIEnabled)
summon->AI()->DoZoneInCombat();
}
else if (summon->GetEntry() == NPC_ANGERED_EARTH)
{
summon->SetCorpseDelay(5);
if (summon->IsAIEnabled)
summon->SetInCombatWithZone();
}
}
uint32 GetData(uint32 type) const override
{
if (type == DATA_CRUSHING_BONES_AND_CRACKING_SKULLS)
return _killedElementals >= 10;
return 0;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CHAINS_OF_WOE:
Talk(SAY_CHAINS_OF_WOE);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
DoCast(me, SPELL_CHAINS_OF_WOE);
events.ScheduleEvent(EVENT_SKULLCRACKER, 3s);
events.Repeat(35s);
break;
case EVENT_SKULLCRACKER:
Talk(SAY_ANNOUNCE_SKULLCRACKER);
DoCast(me, SPELL_THE_SKULLCRACKER);
me->SetReactState(REACT_AGGRESSIVE);
break;
case EVENT_QUAKE:
DoCast(me, SPELL_QUAKE);
events.ScheduleEvent(EVENT_QUAKE, 24s);
break;
case EVENT_WOUNDING_STRIKE:
DoCastVictim(SPELL_WOUNDING_STRIKE);
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 13s, 14s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
uint8 _killedElementals;
};
class spell_romogg_quake : public SpellScript
{
PrepareSpellScript(spell_romogg_quake);
void HandleScriptEffect(SpellEffIndex effIndex)
{
GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_romogg_quake::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_romogg_chains_of_woe : public SpellScript
{
PrepareSpellScript(spell_romogg_chains_of_woe);
void SetDest(SpellDestination& dest)
{
dest.RelocateOffset({ 0.0f, 0.0f, 1.6f, 0.0f });
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_romogg_chains_of_woe::SetDest, EFFECT_0, TARGET_DEST_CASTER_FRONT);
}
};
class spell_romogg_chains_of_woe_teleport : public SpellScript
{
PrepareSpellScript(spell_romogg_chains_of_woe_teleport);
void HandleScriptEffect(SpellEffIndex effIndex)
{
if (Unit* caster = GetCaster())
GetHitUnit()->CastSpell(caster, GetSpellInfo()->Effects[effIndex].BasePoints, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_romogg_chains_of_woe_teleport::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_romogg_chains_of_woe_teleport_dest : public SpellScript
{
PrepareSpellScript(spell_romogg_chains_of_woe_teleport_dest);
void SetDest(SpellDestination& dest)
{
Position pos = dest._position;
Unit* caster = GetCaster();
if (!caster)
return;
float dist = 3.0f; // Value taken from DBC value (3 yards)
float angle = pos.GetAngle(caster);
pos.m_positionX += cos(angle) * dist;
pos.m_positionY += sin(angle) * dist;
pos.m_positionZ = caster->GetMap()->GetStaticHeight(caster->GetPhaseShift(), pos.m_positionX, pos.m_positionY, caster->GetPositionZ(), true);
dest.Relocate(pos);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_romogg_chains_of_woe_teleport_dest::SetDest, EFFECT_0, TARGET_DEST_TARGET_RADIUS);
}
};
class spell_romogg_chains_of_woe_root : public SpellScript
{
PrepareSpellScript(spell_romogg_chains_of_woe_root);
void HandleScriptEffect(SpellEffIndex effIndex)
{
GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_romogg_chains_of_woe_root::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_romogg_call_for_help : public SpellScript
{
PrepareSpellScript(spell_romogg_call_for_help);
void HandleScriptEffect(SpellEffIndex effIndex)
{
if (Creature* creature = GetHitCreature())
if (creature->IsAIEnabled)
creature->AI()->DoZoneInCombat();
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_romogg_call_for_help::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class achievement_crushing_bones_and_cracking_skulls : public AchievementCriteriaScript
{
public:
boss_romogg_bonecrusher() : CreatureScript("boss_romogg_bonecrusher") { }
achievement_crushing_bones_and_cracking_skulls() : AchievementCriteriaScript("achievement_crushing_bones_and_cracking_skulls") { }
struct boss_romogg_bonecrusherAI : public BossAI
bool OnCheck(Player* /*source*/, Unit* target) override
{
boss_romogg_bonecrusherAI(Creature* creature) : BossAI(creature, DATA_ROMOGG_BONECRUSHER)
{
me->SummonCreature(NPC_RAZ_THE_CRAZED, SummonPos, TEMPSUMMON_MANUAL_DESPAWN, 200000);
}
if (!target)
return false;
void Reset() override
{
_Reset();
}
if (target->IsAIEnabled)
return target->GetAI()->GetData(DATA_CRUSHING_BONES_AND_CRACKING_SKULLS);
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(YELL_DEATH);
if (Creature* raz = instance->GetCreature(DATA_RAZ_THE_CRAZED))
raz->AI()->SetData(TYPE_RAZ, DATA_ROMOGG_DEAD);
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(YELL_KILL);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
events.ScheduleEvent(EVENT_CHAINS_OF_WOE, urand(22000, 32000));
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, urand(26000, 32000));
events.ScheduleEvent(EVENT_QUAKE, 45000);
Talk(YELL_AGGRO);
Talk(EMOTE_CALL_FOR_HELP);
DoCast(me, SPELL_CALL_FOR_HELP);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CHAINS_OF_WOE:
Talk(YELL_SKULLCRACKER);
DoCast(me, SPELL_CHAINS_OF_WOE);
events.ScheduleEvent(EVENT_CHAINS_OF_WOE, urand(22000, 32000));
events.ScheduleEvent(EVENT_SKULLCRACKER, 3000);
break;
case EVENT_SKULLCRACKER:
Talk(EMOTE_SKULLCRACKER);
DoCast(me, SPELL_SKULLCRACKER);
break;
case EVENT_QUAKE:
DoCast(me, SPELL_QUAKE);
events.ScheduleEvent(EVENT_QUAKE, urand(32000, 40000));
break;
case EVENT_WOUNDING_STRIKE:
DoCastVictim(SPELL_WOUNDING_STRIKE, true);
events.ScheduleEvent(EVENT_WOUNDING_STRIKE, urand(26000, 32000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockCavernsAI<boss_romogg_bonecrusherAI>(creature);
return false;
}
};
void AddSC_boss_romogg_bonecrusher()
{
new boss_romogg_bonecrusher();
RegisterBlackrockCavernsCreatureAI(boss_romogg_bonecrusher);
RegisterSpellScript(spell_romogg_quake);
RegisterSpellScript(spell_romogg_chains_of_woe);
RegisterSpellScript(spell_romogg_chains_of_woe_teleport);
RegisterSpellScript(spell_romogg_chains_of_woe_teleport_dest);
RegisterSpellScript(spell_romogg_chains_of_woe_root);
RegisterSpellScript(spell_romogg_call_for_help);
new achievement_crushing_bones_and_cracking_skulls();
}

View File

@@ -22,8 +22,9 @@
ObjectData const creatureData[] =
{
{ NPC_RAZ_THE_CRAZED, DATA_RAZ_THE_CRAZED },
{ 0, 0 }
{ BOSS_ROMOGG_BONECRUSHER, DATA_ROMOGG_BONECRUSHER },
{ NPC_RAZ_THE_CRAZED, DATA_RAZ_THE_CRAZED },
{ 0, 0 }
};
class instance_blackrock_caverns : public InstanceMapScript
@@ -59,6 +60,22 @@ class instance_blackrock_caverns : public InstanceMapScript
return true;
}
void OnCreatureCreate(Creature* creature) override
{
InstanceScript::OnCreatureCreate(creature);
switch (creature->GetEntry())
{
case NPC_QUAKE:
case NPC_ANGERED_EARTH:
if (Creature* romogg = GetCreature(DATA_ROMOGG_BONECRUSHER))
romogg->AI()->JustSummoned(creature);
break;
default:
break;
}
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override