From 09ed6edb3e2b82bf0fa9d10eeb67ddbd92b5f0ac Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 15 Mar 2026 13:54:48 -0700 Subject: [PATCH] Fix player count not updating when exiting Isle overlay areas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When transitioning from a restricted area (elevator, observatory, etc.) back to the Isle world, the player count stayed at 0 because nothing triggered a recount — the Isle world was already enabled so OnWorldEnabled didn't fire. Track restricted-area status changes in BroadcastLocalState and call NotifyPlayerCountChanged on transitions. Also sync the flag in OnWorldEnabled/OnWorldDisabled to prevent spurious recounts across world transitions. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../include/extensions/multiplayer/networkmanager.h | 1 + extensions/src/multiplayer/networkmanager.cpp | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/extensions/include/extensions/multiplayer/networkmanager.h b/extensions/include/extensions/multiplayer/networkmanager.h index 47926ade..3ed806a0 100644 --- a/extensions/include/extensions/multiplayer/networkmanager.h +++ b/extensions/include/extensions/multiplayer/networkmanager.h @@ -147,6 +147,7 @@ class NetworkManager : public MxCore { bool m_disableAllNPCs; bool m_showNameBubbles; bool m_lastCameraEnabled; + bool m_wasInRestrictedArea; static const uint32_t BROADCAST_INTERVAL_MS = 66; // ~15Hz static const uint32_t TIMEOUT_MS = 5000; // 5 second timeout diff --git a/extensions/src/multiplayer/networkmanager.cpp b/extensions/src/multiplayer/networkmanager.cpp index 75c2d5a2..29586c85 100644 --- a/extensions/src/multiplayer/networkmanager.cpp +++ b/extensions/src/multiplayer/networkmanager.cpp @@ -49,7 +49,7 @@ NetworkManager::NetworkManager() m_sequence(0), m_lastBroadcastTime(0), m_lastValidActorId(0), m_localAllowRemoteCustomize(true), m_inIsleWorld(false), m_registered(false), m_pendingToggleThirdPerson(false), m_pendingToggleNameBubbles(false), m_pendingWalkAnim(-1), m_pendingIdleAnim(-1), m_pendingEmote(-1), m_pendingToggleAllowCustomize(false), - m_disableAllNPCs(false), m_showNameBubbles(true), m_lastCameraEnabled(false) + m_disableAllNPCs(false), m_showNameBubbles(true), m_lastCameraEnabled(false), m_wasInRestrictedArea(false) { } @@ -201,6 +201,7 @@ void NetworkManager::OnWorldEnabled(LegoWorld* p_world) if (p_world->GetWorldId() == LegoOmni::e_act1) { m_inIsleWorld = true; + m_wasInRestrictedArea = IsRestrictedArea(GameState()->m_currentArea); m_worldSync.SetInIsleWorld(true); for (auto& [peerId, player] : m_remotePlayers) { @@ -236,6 +237,7 @@ void NetworkManager::OnWorldDisabled(LegoWorld* p_world) if (p_world->GetWorldId() == LegoOmni::e_act1) { m_inIsleWorld = false; + m_wasInRestrictedArea = false; m_worldSync.SetInIsleWorld(false); // Destroy local name bubble (ROI is about to be destroyed) @@ -407,11 +409,16 @@ void NetworkManager::BroadcastLocalState() ThirdPersonCamera::Controller* cam = GetCamera(); + bool inRestrictedArea = IsRestrictedArea(GameState()->m_currentArea); + if (m_inIsleWorld && m_wasInRestrictedArea != inRestrictedArea) { + m_wasInRestrictedArea = inRestrictedArea; + NotifyPlayerCountChanged(); + } + PlayerStateMsg msg{}; msg.header = {MSG_STATE, m_localPeerId, m_sequence++, TARGET_BROADCAST}; msg.actorId = actorId; - msg.worldId = - IsRestrictedArea(GameState()->m_currentArea) ? WORLD_NOT_VISIBLE : (int8_t) currentWorld->GetWorldId(); + msg.worldId = inRestrictedArea ? WORLD_NOT_VISIBLE : (int8_t) currentWorld->GetWorldId(); msg.vehicleType = DetectVehicleType(userActor); SDL_memcpy(msg.position, pos, sizeof(msg.position)); SDL_memcpy(msg.direction, dir, sizeof(msg.direction));