diff options
6 files changed, 457 insertions, 0 deletions
diff --git a/sql/updates/hotfixes/master/2204_10_07_00_hotfixes.sql b/sql/updates/hotfixes/master/2204_10_07_00_hotfixes.sql new file mode 100644 index 00000000000..174d3d09e4c --- /dev/null +++ b/sql/updates/hotfixes/master/2204_10_07_00_hotfixes.sql @@ -0,0 +1,10 @@ +DELETE FROM `broadcast_text` WHERE `ID` IN (256584, 256583, 256581, 256930, 256580, 256562, 256546, 257387); +INSERT INTO `broadcast_text` (`Text`, `Text1`, `ID`, `LanguageID`, `ConditionID`, `EmotesID`, `Flags`, `ChatBubbleDurationMs`, `VoiceOverPriorityID`, `SoundKitID1`, `SoundKitID2`, `EmoteID1`, `EmoteID2`, `EmoteID3`, `EmoteDelay1`, `EmoteDelay2`, `EmoteDelay3`, `VerifiedBuild`) VALUES +('', 'Ulgrax, feed.', 256584, 0, 0, 0, 0, 0, 4, 0, 249814, 0, 0, 0, 0, 0, 0, 56819), +('', 'I appreciate you making the extermination of your futile resistance all the easier.', 256583, 0, 0, 0, 0, 0, 4, 0, 249813, 0, 0, 0, 0, 0, 0, 56819), +('', 'The pathetic conspirators have finally crawled from their holes to attack my palace?', 256581, 0, 0, 0, 0, 0, 4, 0, 249812, 0, 0, 0, 0, 0, 0, 56819), +('Invaders! Sound the alarm.', 'Invaders! Sound the alarm.', 256930, 0, 0, 0, 0, 0, 4, 246765, 253836, 0, 0, 0, 0, 0, 0, 56819), +('Otherwise you will be encumbered with additional forces.', '', 256580, 0, 0, 0, 0, 0, 4, 249811, 0, 0, 0, 0, 0, 0, 0, 56819), +('Dispatch these guards before they can raise an alarm.', '', 256562, 0, 0, 0, 0, 0, 4, 249810, 0, 0, 0, 0, 0, 0, 0, 56819), +('I have redirected forces loyal to me away from the entrance.', '', 256546, 0, 0, 0, 0, 0, 4, 249808, 0, 0, 0, 0, 0, 0, 0, 56819), +('', 'I told you that you were destined for great things. Rejoice, for you have aided the end of all things.', 257387, 0, 0, 0, 0, 0, 4, 0, 251930, 0, 0, 0, 0, 0, 0, 56819); diff --git a/sql/updates/world/master/2024_10_07_00_world.sql b/sql/updates/world/master/2024_10_07_00_world.sql new file mode 100644 index 00000000000..b6c793ef2d4 --- /dev/null +++ b/sql/updates/world/master/2024_10_07_00_world.sql @@ -0,0 +1,64 @@ +SET @ATID := 96; +SET @ATCP := 85; +SET @ATSPAWNID := 99; + +-- Creature +UPDATE `creature_template` SET `flags_extra`=536870912, `ScriptName`='boss_ulgrax_the_devourer' WHERE `entry`=215657; -- CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING must be added since the combat is on a gameobject + +DELETE FROM `creature_formations` WHERE `leaderGUID`=10001982; +INSERT INTO `creature_formations` (`leaderGUID`,`memberGUID`,`dist`,`angle`,`groupAI`,`point_1`,`point_2`) VALUES +(10001982,10001982,0,0,0,0,0), +(10001982,10002001,0,0,0,0,0), +(10001982,10001998,0,0,0,0,0), +(10001982,10001995,0,0,0,0,0), +(10001982,10001989,0,0,0,0,0); +UPDATE `creature` SET `StringId`='nerubar_palace_intro_trash' WHERE `guid` IN (10001982, 10002001, 10001998, 10001995, 10001989); + +DELETE FROM `creature_formations` WHERE `leaderGUID`=10001991; +INSERT INTO `creature_formations` (`leaderGUID`,`memberGUID`,`dist`,`angle`,`groupAI`,`point_1`,`point_2`) VALUES +(10001991,10001991,0,0,0,0,0), +(10001991,10002009,0,0,0,0,0), +(10001991,10002016,0,0,0,0,0), +(10001991,10002018,0,0,0,0,0), +(10001991,10002006,0,0,0,0,0), +(10001991,10002010,0,0,0,0,0); +UPDATE `creature` SET `StringId`='ulgrax_intro_trash' WHERE `guid` IN (10001991, 10002009, 10002016, 10002018, 10002006, 10002010); + +-- Instance +DELETE FROM `instance_template` WHERE `map`=2657; +INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES +(2657, 0, 'instance_nerubar_palace'); + +-- Areatrigger +DELETE FROM `areatrigger_template` WHERE `Id` = @ATID+0; +INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `ActionSetId`, `ActionSetFlags`, `VerifiedBuild`) VALUES +(@ATID+0, 1, 1, 0, 0, 0); + +DELETE FROM `areatrigger_create_properties` WHERE `Id` = @ATID+0; +INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES +(@ATCP+0, 1, @ATID+0, 1, 0, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 1, 30, 60, 2, 30, 60, 2, 0, 0, 'at_ulgrax_intro', 0); + +DELETE FROM `areatrigger` WHERE `SpawnId` = @ATID+0; +INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerCreatePropertiesId`, `IsCustom`, `MapId`, `SpawnDifficulties`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `PhaseId`, `PhaseGroup`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES +(@ATSPAWNID+0, @ATCP+0, 1, 2657, '14,15,16,17', -2841.09, -273.894, -1189.997, 5.509477, 0, 0, 0, '', 'Nerub\'ar Palace - Ulgrax the Devourer intro', 0); + +-- Conversation +DELETE FROM `conversation_line_template` WHERE `Id` IN (66068, 66067, 66066); +INSERT INTO `conversation_line_template` (`Id`, `UiCameraID`, `ActorIdx`, `Flags`, `ChatType`, `VerifiedBuild`) VALUES +(66068, 0, 0, 1, 1, 56513), +(66067, 0, 0, 1, 1, 56513), +(66066, 0, 0, 1, 1, 56513); + +DELETE FROM `conversation_template` WHERE `Id` = 24332; +INSERT INTO `conversation_template` (`Id`, `FirstLineID`, `TextureKitId`, `VerifiedBuild`) VALUES +(24332, 66066, 0, 56513); + +DELETE FROM `conversation_actors` WHERE `ConversationId`=24332 AND `Idx`=0; +INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `ConversationActorGuid`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES +(24332, 97324, 10002046, 0, 0, 0, 0, 0, 56513); + +-- Spells +DELETE FROM `spell_script_names` WHERE `spell_id` IN (451409, 451411); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(451409, 'spell_ulgrax_the_devourer_swallowing_darkness_intro'), +(451411, 'spell_ulgrax_the_devourer_swallowing_darkness_teleport'); diff --git a/src/server/scripts/KhazAlgar/NerubarPalace/boss_ulgrax_the_devourer.cpp b/src/server/scripts/KhazAlgar/NerubarPalace/boss_ulgrax_the_devourer.cpp new file mode 100644 index 00000000000..1506141977d --- /dev/null +++ b/src/server/scripts/KhazAlgar/NerubarPalace/boss_ulgrax_the_devourer.cpp @@ -0,0 +1,160 @@ +/* + * 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 "Player.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "nerubar_palace.h" + +enum UlgraxTheDevourerSpells +{ + // Intro + SPELL_SWALLOWING_DARKNESS = 451409, + SPELL_SWALLOWING_DARKNESS_TELEPORT = 451411, + SPELL_SWALLOWING_DARKNESS_DAMAGE = 451412 +}; + +enum UlgraxTheDevourerConversations +{ + CONVERSATION_ULGRAX_INTRO = 24332 +}; + +enum UlgraxTheDevourerPoints +{ + POINT_ULGRAX_INTRO = 1 +}; + +constexpr Position UlgraxStartTeleportPosition = { -2991.9705f, -124.82639f, -1137.0024f }; +constexpr Position UlgraxStartCombatPosition = { -2862.7395f, -251.90973f, -1189.6f, 5.550147f }; + +// Id xxxx - Areatrigger +struct at_ulgrax_intro : AreaTriggerAI +{ + at_ulgrax_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + void OnUnitEnter(Unit* unit) override + { + InstanceScript* instance = at->GetInstanceScript(); + if (!instance) + return; + + Player* player = unit->ToPlayer(); + if (!player || player->IsGameMaster()) + return; + + if (Creature* queenAnsurek = instance->GetCreature(DATA_QUEEN_ANSUREK)) + Conversation::CreateConversation(CONVERSATION_ULGRAX_INTRO, queenAnsurek, queenAnsurek->GetPosition(), ObjectGuid::Empty); + + if (Creature* ulgrax = instance->GetCreature(DATA_ULGRAX_THE_DEVOURER)) + ulgrax->GetMotionMaster()->MovePoint(POINT_ULGRAX_INTRO, UlgraxStartTeleportPosition); + + at->Remove(); + } +}; + +// 215657 - Ulgrax the Devourer +struct boss_ulgrax_the_devourer : public BossAI +{ + boss_ulgrax_the_devourer(Creature* creature) : BossAI(creature, DATA_ULGRAX_THE_DEVOURER) { } + + void MovementInform(uint32 /*type*/, uint32 id) override + { + if (id == POINT_ULGRAX_INTRO) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_BATTLE_ROAR); + + scheduler.Schedule(2s, [this](TaskContext context) + { + DoCastSelf(SPELL_SWALLOWING_DARKNESS); + + context.Schedule(11s, [this](TaskContext /*context*/) + { + me->SetHomePosition(UlgraxStartCombatPosition); + me->SetImmuneToAll(false); + }); + }); + } + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + + if (!UpdateVictim()) + return; + } +}; + +// 451409 - Swallowing Darkness +class spell_ulgrax_the_devourer_swallowing_darkness_intro : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SWALLOWING_DARKNESS_TELEPORT }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_SWALLOWING_DARKNESS_TELEPORT, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ulgrax_the_devourer_swallowing_darkness_intro::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 451411 - Swallowing Darkness +class spell_ulgrax_the_devourer_swallowing_darkness_teleport : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SWALLOWING_DARKNESS_DAMAGE }); + } + + void SetDest(SpellDestination& dest) + { + dest.Relocate(UlgraxStartCombatPosition); + } + + void HandleAfterHit() + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_SWALLOWING_DARKNESS_DAMAGE, true); + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_ulgrax_the_devourer_swallowing_darkness_teleport::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + AfterHit += SpellHitFn(spell_ulgrax_the_devourer_swallowing_darkness_teleport::HandleAfterHit); + } +}; + +void AddSC_boss_ulgrax_the_devourer() +{ + RegisterAreaTriggerAI(at_ulgrax_intro); + RegisterNerubarPalaceCreatureAI(boss_ulgrax_the_devourer); + RegisterSpellScript(spell_ulgrax_the_devourer_swallowing_darkness_intro); + RegisterSpellScript(spell_ulgrax_the_devourer_swallowing_darkness_teleport); +} diff --git a/src/server/scripts/KhazAlgar/NerubarPalace/instance_nerubar_palace.cpp b/src/server/scripts/KhazAlgar/NerubarPalace/instance_nerubar_palace.cpp new file mode 100644 index 00000000000..5eb404571b3 --- /dev/null +++ b/src/server/scripts/KhazAlgar/NerubarPalace/instance_nerubar_palace.cpp @@ -0,0 +1,121 @@ +/* + * 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 "AreaBoundary.h" +#include "Creature.h" +#include "CreatureGroups.h" +#include "GameObject.h" +#include "InstanceScript.h" +#include "ScriptMgr.h" +#include "nerubar_palace.h" + +static constexpr ObjectData creatureData[] = +{ + { BOSS_ULGRAX_THE_DEVOURER, DATA_ULGRAX_THE_DEVOURER }, + { BOSS_THE_BLOODBOUND_HORROR, DATA_THE_BLOODBOUND_HORROR }, + { BOSS_SIKRAN, DATA_SIKRAN }, + { BOSS_RASHANAN, DATA_RASHANAN }, + { BOSS_BROODTWISTER_OVINAX, DATA_BROODTWISTER_OVINAX }, + { BOSS_NEXUS_PRINCESS_KYVEZA, DATA_NEXUS_PRINCESS_KYVEZA }, + { BOSS_ANUBARASH, DATA_THE_SILKEN_COURT }, + { BOSS_QUEEN_ANSUREK, DATA_QUEEN_ANSUREK }, + { 0, 0 } // END +}; + +static constexpr DoorData doorData[] = +{ + { GO_WEB_BRIDGE_ULGRAX_INTRO, DATA_WEB_BRIDGE_ULGRAX_INTRO, EncounterDoorBehavior::OpenWhenNotInProgress }, + { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END +}; + +static constexpr ObjectData objectData[] = +{ + { GO_NERUBAR_PALACE_DOOR_INTRO, DATA_NERUBAR_PALACE_DOOR_INTRO }, + { GO_WEB_BRIDGE_ULGRAX_INTRO, DATA_WEB_BRIDGE_ULGRAX_INTRO }, + { 0, 0 } // END +}; + +static BossBoundaryData const boundaries = +{ + { DATA_ULGRAX_THE_DEVOURER, new CircleBoundary(Position(-2862.7395f, -251.90973f), 150.0f) } +}; + +static constexpr DungeonEncounterData const encounters[] = +{ + { DATA_ULGRAX_THE_DEVOURER, {{ 2902 }} }, + { DATA_THE_BLOODBOUND_HORROR, {{ 2917 }} }, + { DATA_SIKRAN, {{ 2898 }} }, + { DATA_RASHANAN, {{ 2918 }} }, + { DATA_BROODTWISTER_OVINAX, {{ 2919 }} }, + { DATA_NEXUS_PRINCESS_KYVEZA, {{ 2920 }} }, + { DATA_THE_SILKEN_COURT, {{ 2921 }} }, + { DATA_QUEEN_ANSUREK, {{ 2922 }} } +}; + +class instance_nerubar_palace : public InstanceMapScript +{ +public: + instance_nerubar_palace() : InstanceMapScript(NPScriptName, 2657) { } + + struct instance_nerubar_palace_InstanceMapScript: public InstanceScript + { + instance_nerubar_palace_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + LoadObjectData(creatureData, objectData); + LoadDoorData(doorData); + LoadBossBoundaries(boundaries); + LoadDungeonEncounterData(encounters); + + _entranceRoomCleared = false; + _ulgraxIntroDone = false; + } + + void OnCreatureGroupDepleted(CreatureGroup const* creatureGroup) override + { + if (!_entranceRoomCleared && creatureGroup->LeaderHasStringId("nerubar_palace_intro_trash")) + { + _entranceRoomCleared = true; + + if (GameObject* door = GetGameObject(DATA_NERUBAR_PALACE_DOOR_INTRO)) + door->UseDoorOrButton(); + } + else if (!_ulgraxIntroDone && creatureGroup->LeaderHasStringId("ulgrax_intro_trash")) + { + _ulgraxIntroDone = true; + + if (GameObject* webBridge = GetGameObject(DATA_WEB_BRIDGE_ULGRAX_INTRO)) + webBridge->UseDoorOrButton(); + } + } + + protected: + bool _entranceRoomCleared; + bool _ulgraxIntroDone; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_nerubar_palace_InstanceMapScript(map); + } +}; + +void AddSC_instance_nerubar_palace() +{ + new instance_nerubar_palace(); +} diff --git a/src/server/scripts/KhazAlgar/NerubarPalace/nerubar_palace.h b/src/server/scripts/KhazAlgar/NerubarPalace/nerubar_palace.h new file mode 100644 index 00000000000..8990daad1ca --- /dev/null +++ b/src/server/scripts/KhazAlgar/NerubarPalace/nerubar_palace.h @@ -0,0 +1,72 @@ +/* + * 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_NERUBAR_PALACE_H_ +#define DEF_NERUBAR_PALACE_H_ + +#include "CreatureAIImpl.h" + +#define NPScriptName "instance_nerubar_palace" +#define DataHeader "NerubarPalace" + +uint32 const EncounterCount = 8; + +enum NerubarPalaceDataTypes +{ + // Encounters + DATA_ULGRAX_THE_DEVOURER = 0, + DATA_THE_BLOODBOUND_HORROR = 1, + DATA_SIKRAN = 2, + DATA_RASHANAN = 3, + DATA_BROODTWISTER_OVINAX = 4, + DATA_NEXUS_PRINCESS_KYVEZA = 5, + DATA_THE_SILKEN_COURT = 6, + DATA_QUEEN_ANSUREK = 7, + + // Additional Data + DATA_NERUBAR_PALACE_DOOR_INTRO, + DATA_WEB_BRIDGE_ULGRAX_INTRO +}; + +enum NerubarPalaceCreatureIds +{ + // Bosses + BOSS_ULGRAX_THE_DEVOURER = 215657, + BOSS_THE_BLOODBOUND_HORROR = 214502, + BOSS_SIKRAN = 219853, + BOSS_RASHANAN = 224552, + BOSS_BROODTWISTER_OVINAX = 214506, + BOSS_NEXUS_PRINCESS_KYVEZA = 228470, + BOSS_ANUBARASH = 223779, + BOSS_QUEEN_ANSUREK = 219778 +}; + +enum NerubarPalaceGameObjectIds +{ + GO_NERUBAR_PALACE_DOOR_INTRO = 444355, + GO_WEB_BRIDGE_ULGRAX_INTRO = 437052 +}; + +template <class AI, class T> +inline AI* GetNerubarPalaceAI(T* obj) +{ + return GetInstanceAI<AI>(obj, NPScriptName); +} + +#define RegisterNerubarPalaceCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetNerubarPalaceAI) + +#endif diff --git a/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp b/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp new file mode 100644 index 00000000000..d67f17a6373 --- /dev/null +++ b/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp @@ -0,0 +1,30 @@ +/* + * 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/>. + */ + +// This is where scripts' loading functions should be declared: +// Nerub'ar Palace +void AddSC_instance_nerubar_palace(); +void AddSC_boss_ulgrax_the_devourer(); + +// The name of this function should match: +// void Add${NameOfDirectory}Scripts() +void AddKhazAlgarScripts() +{ + // Nerub'ar Palace + AddSC_instance_nerubar_palace(); + AddSC_boss_ulgrax_the_devourer(); +} |
