diff options
author | Riztazz <felianther15@gmail.com> | 2017-12-16 01:58:45 +0100 |
---|---|---|
committer | Keader <keader.android@gmail.com> | 2017-12-15 21:58:45 -0300 |
commit | 56b0433b6d842e5928a453fc4bac837856ef91a7 (patch) | |
tree | 9e0a32c171a5b22a0cd8168a03a1a595d81529c1 /src | |
parent | 51c4196acf9d670601c0bba999498c8e7bb863dd (diff) |
Scripts/UBRS: The Beast (#20751)
Diffstat (limited to 'src')
3 files changed, 220 insertions, 55 deletions
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h index 8d9b2c393bb..949f201f2ba 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/blackrock_spire.h @@ -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 diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_the_beast.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_the_beast.cpp index 6b1c72cb715..432ae0d44da 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_the_beast.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_the_beast.cpp @@ -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 - { - _Reset(); - } + 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 EnterCombat(Unit* /*who*/) override + void SetData(uint32 type, uint32 /*data*/) override + { + switch (type) { - _EnterCombat(); - events.ScheduleEvent(EVENT_FLAME_BREAK, 12 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_IMMOLATE, 3 * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_TERRIFYING_ROAR, 23 * IN_MILLISECONDS); + 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 + { + _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; - void JustDied(Unit* /*killer*/) override + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - _JustDied(); + 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; } + 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") { } + - void UpdateAI(uint32 diff) override + bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override + { + if (player->IsGameMaster()) + return false; + + if (InstanceScript* instance = player->GetInstanceScript()) { - if (!UpdateVictim()) - return; + if (Creature* beast = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_THE_BEAST))) + beast->AI()->SetData(DATA_BEAST_REACHED, DATA_BEAST_REACHED); + return true; + } + return false; + } +}; - events.Update(diff); +class at_the_beast_room : public AreaTriggerScript +{ +public: + at_the_beast_room() : AreaTriggerScript("at_the_beast_room") { } - 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; - } + bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override + { + if (player->IsGameMaster()) + return false; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - DoMeleeAttackIfReady(); + 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(); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp index 21fe1450a3b..05b047f10dc 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/instance_blackrock_spire.cpp @@ -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; } |