diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index cf90a821a..0e52caa4f 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -12417,21 +12417,23 @@ void ObjectMgr::LoadQuestTasks() for (auto const& it : _questTemplates) { Quest const* quest_template = it.second.get(); + if (!quest_template) + continue; //CriteriaEntry const* criteria = sCriteriaStore.LookupEntry(l_I); //if (!criteria || criteria->Type != CRITERIA_TYPE_COMPLETE_QUEST) // continue; + if (quest_template->GetQuestType() != QUEST_TYPE_TASK) + continue; + QuestV2CliTaskEntry const* cliTask = sQuestV2CliTaskStore.LookupEntry(quest_template->GetQuestId()); if (!cliTask) continue; - if (!quest_template || quest_template->GetQuestType() != QUEST_TYPE_TASK) - continue; - if (QuestPOIData const* questPOIs = GetQuestPOIData(quest_template->GetQuestId())) { - if (questPOIs->Blobs.size() <= 0) + if (questPOIs->Blobs.empty()) continue; for (auto itr = questPOIs->Blobs.begin(); itr != questPOIs->Blobs.end(); ++itr) diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 4c3c7f761..77494ce94 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -41,6 +41,7 @@ #include "ReputationMgr.h" #include "ScriptMgr.h" #include "World.h" +#include "WorldQuestMgr.h" //WowCommunity #include "Item.h" @@ -759,9 +760,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::Ques void WorldSession::HandleRequestWorldQuestUpdate(WorldPackets::Quest::RequestWorldQuestUpdate& /*packet*/) { WorldPackets::Quest::WorldQuestUpdateResponse response; - - /// @todo: 7.x Has to be implemented - //response.WorldQuestUpdates.push_back(WorldPackets::Quest::WorldQuestUpdateInfo(lastUpdate, questID, timer, variableID, value)); + sWorldQuestMgr->FillActiveWorldQuests(response.WorldQuestUpdates); SendPacket(response.Write()); } diff --git a/src/server/game/Quests/WorldQuestMgr.cpp b/src/server/game/Quests/WorldQuestMgr.cpp index b72347695..80bf5e600 100644 --- a/src/server/game/Quests/WorldQuestMgr.cpp +++ b/src/server/game/Quests/WorldQuestMgr.cpp @@ -154,15 +154,16 @@ void WorldQuestMgr::Update(uint32 diff) void WorldQuestMgr::FillActiveWorldQuests(std::vector& updates) const { updates.reserve(updates.size() + _active.size()); - time_t const now = GameTime::GetGameTime(); for (auto const& [questId, active] : _active) { - // Retail contract: the client derives remaining time from LastUpdate + Timer, so Timer must be - // the REMAINING time (EndTime - now), not the full active duration. Sending EndTime - StartTime - // pins the client countdown at full forever; the quest never visibly ticks toward expiry and - // this file's own comment on SMSG_WORLD_QUEST_UPDATE_RESPONSE explicitly says the opposite. - uint32 remaining = active.EndTime > now ? uint32(active.EndTime - now) : 0; - updates.emplace_back(active.StartTime, active.QuestID, remaining, active.VariableID, active.Value); + // Retail contract, from 12.0.7 captures: Timer is the quest's FULL rotation duration, not the + // remaining time. Verified on quest 81815 - Timer stays byte-identical at 302400 across eight + // SMSG_WORLD_QUEST_UPDATE_RESPONSE packets sent 7 minutes apart, so it is a constant. The client + // derives the countdown itself as Timer - (now - LastUpdate), which is why LastUpdate is sent + // alongside it. Sending EndTime - now here would make the client subtract elapsed time twice + // and the countdown would run at double speed and hit zero Duration seconds early. + uint32 duration = active.EndTime > active.StartTime ? uint32(active.EndTime - active.StartTime) : 0; + updates.emplace_back(active.StartTime, active.QuestID, duration, active.VariableID, active.Value); } }