Scripts/UBRS: The Beast (#20751)

This commit is contained in:
Riztazz
2017-12-16 01:58:45 +01:00
committed by Keader
parent 51c4196acf
commit 56b0433b6d
4 changed files with 259 additions and 60 deletions

View File

@@ -0,0 +1,34 @@
SET @PATH:= 137969 * 10;
DELETE FROM `waypoint_data` WHERE `id` = @PATH;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(@PATH, 1 , 117.894, -560.9407, 107.8397, 0, 0, 1, 0, 100, 0),
(@PATH, 2 , 104.644, -557.4407, 108.0897, 0, 0, 1, 0, 100, 0),
(@PATH, 3 , 99.9641, -555.8882, 109.5087, 0, 0, 1, 0, 100, 0),
(@PATH, 4 , 96.7141, -554.3882, 110.7587, 0, 0, 1, 0, 100, 0),
(@PATH, 5 , 95.2141, -553.8882, 110.7587, 0, 0, 1, 0, 100, 0),
(@PATH, 6 , 91.2141, -552.1382, 110.7587, 0, 0, 1, 0, 100, 0),
(@PATH, 7 , 89.7141, -551.3882, 111.0087, 0, 0, 1, 0, 100, 0),
(@PATH, 8 , 87.9641, -550.6382, 111.0087, 0, 0, 1, 0, 100, 0),
(@PATH, 9 , 89.5555, -551.2523, 111.0189, 0, 0, 1, 0, 100, 0),
(@PATH, 10, 87.8055, -550.5023, 111.0189, 0, 0, 1, 0, 100, 0),
(@PATH, 11, 82.5555, -548.2523, 111.0189, 0, 0, 1, 0, 100, 0),
(@PATH, 12, 55.5090, -534.9372, 110.9415, 0, 0, 1, 0, 100, 0),
(@PATH, 13, 27.8879, -513.8772, 110.9468, 0, 0, 1, 0, 100, 0),
(@PATH, 14, 17.0559, -545.8477, 110.9305, 0, 0, 1, 0, 100, 0),
(@PATH, 15, 74.8466, -549.6145, 110.9279, 0, 0, 1, 0, 100, 0),
(@PATH, 16, 70.5093, -524.7200, 110.9333, 0, 0, 1, 0, 100, 0),
(@PATH, 17, 78.7893, -549.1487, 110.9274, 0, 0, 1, 0, 100, 0);
DELETE FROM `areatrigger_scripts` WHERE `entry` IN (2066, 2067);
INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES
(2066, 'at_trigger_the_beast_movement'),
(2067, 'at_the_beast_room');
DELETE FROM `creature_text` WHERE `CreatureID` IN (10317, 10776);
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(10317, 0, 0, "We're doomed!", 14, 0, 100, 0, 0, 0, 5622, 0, 'Blackhand elite'),
(10776, 0, 0, "Leaping leper gnomes! I've been stuck in there for months. Thanks, gang.", 12, 0, 100, 0, 0, 0, 6066, 0, 'Finkle Einhorn');
-- Its not perm spawn, its dynamic depending if the beast has been skinned or not
DELETE FROM `creature` WHERE `guid` = 42637;

View File

@@ -75,7 +75,8 @@ enum BRSCreaturesIds
NPC_BLACKHAND_VETERAN = 9819,
NPC_BLACKHAND_INCARCERATOR = 10316,
NPC_LORD_VICTOR_NEFARIUS = 10162,
NPC_SCARSHIELD_INFILTRATOR = 10299
NPC_SCARSHIELD_INFILTRATOR = 10299,
NPC_FINKLE_EINHORN = 10776
};
enum BRSAdditionalData
@@ -85,7 +86,8 @@ enum BRSAdditionalData
EVENT_PYROGUARD_EMBERSEER = 4884,
AREATRIGGER = 1,
AREATRIGGER_DRAGONSPIRE_HALL = 2046,
AREATRIGGER_BLACKROCK_STADIUM = 2026
AREATRIGGER_BLACKROCK_STADIUM = 2026,
SAY_FINKLE_GANG = 0
};
enum BRSGameObjectsIds
@@ -128,4 +130,6 @@ inline AI* GetBlackrockSpireAI(T* obj)
return GetInstanceAI<AI>(obj, BRSScriptName);
}
#define RegisterBlackrockSpireCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackrockSpireAI)
#endif

View File

@@ -20,90 +20,247 @@
#include "blackrock_spire.h"
#include "ScriptedCreature.h"
enum Spells
enum BeastSpells
{
SPELL_FLAMEBREAK = 16785,
SPELL_IMMOLATE = 20294,
SPELL_IMMOLATE = 15570,
SPELL_TERRIFYINGROAR = 14100,
SPELL_BERSERKER_CHARGE = 16636,
SPELL_FIREBALL = 16788,
SPELL_FIREBLAST = 16144,
SPELL_FINKLE_IS_EINHORN = 16710,
SPELL_SUICIDE = 7
};
enum Events
enum BeastEvents
{
EVENT_FLAME_BREAK = 1,
EVENT_IMMOLATE = 2,
EVENT_TERRIFYING_ROAR = 3,
EVENT_FLAME_BREAK = 1,
EVENT_IMMOLATE = 2,
EVENT_TERRIFYING_ROAR = 3,
EVENT_BERSERKER_CHARGE = 4,
EVENT_FIREBALL = 5,
EVENT_FIREBLAST = 6
};
class boss_the_beast : public CreatureScript
enum BeastMisc
{
DATA_BEAST_REACHED = 1,
DATA_BEAST_ROOM = 2,
BEAST_MOVEMENT_ID = 1379690,
NPC_BLACKHAND_ELITE = 10317,
SAY_BLACKHAND_DOOMED = 0
};
Position const OrcsRunawayPosition = { 34.163567f, -536.852356f, 110.935196f, 6.056306f };
class OrcDeathEvent : public BasicEvent
{
public:
boss_the_beast() : CreatureScript("boss_the_beast") { }
OrcDeathEvent(Creature* me) : _me(me) { }
CreatureAI* GetAI(Creature* creature) const override
bool Execute(uint64 /*time*/, uint32 /*diff*/) override
{
return GetBlackrockSpireAI<boss_thebeastAI>(creature);
_me->CastSpell(_me, SPELL_SUICIDE, true);
return true;
}
struct boss_thebeastAI : public BossAI
private:
Creature* _me;
};
struct boss_the_beast : public BossAI
{
boss_the_beast(Creature* creature) : BossAI(creature, DATA_THE_BEAST), _beastReached(false), _orcYelled(false) { }
void Reset() override
{
boss_thebeastAI(Creature* creature) : BossAI(creature, DATA_THE_BEAST) { }
_Reset();
if (_beastReached)
me->GetMotionMaster()->MovePath(BEAST_MOVEMENT_ID, true);
}
void Reset() override
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (spell->Effects[i].IsEffect(SPELL_EFFECT_SKINNING))
if (!me->IsAlive()) // can that even happen?
DoCastAOE(SPELL_FINKLE_IS_EINHORN, true);
}
void SetData(uint32 type, uint32 /*data*/) override
{
switch (type)
{
_Reset();
case DATA_BEAST_ROOM:
{
if (!_orcYelled)
{
if (_nearbyOrcsGUIDs.empty())
FindNearbyOrcs();
//! vector still empty, creatures are missing
if (_nearbyOrcsGUIDs.empty())
return;
_orcYelled = true;
// we only need one orc to say the line
if (Creature* orc = ObjectAccessor::GetCreature(*me, _nearbyOrcsGUIDs.front()))
orc->AI()->Talk(SAY_BLACKHAND_DOOMED);
}
break;
}
case DATA_BEAST_REACHED:
{
if (!_beastReached)
{
_beastReached = true;
me->GetMotionMaster()->MovePath(BEAST_MOVEMENT_ID, true);
if (_nearbyOrcsGUIDs.empty())
FindNearbyOrcs();
for (ObjectGuid guid : _nearbyOrcsGUIDs)
{
if (Creature* orc = ObjectAccessor::GetCreature(*me, guid))
{
orc->GetMotionMaster()->MovePoint(1, orc->GetRandomPoint(OrcsRunawayPosition, 5.0f));
orc->m_Events.AddEvent(new OrcDeathEvent(orc), me->m_Events.CalculateTime(6 * IN_MILLISECONDS));
orc->SetReactState(REACT_PASSIVE);
}
}
// There is a chance player logged in between areatriggers (realm crash or restart)
// executing part of script which happens when player enters boss room
// otherwise we will see weird behaviour when someone steps on the previous areatrigger (dead mob yelling/moving)
SetData(DATA_BEAST_ROOM, DATA_BEAST_ROOM);
}
break;
}
}
}
void EnterCombat(Unit* /*who*/) override
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(EVENT_FLAME_BREAK, Seconds(12));
events.ScheduleEvent(EVENT_IMMOLATE, Seconds(3));
events.ScheduleEvent(EVENT_TERRIFYING_ROAR, Seconds(23));
events.ScheduleEvent(EVENT_BERSERKER_CHARGE, Seconds(2));
events.ScheduleEvent(EVENT_FIREBALL, Seconds(8), Seconds(21));
events.ScheduleEvent(EVENT_FIREBLAST, Seconds(5), Seconds(8));
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
_EnterCombat();
events.ScheduleEvent(EVENT_FLAME_BREAK, 12 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_IMMOLATE, 3 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_TERRIFYING_ROAR, 23 * IN_MILLISECONDS);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
switch (eventId)
{
case EVENT_FLAME_BREAK:
DoCastVictim(SPELL_FLAMEBREAK);
events.Repeat(Seconds(10));
break;
case EVENT_IMMOLATE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.f, true))
DoCast(target, SPELL_IMMOLATE);
events.Repeat(Seconds(8));
break;
case EVENT_TERRIFYING_ROAR:
DoCastVictim(SPELL_TERRIFYINGROAR);
events.Repeat(Seconds(20));
break;
case EVENT_BERSERKER_CHARGE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 38.f, true))
DoCast(target, SPELL_BERSERKER_CHARGE);
events.Repeat(Seconds(15), Seconds(23));
break;
case EVENT_FIREBALL:
DoCastVictim(SPELL_FIREBALL);
events.Repeat(Seconds(8), Seconds(21));
break;
case EVENT_FIREBLAST:
DoCastVictim(SPELL_FIREBLAST);
events.Repeat(Seconds(5), Seconds(8));
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_FLAME_BREAK:
DoCastVictim(SPELL_FLAMEBREAK);
events.ScheduleEvent(EVENT_FLAME_BREAK, 10 * IN_MILLISECONDS);
break;
case EVENT_IMMOLATE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_IMMOLATE);
events.ScheduleEvent(EVENT_IMMOLATE, 8 * IN_MILLISECONDS);
break;
case EVENT_TERRIFYING_ROAR:
DoCastVictim(SPELL_TERRIFYINGROAR);
events.ScheduleEvent(EVENT_TERRIFYING_ROAR, 20 * IN_MILLISECONDS);
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
DoMeleeAttackIfReady();
}
};
DoMeleeAttackIfReady();
}
void FindNearbyOrcs()
{
std::vector<Creature*> temp;
me->GetCreatureListWithEntryInGrid(temp, NPC_BLACKHAND_ELITE, 50.0f);
for (Creature* creature : temp)
_nearbyOrcsGUIDs.push_back(creature->GetGUID());
}
private:
bool _beastReached;
bool _orcYelled;
GuidVector _nearbyOrcsGUIDs;
};
//! The beast room areatrigger, this one triggers boss pathing. (AT Id 2066)
class at_trigger_the_beast_movement : public AreaTriggerScript
{
public:
at_trigger_the_beast_movement() : AreaTriggerScript("at_trigger_the_beast_movement") { }
bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override
{
if (player->IsGameMaster())
return false;
if (InstanceScript* instance = player->GetInstanceScript())
{
if (Creature* beast = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THE_BEAST)))
beast->AI()->SetData(DATA_BEAST_REACHED, DATA_BEAST_REACHED);
return true;
}
return false;
}
};
class at_the_beast_room : public AreaTriggerScript
{
public:
at_the_beast_room() : AreaTriggerScript("at_the_beast_room") { }
bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override
{
if (player->IsGameMaster())
return false;
if (InstanceScript* instance = player->GetInstanceScript())
{
if (Creature* beast = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THE_BEAST)))
beast->AI()->SetData(DATA_BEAST_ROOM, DATA_BEAST_ROOM);
return true;
}
return false;
}
};
void AddSC_boss_thebeast()
{
new boss_the_beast();
RegisterBlackrockSpireCreatureAI(boss_the_beast);
new at_trigger_the_beast_movement();
new at_the_beast_room();
}

View File

@@ -111,6 +111,9 @@ public:
case NPC_SCARSHIELD_INFILTRATOR:
ScarshieldInfiltrator = creature->GetGUID();
break;
case NPC_FINKLE_EINHORN:
creature->AI()->Talk(SAY_FINKLE_GANG);
break;
}
}
@@ -283,6 +286,7 @@ public:
if (GetBossState(DATA_DRAGONSPIRE_ROOM) != DONE)
Events.ScheduleEvent(EVENT_DARGONSPIRE_ROOM_STORE, 1000);
}
break;
default:
break;
}