mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-02 02:23:56 +00:00
Disable all NPCs when maxActors=0
Allow the game room server to accept maxActors=0 (previously floored at 5). When received, the client disables extra actor spawning, camera animations, and continuously purges all extras including the ambient NPCs (mama, papa, brickster) that PurgeExtra(TRUE) deliberately skips. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4269a1b0fc
commit
a588e3bb67
@ -115,6 +115,7 @@ class NetworkManager : public MxCore {
|
||||
void RemoveAllRemotePlayers();
|
||||
|
||||
void NotifyPlayerCountChanged();
|
||||
void EnforceDisableNPCs();
|
||||
|
||||
// Serialize and send a fixed-size message via the transport
|
||||
template <typename T>
|
||||
@ -143,6 +144,7 @@ class NetworkManager : public MxCore {
|
||||
std::atomic<int> m_pendingEmote;
|
||||
std::atomic<bool> m_pendingToggleAllowCustomize;
|
||||
|
||||
bool m_disableAllNPCs;
|
||||
bool m_showNameBubbles;
|
||||
bool m_lastCameraEnabled;
|
||||
|
||||
|
||||
@ -6,9 +6,12 @@
|
||||
#include "extensions/thirdpersoncamera.h"
|
||||
#include "extensions/thirdpersoncamera/controller.h"
|
||||
#include "legoanimationmanager.h"
|
||||
#include "legocharactermanager.h"
|
||||
#include "legoextraactor.h"
|
||||
#include "legogamestate.h"
|
||||
#include "legomain.h"
|
||||
#include "legopathactor.h"
|
||||
#include "legopathcontroller.h"
|
||||
#include "legoworld.h"
|
||||
#include "misc.h"
|
||||
#include "mxmisc.h"
|
||||
@ -41,9 +44,9 @@ void NetworkManager::SendMessage(const T& p_msg)
|
||||
NetworkManager::NetworkManager()
|
||||
: m_transport(nullptr), m_callbacks(nullptr), m_localNameBubble(nullptr), m_localPeerId(0), m_hostPeerId(0),
|
||||
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_showNameBubbles(true), m_lastCameraEnabled(false)
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,6 +64,10 @@ MxResult NetworkManager::Tickle()
|
||||
{
|
||||
ProcessPendingRequests();
|
||||
|
||||
if (m_disableAllNPCs) {
|
||||
EnforceDisableNPCs();
|
||||
}
|
||||
|
||||
// Detect camera state changes for platform notification
|
||||
ThirdPersonCamera::Controller* cam = GetCamera();
|
||||
if (cam) {
|
||||
@ -202,6 +209,10 @@ void NetworkManager::OnWorldEnabled(LegoWorld* p_world)
|
||||
}
|
||||
|
||||
NotifyPlayerCountChanged();
|
||||
|
||||
if (m_disableAllNPCs) {
|
||||
EnforceDisableNPCs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,6 +278,36 @@ MxBool NetworkManager::HandleSkyLightMutation(uint8_t p_entityType, uint8_t p_ch
|
||||
return m_worldSync.HandleSkyLightMutation(p_entityType, p_changeType);
|
||||
}
|
||||
|
||||
void NetworkManager::EnforceDisableNPCs()
|
||||
{
|
||||
LegoAnimationManager* am = AnimationManager();
|
||||
if (!am) {
|
||||
return;
|
||||
}
|
||||
|
||||
am->m_numAllowedExtras = 0;
|
||||
am->m_enableCamAnims = FALSE;
|
||||
am->m_unk0x400 = FALSE;
|
||||
|
||||
// Purge all extras including ambient NPCs (mama, papa, brickster)
|
||||
// that are spawned by camera path triggers via FUN_10064380.
|
||||
// PurgeExtra(TRUE) deliberately skips mama/papa, so we purge manually.
|
||||
for (MxS32 i = 0; i < (MxS32) sizeOfArray(am->m_extras); i++) {
|
||||
if (am->m_extras[i].m_roi != NULL) {
|
||||
LegoPathActor* actor = CharacterManager()->GetExtraActor(am->m_extras[i].m_roi->GetName());
|
||||
if (actor != NULL && actor->GetController() != NULL) {
|
||||
actor->GetController()->RemoveActor(actor);
|
||||
actor->SetController(NULL);
|
||||
}
|
||||
|
||||
CharacterManager()->ReleaseActor(am->m_extras[i].m_roi);
|
||||
am->m_extras[i].m_roi = NULL;
|
||||
am->m_extras[i].m_characterId = -1;
|
||||
am->m_unk0x414--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkManager::ProcessPendingRequests()
|
||||
{
|
||||
ThirdPersonCamera::Controller* cam = GetCamera();
|
||||
@ -409,10 +450,16 @@ void NetworkManager::ProcessIncomingPackets()
|
||||
}
|
||||
if (length >= 6) {
|
||||
uint8_t maxActors = data[5];
|
||||
if (maxActors >= 5 && maxActors <= 40) {
|
||||
if (maxActors <= 40) {
|
||||
LegoAnimationManager::configureLegoAnimationManager(maxActors);
|
||||
if (AnimationManager()) {
|
||||
AnimationManager()->m_maxAllowedExtras = maxActors;
|
||||
AnimationManager()->m_numAllowedExtras =
|
||||
SDL_min(AnimationManager()->m_numAllowedExtras, (MxU32) maxActors);
|
||||
}
|
||||
m_disableAllNPCs = (maxActors == 0);
|
||||
if (m_disableAllNPCs) {
|
||||
EnforceDisableNPCs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ export class GameRoom implements DurableObject {
|
||||
}
|
||||
if (body.maxActors !== undefined) {
|
||||
this.maxActors = Math.max(
|
||||
5,
|
||||
0,
|
||||
Math.min(body.maxActors, 40)
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user