diff options
Diffstat (limited to 'src')
5 files changed, 573 insertions, 0 deletions
diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.cpp b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.cpp new file mode 100644 index 00000000000..0a7268a10eb --- /dev/null +++ b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.cpp @@ -0,0 +1,218 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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 "AreaTrigger.h" +#include "AreaTriggerAI.h" +#include "Conversation.h" +#include "InstanceScript.h" +#include "MotionMaster.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Unit.h" +#include "aberrus_the_shadowed_crucible.h" + +enum AberrusEvents +{ + EVENT_SABELLIAN_MOVE = 1, + EVENT_SABELLIAN_MOVE_HOME_POS, + EVENT_KAZZARA_INTRO, + EVENT_KAZZARA_INTRO_DONE +}; + +enum AberrusPaths +{ + PATH_SARKARETH = (202416 * 10) << 3, + PATH_WINGLORD_DEZRAN = (202610 * 10) << 3, + PATH_ZSKARN = (202637 * 10) << 3 +}; + +enum AberrusSpells +{ + SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_1 = 400785, // Sabellian and Wrathion + SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_2 = 403340, // Sabellian and Sarkareth +}; + +enum AberrusMisc +{ + // Sabellian intro + CONVO_ACTOR_IDX_SABELLIAN = 0, + + CONVO_SABELLIAN_INTRO_LINE_01 = 56690, + CONVO_SABELLIAN_INTRO_LINE_02 = 56692, + + // Kazzara intro + CONVO_ACTOR_IDX_WINGLORD_DEZRAN = 0, + CONVO_ACTOR_IDX_ZSKARN = 1, + CONVO_ACTOR_IDX_SARKARETH = 2, + + CONVO_SARKARETH_LAST_LINE = 57821 +}; + +Position const SabellianIntroConvoMovePosition = { 2250.6372f, 2482.3003f, 711.9592f }; + +// Id 26 - Areatrigger +struct at_aberrus_sabellian_conversation_intro : AreaTriggerAI +{ + at_aberrus_sabellian_conversation_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + void OnUnitEnter(Unit* unit) override + { + Player* player = unit->ToPlayer(); + if (!player) + return; + + Creature* sabellian = unit->FindNearestCreature(NPC_SABELLIAN_AT_ABERRUS_ENTRANCE, 50.0f); + + if (!sabellian) + return; + + sabellian->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_1); + at->Remove(); + } +}; + +// Id 27 - Areatrigger +struct at_aberrus_sarkareth_conversation_intro : AreaTriggerAI +{ + at_aberrus_sarkareth_conversation_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + void OnUnitEnter(Unit* unit) override + { + Player* player = unit->ToPlayer(); + if (!player) + return; + + Creature* sabellian = unit->FindNearestCreature(NPC_SABELLIAN_AT_ABERRUS_ENTRANCE, 50.0f); + + if (!sabellian) + return; + + sabellian->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_2); + at->Remove(); + } +}; + +// 20800 - Conversation +class conversation_aberrus_sabellian_intro : public ConversationScript +{ +public: + conversation_aberrus_sabellian_intro() : ConversationScript("conversation_aberrus_sabellian_intro") { } + + void OnConversationStart(Conversation* conversation) override + { + if (Milliseconds const* sabellianMoveStartTime = conversation->GetLineStartTime(DEFAULT_LOCALE, CONVO_SABELLIAN_INTRO_LINE_01)) + _events.ScheduleEvent(EVENT_SABELLIAN_MOVE, *sabellianMoveStartTime); + + if (Milliseconds const* sabellianHomeMoveStartTime = conversation->GetLineStartTime(DEFAULT_LOCALE, CONVO_SABELLIAN_INTRO_LINE_02)) + _events.ScheduleEvent(EVENT_SABELLIAN_MOVE_HOME_POS, *sabellianHomeMoveStartTime + Seconds(2)); + } + + void OnConversationUpdate(Conversation* conversation, uint32 diff) override + { + _events.Update(diff); + + switch (_events.ExecuteEvent()) + { + case EVENT_SABELLIAN_MOVE: + { + Creature* sabellian = conversation->GetActorCreature(CONVO_ACTOR_IDX_SABELLIAN); + if (!sabellian) + break; + + sabellian->SetWalk(true); + sabellian->GetMotionMaster()->MovePoint(0, SabellianIntroConvoMovePosition); + break; + } + case EVENT_SABELLIAN_MOVE_HOME_POS: + { + Creature* sabellian = conversation->GetActorCreature(CONVO_ACTOR_IDX_SABELLIAN); + if (!sabellian) + break; + + sabellian->SetWalk(true); + sabellian->GetMotionMaster()->MovePoint(0, sabellian->ToCreature()->GetHomePosition(), false, sabellian->ToCreature()->GetHomePosition().GetOrientation()); + break; + } + default: + break; + } + } + +private: + EventMap _events; +}; + +// 20985 - Conversation +class conversation_aberrus_kazzara_intro : public ConversationScript +{ +public: + conversation_aberrus_kazzara_intro() : ConversationScript("conversation_aberrus_kazzara_intro") { } + + void OnConversationStart(Conversation* conversation) override + { + _events.ScheduleEvent(EVENT_KAZZARA_INTRO, conversation->GetLineEndTime(DEFAULT_LOCALE, CONVO_SARKARETH_LAST_LINE)); + } + + void OnConversationUpdate(Conversation* conversation, uint32 diff) override + { + _events.Update(diff); + + switch (_events.ExecuteEvent()) + { + case EVENT_KAZZARA_INTRO: + { + Creature* winglordDezran = conversation->GetActorCreature(CONVO_ACTOR_IDX_WINGLORD_DEZRAN); + Creature* zskarn = conversation->GetActorCreature(CONVO_ACTOR_IDX_ZSKARN); + Creature* sarkareth = conversation->GetActorCreature(CONVO_ACTOR_IDX_SARKARETH); + + if (!winglordDezran || !zskarn || !sarkareth) + return; + + sarkareth->GetMotionMaster()->MovePath(PATH_SARKARETH, false); + sarkareth->DespawnOrUnsummon(45s); + + winglordDezran->GetMotionMaster()->MovePath(PATH_WINGLORD_DEZRAN, false); + winglordDezran->DespawnOrUnsummon(45s); + + zskarn->GetMotionMaster()->MovePath(PATH_ZSKARN, false); + zskarn->DespawnOrUnsummon(45s, Seconds::max()); // override respawn time to prevent instant respawn due to CREATURE_FLAG_EXTRA_DUNGEON_BOSS + + if (InstanceScript* instance = conversation->GetInstanceScript()) + { + instance->SetData(DATA_KAZZARA_INTRO_DONE, 1); + if (Creature* kazzara = instance->GetCreature(DATA_KAZZARA_THE_HELLFORGED)) + kazzara->AI()->DoAction(ACTION_START_KAZZARA_INTRO); + } + break; + } + default: + break; + } + } + +private: + EventMap _events; +}; + +void AddSC_aberrus_the_shadowed_crucible() +{ + RegisterAreaTriggerAI(at_aberrus_sabellian_conversation_intro); + RegisterAreaTriggerAI(at_aberrus_sarkareth_conversation_intro); + + new conversation_aberrus_sabellian_intro(); + new conversation_aberrus_kazzara_intro(); +} diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h new file mode 100644 index 00000000000..e1797e26faf --- /dev/null +++ b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h @@ -0,0 +1,92 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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/>. + */ + +#ifndef DEF_ABERRUS_THE_SHADOWED_CRUCIBLE_H_ +#define DEF_ABERRUS_THE_SHADOWED_CRUCIBLE_H_ + +#include "CreatureAIImpl.h" + +#define ATSCScriptName "instance_aberrus_the_shadowed_crucible" +#define DataHeader "Aberrus" + +uint32 const EncounterCount = 9; + +enum AberrusDataTypes +{ + // Encounters + DATA_KAZZARA_THE_HELLFORGED = 0, + DATA_THE_AMALGAMATION_CHAMBER = 1, + DATA_THE_FORGOTTEN_EXPERIMENTS = 2, + DATA_ASSAULT_OF_THE_ZAQALI = 3, + DATA_RASHOK_THE_ELDER = 4, + DATA_ZSKARN_THE_VIGILANT_STEWARD = 5, + DATA_MAGMORAX = 6, + DATA_ECHO_OF_NELTHARION = 7, + DATA_SCALECOMMANDER_SARKARETH = 8, + + // Additional Data + DATA_KAZZARA_GATE, + + // Misc + DATA_KAZZARA_INTRO_DONE +}; + +enum AberrusCreatureIds +{ + // Bosses + BOSS_KAZZARA_THE_HELLFORGED = 201261, + + BOSS_ETERNAL_BLAZE = 201773, + BOSS_ESSENCE_OF_SHADOW = 201774, + BOSS_SHADOWFLAME_AMALGAMATION = 201934, + + BOSS_NELDRIS = 200912, + BOSS_THADRION = 200913, + BOSS_RIONTHUS = 200918, + + BOSS_WARLORD_KAGNI = 199659, + BOSS_RASHOK_THE_ELDER = 201320, + BOSS_ZSKARN_THE_VIGILANT_STEWARD = 202637, + BOSS_MAGMORAX = 201579, + BOSS_ECHO_OF_NELTHARION = 204223, + BOSS_SCALECOMMANDER_SARKARETH = 205319, + + // Misc + NPC_SABELLIAN_AT_ABERRUS_ENTRANCE = 201575 +}; + +enum AberrusGameObjectIds +{ + GO_KAZZARA_DOOR = 398742, + GO_KAZZARA_GATE = 397996, + GO_INVISIBLE_DOOR = 398588 +}; + +enum AberrusSharedActions +{ + ACTION_START_KAZZARA_INTRO = 0, +}; + +template <class AI, class T> +inline AI* GetAberrusTheShadowedCrucibleAI(T* obj) +{ + return GetInstanceAI<AI>(obj, ATSCScriptName); +} + +#define RegisterAberrusTheShadowedCrucibleCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAberrusTheShadowedCrucibleAI) + +#endif diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/boss_kazzara_the_hellforged.cpp b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/boss_kazzara_the_hellforged.cpp new file mode 100644 index 00000000000..ed7e7328a2c --- /dev/null +++ b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/boss_kazzara_the_hellforged.cpp @@ -0,0 +1,102 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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 "CellImpl.h" +#include "GameObject.h" +#include "GridNotifiersImpl.h" +#include "InstanceScript.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "aberrus_the_shadowed_crucible.h" + +enum KazzaraSpells +{ + // Sundered NPCs + SPELL_FEAR = 220540, + + // Kazzara + SPELL_DREAD_LANDING = 411872, + SPELL_KAZZARA_INTRO = 410541 +}; + +// 201261 - Kazzara the Hellforged +struct boss_kazzara_the_hellforged : public BossAI +{ + boss_kazzara_the_hellforged(Creature* creature) : BossAI(creature, DATA_KAZZARA_THE_HELLFORGED) { } + + void JustAppeared() override + { + if (!instance->GetData(DATA_KAZZARA_INTRO_DONE)) + { + me->SetUninteractible(true); + me->SetImmuneToAll(true); + me->SetVisible(false); + } + } + + void DoAction(int32 actionId) override + { + switch (actionId) + { + case ACTION_START_KAZZARA_INTRO: + { + if (GameObject* gate = instance->GetGameObject(DATA_KAZZARA_GATE)) + { + gate->SetFlag(GO_FLAG_IN_USE); + gate->SetGoState(GO_STATE_READY); + } + + me->SetVisible(true); + + DoCast(SPELL_DREAD_LANDING); + DoCast(SPELL_KAZZARA_INTRO); + + scheduler.Schedule(1s + 500ms, [this](TaskContext /*context*/) + { + std::vector<Creature*> sunderedMobs; + GetCreatureListWithOptionsInGrid(sunderedMobs, me, 50.0f, FindCreatureOptions().SetStringId("sundered_mob")); + for (Creature* sunderedMob : sunderedMobs) + { + if (!sunderedMob->IsAlive() || sunderedMob->IsInCombat()) + continue; + + sunderedMob->CastSpell(nullptr, SPELL_FEAR, false); + } + }); + + scheduler.Schedule(12s, [this](TaskContext /*context*/) + { + me->SetUninteractible(false); + me->SetImmuneToAll(false); + }); + break; + } + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + } +}; + +void AddSC_boss_kazzara_the_hellforged() +{ + RegisterAberrusTheShadowedCrucibleCreatureAI(boss_kazzara_the_hellforged); +} diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp new file mode 100644 index 00000000000..a606d97717b --- /dev/null +++ b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp @@ -0,0 +1,151 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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 "InstanceScript.h" +#include "ScriptMgr.h" +#include "Unit.h" +#include "aberrus_the_shadowed_crucible.h" + +ObjectData const creatureData[] = +{ + { BOSS_KAZZARA_THE_HELLFORGED, DATA_KAZZARA_THE_HELLFORGED }, + { BOSS_SHADOWFLAME_AMALGAMATION, DATA_THE_AMALGAMATION_CHAMBER }, + { BOSS_RIONTHUS, DATA_THE_FORGOTTEN_EXPERIMENTS }, + { BOSS_WARLORD_KAGNI, DATA_ASSAULT_OF_THE_ZAQALI }, + { BOSS_RASHOK_THE_ELDER, DATA_RASHOK_THE_ELDER }, + { BOSS_ZSKARN_THE_VIGILANT_STEWARD, DATA_ZSKARN_THE_VIGILANT_STEWARD }, + { BOSS_MAGMORAX, DATA_MAGMORAX }, + { BOSS_ECHO_OF_NELTHARION, DATA_ECHO_OF_NELTHARION }, + { BOSS_SCALECOMMANDER_SARKARETH, DATA_SCALECOMMANDER_SARKARETH }, + { 0, 0 } // END +}; + +DoorData const doorData[] = +{ + { GO_KAZZARA_DOOR, DATA_KAZZARA_THE_HELLFORGED, DOOR_TYPE_ROOM }, + { 0, 0, DOOR_TYPE_ROOM } // END +}; + +ObjectData const objectData[] = +{ + { GO_KAZZARA_GATE, DATA_KAZZARA_GATE }, + { 0, 0 } // END +}; + +DungeonEncounterData const encounters[] = +{ + { DATA_KAZZARA_THE_HELLFORGED, {{ 2688 }} }, + { DATA_THE_AMALGAMATION_CHAMBER, {{ 2687 }} }, + { DATA_THE_FORGOTTEN_EXPERIMENTS, {{ 2693 }} }, + { DATA_ASSAULT_OF_THE_ZAQALI, {{ 2682 }} }, + { DATA_RASHOK_THE_ELDER, {{ 2680 }} }, + { DATA_ZSKARN_THE_VIGILANT_STEWARD, {{ 2689 }} }, + { DATA_MAGMORAX, {{ 2683 }} }, + { DATA_ECHO_OF_NELTHARION, {{ 2684 }} }, + { DATA_SCALECOMMANDER_SARKARETH, {{ 2685 }} } +}; + +enum AberrusInstanceCreatureIds +{ + NPC_SCALECOMMANDER_SARKARETH_AT_KAZZARA = 202416 +}; + +enum AberrusInstanceSpells +{ + SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_3 = 403409 // Winglord Dezran, Sarkareth and Zskarn (Kazzara Summon) +}; + +class instance_aberrus_the_shadowed_crucible : public InstanceMapScript +{ +public: + instance_aberrus_the_shadowed_crucible() : InstanceMapScript(ATSCScriptName, 2569) { } + + struct instance_aberrus_the_shadowed_crucible_InstanceMapScript: public InstanceScript + { + instance_aberrus_the_shadowed_crucible_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + LoadObjectData(creatureData, objectData); + LoadDoorData(doorData); + LoadDungeonEncounterData(encounters); + + _kazzaraIntroDone = false; + _deadSunderedMobs = 0; + } + + uint32 GetData(uint32 dataId) const override + { + switch (dataId) + { + case DATA_KAZZARA_INTRO_DONE: + return _kazzaraIntroDone ? 1 : 0; + default: + break; + } + return 0; + } + + void SetData(uint32 dataId, uint32 /*value*/) override + { + switch (dataId) + { + case DATA_KAZZARA_INTRO_DONE: + _kazzaraIntroDone = true; // no need to pass value, it will never reset to false + break; + default: + break; + } + } + + void OnUnitDeath(Unit* unit) override + { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + + if (creature->HasStringId("sundered_mob")) + { + if (_deadSunderedMobs >= 6) + return; + + _deadSunderedMobs++; + if (_deadSunderedMobs >= 6) + { + Creature* sarkareth = creature->FindNearestCreature(NPC_SCALECOMMANDER_SARKARETH_AT_KAZZARA, 300.0f); + if (!sarkareth) + return; + sarkareth->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_3); + } + } + } + + private: + uint8 _deadSunderedMobs; + bool _kazzaraIntroDone; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_aberrus_the_shadowed_crucible_InstanceMapScript(map); + } +}; + +void AddSC_instance_aberrus_the_shadowed_crucible() +{ + new instance_aberrus_the_shadowed_crucible(); +} diff --git a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp b/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp index 39123bc1c02..32150946143 100644 --- a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp +++ b/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp @@ -26,6 +26,11 @@ void AddSC_ruby_life_pools(); void AddSC_instance_azure_vault(); void AddSC_boss_leymor(); +// Aberrus the Shadowed Crucible +void AddSC_instance_aberrus_the_shadowed_crucible(); +void AddSC_aberrus_the_shadowed_crucible(); +void AddSC_boss_kazzara_the_hellforged(); + // The name of this function should match: // void Add${NameOfDirectory}Scripts() void AddDragonIslesScripts() @@ -39,4 +44,9 @@ void AddDragonIslesScripts() // Azure Vault AddSC_instance_azure_vault(); AddSC_boss_leymor(); + + // Aberrus the Shadowed Crucible + AddSC_instance_aberrus_the_shadowed_crucible(); + AddSC_aberrus_the_shadowed_crucible(); + AddSC_boss_kazzara_the_hellforged(); } |