Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

24 player support (from Stannnn) #5

Merged
merged 1 commit into from
Apr 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ghost/bnetprotocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ Observers: (mask 0x00700000) cant be combined
UTIL_AppendByteArray( packet, CustomGame, 4 ); // Custom Game
UTIL_AppendByteArrayFast( packet, gameName ); // Game Name
packet.push_back( 0 ); // Game Password is NULL
packet.push_back( 98 ); // Slots Free (ascii 98 = char 'b' = 11 slots free) - note: do not reduce this as this is the # of PID's Warcraft III will allocate
packet.push_back( 110 ); // Slots Free (ascii 98 = char 'b' = 11 slots free) - note: do not reduce this as this is the # of PID's Warcraft III will allocate
UTIL_AppendByteArrayFast( packet, HostCounterString, false ); // Host Counter
UTIL_AppendByteArrayFast( packet, StatString ); // Stat String
packet.push_back( 0 ); // Stat String null terminator (the stat string is encoded to remove all even numbers i.e. zeros)
Expand Down
20 changes: 10 additions & 10 deletions ghost/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
{
unsigned char SID = (unsigned char)( Slot - 1 );

if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && Colour < 12 && SID < m_Slots.size( ) )
if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && Colour < MAX_SLOTS && SID < m_Slots.size( ) )
{
if( m_Slots[SID].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[SID].GetComputer( ) == 1 )
ColourSlot( SID, Colour );
Expand Down Expand Up @@ -879,7 +879,7 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
{
unsigned char SID = (unsigned char)( Slot - 1 );

if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && Team < 12 && SID < m_Slots.size( ) )
if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && Team < MAX_SLOTS && SID < m_Slots.size( ) )
{
if( m_Slots[SID].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[SID].GetComputer( ) == 1 )
{
Expand Down Expand Up @@ -1446,14 +1446,14 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string

uint32_t FixedHostCounter = m_HostCounter & 0x0FFFFFFF;

// we send 12 for SlotsTotal because this determines how many PID's Warcraft 3 allocates
// we need to make sure Warcraft 3 allocates at least SlotsTotal + 1 but at most 12 PID's
// this is because we need an extra PID for the virtual host player (but we always delete the virtual host player when the 12th person joins)
// we send MAX_SLOTS for SlotsTotal because this determines how many PID's Warcraft 3 allocates
// we need to make sure Warcraft 3 allocates at least SlotsTotal + 1 but at most MAX_SLOTS PID's
// this is because we need an extra PID for the virtual host player (but we always delete the virtual host player when the MAX_SLOTSth person joins)
// however, we can't send 13 for SlotsTotal because this causes Warcraft 3 to crash when sharing control of units
// nor can we send SlotsTotal because then Warcraft 3 crashes when playing maps with less than 12 PID's (because of the virtual host player taking an extra PID)
// we also send 12 for SlotsOpen because Warcraft 3 assumes there's always at least one player in the game (the host)
// nor can we send SlotsTotal because then Warcraft 3 crashes when playing maps with less than MAX_SLOTS PID's (because of the virtual host player taking an extra PID)
// we also send MAX_SLOTS for SlotsOpen because Warcraft 3 assumes there's always at least one player in the game (the host)
// so if we try to send accurate numbers it'll always be off by one and results in Warcraft 3 assuming the game is full when it still needs one more player
// the easiest solution is to simply send 12 for both so the game will always show up as (1/12) players
// the easiest solution is to simply send MAX_SLOTS for both so the game will always show up as (1/MAX_SLOTS) players

if( m_SaveGame )
{
Expand All @@ -1466,15 +1466,15 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
BYTEARRAY MapHeight;
MapHeight.push_back( 0 );
MapHeight.push_back( 0 );
m_GHost->m_UDPSocket->SendTo( IP, Port, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), MapWidth, MapHeight, m_GameName, "Varlock", GetTime( ) - m_CreationTime, "Save\\Multiplayer\\" + m_SaveGame->GetFileNameNoPath( ), m_SaveGame->GetMagicNumber( ), 12, 12, m_HostPort, FixedHostCounter, m_EntryKey ) );
m_GHost->m_UDPSocket->SendTo( IP, Port, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), MapWidth, MapHeight, m_GameName, "Varlock", GetTime( ) - m_CreationTime, "Save\\Multiplayer\\" + m_SaveGame->GetFileNameNoPath( ), m_SaveGame->GetMagicNumber( ), MAX_SLOTS, MAX_SLOTS, m_HostPort, FixedHostCounter, m_EntryKey ) );
}
else
{
// note: the PrivateGame flag is not set when broadcasting to LAN (as you might expect)
// note: we do not use m_Map->GetMapGameType because none of the filters are set when broadcasting to LAN (also as you might expect)

uint32_t MapGameType = MAPGAMETYPE_UNKNOWN0;
m_GHost->m_UDPSocket->SendTo( IP, Port, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), m_Map->GetMapWidth( ), m_Map->GetMapHeight( ), m_GameName, "Varlock", GetTime( ) - m_CreationTime, m_Map->GetMapPath( ), m_Map->GetMapCRC( ), 12, 12, m_HostPort, FixedHostCounter, m_EntryKey ) );
m_GHost->m_UDPSocket->SendTo( IP, Port, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), m_Map->GetMapWidth( ), m_Map->GetMapHeight( ), m_GameName, "Varlock", GetTime( ) - m_CreationTime, m_Map->GetMapPath( ), m_Map->GetMapCRC( ), MAX_SLOTS, MAX_SLOTS, m_HostPort, FixedHostCounter, m_EntryKey ) );
}
}
}
Expand Down
82 changes: 41 additions & 41 deletions ghost/game_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ bool CBaseGame :: Update( void *fd, void *send_fd )

// create the virtual host player

if( !m_GameLoading && !m_GameLoaded && GetNumPlayers( ) < 12 )
if( !m_GameLoading && !m_GameLoaded && GetNumPlayers( ) < MAX_SLOTS )
CreateVirtualHost( );

// unlock the game
Expand Down Expand Up @@ -473,14 +473,14 @@ bool CBaseGame :: Update( void *fd, void *send_fd )

uint32_t FixedHostCounter = m_HostCounter & 0x0FFFFFFF;

// we send 12 for SlotsTotal because this determines how many PID's Warcraft 3 allocates
// we need to make sure Warcraft 3 allocates at least SlotsTotal + 1 but at most 12 PID's
// this is because we need an extra PID for the virtual host player (but we always delete the virtual host player when the 12th person joins)
// we send MAX_SLOTS for SlotsTotal because this determines how many PID's Warcraft 3 allocates
// we need to make sure Warcraft 3 allocates at least SlotsTotal + 1 but at most MAX_SLOTS PID's
// this is because we need an extra PID for the virtual host player (but we always delete the virtual host player when the MAX_SLOTSth person joins)
// however, we can't send 13 for SlotsTotal because this causes Warcraft 3 to crash when sharing control of units
// nor can we send SlotsTotal because then Warcraft 3 crashes when playing maps with less than 12 PID's (because of the virtual host player taking an extra PID)
// we also send 12 for SlotsOpen because Warcraft 3 assumes there's always at least one player in the game (the host)
// nor can we send SlotsTotal because then Warcraft 3 crashes when playing maps with less than MAX_SLOTS PID's (because of the virtual host player taking an extra PID)
// we also send MAX_SLOTS for SlotsOpen because Warcraft 3 assumes there's always at least one player in the game (the host)
// so if we try to send accurate numbers it'll always be off by one and results in Warcraft 3 assuming the game is full when it still needs one more player
// the easiest solution is to simply send 12 for both so the game will always show up as (1/12) players
// the easiest solution is to simply send MAX_SLOTS for both so the game will always show up as (1/MAX_SLOTS) players

if( m_SaveGame )
{
Expand All @@ -493,15 +493,15 @@ bool CBaseGame :: Update( void *fd, void *send_fd )
BYTEARRAY MapHeight;
MapHeight.push_back( 0 );
MapHeight.push_back( 0 );
m_GHost->m_UDPSocket->Broadcast( 6112, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), MapWidth, MapHeight, m_GameName, "Varlock", GetTime( ) - m_CreationTime, "Save\\Multiplayer\\" + m_SaveGame->GetFileNameNoPath( ), m_SaveGame->GetMagicNumber( ), 12, 12, m_HostPort, FixedHostCounter, m_EntryKey ) );
m_GHost->m_UDPSocket->Broadcast( 6112, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), MapWidth, MapHeight, m_GameName, "Varlock", GetTime( ) - m_CreationTime, "Save\\Multiplayer\\" + m_SaveGame->GetFileNameNoPath( ), m_SaveGame->GetMagicNumber( ), MAX_SLOTS, MAX_SLOTS, m_HostPort, FixedHostCounter, m_EntryKey ) );
}
else
{
// note: the PrivateGame flag is not set when broadcasting to LAN (as you might expect)
// note: we do not use m_Map->GetMapGameType because none of the filters are set when broadcasting to LAN (also as you might expect)

uint32_t MapGameType = MAPGAMETYPE_UNKNOWN0;
m_GHost->m_UDPSocket->Broadcast( 6112, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), m_Map->GetMapWidth( ), m_Map->GetMapHeight( ), m_GameName, "Varlock", GetTime( ) - m_CreationTime, m_Map->GetMapPath( ), m_Map->GetMapCRC( ), 12, 12, m_HostPort, FixedHostCounter, m_EntryKey ) );
m_GHost->m_UDPSocket->Broadcast( 6112, m_Protocol->SEND_W3GS_GAMEINFO( m_GHost->m_TFT, m_GHost->m_LANWar3Version, UTIL_CreateByteArray( MapGameType, false ), m_Map->GetMapGameFlags( ), m_Map->GetMapWidth( ), m_Map->GetMapHeight( ), m_GameName, "Varlock", GetTime( ) - m_CreationTime, m_Map->GetMapPath( ), m_Map->GetMapCRC( ), MAX_SLOTS, MAX_SLOTS, m_HostPort, FixedHostCounter, m_EntryKey ) );
}
}

Expand Down Expand Up @@ -2049,7 +2049,7 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP
// we have a slot for the new player
// make room for them by deleting the virtual host player if we have to

if( GetNumPlayers( ) >= 11 || EnforcePID == m_VirtualHostPID )
if( GetNumPlayers( ) >= MAX_SLOTS-1 || EnforcePID == m_VirtualHostPID )
DeleteVirtualHost( );

// turning the CPotentialPlayer into a CGamePlayer is a bit of a pain because we have to be careful not to close the socket
Expand Down Expand Up @@ -2079,9 +2079,9 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP
else
{
if( m_Map->GetMapFlags( ) & MAPFLAG_RANDOMRACES )
m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, 12, 12, SLOTRACE_RANDOM );
m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, MAX_SLOTS, MAX_SLOTS, SLOTRACE_RANDOM );
else
m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, 12, 12, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE );
m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, MAX_SLOTS, MAX_SLOTS, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE );

// try to pick a team and colour
// make sure there aren't too many other players already
Expand All @@ -2090,7 +2090,7 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP

for( unsigned char i = 0; i < m_Slots.size( ); ++i )
{
if( m_Slots[i].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[i].GetTeam( ) != 12 )
if( m_Slots[i].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[i].GetTeam( ) != MAX_SLOTS )
NumOtherPlayers++;
}

Expand Down Expand Up @@ -2439,7 +2439,7 @@ void CBaseGame :: EventPlayerJoinedWithScore( CPotentialPlayer *potential, CInco
// we have a slot for the new player
// make room for them by deleting the virtual host player if we have to

if( GetNumPlayers( ) >= 11 )
if( GetNumPlayers( ) >= MAX_SLOTS-1 )
DeleteVirtualHost( );

// identify their joined realm
Expand Down Expand Up @@ -3033,10 +3033,10 @@ void CBaseGame :: EventPlayerChangeTeam( CGamePlayer *player, unsigned char team
}
else
{
if( team > 12 )
if( team > MAX_SLOTS )
return;

if( team == 12 )
if( team == MAX_SLOTS )
{
if( m_Map->GetMapObservers( ) != MAPOBS_ALLOWED && m_Map->GetMapObservers( ) != MAPOBS_REFEREES )
return;
Expand All @@ -3052,7 +3052,7 @@ void CBaseGame :: EventPlayerChangeTeam( CGamePlayer *player, unsigned char team

for( unsigned char i = 0; i < m_Slots.size( ); ++i )
{
if( m_Slots[i].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[i].GetTeam( ) != 12 && m_Slots[i].GetPID( ) != player->GetPID( ) )
if( m_Slots[i].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[i].GetTeam( ) != MAX_SLOTS && m_Slots[i].GetPID( ) != player->GetPID( ) )
++NumOtherPlayers;
}

Expand All @@ -3066,13 +3066,13 @@ void CBaseGame :: EventPlayerChangeTeam( CGamePlayer *player, unsigned char team
{
m_Slots[SID].SetTeam( team );

if( team == 12 )
if( team == MAX_SLOTS )
{
// if they're joining the observer team give them the observer colour

m_Slots[SID].SetColour( 12 );
m_Slots[SID].SetColour( MAX_SLOTS );
}
else if( m_Slots[SID].GetColour( ) == 12 )
else if( m_Slots[SID].GetColour( ) == MAX_SLOTS )
{
// if they're joining a regular team give them an unused colour

Expand All @@ -3094,7 +3094,7 @@ void CBaseGame :: EventPlayerChangeColour( CGamePlayer *player, unsigned char co
if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
return;

if( colour > 11 )
if( colour > MAX_SLOTS-1 )
return;

unsigned char SID = GetSIDFromPID( player->GetPID( ) );
Expand All @@ -3103,7 +3103,7 @@ void CBaseGame :: EventPlayerChangeColour( CGamePlayer *player, unsigned char co
{
// make sure the player isn't an observer

if( m_Slots[SID].GetTeam( ) == 12 )
if( m_Slots[SID].GetTeam( ) == MAX_SLOTS )
return;

ColourSlot( SID, colour );
Expand Down Expand Up @@ -3698,7 +3698,7 @@ unsigned char CBaseGame :: GetNewColour( )
{
// find an unused colour for a player to use

for( unsigned char TestColour = 0; TestColour < 12; ++TestColour )
for( unsigned char TestColour = 0; TestColour < MAX_SLOTS; ++TestColour )
{
bool InUse = false;

Expand All @@ -3717,7 +3717,7 @@ unsigned char CBaseGame :: GetNewColour( )

// this should never happen

return 12;
return MAX_SLOTS;
}

BYTEARRAY CBaseGame :: GetPIDs( )
Expand Down Expand Up @@ -4013,7 +4013,7 @@ void CBaseGame :: ComputerSlot( unsigned char SID, unsigned char skill, bool kic

void CBaseGame :: ColourSlot( unsigned char SID, unsigned char colour )
{
if( SID < m_Slots.size( ) && colour < 12 )
if( SID < m_Slots.size( ) && colour < MAX_SLOTS )
{
// make sure the requested colour isn't already taken

Expand Down Expand Up @@ -4094,7 +4094,7 @@ void CBaseGame :: ShuffleSlots( )

for( vector<CGameSlot> :: iterator i = m_Slots.begin( ); i != m_Slots.end( ); ++i )
{
if( (*i).GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && (*i).GetComputer( ) == 0 && (*i).GetTeam( ) != 12 )
if( (*i).GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && (*i).GetComputer( ) == 0 && (*i).GetTeam( ) != MAX_SLOTS )
PlayerSlots.push_back( *i );
}

Expand Down Expand Up @@ -4140,7 +4140,7 @@ void CBaseGame :: ShuffleSlots( )

for( vector<CGameSlot> :: iterator i = m_Slots.begin( ); i != m_Slots.end( ); ++i )
{
if( (*i).GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && (*i).GetComputer( ) == 0 && (*i).GetTeam( ) != 12 )
if( (*i).GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && (*i).GetComputer( ) == 0 && (*i).GetTeam( ) != MAX_SLOTS )
{
Slots.push_back( *CurrentPlayer );
++CurrentPlayer;
Expand Down Expand Up @@ -4168,7 +4168,7 @@ vector<unsigned char> CBaseGame :: BalanceSlotsRecursive( vector<unsigned char>
vector<unsigned char> BestOrdering = PlayerIDs;
double BestDifference = -1.0;

for( unsigned char i = StartTeam; i < 12; ++i )
for( unsigned char i = StartTeam; i < MAX_SLOTS; ++i )
{
if( TeamSizes[i] > 0 )
{
Expand All @@ -4195,9 +4195,9 @@ vector<unsigned char> CBaseGame :: BalanceSlotsRecursive( vector<unsigned char>
// now calculate the team scores for all the teams that we know about (e.g. on subsequent recursion steps this will NOT be every possible team)

vector<unsigned char> :: iterator CurrentPID = TestOrdering.begin( );
double TeamScores[12];
double TeamScores[MAX_SLOTS];

for( unsigned char j = StartTeam; j < 12; ++j )
for( unsigned char j = StartTeam; j < MAX_SLOTS; ++j )
{
TeamScores[j] = 0.0;

Expand All @@ -4212,11 +4212,11 @@ vector<unsigned char> CBaseGame :: BalanceSlotsRecursive( vector<unsigned char>

double LargestDifference = 0.0;

for( unsigned char j = StartTeam; j < 12; ++j )
for( unsigned char j = StartTeam; j < MAX_SLOTS; ++j )
{
if( TeamSizes[j] > 0 )
{
for( unsigned char k = j + 1; k < 12; ++k )
for( unsigned char k = j + 1; k < MAX_SLOTS; ++k )
{
if( TeamSizes[k] > 0 )
{
Expand Down Expand Up @@ -4252,12 +4252,12 @@ void CBaseGame :: BalanceSlots( )
}

// setup the necessary variables for the balancing algorithm
// use an array of 13 elements for 12 players because GHost++ allocates PID's from 1-12 (i.e. excluding 0) and we use the PID to index the array
// use an array of 13 elements for MAX_SLOTS players because GHost++ allocates PID's from 1-MAX_SLOTS (i.e. excluding 0) and we use the PID to index the array

vector<unsigned char> PlayerIDs;
unsigned char TeamSizes[12];
unsigned char TeamSizes[MAX_SLOTS];
double PlayerScores[13];
memset( TeamSizes, 0, sizeof( unsigned char ) * 12 );
memset( TeamSizes, 0, sizeof( unsigned char ) * MAX_SLOTS );

for( vector<CGamePlayer *> :: iterator i = m_Players.begin( ); i != m_Players.end( ); ++i )
{
Expand All @@ -4271,7 +4271,7 @@ void CBaseGame :: BalanceSlots( )
{
unsigned char Team = m_Slots[SID].GetTeam( );

if( Team < 12 )
if( Team < MAX_SLOTS )
{
// we are forced to use a default score because there's no way to balance the teams otherwise

Expand All @@ -4291,7 +4291,7 @@ void CBaseGame :: BalanceSlots( )
sort( PlayerIDs.begin( ), PlayerIDs.end( ) );

// balancing the teams is a variation of the bin packing problem which is NP
// we can have up to 12 players and/or teams so the scope of the problem is sometimes small enough to process quickly
// we can have up to MAX_SLOTS players and/or teams so the scope of the problem is sometimes small enough to process quickly
// let's try to figure out roughly how much work this is going to take
// examples:
// 2 teams of 4 = 70 ~ 5ms *** ok
Expand All @@ -4306,7 +4306,7 @@ void CBaseGame :: BalanceSlots( )
uint32_t AlgorithmCost = 0;
uint32_t PlayersLeft = PlayerIDs.size( );

for( unsigned char i = 0; i < 12; ++i )
for( unsigned char i = 0; i < MAX_SLOTS; ++i )
{
if( TeamSizes[i] > 0 )
{
Expand Down Expand Up @@ -4339,7 +4339,7 @@ void CBaseGame :: BalanceSlots( )

vector<unsigned char> :: iterator CurrentPID = BestOrdering.begin( );

for( unsigned char i = 0; i < 12; ++i )
for( unsigned char i = 0; i < MAX_SLOTS; ++i )
{
unsigned char CurrentSlot = 0;

Expand Down Expand Up @@ -4377,7 +4377,7 @@ void CBaseGame :: BalanceSlots( )
SendAllChat( m_GHost->m_Language->BalancingSlotsCompleted( ) );
SendAllSlotInfo( );

for( unsigned char i = 0; i < 12; ++i )
for( unsigned char i = 0; i < MAX_SLOTS; ++i )
{
bool TeamHasPlayers = false;
double TeamScore = 0.0;
Expand Down Expand Up @@ -4731,7 +4731,7 @@ void CBaseGame :: CreateFakePlayer( )

if( SID < m_Slots.size( ) )
{
if( GetNumPlayers( ) >= 11 )
if( GetNumPlayers( ) >= MAX_SLOTS-1 )
DeleteVirtualHost( );

m_FakePlayerPID = GetNewPID( );
Expand Down
Loading