From aed16a8c80d695462a58e9155a820194f231e99c Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 29 Sep 2026 02:20:32 -0500 Subject: [PATCH] fix(stats): RocketsUsed and QuickBuildsCompleted where live sent them RocketsUsed: live counted the rocket when the client asked to go (FireEventServerSide "ZonePlayer"), right before TransferToZone (captures: 94 of 117 directly before it). DLU counted it when the launch animation started, so a launch that never went counted too. QuickBuildsCompleted: live sent it after RebuildNotifyState(Completed) and the completion effect (507), before EnableRebuild (218 of 227 samples); DLU counted it before the notify state. Check in game: launch a rocket to another world; Rockets Used goes up by 1 as the screen fades out. Finish a quick build: Quick Builds Completed goes up by 1 as the build finishes. Co-Authored-By: Claude Opus 5.5 --- dGame/dComponents/QuickBuildComponent.cpp | 3 ++- dGame/dComponents/RocketLaunchpadControlComponent.cpp | 2 -- dGame/dGameMessages/ObjectMessages.cpp | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/QuickBuildComponent.cpp b/dGame/dComponents/QuickBuildComponent.cpp index 698750596..70c4a2ad4 100644 --- a/dGame/dComponents/QuickBuildComponent.cpp +++ b/dGame/dComponents/QuickBuildComponent.cpp @@ -448,7 +448,6 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* const user) { auto* characterComponent = user->GetComponent(); if (characterComponent != nullptr) { characterComponent->SetCurrentActivity(eGameActivity::NONE); - characterComponent->TrackQuickBuildComplete(); EconomyLedger::RecordMapEvent(IEconomyLedger::eMapEvent::QUICKBUILDS_COMPLETED, m_Parent->GetLOT(), m_Parent->GetPosition(), 1, user); } else { LOG("Some user tried to finish the rebuild but they didn't have a character somehow."); @@ -466,6 +465,8 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* const user) { GameMessages::PlayFXEffect fx(m_Parent->GetObjectID(), 507, u"create", "BrickFadeUpVisCompleteEffect"); fx.priority = 0.4f; fx.Send(UNASSIGNED_SYSTEM_ADDRESS); + // Live: RebuildNotifyState(Completed), the effect, then QuickBuildsCompleted, then EnableRebuild + characterComponent->TrackQuickBuildComplete(); GameMessages::EnableRebuild enableRebuild; enableRebuild.target = m_Parent->GetObjectID(); enableRebuild.bEnable = false; diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 73243c80b..6a0beec72 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -74,8 +74,6 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId, character->SetTargetScene(m_TargetScene); } - characterComponent->UpdatePlayerStatistic(RocketsUsed); - character->SaveXMLToDatabase(); SetSelectedMapId(originator->GetObjectID(), zone); diff --git a/dGame/dGameMessages/ObjectMessages.cpp b/dGame/dGameMessages/ObjectMessages.cpp index 93c976f5a..62ac10ccb 100644 --- a/dGame/dGameMessages/ObjectMessages.cpp +++ b/dGame/dGameMessages/ObjectMessages.cpp @@ -97,6 +97,10 @@ namespace GameMessages { return; } + // Live counted the rocket when the client asked to go (after the launch), before TransferToZone + auto* launcher = player->GetComponent(); + if (launcher) launcher->UpdatePlayerStatistic(RocketsUsed); + ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, mapId, cloneId, false, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) { LOG("Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i", character->GetName().c_str(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);