diff --git a/dll/dll/steam_user_stats.h b/dll/dll/steam_user_stats.h index 8681a492..5821fdd7 100644 --- a/dll/dll/steam_user_stats.h +++ b/dll/dll/steam_user_stats.h @@ -50,8 +50,11 @@ struct achievement_trigger { std::string min_value{}; std::string max_value{}; - bool check_triggered(float stat) const; - bool check_triggered(int32 stat) const; + bool should_unlock_ach(float stat) const; + bool should_unlock_ach(int32 stat) const; + + bool should_indicate_progress(float stat) const; + bool should_indicate_progress(int32 stat) const; }; class Steam_User_Stats : diff --git a/dll/steam_user_stats.cpp b/dll/steam_user_stats.cpp index 28bbd760..c32b1ab4 100644 --- a/dll/steam_user_stats.cpp +++ b/dll/steam_user_stats.cpp @@ -69,7 +69,7 @@ void Steam_Leaderboard::sort_entries() // --- achievement_trigger --- -bool achievement_trigger::check_triggered(float stat) const +bool achievement_trigger::should_unlock_ach(float stat) const { try { if (std::stof(max_value) <= stat) return true; @@ -78,7 +78,7 @@ bool achievement_trigger::check_triggered(float stat) const return false; } -bool achievement_trigger::check_triggered(int32 stat) const +bool achievement_trigger::should_unlock_ach(int32 stat) const { try { if (std::stoi(max_value) <= stat) return true; @@ -86,6 +86,26 @@ bool achievement_trigger::check_triggered(int32 stat) const return false; } + +bool achievement_trigger::should_indicate_progress(float stat) const +{ + // show progress if number < max + try { + if (std::stof(max_value) > stat) return true; + } catch (...) {} + + return false; +} + +bool achievement_trigger::should_indicate_progress(int32 stat) const +{ + // show progress if number < max + try { + if (std::stoi(max_value) > stat) return true; + } catch (...) {} + + return false; +} // --- achievement_trigger --- @@ -377,15 +397,6 @@ bool Steam_User_Stats::clear_stats_internal() stats_cache_int[stat_name] = data; - auto stat_trigger = achievement_stat_trigger.find(stat_name); - if (stat_trigger != achievement_stat_trigger.end()) { - for (auto &t : stat_trigger->second) { - if (t.check_triggered(data)) { - set_achievement_internal(t.name.c_str()); - } - } - } - if (needs_disk_write) local_storage->store_data(Local_Storage::stats_storage_folder, stat_name, (char *)&data, sizeof(data)); } break; @@ -403,15 +414,6 @@ bool Steam_User_Stats::clear_stats_internal() stats_cache_float[stat_name] = data; - auto stat_trigger = achievement_stat_trigger.find(stat_name); - if (stat_trigger != achievement_stat_trigger.end()) { - for (auto &t : stat_trigger->second) { - if (t.check_triggered(data)) { - set_achievement_internal(t.name.c_str()); - } - } - } - if (needs_disk_write) local_storage->store_data(Local_Storage::stats_storage_folder, stat_name, (char *)&data, sizeof(data)); } break; @@ -451,9 +453,12 @@ Steam_User_Stats::InternalSetResult Steam_User_Stats::set_stat_internal( auto stat_trigger = achievement_stat_trigger.find(stat_name); if (stat_trigger != achievement_stat_trigger.end()) { for (auto &t : stat_trigger->second) { - if (t.check_triggered(nData)) { + if (t.should_unlock_ach(nData)) { set_achievement_internal(t.name.c_str()); } + if (t.should_indicate_progress(nData)) { + IndicateAchievementProgress(t.name.c_str(), nData, std::stoi(t.max_value)); + } } } @@ -496,9 +501,12 @@ Steam_User_Stats::InternalSetResultsecond) { - if (t.check_triggered(fData)) { + if (t.should_unlock_ach(fData)) { set_achievement_internal(t.name.c_str()); } + if (t.should_indicate_progress(fData)) { + IndicateAchievementProgress(t.name.c_str(), fData, std::stof(t.max_value)); + } } } @@ -1156,6 +1164,9 @@ bool Steam_User_Stats::IndicateAchievementProgress( const char *pchName, uint32 // save new progress try { + auto old_progress = user_achievements.value(actual_ach_name, nlohmann::json{}).value("progress", ~nCurProgress); + if (old_progress == nCurProgress) return true; + user_achievements[actual_ach_name]["progress"] = nCurProgress; user_achievements[actual_ach_name]["max_progress"] = nMaxProgress; save_achievements(); @@ -1179,7 +1190,6 @@ bool Steam_User_Stats::IndicateAchievementProgress( const char *pchName, uint32 callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); } - // callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); // TODO was this correct? return true; } @@ -1340,7 +1350,6 @@ bool Steam_User_Stats::ResetAllStats( bool bAchievementsToo ) item["earned"] = false; item["earned_time"] = static_cast(0); item["progress"] = static_cast(0); - item["max_progress"] = static_cast(0); overlay->AddAchievementNotification(name, item, false); } catch(const std::exception& e) { diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 3aa524cf..12f96cff 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -2039,15 +2039,13 @@ void Steam_Overlay::AddAchievementNotification(const std::string &ach_name, nloh a.max_progress = ach.value("max_progress", static_cast(0)); } catch(...) {} - if (a.achieved) { + if (a.achieved && !for_progress) { // here we don't show the progress indications + post_achievement_notification(a, for_progress); + notify_sound_user_achievement(); + } else if (for_progress && !settings->disable_overlay_achievement_progress) { // progress indication is shown for locked achievements only // post notification if this isn't a progress, or a progress and the user didn't disable these notifications - if (!for_progress || !settings->disable_overlay_achievement_progress) { - post_achievement_notification(a, for_progress); - } - // don't play sound if this is progress - if (!for_progress) { - notify_sound_user_achievement(); - } + post_achievement_notification(a, for_progress); + // don't play sound } break; }