From 24c236124864619c707ad6f967bbef7471ac38fd Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 16 Dec 2023 10:27:14 -0800 Subject: [PATCH] fix: achievements counting twice when accepted (#1337) Tested that new achievements progress exactly once Tested that already accepted achievements progress as expeected Tested that tiered achievements only count the progress to the current tier and not the next one as well Update MissionComponent.cpp --- dGame/dComponents/MissionComponent.cpp | 29 +++++++++++++------------- dGame/dComponents/MissionComponent.h | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index d7da29d9..277882bf 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -145,8 +145,13 @@ void MissionComponent::RemoveMission(uint32_t missionId) { } void MissionComponent::Progress(eMissionTaskType type, int32_t value, LWOOBJID associate, const std::string& targets, int32_t count, bool ignoreAchievements) { - for (const auto& pair : m_Missions) { - auto* mission = pair.second; + std::vector acceptedAchievements; + if (count > 0 && !ignoreAchievements) { + acceptedAchievements = LookForAchievements(type, value, true, associate, targets, count); + } + + for (const auto& [id, mission] : m_Missions) { + if (!mission || std::find(acceptedAchievements.begin(), acceptedAchievements.end(), mission->GetMissionId()) != acceptedAchievements.end()) continue; if (mission->IsAchievement() && ignoreAchievements) continue; @@ -154,10 +159,6 @@ void MissionComponent::Progress(eMissionTaskType type, int32_t value, LWOOBJID a mission->Progress(type, value, associate, targets, count); } - - if (count > 0 && !ignoreAchievements) { - LookForAchievements(type, value, true, associate, targets, count); - } } void MissionComponent::ForceProgress(const uint32_t missionId, const uint32_t taskId, const int32_t value, const bool acceptMission) { @@ -282,12 +283,12 @@ bool MissionComponent::GetMissionInfo(uint32_t missionId, CDMissions& result) { #define MISSION_NEW_METHOD -bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, bool progress, LWOOBJID associate, const std::string& targets, int32_t count) { +const std::vector MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, bool progress, LWOOBJID associate, const std::string& targets, int32_t count) { #ifdef MISSION_NEW_METHOD // Query for achievments, using the cache const auto& result = QueryAchievements(type, value, targets); - bool any = false; + std::vector acceptedAchievements; for (const uint32_t missionID : result) { // Check if we already have this achievement @@ -309,7 +310,7 @@ bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, instance->Accept(); - any = true; + acceptedAchievements.push_back(missionID); if (progress) { // Progress mission to bring it up to speed @@ -317,7 +318,7 @@ bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, } } - return any; + return acceptedAchievements; #else auto* missionTasksTable = CDClientManager::Instance().GetTable(); auto* missionsTable = CDClientManager::Instance().GetTable(); @@ -326,7 +327,7 @@ bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, return entry.taskType == static_cast(type); }); - auto any = false; + std::vector acceptedAchievements; for (const auto& task : tasks) { if (GetMission(task.id) != nullptr) { @@ -380,14 +381,14 @@ bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value, instance->Accept(); - any = true; + acceptedAchievements.push_back(mission.id); if (progress) { instance->Progress(type, value, associate, targets, count); } } - return any; + return acceptedAchievements; #endif } @@ -499,7 +500,7 @@ bool MissionComponent::RequiresItem(const LOT lot) { const auto required = LookForAchievements(eMissionTaskType::GATHER, lot, false); - return required; + return !required.empty(); } diff --git a/dGame/dComponents/MissionComponent.h b/dGame/dComponents/MissionComponent.h index e82b5b67..37d5cd84 100644 --- a/dGame/dComponents/MissionComponent.h +++ b/dGame/dComponents/MissionComponent.h @@ -141,7 +141,7 @@ public: * @param count the number of values to progress by (differs by task type) * @return true if a achievement was accepted, false otherwise */ - bool LookForAchievements(eMissionTaskType type, int32_t value, bool progress = true, LWOOBJID associate = LWOOBJID_EMPTY, const std::string& targets = "", int32_t count = 1); + const std::vector LookForAchievements(eMissionTaskType type, int32_t value, bool progress = true, LWOOBJID associate = LWOOBJID_EMPTY, const std::string& targets = "", int32_t count = 1); /** * Checks if there's a mission active that requires the collection of the specified LOT