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
This commit is contained in:
David Markowitz 2023-12-16 10:27:14 -08:00 committed by GitHub
parent 511672c5cb
commit 24c2361248
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 15 deletions

View File

@ -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<uint32_t> 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<uint32_t> 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<uint32_t> 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<CDMissionTasksTable>();
auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>();
@ -326,7 +327,7 @@ bool MissionComponent::LookForAchievements(eMissionTaskType type, int32_t value,
return entry.taskType == static_cast<unsigned>(type);
});
auto any = false;
std::vector<uint32_t> 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();
}

View File

@ -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<uint32_t> 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