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.
This commit is contained in:
LillyJadeKatrin 2023-10-20 08:35:41 -04:00
parent b4276049fc
commit 8fbc5960e7
2 changed files with 50 additions and 0 deletions

View File

@ -710,6 +710,12 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti
case RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED: case RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED:
HandleAchievementProgressUpdatedEvent(runtime_event); HandleAchievementProgressUpdatedEvent(runtime_event);
break; 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: case RC_RUNTIME_EVENT_LBOARD_STARTED:
HandleLeaderboardStartedEvent(runtime_event); HandleLeaderboardStartedEvent(runtime_event);
break; break;
@ -857,6 +863,11 @@ void AchievementManager::SetDisabled(bool disable)
} }
}; };
const AchievementManager::NamedIconMap& AchievementManager::GetChallengeIcons() const
{
return m_active_challenges;
}
void AchievementManager::CloseGame() void AchievementManager::CloseGame()
{ {
{ {
@ -1467,6 +1478,34 @@ void AchievementManager::HandleAchievementProgressUpdatedEvent(
nullptr); 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) void AchievementManager::HandleLeaderboardStartedEvent(const rc_runtime_event_t* runtime_event)
{ {
for (u32 ix = 0; ix < m_game_data.num_leaderboards; ix++) for (u32 ix = 0; ix < m_game_data.num_leaderboards; ix++)

View File

@ -7,6 +7,7 @@
#include <array> #include <array>
#include <ctime> #include <ctime>
#include <functional> #include <functional>
#include <map>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <thread> #include <thread>
@ -25,6 +26,11 @@ namespace Core
class System; class System;
} }
namespace OSD
{
struct Icon;
}
class AchievementManager class AchievementManager
{ {
public: public:
@ -61,6 +67,7 @@ public:
static constexpr size_t RP_SIZE = 256; static constexpr size_t RP_SIZE = 256;
using RichPresence = std::array<char, RP_SIZE>; using RichPresence = std::array<char, RP_SIZE>;
using Badge = std::vector<u8>; using Badge = std::vector<u8>;
using NamedIconMap = std::map<std::string, std::unique_ptr<OSD::Icon>, std::less<>>;
struct BadgeStatus struct BadgeStatus
{ {
@ -138,6 +145,7 @@ public:
RichPresence GetRichPresence(); RichPresence GetRichPresence();
bool IsDisabled() const { return m_disabled; }; bool IsDisabled() const { return m_disabled; };
void SetDisabled(bool disabled); void SetDisabled(bool disabled);
const NamedIconMap& GetChallengeIcons() const;
void CloseGame(); void CloseGame();
void Logout(); void Logout();
@ -180,6 +188,8 @@ private:
void HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event); void HandleAchievementTriggeredEvent(const rc_runtime_event_t* runtime_event);
void HandleAchievementProgressUpdatedEvent(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 HandleLeaderboardStartedEvent(const rc_runtime_event_t* runtime_event);
void HandleLeaderboardCanceledEvent(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); void HandleLeaderboardTriggeredEvent(const rc_runtime_event_t* runtime_event);
@ -210,6 +220,7 @@ private:
std::unordered_map<AchievementId, UnlockStatus> m_unlock_map; std::unordered_map<AchievementId, UnlockStatus> m_unlock_map;
std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map; std::unordered_map<AchievementId, LeaderboardStatus> m_leaderboard_map;
NamedIconMap m_active_challenges;
Common::WorkQueueThread<std::function<void()>> m_queue; Common::WorkQueueThread<std::function<void()>> m_queue;
Common::WorkQueueThread<std::function<void()>> m_image_queue; Common::WorkQueueThread<std::function<void()>> m_image_queue;