From 84b24c6228bd1542cc2851a764d7b13a49d4ca4d Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 18 Apr 2024 00:40:06 +1000 Subject: [PATCH] Achievements: Fix HC mode activating on reset of non-cheevo game --- src/core/achievements.cpp | 25 +++++++++++++++++++++---- src/core/achievements.h | 2 +- src/core/system.cpp | 4 ++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/core/achievements.cpp b/src/core/achievements.cpp index 52b1aba3f..b850b489a 100644 --- a/src/core/achievements.cpp +++ b/src/core/achievements.cpp @@ -129,6 +129,7 @@ static void ClearGameHash(); static std::string GetGameHash(CDImage* image); static void SetHardcoreMode(bool enabled, bool force_display_message); static bool IsLoggedInOrLoggingIn(); +static bool CanEnableHardcoreMode(); static void ShowLoginSuccess(const rc_client_t* client); static void ShowLoginNotification(); static void IdentifyGame(const std::string& path, CDImage* image); @@ -497,7 +498,7 @@ void Achievements::UpdateSettings(const Settings& old_config) // Hardcore mode can only be enabled through reset (ResetChallengeMode()). if (s_hardcore_mode && !g_settings.achievements_hardcore_mode) { - ResetHardcoreMode(); + ResetHardcoreMode(false); } else if (!s_hardcore_mode && g_settings.achievements_hardcore_mode) { @@ -927,13 +928,21 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message, return; } + const bool has_achievements = rc_client_has_achievements(client); + const bool has_leaderboards = rc_client_has_leaderboards(client); + + // If the game has a RetroAchievements entry but no achievements or leaderboards, + // enforcing hardcore mode is pointless. + if (!has_achievements && !has_leaderboards) + DisableHardcoreMode(); + // We should have matched hardcore mode state. Assert(s_hardcore_mode == (rc_client_get_hardcore_enabled(client) != 0)); s_game_id = info->id; s_game_title = info->title; - s_has_achievements = rc_client_has_achievements(client); - s_has_leaderboards = rc_client_has_leaderboards(client); + s_has_achievements = has_achievements; + s_has_leaderboards = has_leaderboards; s_has_rich_presence = rc_client_has_rich_presence(client); s_game_icon = {}; @@ -1373,7 +1382,7 @@ void Achievements::DisableHardcoreMode() SetHardcoreMode(false, true); } -bool Achievements::ResetHardcoreMode() +bool Achievements::ResetHardcoreMode(bool is_booting) { if (!IsActive()) return false; @@ -1387,6 +1396,9 @@ bool Achievements::ResetHardcoreMode() if (s_hardcore_mode == wanted_hardcore_mode) return false; + if (!is_booting && wanted_hardcore_mode && !CanEnableHardcoreMode()) + return false; + SetHardcoreMode(wanted_hardcore_mode, false); return true; } @@ -1597,6 +1609,11 @@ bool Achievements::IsLoggedInOrLoggingIn() return (rc_client_get_user_info(s_client) != nullptr || s_login_request); } +bool Achievements::CanEnableHardcoreMode() +{ + return (s_load_game_request || s_has_achievements || s_has_leaderboards); +} + bool Achievements::Login(const char* username, const char* password, Error* error) { auto lock = GetLock(); diff --git a/src/core/achievements.h b/src/core/achievements.h index 504b92389..ef8f0ef3d 100644 --- a/src/core/achievements.h +++ b/src/core/achievements.h @@ -75,7 +75,7 @@ void Logout(); void GameChanged(const std::string& path, CDImage* image); /// Re-enables hardcore mode if it is enabled in the settings. -bool ResetHardcoreMode(); +bool ResetHardcoreMode(bool is_booting); /// Forces hardcore mode off until next reset. void DisableHardcoreMode(); diff --git a/src/core/system.cpp b/src/core/system.cpp index 423000a85..c833bb1fb 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1115,7 +1115,7 @@ void System::ResetSystem() if (!Achievements::ConfirmSystemReset()) return; - if (Achievements::ResetHardcoreMode()) + if (Achievements::ResetHardcoreMode(false)) { // Make sure a pre-existing cheat file hasn't been loaded when resetting // after enabling HC mode. @@ -3502,7 +3502,7 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting) g_texture_replacements.SetGameID(s_running_game_serial); if (booting) - Achievements::ResetHardcoreMode(); + Achievements::ResetHardcoreMode(true); Achievements::GameChanged(s_running_game_path, image);