This is a code of Class Limitation features.
Here we go!
find in g_locals.h:
extern vmCvar_t g_disableComplaints;
below add:
extern vmCvar_t team_maxMedics; // Medics
extern vmCvar_t team_maxEngineers; // Engineers
extern vmCvar_t team_maxFieldOps; // Field Ops
extern vmCvar_t team_maxCovertOps; // Covert Ops
find in g_main.c:
vmCvar_t g_disableComplaints;
below add:
vmCvar_t team_maxMedics;
vmCvar_t team_maxEngineers;
vmCvar_t team_maxFieldOps;
vmCvar_t team_maxCovertOps;
find in g_main.c:
{ &g_disableComplaints, "g_disableComplaints", "0", CVAR_ARCHIVE },
below add:
{ &team_maxMedics, "team_maxMedics", "-1", CVAR_ARCHIVE },
{ &team_maxEngineers, "team_maxEngineers", "-1", CVAR_ARCHIVE },
{ &team_maxFieldOps, "team_maxFieldOps", "-1", CVAR_ARCHIVE },
{ &team_maxCovertOps, "team_maxCovertOps", "-1", CVAR_ARCHIVE },
find in g_cmds.c, and replace this code
// Azyu - Class Limitation
int G_ClassCount( gentity_t* ent, int playerType ) {
int i, j, cnt=0;
if( playerType < PC_SOLDIER || playerType > PC_COVERTOPS )
return 0;
for( i = 0; i < level.numConnectedClients; i++ ) {
j = level.sortedClients[i];
if( j == ent-g_entities ) {
continue;
}
if( level.clients[j].sess.sessionTeam != ent->client->sess.sessionTeam ) {
continue;
}
if( level.clients[j].sess.playerType != playerType && level.clients[j].sess.latchPlayerType != playerType ) {
continue;
}
cnt++;
}
return cnt;
}
void Cmd_Team_f( gentity_t *ent, unsigned int dwCommand, qboolean fValue ) {
char s[MAX_TOKEN_CHARS];
char ptype[4];
char weap[4], weap2[4];
int playerType, count;
weapon_t w, w2;
qboolean limit = qfalse;
if ( trap_Argc() < 2 ) {
char *pszTeamName;
switch ( ent->client->sess.sessionTeam ) {
case TEAM_ALLIES:
pszTeamName = "Allies";
break;
case TEAM_AXIS:
pszTeamName = "Axis";
break;
case TEAM_SPECTATOR:
pszTeamName = "Spectator";
break;
case TEAM_FREE:
default:
pszTeamName = "Free";
break;
}
CP(va("print \"%s team
\"", pszTeamName));
return;
}
trap_Argv( 1, s, sizeof( s ));
trap_Argv( 2, ptype, sizeof( ptype ));
trap_Argv( 3, weap, sizeof( weap ));
trap_Argv( 4, weap2, sizeof( weap2 ));
w = atoi( weap );
w2 = atoi( weap2 );
playerType = ent->client->sess.latchPlayerType = atoi( ptype );
count = G_ClassCount( ent, playerType );
switch( playerType ) {
case PC_MEDIC:
if( team_maxMedics.integer == -1 ) break;
if( count >= team_maxMedics.integer )
{
CP( "cp \"^1Medic^7 is not available! Choose another class!
\"" );
limit = qtrue;
}
break;
case PC_ENGINEER:
if( team_maxEngineers.integer == -1 ) break;
if( count >= team_maxEngineers.integer )
{
CP( "cp \"^1Engineer^7 is not available! Choose another class!
\"" );
limit = qtrue;
}
break;
case PC_FIELDOPS:
if( team_maxFieldOps.integer == -1 ) break;
if( count >= team_maxFieldOps.integer )
{
CP( "cp \"^1Field Ops^7 is not available! Choose another class!
\"" );
limit = qtrue;
}
break;
case PC_COVERTOPS:
if( team_maxFieldOps.integer == -1 ) break;
if( count >= team_maxFieldOps.integer )
{
CP( "cp \"^1Covert Ops^7 is not available! Choose another class!
\"" );
limit = qtrue;
}
break;
}
if( limit )
{
ent->client->sess.latchPlayerType = PC_SOLDIER;
w = (ent->client->sess.sessionTeam == TEAM_AXIS) ? WP_MP40 : WP_THOMPSON;
w2 = (ent->client->sess.sessionTeam == TEAM_AXIS) ? WP_LUGER : WP_COLT;
}
if( ent->client->sess.latchPlayerType < PC_SOLDIER || ent->client->sess.latchPlayerType > PC_COVERTOPS ) {
ent->client->sess.latchPlayerType = PC_SOLDIER;
}
if( ent->client->sess.latchPlayerType < PC_SOLDIER || ent->client->sess.latchPlayerType > PC_COVERTOPS ) {
ent->client->sess.latchPlayerType = PC_SOLDIER;
}
if( !SetTeam( ent, s, qfalse, w, w2, qtrue ) ) {
G_SetClientWeapons( ent, w, w2, qtrue );
}
}

