diff --git a/sql/updates/world/master/2026_02_01_01_world.sql b/sql/updates/world/master/2026_02_01_01_world.sql new file mode 100644 index 0000000000..5b837bbded --- /dev/null +++ b/sql/updates/world/master/2026_02_01_01_world.sql @@ -0,0 +1,89 @@ +-- Template +UPDATE `creature_template` SET `faction`=35, `npcflag`=1, `BaseAttackTime`=2000, `unit_flags2`=0x800 WHERE `entry`=233253; -- Arator + +UPDATE `creature_template` SET `ScriptName` = 'npc_vereesa_windrunner_oztan_isle', `AIName` = '' WHERE `entry` = 231042; + +-- Phasing (Update Condition) +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId`=26 AND `SourceGroup` = 25024 AND `SourceEntry` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `Comment`) VALUE +(26, 25024, 0, 0, 0, 47, 0, 92405, 2|8|64, 0, 0, 'Apply Phase 25024 if Quest 92405 is taken|complete|rewarded'), +(26, 25024, 0, 0, 0, 47, 0, 84996, 2|64, 0, 1, 'Apply Phase 25024 if Quest 84996 is complete|rewarded'); + +-- Conversation +DELETE FROM `conversation_template` WHERE `Id`=27493; +INSERT INTO `conversation_template` (`Id`, `FirstLineID`, `TextureKitId`, `VerifiedBuild`) VALUES +(27493, 75392, 0, 65299); + +UPDATE `conversation_template` SET `ScriptName` = 'conversation_vereesas_tale' WHERE `Id` = 27493; + +DELETE FROM `conversation_actors` WHERE (`ConversationId`=27493 AND `Idx` IN (0,1)); +INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES +(27493, 102984, 0, 0, 0, 0, 0, 65299), -- Full: 0x2042653F00E1A0800000200000677C99 Creature/0 R4249/S32 Map: 2552 (Khaz Algar (Surface)) Entry: 231042 (Vereesa Windrunner) Low: 6782105 +(27493, 102985, 1, 0, 0, 0, 0, 65299); -- Full: 0x2042653F00E19FC00000200000677C99 Creature/0 R4249/S32 Map: 2552 (Khaz Algar (Surface)) Entry: 231039 (Arator) Low: 6782105 + +DELETE FROM `conversation_line_template` WHERE `Id` IN (77713, 77712, 77711, 77703, 77702, 75392); +INSERT INTO `conversation_line_template` (`Id`, `UiCameraID`, `ActorIdx`, `Flags`, `ChatType`, `VerifiedBuild`) VALUES +(77713, 0, 0, 0, 0, 65299), +(77712, 0, 1, 0, 0, 65299), +(77711, 0, 0, 0, 0, 65299), +(77703, 0, 0, 0, 0, 65299), +(77702, 0, 0, 0, 0, 65299), +(75392, 0, 0, 0, 0, 65299); + +-- Gossip +DELETE FROM `gossip_menu_option` WHERE (`MenuID`=37102 AND `OptionID` IN (1,0)); +INSERT INTO `gossip_menu_option` (`MenuID`, `GossipOptionID`, `OptionID`, `OptionNpc`, `OptionText`, `OptionBroadcastTextID`, `Language`, `Flags`, `ActionMenuID`, `ActionPoiID`, `GossipNpcOptionID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `SpellID`, `OverrideIconID`, `VerifiedBuild`) VALUES +(37102, 132038, 1, 0, '|r', 0, 0, 1, 0, 0, NULL, 0, 0, NULL, 0, NULL, NULL, 65299), +(37102, 125280, 0, 0, '', 0, 0, 1, 0, 0, NULL, 0, 0, NULL, 0, NULL, NULL, 65299); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` IN (37102)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `Comment`) VALUES +(15, 37102, 0, 0, 0, 9, 0, 84996, 0, 0, '', 0, 'Player for which gossip text is shown has quest Vereesa\'s Tale (84996) active'), +(15, 37102, 1, 0, 0, 9, 0, 84996, 0, 0, '', 0, 'Player for which gossip text is shown has quest Vereesa\'s Tale (84996) active'); + +-- Quest +DELETE FROM `quest_objectives_completion_effect` WHERE `ObjectiveID` = 455357; +INSERT INTO `quest_objectives_completion_effect` (`ObjectiveID`, `GameEventID`, `SpellID`, `ConversationID`, `UpdatePhaseShift`, `UpdateZoneAuras`) VALUES +(455357, NULL, NULL, NULL, 1, 0); + +-- Difficulty +DELETE FROM `creature_template_difficulty` WHERE (`Entry`=233253 AND `DifficultyID`=0); +INSERT INTO `creature_template_difficulty` (`Entry`, `DifficultyID`, `HealthScalingExpansion`, `HealthModifier`, `ManaModifier`, `CreatureDifficultyID`, `TypeFlags`, `TypeFlags2`, `TypeFlags3`) VALUES +(233253, 0, 10, 30, 1, 284746, 0x0, 32768, 0); -- Arator + +UPDATE `creature_template_difficulty` SET `ContentTuningID`=3020, `StaticFlags1`=0x10000000, `VerifiedBuild`=65299 WHERE (`Entry`=233253 AND `DifficultyID`=0); -- 233253 (Arator) - CanSwim + +-- Arator smart ai +SET @ENTRY := 231039; +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY; +DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryOrGuid` = @ENTRY; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `action_param7`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`, `Difficulties`) VALUES +(@ENTRY, 0, 0, 0, 58, 0, 100, 0, 2, 23103900, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'On waypoint 2 of path 23103900 ended - Self: Despawn instantly', ''); + +-- Path for Vereesa Windrunner +SET @ENTRY := 231042; +SET @PATHOFFSET := 0; +SET @PATH := @ENTRY * 100 + @PATHOFFSET; +DELETE FROM `waypoint_path` WHERE `PathId`= @PATH; +INSERT INTO `waypoint_path` (`PathId`, `MoveType`, `Flags`, `Velocity`, `Comment`) VALUES +(@PATH, 1, 0x0, NULL, 'Vereesa Windrunner - Scripted Path'); + +DELETE FROM `waypoint_path_node` WHERE `PathId`= @PATH; +INSERT INTO `waypoint_path_node` (`PathId`, `NodeId`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `Delay`) VALUES +(@PATH, 0, 2604.9253, -759.8316, 27.298847, NULL, 0), +(@PATH, 1, 2613.3186, -749.8768, 23.326048, NULL, 0), +(@PATH, 2, 2616.9229, -745.73785, 22.463118, NULL, 0); + +-- Path for Arator +SET @ENTRY := 231039; +SET @PATHOFFSET := 0; +SET @PATH := @ENTRY * 100 + @PATHOFFSET; +DELETE FROM `waypoint_path` WHERE `PathId`= @PATH; +INSERT INTO `waypoint_path` (`PathId`, `MoveType`, `Flags`, `Velocity`, `Comment`) VALUES +(@PATH, 1, 0x0, NULL, 'Arator - Scripted Path'); + +DELETE FROM `waypoint_path_node` WHERE `PathId`= @PATH; +INSERT INTO `waypoint_path_node` (`PathId`, `NodeId`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `Delay`) VALUES +(@PATH, 0, 2598.6692, -765.42535, 29.512508, NULL, 0), +(@PATH, 1, 2611.587, -747.559, 23.54781, NULL, 0), +(@PATH, 2, 2616.165, -740.9961, 21.908726, NULL, 0); \ No newline at end of file diff --git a/src/server/scripts/KhazAlgar/campaign_visions_of_a_shadowed_sun.cpp b/src/server/scripts/KhazAlgar/campaign_visions_of_a_shadowed_sun.cpp new file mode 100644 index 0000000000..85ccfb9eb7 --- /dev/null +++ b/src/server/scripts/KhazAlgar/campaign_visions_of_a_shadowed_sun.cpp @@ -0,0 +1,271 @@ +/* + * 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 . + */ + +#include "Containers.h" +#include "Conversation.h" +#include "ConversationAI.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "TemporarySummon.h" + +namespace Scripts::KhazAlgar::CampaignsVisionsOfAShadowedSun +{ + +namespace Creatures +{ + static constexpr uint32 VereesaWindrunnerOztanIsle = 231042; + static constexpr uint32 AratorOztanIsle = 231039; +} + +namespace Mounts +{ + static constexpr uint32 VereesaWindrunnerMount = 69274; + static constexpr uint32 AratorMount = 14584; +} + +namespace Paths +{ + static constexpr uint32 VereesaOztanIslePath = 23104200; + static constexpr uint32 AratorOztanIslePath = 23103900; +} + +namespace Actions +{ + static constexpr uint32 ActionSkipConversation = 1; +} + +namespace Gossips +{ + namespace MenuIds + { + static constexpr uint32 GossipVereesaOztanIsle = 37102; + } + + namespace Options + { + static constexpr uint32 OptionListenToVereesasTale = 0; + static constexpr uint32 OptionSkipListenToVereesasTale = 1; + } +} + +namespace Conversations +{ + namespace Ids + { + static constexpr uint32 ConversationVereesasTale = 27493; + } + + namespace Actors + { + static constexpr uint32 VereesaActorOztanIsle = 102984; + static constexpr uint32 AratorActorOztanIsle = 102985; + } + + namespace Lines + { + static constexpr uint32 VereesaOztanIsleSetFacing = 75392; + } +} + +// 231042 - Vereesa Windrunner +struct npc_vereesa_windrunner_oztan_isle : public ScriptedAI +{ + npc_vereesa_windrunner_oztan_isle(Creature* creature) : ScriptedAI(creature) {} + + bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override + { + if (menuId == Gossips::MenuIds::GossipVereesaOztanIsle && gossipListId == Gossips::Options::OptionListenToVereesasTale) + { + CloseGossipMenuFor(player); + + Conversation::CreateConversation(Conversations::Ids::ConversationVereesasTale, player, *player, player->GetGUID(), nullptr, false); + } + else if (menuId == Gossips::MenuIds::GossipVereesaOztanIsle && gossipListId == Gossips::Options::OptionSkipListenToVereesasTale) + { + CloseGossipMenuFor(player); + + Creature* clone = me->SummonPersonalClone(me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); + if (!clone) + return true; + + clone->AI()->DoAction(Actions::ActionSkipConversation); + } + return true; + } +}; + +// 231042 - Vereesa Windrunner +struct npc_vereesa_windrunner_oztan_isle_private : public ScriptedAI +{ + npc_vereesa_windrunner_oztan_isle_private(Creature* creature) : ScriptedAI(creature) {} + + void DoAction(int32 action) override + { + if (action == Actions::ActionSkipConversation) + { + Player* player = me->GetDemonCreatorPlayer(); + if (!player) + return; + + Creature* aratorObject = me->FindNearestCreatureWithOptions(10.0f, { .CreatureId = Creatures::AratorOztanIsle, .IgnorePhases = true }); + if (!aratorObject) + return; + + Creature* aratorClone = aratorObject->SummonPersonalClone(aratorObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); + if (!aratorClone) + return; + + me->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); + aratorClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); + + _scheduler.Schedule(1s, [this, aratorGuid = aratorClone->GetGUID()](TaskContext task) + { + Creature* aratorClone = ObjectAccessor::GetCreature(*me, aratorGuid); + if (!aratorClone) + return; + + me->SetMountDisplayId(Mounts::VereesaWindrunnerMount); + aratorClone->SetMountDisplayId(Mounts::AratorMount); + task.Schedule(2s, [this, aratorGuid](TaskContext /*task*/) + { + Creature* aratorClone = ObjectAccessor::GetCreature(*me, aratorGuid); + if (!aratorClone) + return; + + me->GetMotionMaster()->MovePath(Paths::VereesaOztanIslePath, false); + aratorClone->GetMotionMaster()->MovePath(Paths::AratorOztanIslePath, false); + }); + }); + } + } + + void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override + { + Player* player = me->GetDemonCreatorPlayer(); + if (!player) + return; + + if (pathId == Paths::VereesaOztanIslePath) + { + player->KilledMonsterCredit(Creatures::VereesaWindrunnerOztanIsle); + me->DespawnOrUnsummon(); + } + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } +private: + TaskScheduler _scheduler; +}; + +CreatureAI* VereesaWindrunnerOztanIsleAISelector(Creature* creature) +{ + if (creature->IsPrivateObject()) + return new npc_vereesa_windrunner_oztan_isle_private(creature); + return new npc_vereesa_windrunner_oztan_isle(creature); +}; + +// 27493 - Conversation: Vereesas Tale +class conversation_vereesas_tale : public ConversationAI +{ +public: + using ConversationAI::ConversationAI; + + void OnCreate(Unit* creator) override + { + Creature* vereesaObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = Creatures::VereesaWindrunnerOztanIsle, .IgnorePhases = true }); + if (!vereesaObject) + return; + + Creature* aratorObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = Creatures::AratorOztanIsle, .IgnorePhases = true }); + if (!aratorObject) + return; + + TempSummon* vereesaClone = vereesaObject->SummonPersonalClone(vereesaObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); + if (!vereesaClone) + return; + + TempSummon* aratorClone = aratorObject->SummonPersonalClone(aratorObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); + if (!aratorClone) + return; + + vereesaClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); + aratorClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); + + conversation->AddActor(Conversations::Actors::VereesaActorOztanIsle, 0, vereesaClone->GetGUID()); + conversation->AddActor(Conversations::Actors::AratorActorOztanIsle, 1, aratorClone->GetGUID()); + conversation->Start(); + } + + void OnStart() override + { + LocaleConstant privateOwnerLocale = conversation->GetPrivateObjectOwnerLocale(); + + conversation->m_Events.AddEvent([conversation = conversation]() + { + Player* player = ObjectAccessor::GetPlayer(*conversation, conversation->GetPrivateObjectOwner()); + if (!player) + return; + + if (Creature* vereesaClone = conversation->GetActorCreature(0)) + vereesaClone->SetFacingToObject(player); + + }, conversation->GetLineEndTime(privateOwnerLocale, Conversations::Lines::VereesaOztanIsleSetFacing)); + + conversation->m_Events.AddEvent([conversation = conversation]() + { + if (Creature* vereesaClone = conversation->GetActorCreature(0)) + vereesaClone->SetMountDisplayId(Mounts::VereesaWindrunnerMount); + + if (Creature* aratorClone = conversation->GetActorCreature(1)) + aratorClone->SetMountDisplayId(Mounts::AratorMount); + + }, conversation->GetLastLineEndTime(privateOwnerLocale)); + + conversation->m_Events.AddEvent([conversation = conversation]() + { + Player* player = ObjectAccessor::GetPlayer(*conversation, conversation->GetPrivateObjectOwner()); + if (!player) + return; + + if (Creature* vereesaClone = conversation->GetActorCreature(0)) + vereesaClone->GetMotionMaster()->MovePath(Paths::VereesaOztanIslePath, false); + + if (Creature* aratorClone = conversation->GetActorCreature(1)) + aratorClone->GetMotionMaster()->MovePath(Paths::AratorOztanIslePath, false); + + }, conversation->GetLastLineEndTime(privateOwnerLocale) + 2s); + } +}; +} + +void AddSC_campaign_visions_of_a_shadowed_sun() +{ + using namespace Scripts::KhazAlgar::CampaignsVisionsOfAShadowedSun; + + // AISelector + new FactoryCreatureScript("npc_vereesa_windrunner_oztan_isle"); + + // Conversation + RegisterConversationAI(conversation_vereesas_tale); +} diff --git a/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp b/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp index 86ae7069db..117ff91ef2 100644 --- a/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp +++ b/src/server/scripts/KhazAlgar/khaz_algar_script_loader.cpp @@ -23,6 +23,9 @@ void AddSC_zone_dornogal(); // Zone Isle Of Dorn void AddSC_zone_isle_of_dorn(); +// Campaign: Visions of a Shadowed Sun +void AddSC_campaign_visions_of_a_shadowed_sun(); + // The Stonevault void AddSC_instance_the_stonevault(); void AddSC_boss_edna(); @@ -46,6 +49,9 @@ void AddKhazAlgarScripts() // Zone Isle of Dorn AddSC_zone_isle_of_dorn(); + // Campaign: Visions of a Shadowed Sun + AddSC_campaign_visions_of_a_shadowed_sun(); + // The Stonevault AddSC_instance_the_stonevault(); AddSC_boss_edna();