diff --git a/Gameleap/code/mw4/Code/MW4/MW4Shell.cpp b/Gameleap/code/mw4/Code/MW4/MW4Shell.cpp index 3548841f..7e0892db 100644 --- a/Gameleap/code/mw4/Code/MW4/MW4Shell.cpp +++ b/Gameleap/code/mw4/Code/MW4/MW4Shell.cpp @@ -57,6 +57,19 @@ #include "mechspecs.cpp" +// [16 pilots + 1 cameraship fix] +// +// A cameraship seat occupies a network (DirectPlay) slot but pilots no 'Mech, so slots must +// be reserved for cameraships on top of the pilot cap, and cameraships must NOT be counted +// against the 'Mech cap. +// +// The reserve has to be a CONSTANT rather than being derived from +// (CTCL_GetTeslaCountAll() - CTCL_GetTeslaCount()): the CTCL tesla table is only populated +// when CTCL_IsConsoleOrCOOP() is true (see ctcl.cpp), so on a pod - including the cameraship +// pod, which is the machine that actually creates the network session in CTCL_DoCreateGame() +// - both counters return 0 and the reserve collapsed to +0. +#define MW4_CAMERASHIP_RESERVE 4 // must be >= MAX_CAMERAS in ctcl.cpp + // MSL 5.03 Mechview void __stdcall CTCL_AfterBeginScene(); void __stdcall CTCL_UpdateMechView(); @@ -1968,8 +1981,13 @@ int MW4Shell::SetNetworkMissionParamater(void * instance, int numParms, void **d case PLAYER_LIMIT_PARAMETER: params->m_playerLimit = INTPARM(1); Min_Clamp(params->m_playerLimit, Network::GetInstance()->GetPlayerCount()); - // Add camera slots on top of the pilot limit so cameraships can still connect - Environment.NetworkMaxPlayers = params->m_playerLimit + (CTCL_GetTeslaCountAll() - CTCL_GetTeslaCount()); + // [16 pilots + 1 cameraship fix] Add camera slots on top of the pilot limit so + // cameraships can still connect. Uses the constant reserve for the same reason as + // CTCL_DefaultHostSetup: the CTCL tesla counters are console-only and read 0 on a pod. + // Only applied under CTCL - a standalone (non-pod) host must keep its exact limit. + Environment.NetworkMaxPlayers = params->m_playerLimit; + if (!CTCL_IsNone()) + Environment.NetworkMaxPlayers += MW4_CAMERASHIP_RESERVE; gos_NetServerCommands(gos_Commend_UpdateMaxPlayers,0); break; @@ -9071,6 +9089,24 @@ int MW4Shell::LoadDefaultOptions() return 1; } +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// [16 pilots + 1 cameraship fix] +// Number of cameraship participants in the current roster. Only meaningful on the server +// pod, which is the only machine that holds the full g_aPlayerInfos roster (filled by +// CSOC_Client::OnBOTS) and the only machine that calls AddBot in CTCL mode. +// A cameraship entry is a non-bot player with no 'Mech (m_nMechIndex == 0). +static int CTCL_CountCameraShipsInGame() +{ + int count = 0; + for (int i = 0; i < g_nPlayerInfos; i++) + { + const SPlayerInfo& PI = g_aPlayerInfos[i]; + if (!PI.m_bBot && (PI.m_nMechIndex == 0)) + count++; + } + return count; +} + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int _stdcall MW4Shell::AddBot(void *instance, int numParams, void* data[]) @@ -9087,6 +9123,16 @@ int _stdcall MW4Shell::AddBot(void *instance, int numParams, void* data[]) bot_count++; } player_count = Network::GetInstance()->GetPlayerCount(); + // [16 pilots + 1 cameraship fix] Cameraships hold a network slot but no 'Mech slot. + // Counting them here capped pilots+cameras+bots at m_maxPlayers (16), so a full 16-'Mech + // roster plus a cameraship silently lost its last bot; g_nBOTs then never matched the + // connected lancemates and CTCL_CheckServerReady() spun forever without ever launching. + if (CTCL_IsConsoleX()) + { + player_count -= CTCL_CountCameraShipsInGame(); + if (player_count < 0) + player_count = 0; + } NetMissionParameters::MWNetMissionParameters *params = app->GetLocalNetParams(); if (params->m_runDedicated) { @@ -13592,10 +13638,13 @@ void CTCL_API CTCL_DefaultHostSetup(int nMode) params->m_maxBots = 8; } else { params->m_maxPlayers = 16; - // Reserve extra DirectPlay slots for cameraships: they share the session but are tracked - // separately from pilot seats in CTCL (CTCL_GetTeslaCountAll - CTCL_GetTeslaCount = camera count). - // Without this, cameraship connection is rejected by DirectPlay because slot 17 doesn't exist. - Environment.NetworkMaxPlayers = params->m_maxPlayers + (CTCL_GetTeslaCountAll() - CTCL_GetTeslaCount()); + // [16 pilots + 1 cameraship fix] Reserve network slots for cameraship seats on top of the + // pilot cap. This runs on the cameraship pod too (via CTCL_DoCreateGame -> nMode 0), which + // is the machine that creates the session with dwMaxPlayers = Environment.NetworkMaxPlayers. + // Do NOT derive the reserve from the CTCL tesla counters here: that table is console-only, + // so on the pod they both return 0, the reserve became +0, the session was created with + // 16 slots, and the 17th connection was refused - the mission then never finished loading. + Environment.NetworkMaxPlayers = params->m_maxPlayers + MW4_CAMERASHIP_RESERVE; params->m_maxBots = 16; } params->m_allow3rdPerson = 1;