diff options
author | Meji <alvaro.megias@outlook.com> | 2024-08-30 18:11:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-30 18:11:07 +0200 |
commit | efa76de54011d40d69412d2af23cb071ed352688 (patch) | |
tree | 8a02bf7b0aec70912f33ffd1b380c11adea0854e /src | |
parent | f213a580540bfc1ec3a7263782aa64d317afc4ce (diff) |
Core/PacketIO: Implemented UIMap questlines (#30030)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 106 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 11 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 35 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.cpp | 20 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.h | 22 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 2 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 7 |
9 files changed, 208 insertions, 8 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index f3552765c43..22e4fd2496d 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -1467,8 +1467,13 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul } } - for (QuestLineXQuestEntry const* questLineQuest : sQuestLineXQuestStore) - _questsByQuestLine[questLineQuest->QuestLineID].push_back(questLineQuest); + { + for (QuestLineXQuestEntry const* questLineQuest : sQuestLineXQuestStore) + _questsByQuestLine[questLineQuest->QuestLineID].push_back(questLineQuest); + + for (auto& [questLineId, questLineQuests] : _questsByQuestLine) + std::ranges::sort(questLineQuests, std::ranges::less(), &QuestLineXQuestEntry::OrderIndex); + } for (QuestPackageItemEntry const* questPackageItem : sQuestPackageItemStore) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index a684806b88c..fca4e4ff71b 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3518,7 +3518,7 @@ void ObjectMgr::LoadVehicleAccessories() if (!result) { - TC_LOG_INFO("server.loading", ">> Loaded 0 Vehicle Accessories in {} ms", GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded 0 vehicle accessories. DB table `vehicle_accessory` is empty."); return; } @@ -11060,8 +11060,6 @@ void ObjectMgr::LoadSceneTemplates() return; } - uint32 count = 0; - do { Field* fields = templates->Fetch(); @@ -11076,7 +11074,7 @@ void ObjectMgr::LoadSceneTemplates() } while (templates->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded {} scene templates in {} ms.", count, GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded {} scene templates in {} ms.", _sceneTemplateStore.size(), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadPlayerChoices() @@ -11544,6 +11542,106 @@ void ObjectMgr::LoadPlayerChoicesLocale() } } +void ObjectMgr::LoadUiMapQuestLines() +{ + uint32 oldMSTime = getMSTime(); + + // need for reload case + _uiMapQuestLinesStore.clear(); + + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT UiMapId, QuestLineId FROM ui_map_quest_line"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 questlines for UIMaps. DB table `ui_map_quest_line` is empty!"); + return; + } + + uint32 count = 0; + + do + { + Field* fields = result->Fetch(); + + uint32 uiMapId = fields[0].GetUInt32(); + uint32 questLineId = fields[1].GetUInt32(); + + if (!sUiMapStore.HasRecord(uiMapId)) + { + TC_LOG_ERROR("sql.sql", "Table `ui_map_quest_line` references non-existing UIMap {}, skipped", uiMapId); + continue; + } + + if (!sDB2Manager.GetQuestsForQuestLine(questLineId)) + { + TC_LOG_ERROR("sql.sql", "Table `ui_map_quest_line` references empty or non-existing questline {}, skipped", questLineId); + continue; + } + + _uiMapQuestLinesStore[uiMapId].push_back(questLineId); + ++count; + + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded {} UiMap questlines definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +std::vector<uint32> const* ObjectMgr::GetUiMapQuestLinesList(uint32 uiMapId) const +{ + return Trinity::Containers::MapGetValuePtr(_uiMapQuestLinesStore, uiMapId); +} + +void ObjectMgr::LoadUiMapQuests() +{ + uint32 oldMSTime = getMSTime(); + + // need for reload case + _uiMapQuestsStore.clear(); + + // 0 1 + QueryResult result = WorldDatabase.Query("SELECT UiMapId, QuestId FROM ui_map_quest"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 quests for UIMaps. DB table `ui_map_quest` is empty!"); + return; + } + + uint32 count = 0; + + do + { + Field* fields = result->Fetch(); + + uint32 uiMapId = fields[0].GetUInt32(); + uint32 questId = fields[1].GetUInt32(); + + if (!sUiMapStore.HasRecord(uiMapId)) + { + TC_LOG_ERROR("sql.sql", "Table `ui_map_quest` references non-existing UIMap {}, skipped", uiMapId); + continue; + } + + if (!GetQuestTemplate(questId)) + { + TC_LOG_ERROR("sql.sql", "Table `ui_map_quest` references non-existing quest {}, skipped", questId); + continue; + } + + _uiMapQuestsStore[uiMapId].push_back(questId); + ++count; + + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded {} UiMap quests definitions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +std::vector<uint32> const* ObjectMgr::GetUiMapQuestsList(uint32 uiMapId) const +{ + return Trinity::Containers::MapGetValuePtr(_uiMapQuestsStore, uiMapId); +} + void ObjectMgr::LoadJumpChargeParams() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 9a0423daa8c..32318209a39 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -530,6 +530,8 @@ typedef std::unordered_map<uint32, QuestObjectivesLocale> QuestObjectivesLocaleC typedef std::unordered_map<uint32, QuestOfferRewardLocale> QuestOfferRewardLocaleContainer; typedef std::unordered_map<uint32, QuestRequestItemsLocale> QuestRequestItemsLocaleContainer; typedef std::unordered_map<uint32, PageTextLocale> PageTextLocaleContainer; +typedef std::unordered_map<uint32, std::vector<uint32>> UiMapQuestLinesMap; +typedef std::unordered_map<uint32, std::vector<uint32>> UiMapQuestsMap; typedef std::unordered_map<uint32, VehicleSeatAddon> VehicleSeatAddonContainer; struct GossipMenuItemsLocale @@ -1283,6 +1285,9 @@ class TC_GAME_API ObjectMgr QuestPOIData const* GetQuestPOIData(int32 questId); + std::vector<uint32> const* GetUiMapQuestLinesList(uint32 uiMapId) const; + std::vector<uint32> const* GetUiMapQuestsList(uint32 uiMapId) const; + VehicleTemplate const* GetVehicleTemplate(Vehicle* veh) const; VehicleAccessoryList const* GetVehicleAccessoryList(Vehicle* veh) const; @@ -1420,6 +1425,9 @@ class TC_GAME_API ObjectMgr void LoadPlayerChoices(); void LoadPlayerChoicesLocale(); + void LoadUiMapQuestLines(); + void LoadUiMapQuests(); + void LoadJumpChargeParams(); void LoadPhaseNames(); @@ -1957,6 +1965,9 @@ class TC_GAME_API ObjectMgr SceneTemplateContainer _sceneTemplateStore; + UiMapQuestLinesMap _uiMapQuestLinesStore; + UiMapQuestsMap _uiMapQuestsStore; + std::unordered_map<int32, JumpChargeParams> _jumpChargeParams; PhaseNameContainer _phaseNameStore; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 9a95bd79374..b6636b1e246 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -826,3 +826,38 @@ void WorldSession::HandlePlayerChoiceResponse(WorldPackets::Quest::ChoiceRespons _player->GetReputationMgr().ModifyReputation(sFactionStore.AssertEntry(faction.Id), faction.Quantity); } } + +void WorldSession::HandleUiMapQuestLinesRequest(WorldPackets::Quest::UiMapQuestLinesRequest& uiMapQuestLinesRequest) +{ + UiMapEntry const* uiMap = sUiMapStore.LookupEntry(uiMapQuestLinesRequest.UiMapID); + if (!uiMap) + return; + + WorldPackets::Quest::UiMapQuestLinesResponse response; + response.UiMapID = uiMap->ID; + + if (std::vector<uint32> const* questLines = sObjectMgr->GetUiMapQuestLinesList(uiMap->ID)) + { + for (uint32 questLineId : *questLines) + { + std::vector<QuestLineXQuestEntry const*> const* questLineQuests = sDB2Manager.GetQuestsForQuestLine(questLineId); + if (!questLineQuests) + continue; + + for (QuestLineXQuestEntry const* questLineQuest : *questLineQuests) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(questLineQuest->QuestID)) + if (_player->CanTakeQuest(quest, false)) + response.QuestLineXQuestIDs.push_back(questLineQuest->ID); + } + } + + if (std::vector<uint32> const* quests = sObjectMgr->GetUiMapQuestsList(uiMap->ID)) + { + for (uint32 questId : *quests) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) + if (_player->CanTakeQuest(quest, false)) + response.QuestIDs.push_back(questId); + } + + SendPacket(response.Write()); +} diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index 3b63196b7d1..6c8b9517a78 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -858,4 +858,24 @@ void ChoiceResponse::Read() _worldPacket >> ResponseIdentifier; IsReroll = _worldPacket.ReadBit(); } + +WorldPacket const* UiMapQuestLinesResponse::Write() +{ + _worldPacket << int32(UiMapID); + _worldPacket << uint32(QuestLineXQuestIDs.size()); + _worldPacket << uint32(QuestIDs.size()); + + for (uint32 const& questLineQuestID : QuestLineXQuestIDs) + _worldPacket << uint32(questLineQuestID); + + for (uint32 const& questID : QuestIDs) + _worldPacket << uint32(questID); + + return &_worldPacket; +} + +void UiMapQuestLinesRequest::Read() +{ + _worldPacket >> UiMapID; +} } diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index 2e295a44b9b..2fb56be4c3f 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -788,6 +788,28 @@ namespace WorldPackets int32 ResponseIdentifier = 0; bool IsReroll = false; }; + + class UiMapQuestLinesResponse final : public ServerPacket + { + public: + UiMapQuestLinesResponse() : ServerPacket(SMSG_UI_MAP_QUEST_LINES_RESPONSE, 4) { } + + WorldPacket const* Write() override; + + int32 UiMapID = 0; + std::vector<uint32> QuestLineXQuestIDs; + std::vector<uint32> QuestIDs; + }; + + class UiMapQuestLinesRequest final : public ClientPacket + { + public: + UiMapQuestLinesRequest(WorldPacket&& packet) : ClientPacket(CMSG_UI_MAP_QUEST_LINES_REQUEST, std::move(packet)) { } + + void Read() override; + + int32 UiMapID = 0; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 82e261ff5bf..29bc0765015 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -981,7 +981,7 @@ void OpcodeTable::InitializeClientOpcodes() DEFINE_HANDLER(CMSG_TRANSMOGRIFY_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems); DEFINE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetition); DEFINE_HANDLER(CMSG_TUTORIAL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag); - DEFINE_HANDLER(CMSG_UI_MAP_QUEST_LINES_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_UI_MAP_QUEST_LINES_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleUiMapQuestLinesRequest); DEFINE_HANDLER(CMSG_UNACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode); DEFINE_HANDLER(CMSG_UNDELETE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharUndeleteOpcode); DEFINE_HANDLER(CMSG_UNLEARN_SKILL, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleUnlearnSkillOpcode); @@ -2161,7 +2161,7 @@ void OpcodeTable::InitializeServerOpcodes() DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UI_MAP_QUEST_LINES_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UI_MAP_QUEST_LINES_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_CHARACTER_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_COOLDOWN_STATUS_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNLEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 1b61d60b027..1c3052a3f8a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -674,6 +674,7 @@ namespace WorldPackets class PushQuestToParty; class RequestWorldQuestUpdate; class ChoiceResponse; + class UiMapQuestLinesRequest; } namespace RaF @@ -1566,6 +1567,7 @@ class TC_GAME_API WorldSession void HandleQuestPushResult(WorldPackets::Quest::QuestPushResult& packet); void HandleRequestWorldQuestUpdate(WorldPackets::Quest::RequestWorldQuestUpdate& packet); void HandlePlayerChoiceResponse(WorldPackets::Quest::ChoiceResponse& choiceResponse); + void HandleUiMapQuestLinesRequest(WorldPackets::Quest::UiMapQuestLinesRequest& uiMapQuestLinesRequest); void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& chatMessage); void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& chatMessageWhisper); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 5321f6c476b..2ec553204c7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2197,6 +2197,13 @@ bool World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Player Choices Locales..."); sObjectMgr->LoadPlayerChoicesLocale(); } + + TC_LOG_INFO("server.loading", "Loading UIMap questlines..."); + sObjectMgr->LoadUiMapQuestLines(); + + TC_LOG_INFO("server.loading", "Loading UIMap quests..."); + sObjectMgr->LoadUiMapQuests(); + TC_LOG_INFO("server.loading", "Loading Jump Charge Params..."); sObjectMgr->LoadJumpChargeParams(); |