From 8fbc5960e7b14babe5eaa113e59814451c1486c6 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 20 Oct 2023 08:35:41 -0400 Subject: [PATCH] Handle Achievement Un/Primed Events When an achievement is "primed", a challenge is active, for example completing a portion of the game in under a time limit or without taking damage or using certain items. This is stored in a map in the Achievement Manager (and removed when the achievement is unprimed) so a later commit can display it on screen. --- Source/Core/Core/AchievementManager.cpp | 39 +++++++++++++++++++++++++ Source/Core/Core/AchievementManager.h | 11 +++++++ 2 files changed, 50 insertions(+) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index ebb83ac801..2862fbdac3 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -710,6 +710,12 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti case RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED: HandleAchievementProgressUpdatedEvent(runtime_event); break; + case RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED: + HandleAchievementPrimedEvent(runtime_event); + break; + case RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED: + HandleAchievementUnprimedEvent(runtime_event); + break; case RC_RUNTIME_EVENT_LBOARD_STARTED: HandleLeaderboardStartedEvent(runtime_event); break; @@ -857,6 +863,11 @@ void AchievementManager::SetDisabled(bool disable) } }; +const AchievementManager::NamedIconMap& AchievementManager::GetChallengeIcons() const +{ + return m_active_challenges; +} + void AchievementManager::CloseGame() { { @@ -1467,6 +1478,34 @@ void AchievementManager::HandleAchievementProgressUpdatedEvent( nullptr); } +void AchievementManager::HandleAchievementPrimedEvent(const rc_runtime_event_t* runtime_event) +{ + if (!Config::Get(Config::RA_BADGES_ENABLED)) + return; + auto it = m_unlock_map.find(runtime_event->id); + if (it == m_unlock_map.end()) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Invalid achievement primed event with id {}.", runtime_event->id); + return; + } + m_active_challenges[it->second.unlocked_badge.name] = + DecodeBadgeToOSDIcon(it->second.unlocked_badge.badge); +} + +void AchievementManager::HandleAchievementUnprimedEvent(const rc_runtime_event_t* runtime_event) +{ + if (!Config::Get(Config::RA_BADGES_ENABLED)) + return; + auto it = m_unlock_map.find(runtime_event->id); + if (it == m_unlock_map.end()) + { + ERROR_LOG_FMT(ACHIEVEMENTS, "Invalid achievement unprimed event with id {}.", + runtime_event->id); + return; + } + m_active_challenges.erase(it->second.unlocked_badge.name); +} + 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 7d93b7d781..3a260f9e8b 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,11 @@ namespace Core class System; } +namespace OSD +{ +struct Icon; +} + class AchievementManager { public: @@ -61,6 +67,7 @@ public: static constexpr size_t RP_SIZE = 256; using RichPresence = std::array; using Badge = std::vector; + using NamedIconMap = std::map, std::less<>>; struct BadgeStatus { @@ -138,6 +145,7 @@ public: RichPresence GetRichPresence(); bool IsDisabled() const { return m_disabled; }; void SetDisabled(bool disabled); + const NamedIconMap& GetChallengeIcons() const; void CloseGame(); void Logout(); @@ -180,6 +188,8 @@ private: void HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event); void HandleAchievementProgressUpdatedEvent(const rc_runtime_event_t* runtime_event); + void HandleAchievementPrimedEvent(const rc_runtime_event_t* runtime_event); + void HandleAchievementUnprimedEvent(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); @@ -210,6 +220,7 @@ private: std::unordered_map m_unlock_map; std::unordered_map m_leaderboard_map; + NamedIconMap m_active_challenges; Common::WorkQueueThread> m_queue; Common::WorkQueueThread> m_image_queue;