Skip to content

Commit

Permalink
Core/PacketIO: Implemented UIMap questlines (TrinityCore#30030)
Browse files Browse the repository at this point in the history
  • Loading branch information
meji46 committed Aug 30, 2024
1 parent f213a58 commit efa76de
Show file tree
Hide file tree
Showing 10 changed files with 1,329 additions and 8 deletions.
1,121 changes: 1,121 additions & 0 deletions sql/updates/world/master/2024_08_30_00_world.sql

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions src/server/game/DataStores/DB2Stores.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
106 changes: 102 additions & 4 deletions src/server/game/Globals/ObjectMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -11060,8 +11060,6 @@ void ObjectMgr::LoadSceneTemplates()
return;
}

uint32 count = 0;

do
{
Field* fields = templates->Fetch();
Expand All @@ -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()
Expand Down Expand Up @@ -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();
Expand Down
11 changes: 11 additions & 0 deletions src/server/game/Globals/ObjectMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -1420,6 +1425,9 @@ class TC_GAME_API ObjectMgr
void LoadPlayerChoices();
void LoadPlayerChoicesLocale();

void LoadUiMapQuestLines();
void LoadUiMapQuests();

void LoadJumpChargeParams();
void LoadPhaseNames();

Expand Down Expand Up @@ -1957,6 +1965,9 @@ class TC_GAME_API ObjectMgr

SceneTemplateContainer _sceneTemplateStore;

UiMapQuestLinesMap _uiMapQuestLinesStore;
UiMapQuestsMap _uiMapQuestsStore;

std::unordered_map<int32, JumpChargeParams> _jumpChargeParams;

PhaseNameContainer _phaseNameStore;
Expand Down
35 changes: 35 additions & 0 deletions src/server/game/Handlers/QuestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
20 changes: 20 additions & 0 deletions src/server/game/Server/Packets/QuestPackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
22 changes: 22 additions & 0 deletions src/server/game/Server/Packets/QuestPackets.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/server/game/Server/Protocol/Opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/server/game/Server/WorldSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ namespace WorldPackets
class PushQuestToParty;
class RequestWorldQuestUpdate;
class ChoiceResponse;
class UiMapQuestLinesRequest;
}

namespace RaF
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/server/game/World/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down

0 comments on commit efa76de

Please sign in to comment.