diff --git a/src/services/AchievementRuntime.cpp b/src/services/AchievementRuntime.cpp index 46b72b33..7527d6b8 100644 --- a/src/services/AchievementRuntime.cpp +++ b/src/services/AchievementRuntime.cpp @@ -1584,24 +1584,13 @@ void AchievementRuntime::InvalidateAddress(ra::data::ByteAddress nAddress) static void HandleAchievementTriggeredEvent(const rc_client_achievement_t& pAchievement) { - auto& pGameContext = ra::services::ServiceLocator::GetMutable(); - auto* vmAchievement = pGameContext.Assets().FindAchievement(pAchievement.id); + const auto* vmAchievement = CheckForPauseOnTrigger(pAchievement); if (!vmAchievement) { RA_LOG_ERR("Received achievement triggered event for unknown achievement %u", pAchievement.id); return; } - // immediately update the state to Triggered (instead of waiting for AssetListViewModel::DoFrame to do it). - // this captures the unlock time and rich presence state, even if KeepActive it selected. - vmAchievement->SetState(ra::data::models::AssetState::Triggered); - - if (vmAchievement->IsPauseOnTrigger()) - { - auto& pFrameEventQueue = ra::services::ServiceLocator::GetMutable(); - pFrameEventQueue.QueuePauseOnTrigger(vmAchievement->GetName()); - } - const auto& pConfiguration = ra::services::ServiceLocator::Get(); bool bTakeScreenshot = pConfiguration.IsFeatureEnabled(ra::services::Feature::AchievementTriggeredScreenshot); bool bSubmit = false; @@ -1648,7 +1637,7 @@ static void HandleAchievementTriggeredEvent(const rc_client_achievement_t& pAchi bTakeScreenshot = false; } - if (bSubmit && pGameContext.GetMode() == ra::data::context::GameContext::Mode::CompatibilityTest) + if (bSubmit && ra::services::ServiceLocator::Get().GetMode() == ra::data::context::GameContext::Mode::CompatibilityTest) { std::wstring sHeader = vmPopup->GetTitle(); sHeader.insert(0, L"Test "); diff --git a/src/services/AchievementRuntimeExports.cpp b/src/services/AchievementRuntimeExports.cpp index 860b6aef..bbc008dd 100644 --- a/src/services/AchievementRuntimeExports.cpp +++ b/src/services/AchievementRuntimeExports.cpp @@ -1,4 +1,5 @@ #include "AchievementRuntime.hh" +#include "AchievementRuntimeExports.hh" #include "Exports.hh" #include "util\Log.hh" @@ -11,6 +12,7 @@ #include "data\context\GameContext.hh" +#include "services\FrameEventQueue.hh" #include "services\IConfiguration.hh" #include "services\ServiceLocator.hh" #include "services\impl\JsonFileConfiguration.hh" @@ -850,8 +852,13 @@ class AchievementRuntimeExports : private AchievementRuntime s_callbacks.log_callback(sMessage, s_callbacks.log_client); } - static void EventHandlerExternal(const rc_client_event_t* event, rc_client_t*) noexcept(false) + static void EventHandlerExternal(const rc_client_event_t* event, rc_client_t*) { + Expects(event != nullptr); + + if (event->type == RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED) + CheckForPauseOnTrigger(*event->achievement); + if (s_callbacks.event_handler) s_callbacks.event_handler(event, s_callbacks.event_client); } @@ -1030,6 +1037,26 @@ std::array AchievementRuntime } // namespace services } // namespace ra +const ra::data::models::AchievementModel* CheckForPauseOnTrigger(const rc_client_achievement_t& pAchievement) +{ + auto& pGameContext = ra::services::ServiceLocator::GetMutable(); + auto* vmAchievement = pGameContext.Assets().FindAchievement(pAchievement.id); + if (vmAchievement) + { + // immediately update the state to Triggered (instead of waiting for AssetListViewModel::DoFrame to do it). + // this captures the unlock time and rich presence state, even if KeepActive it selected. + vmAchievement->SetState(ra::data::models::AssetState::Triggered); + + if (vmAchievement->IsPauseOnTrigger()) + { + auto& pFrameEventQueue = ra::services::ServiceLocator::GetMutable(); + pFrameEventQueue.QueuePauseOnTrigger(vmAchievement->GetName()); + } + } + + return vmAchievement; +} + void ResetExternalRcheevosClient() noexcept { ra::services::AchievementRuntimeExports::destroy(); diff --git a/src/services/AchievementRuntimeExports.hh b/src/services/AchievementRuntimeExports.hh index 726819b5..c9787f9b 100644 --- a/src/services/AchievementRuntimeExports.hh +++ b/src/services/AchievementRuntimeExports.hh @@ -2,11 +2,17 @@ #define RA_SERVICES_ACHIEVEMENT_RUNTIME_EXPORTS_HH #pragma once -void RaiseClientExternalMenuChanged(); +#include "data/models/AchievementModel.hh" + +#include + +void RaiseClientExternalMenuChanged() noexcept; void SyncClientExternalRAIntegrationMenuItem(int nMenuItemId); void SyncClientExternalHardcoreState(); bool IsExternalRcheevosClient() noexcept; void ResetExternalRcheevosClient() noexcept; void ResetEmulatorMemoryRegionsForRcheevosClient(); +const ra::data::models::AchievementModel* CheckForPauseOnTrigger(const rc_client_achievement_t& pAchievement); + #endif // !RA_SERVICES_ACHIEVEMENT_RUNTIME_EXPORTS_HH