From 6d96b7173e2e747a4742f163388361dd41fc45bb Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 16 Jun 2023 20:27:04 -0400 Subject: [PATCH 1/2] Handle Achievement Progress Event Added handling to Achievement Progress Events, which are generated when an achievement with a Measured field updates in value. For example, an achievement for collecting 120 stars will throw this event when the player collects each star, and with this handling, the player will get a message on screen informing them of this progress. This message will only appear if the newly added RA_PROGRESS_ENABLED setting is true. --- Source/Core/Core/AchievementManager.cpp | 28 +++++++++++++++++++ Source/Core/Core/AchievementManager.h | 1 + .../Core/Core/Config/AchievementSettings.cpp | 2 ++ Source/Core/Core/Config/AchievementSettings.h | 1 + .../Core/ConfigLoaders/IsSettingSaveable.cpp | 1 + 5 files changed, 33 insertions(+) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 1cf02daa5d..7eb23fbf14 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -606,6 +606,9 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti case RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED: HandleAchievementTriggeredEvent(runtime_event); break; + case RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED: + HandleAchievementProgressUpdatedEvent(runtime_event); + break; case RC_RUNTIME_EVENT_LBOARD_STARTED: HandleLeaderboardStartedEvent(runtime_event); break; @@ -1104,6 +1107,31 @@ void AchievementManager::HandleAchievementTriggeredEvent(const rc_runtime_event_ Config::Get(Config::RA_ENCORE_ENABLED)); } +void AchievementManager::HandleAchievementProgressUpdatedEvent( + const rc_runtime_event_t* runtime_event) +{ + if (!Config::Get(Config::RA_PROGRESS_ENABLED)) + return; + auto it = m_unlock_map.find(runtime_event->id); + if (it == m_unlock_map.end()) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Invalid achievement progress updated event with id {}.", + runtime_event->id); + return; + } + AchievementId game_data_index = it->second.game_data_index; + FormattedValue value{}; + if (rc_runtime_format_achievement_measured(&m_runtime, runtime_event->id, value.data(), + FORMAT_SIZE) == 0) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Failed to format measured data {}.", value.data()); + return; + } + OSD::AddMessage( + fmt::format("{} {}", m_game_data.achievements[game_data_index].title, value.data()), + OSD::Duration::VERY_LONG, OSD::Color::GREEN); +} + void AchievementManager::HandleLeaderboardStartedEvent(const rc_runtime_event_t* runtime_event) { for (u32 ix = 0; ix < m_game_data.num_leaderboards; ix++) diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index f7866f0926..8ec0866681 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -137,6 +137,7 @@ private: ResponseType PingRichPresence(const RichPresence& rich_presence); void HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event); + void HandleAchievementProgressUpdatedEvent(const rc_runtime_event_t* runtime_event); void HandleLeaderboardStartedEvent(const rc_runtime_event_t* runtime_event); void HandleLeaderboardCanceledEvent(const rc_runtime_event_t* runtime_event); void HandleLeaderboardTriggeredEvent(const rc_runtime_event_t* runtime_event); diff --git a/Source/Core/Core/Config/AchievementSettings.cpp b/Source/Core/Core/Config/AchievementSettings.cpp index 9211fb712e..a425605f8c 100644 --- a/Source/Core/Core/Config/AchievementSettings.cpp +++ b/Source/Core/Core/Config/AchievementSettings.cpp @@ -19,6 +19,8 @@ const Info RA_LEADERBOARDS_ENABLED{ {System::Achievements, "Achievements", "LeaderboardsEnabled"}, false}; const Info RA_RICH_PRESENCE_ENABLED{ {System::Achievements, "Achievements", "RichPresenceEnabled"}, false}; +const Info RA_PROGRESS_ENABLED{{System::Achievements, "Achievements", "ProgressEnabled"}, + false}; const Info RA_BADGES_ENABLED{{System::Achievements, "Achievements", "BadgesEnabled"}, false}; const Info RA_UNOFFICIAL_ENABLED{{System::Achievements, "Achievements", "UnofficialEnabled"}, false}; diff --git a/Source/Core/Core/Config/AchievementSettings.h b/Source/Core/Core/Config/AchievementSettings.h index c3dec06d01..b17d00c65f 100644 --- a/Source/Core/Core/Config/AchievementSettings.h +++ b/Source/Core/Core/Config/AchievementSettings.h @@ -14,6 +14,7 @@ extern const Info RA_API_TOKEN; extern const Info RA_ACHIEVEMENTS_ENABLED; extern const Info RA_LEADERBOARDS_ENABLED; extern const Info RA_RICH_PRESENCE_ENABLED; +extern const Info RA_PROGRESS_ENABLED; extern const Info RA_BADGES_ENABLED; extern const Info RA_UNOFFICIAL_ENABLED; extern const Info RA_ENCORE_ENABLED; diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp index 7d0b63f9bb..ac8e70e10f 100644 --- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp +++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp @@ -47,6 +47,7 @@ bool IsSettingSaveable(const Config::Location& config_location) &Config::RA_ACHIEVEMENTS_ENABLED.GetLocation(), &Config::RA_LEADERBOARDS_ENABLED.GetLocation(), &Config::RA_RICH_PRESENCE_ENABLED.GetLocation(), + &Config::RA_PROGRESS_ENABLED.GetLocation(), &Config::RA_BADGES_ENABLED.GetLocation(), &Config::RA_UNOFFICIAL_ENABLED.GetLocation(), &Config::RA_ENCORE_ENABLED.GetLocation(), From 6b110bb6fe4a33ea647f06b979fb43d62ab3b4bb Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 16 Jun 2023 20:32:31 -0400 Subject: [PATCH 2/2] Added Progress switch to Achievements dialog Added a switch for the progress messages to the settings tab of the Achievements dialog. --- .../AchievementSettingsWidget.cpp | 19 +++++++++++++++++++ .../Achievements/AchievementSettingsWidget.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp index fb8b0cb662..dbfb13f7a6 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp @@ -75,6 +75,11 @@ void AchievementSettingsWidget::CreateLayout() "achievements.

Unofficial achievements may be optional or unfinished achievements " "that have not been deemed official by RetroAchievements and may be useful for testing or " "simply for fun.")); + m_common_progress_enabled_input = new ToolTipCheckBox(tr("Enable Progress Notifications")); + m_common_progress_enabled_input->SetDescription( + tr("Enable progress notifications on achievements.

Displays a brief popup message " + "whenever the player makes progress on an achievement that tracks an accumulated value, " + "such as 60 out of 120 stars.")); m_common_badges_enabled_input = new ToolTipCheckBox(tr("Enable Achievement Badges")); m_common_badges_enabled_input->SetDescription( tr("Enable achievement badges.

Displays icons for the player, game, and achievements. " @@ -97,6 +102,7 @@ void AchievementSettingsWidget::CreateLayout() m_common_layout->addWidget(m_common_achievements_enabled_input); m_common_layout->addWidget(m_common_leaderboards_enabled_input); m_common_layout->addWidget(m_common_rich_presence_enabled_input); + m_common_layout->addWidget(m_common_progress_enabled_input); m_common_layout->addWidget(m_common_badges_enabled_input); m_common_layout->addWidget(m_common_unofficial_enabled_input); m_common_layout->addWidget(m_common_encore_enabled_input); @@ -117,6 +123,8 @@ void AchievementSettingsWidget::ConnectWidgets() &AchievementSettingsWidget::ToggleLeaderboards); connect(m_common_rich_presence_enabled_input, &QCheckBox::toggled, this, &AchievementSettingsWidget::ToggleRichPresence); + connect(m_common_progress_enabled_input, &QCheckBox::toggled, this, + &AchievementSettingsWidget::ToggleProgress); connect(m_common_badges_enabled_input, &QCheckBox::toggled, this, &AchievementSettingsWidget::ToggleBadges); connect(m_common_unofficial_enabled_input, &QCheckBox::toggled, this, @@ -165,6 +173,10 @@ void AchievementSettingsWidget::LoadSettings() ->setChecked(Config::Get(Config::RA_RICH_PRESENCE_ENABLED)); SignalBlocking(m_common_rich_presence_enabled_input)->setEnabled(enabled); + SignalBlocking(m_common_progress_enabled_input) + ->setChecked(Config::Get(Config::RA_PROGRESS_ENABLED)); + SignalBlocking(m_common_progress_enabled_input)->setEnabled(enabled && achievements_enabled); + SignalBlocking(m_common_badges_enabled_input)->setChecked(Config::Get(Config::RA_BADGES_ENABLED)); SignalBlocking(m_common_badges_enabled_input)->setEnabled(enabled); @@ -187,6 +199,8 @@ void AchievementSettingsWidget::SaveSettings() m_common_leaderboards_enabled_input->isChecked()); Config::SetBaseOrCurrent(Config::RA_RICH_PRESENCE_ENABLED, m_common_rich_presence_enabled_input->isChecked()); + Config::SetBaseOrCurrent(Config::RA_PROGRESS_ENABLED, + m_common_unofficial_enabled_input->isChecked()); Config::SetBaseOrCurrent(Config::RA_BADGES_ENABLED, m_common_badges_enabled_input->isChecked()); Config::SetBaseOrCurrent(Config::RA_UNOFFICIAL_ENABLED, m_common_unofficial_enabled_input->isChecked()); @@ -236,6 +250,11 @@ void AchievementSettingsWidget::ToggleRichPresence() AchievementManager::GetInstance()->ActivateDeactivateRichPresence(); } +void AchievementSettingsWidget::ToggleProgress() +{ + SaveSettings(); +} + void AchievementSettingsWidget::ToggleBadges() { SaveSettings(); diff --git a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h index c086b3380b..edf22b7350 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h +++ b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h @@ -36,6 +36,7 @@ private: void ToggleLeaderboards(); void ToggleRichPresence(); void ToggleHardcore(); + void ToggleProgress(); void ToggleBadges(); void ToggleUnofficial(); void ToggleEncore(); @@ -55,6 +56,7 @@ private: ToolTipCheckBox* m_common_achievements_enabled_input; ToolTipCheckBox* m_common_leaderboards_enabled_input; ToolTipCheckBox* m_common_rich_presence_enabled_input; + ToolTipCheckBox* m_common_progress_enabled_input; ToolTipCheckBox* m_common_badges_enabled_input; ToolTipCheckBox* m_common_unofficial_enabled_input; ToolTipCheckBox* m_common_encore_enabled_input;