From 1ceaa244327f6a95a843a6c0cca3c23231634a29 Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Thu, 10 Oct 2024 10:08:02 -0400 Subject: [PATCH] Core/PacketIO: Implemented UIMap questlines Port From (https://github.com/TrinityCore/TrinityCore/commit/efa76de54011d40d69412d2af23cb071ed352688) --- Source/Game/DataStorage/DB2Manager.cs | 5 +- Source/Game/Globals/ObjectManager.cs | 102 +++++++++++++++++- Source/Game/Handlers/QuestHandler.cs | 36 +++++++ .../Game/Networking/Packets/QuestPackets.cs | 34 ++++++ Source/Game/World/WorldManager.cs | 6 ++ 5 files changed, 179 insertions(+), 4 deletions(-) diff --git a/Source/Game/DataStorage/DB2Manager.cs b/Source/Game/DataStorage/DB2Manager.cs index 293ba24e8..45bfdd15b 100644 --- a/Source/Game/DataStorage/DB2Manager.cs +++ b/Source/Game/DataStorage/DB2Manager.cs @@ -429,7 +429,7 @@ namespace Game.DataStorage unsortedNodes[pathNode.PathID] = new(); unsortedNodes[pathNode.PathID].Add(pathNode); - } + } } foreach (var (pathId, pathNodes) in unsortedNodes) @@ -478,6 +478,9 @@ namespace Game.DataStorage foreach (QuestLineXQuestRecord questLineQuest in QuestLineXQuestStorage.Values) _questsByQuestLine.Add(questLineQuest.QuestLineID, questLineQuest); + foreach (var questLineId in _questsByQuestLine.Keys) + _questsByQuestLine[questLineId].OrderByDescending(p => p.OrderIndex); + foreach (QuestPackageItemRecord questPackageItem in QuestPackageItemStorage.Values) { if (!_questPackages.ContainsKey(questPackageItem.PackageID)) diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 28bd332cf..b79c4fbd9 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -9772,7 +9772,6 @@ namespace Game return; } - uint count = 0; do { uint sceneId = result.Read(0); @@ -9787,7 +9786,7 @@ namespace Game } while (result.NextRow()); - Log.outInfo(LogFilter.ServerLoading, "Loaded {0} scene templates in {1} ms.", count, Time.GetMSTimeDiffToNow(oldMSTime)); + Log.outInfo(LogFilter.ServerLoading, "Loaded {0} scene templates in {1} ms.", _sceneTemplateStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime)); } public void LoadPlayerChoices() { @@ -10150,6 +10149,7 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, $"Loaded {_playerChoices.Count} player choices, {responseCount} responses, {rewardCount} rewards, {itemRewardCount} item rewards, " + $"{currencyRewardCount} currency rewards, {factionRewardCount} faction rewards, {itemChoiceRewardCount} item choice rewards and {mawPowersCount} maw powers in {Time.GetMSTimeDiffToNow(oldMSTime)} ms."); } + public void LoadPlayerChoicesLocale() { uint oldMSTime = Time.GetMSTime(); @@ -10463,6 +10463,90 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} phase names in {Time.GetMSTimeDiffToNow(oldMSTime)} ms."); } + public void LoadUiMapQuestLines() + { + uint oldMSTime = Time.GetMSTime(); + + // need for reload case + _uiMapQuestLinesStorage.Clear(); + + // 0 1 + SQLResult result = DB.World.Query("SELECT UiMapId, QuestLineId FROM ui_map_quest_line"); + if (result.IsEmpty()) + { + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 questlines for UIMaps. DB table `ui_map_quest_line` is empty!"); + return; + } + + uint count = 0; + + do + { + uint uiMapId = result.Read(0); + uint questLineId = result.Read(1); + + if (!CliDB.UiMapStorage.HasRecord(uiMapId)) + { + Log.outError(LogFilter.Sql, $"Table `ui_map_quest_line` references non-existing UIMap {uiMapId}, skipped"); + continue; + } + + if (Global.DB2Mgr.GetQuestsForQuestLine(questLineId) == null) + { + Log.outError(LogFilter.Sql, $"Table `ui_map_quest_line` references empty or non-existing questline {questLineId}, skipped"); + continue; + } + + _uiMapQuestLinesStorage.Add(uiMapId, questLineId); + ++count; + + } while (result.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} UiMap questlines definitions in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); + } + + public void LoadUiMapQuests() + { + uint oldMSTime = Time.GetMSTime(); + + // need for reload case + _uiMapQuestsStorage.Clear(); + + // 0 1 + SQLResult result = DB.World.Query("SELECT UiMapId, QuestId FROM ui_map_quest"); + if (result.IsEmpty()) + { + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 quests for UIMaps. DB table `ui_map_quest` is empty!"); + return; + } + + uint count = 0; + + do + { + uint uiMapId = result.Read(0); + uint questId = result.Read(1); + + if (!CliDB.UiMapStorage.HasRecord(uiMapId)) + { + Log.outError(LogFilter.Sql, $"Table `ui_map_quest` references non-existing UIMap {uiMapId}, skipped"); + continue; + } + + if (GetQuestTemplate(questId) == null) + { + Log.outError(LogFilter.Sql, $"Table `ui_map_quest` references non-existing quest {questId}, skipped"); + continue; + } + + _uiMapQuestsStorage.Add(uiMapId, questId); + ++count; + + } while (result.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} UiMap quests definitions in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); + } + public MailLevelReward GetMailLevelReward(uint level, Race race) { var mailList = _mailLevelRewardStorage.LookupByKey((byte)level); @@ -10913,6 +10997,16 @@ namespace Game return _phaseNameStorage.TryGetValue(phaseId, out string value) ? value : "Unknown Name"; } + public List GetUiMapQuestLinesList(uint uiMapId) + { + return _uiMapQuestLinesStorage.LookupByKey(uiMapId); + } + + public List GetUiMapQuestsList(uint uiMapId) + { + return _uiMapQuestsStorage.LookupByKey(uiMapId); + } + //Vehicles public void LoadVehicleTemplate() { @@ -11010,7 +11104,7 @@ namespace Game if (result.IsEmpty()) { - Log.outInfo(LogFilter.ServerLoading, "Loaded 0 Vehicle Accessories in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime)); + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 vehicle Accessories. DB table `vehicle_accessory` is empty"); return; } @@ -11126,6 +11220,8 @@ namespace Game Dictionary _sceneTemplateStorage = new(); Dictionary _jumpChargeParams = new(); Dictionary _phaseNameStorage = new(); + MultiMap _uiMapQuestLinesStorage = new(); + MultiMap _uiMapQuestsStorage = new(); Dictionary<(ulong, Difficulty), CreatureStaticFlagsOverride> _creatureStaticFlagsOverrideStorage = new(); Dictionary _raceUnlockRequirementStorage = new(); diff --git a/Source/Game/Handlers/QuestHandler.cs b/Source/Game/Handlers/QuestHandler.cs index 963f5d92c..aa6e25f5c 100644 --- a/Source/Game/Handlers/QuestHandler.cs +++ b/Source/Game/Handlers/QuestHandler.cs @@ -792,5 +792,41 @@ namespace Game _player.GetReputationMgr().ModifyReputation(CliDB.FactionStorage.LookupByKey(faction.Id), faction.Quantity); } } + + [WorldPacketHandler(ClientOpcodes.UiMapQuestLinesRequest)] + void HandleUiMapQuestLinesRequest(UiMapQuestLinesRequest uiMapQuestLinesRequest) + { + var uiMap = CliDB.UiMapStorage.LookupByKey(uiMapQuestLinesRequest.UiMapID); + if (uiMap == null) + return; + + UiMapQuestLinesResponse response = new(); + response.UiMapID = uiMap.Id; + + var questLines = Global.ObjectMgr.GetUiMapQuestLinesList(uiMap.Id); + foreach (uint questLineId in questLines) + { + var questLineQuests = Global.DB2Mgr.GetQuestsForQuestLine(questLineId); + if (questLineQuests.Empty()) + continue; + + foreach (var questLineQuest in questLineQuests) + { + Quest quest = Global.ObjectMgr.GetQuestTemplate(questLineQuest.QuestID); + if (quest != null && _player.CanTakeQuest(quest, false)) + response.QuestLineXQuestIDs.Add(questLineQuest.Id); + } + } + + var quests = Global.ObjectMgr.GetUiMapQuestsList(uiMap.Id); + foreach (uint questId in quests) + { + Quest quest = Global.ObjectMgr.GetQuestTemplate(questId); + if (quest != null && _player.CanTakeQuest(quest, false)) + response.QuestIDs.Add(questId); + } + + SendPacket(response); + } } } diff --git a/Source/Game/Networking/Packets/QuestPackets.cs b/Source/Game/Networking/Packets/QuestPackets.cs index fff33fc39..b93e1fcc3 100644 --- a/Source/Game/Networking/Packets/QuestPackets.cs +++ b/Source/Game/Networking/Packets/QuestPackets.cs @@ -953,6 +953,40 @@ namespace Game.Networking.Packets public bool IsReroll; } + class UiMapQuestLinesResponse : ServerPacket + { + public uint UiMapID; + public List QuestLineXQuestIDs = new(); + public List QuestIDs = new(); + + public UiMapQuestLinesResponse() : base(ServerOpcodes.UiMapQuestLinesResponse, ConnectionType.Instance) { } + + public override void Write() + { + _worldPacket.WriteUInt32(UiMapID); + _worldPacket.WriteInt32(QuestLineXQuestIDs.Count); + _worldPacket.WriteInt32(QuestIDs.Count); + + foreach (var questLineQuestID in QuestLineXQuestIDs) + _worldPacket.WriteUInt32(questLineQuestID); + + foreach (var questID in QuestIDs) + _worldPacket.WriteUInt32(questID); + } + } + + class UiMapQuestLinesRequest : ClientPacket + { + public int UiMapID; + + public UiMapQuestLinesRequest(WorldPacket packet) : base(packet) { } + + public override void Read() + { + UiMapID = _worldPacket.ReadInt32(); + } + } + //Structs public class QuestGiverInfo { diff --git a/Source/Game/World/WorldManager.cs b/Source/Game/World/WorldManager.cs index 6f097542e..1d912de40 100644 --- a/Source/Game/World/WorldManager.cs +++ b/Source/Game/World/WorldManager.cs @@ -806,6 +806,12 @@ namespace Game Global.ObjectMgr.LoadPlayerChoicesLocale(); } + Log.outInfo(LogFilter.ServerLoading, "Loading UIMap questlines..."); + Global.ObjectMgr.LoadUiMapQuestLines(); + + Log.outInfo(LogFilter.ServerLoading, "Loading UIMap quests..."); + Global.ObjectMgr.LoadUiMapQuests(); + Log.outInfo(LogFilter.ServerLoading, "Loading Jump Charge Params..."); Global.ObjectMgr.LoadJumpChargeParams();