/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (Wolf ET Source Code).
Wolf ET Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Wolf ET Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wolf ET Source Code. If not, see .
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "g_local.h"
// Gordon
// What we need....
// invite
// apply
// create
// leave
// player can only be on single fire team
// only leader can invite
// leaving a team causes the first person to join the team after the leader to become leader
// 32 char limit on fire team names, mebe reduce to 16..
// Application commad overview
//
// clientNum < 0 = special, otherwise is client that the command refers to
// -1 = Application sent
// -2 = Application Failed
// -3 = Application Approved
// -4 = Response sent
// Invitation commad overview
//
// clientNum < 0 = special, otherwise is client that the command refers to
// -1 = Invitation sent
// -2 = Invitation Rejected
// -3 = Invitation Accepted
// -4 = Response sent
// Proposition commad overview
//
// clientNum < 0 = special, otherwise is client that the command refers to
// -1 = Proposition sent
// -2 = Proposition Rejected
// -3 = Proposition Accepted
// -4 = Response sent
// Auto fireteam priv/pub
//
// -1 = ask
// -2 = confirmed
//
// Configstring for each fireteam "\\n\\%NAME%\\l\\%LEADERNUM%\\c\\%CLIENTS%"
// clients "compressed" using hex
#define G_ClientPrintAndReturn( entityNum, text ) trap_SendServerCommand( entityNum, "cpm \"" text "\"\n" ); return;
// Utility functions
fireteamData_t* G_FindFreeFireteam() {
int i;
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( !level.fireTeams[i].inuse ) {
return &level.fireTeams[i];
}
}
return NULL;
}
team_t G_GetFireteamTeam( fireteamData_t* ft ) {
if ( !ft->inuse ) {
return -1;
}
if ( ft->joinOrder[0] == -1 || !g_entities[(int)ft->joinOrder[0]].client ) {
G_Error( "G_GetFireteamTeam: Fireteam leader is invalid\n" );
}
return g_entities[(int)ft->joinOrder[0]].client->sess.sessionTeam;
}
int G_CountTeamFireteams( team_t team ) {
int i, cnt = 0;
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( G_GetFireteamTeam( &level.fireTeams[i] ) == team ) {
cnt++;
}
}
return cnt;
}
void G_UpdateFireteamConfigString( fireteamData_t* ft ) {
char buffer [128];
int i;
int clnts[2] = { 0, 0 };
if ( !ft->inuse ) {
Com_sprintf( buffer, 128, "\\id\\-1" );
} else {
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( ft->joinOrder[i] != -1 ) {
COM_BitSet( clnts, ft->joinOrder[i] );
}
}
// Com_sprintf(buffer, 128, "\\n\\%s\\l\\%i\\c\\%.8x%.8x", ft->name, ft->joinOrder[0], clnts[1], clnts[0]);
Com_sprintf( buffer, 128, "\\id\\%i\\l\\%i\\c\\%.8x%.8x", ft->ident - 1, ft->joinOrder[0], clnts[1], clnts[0] );
// G_Printf(va("%s\n", buffer));
}
trap_SetConfigstring( CS_FIRETEAMS + ( ft - level.fireTeams ), buffer );
}
qboolean G_IsOnFireteam( int entityNum, fireteamData_t** teamNum ) {
int i, j;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_IsOnFireteam: invalid client" );
}
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( !level.fireTeams[i].inuse ) {
continue;
}
for ( j = 0; j < MAX_CLIENTS; j++ ) {
if ( level.fireTeams[i].joinOrder[j] == -1 ) {
break;
}
if ( level.fireTeams[i].joinOrder[j] == entityNum ) {
if ( teamNum ) {
*teamNum = &level.fireTeams[i];
}
return qtrue;
}
}
}
if ( teamNum ) {
*teamNum = NULL;
}
return qfalse;
}
qboolean G_IsFireteamLeader( int entityNum, fireteamData_t** teamNum ) {
int i;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_IsFireteamLeader: invalid client" );
}
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( !level.fireTeams[i].inuse ) {
continue;
}
if ( level.fireTeams[i].joinOrder[0] == entityNum ) {
if ( teamNum ) {
*teamNum = &level.fireTeams[i];
}
return qtrue;
}
}
if ( teamNum ) {
*teamNum = NULL;
}
return qfalse;
}
int G_FindFreeFireteamIdent( team_t team ) {
qboolean freeIdent[MAX_FIRETEAMS / 2];
int i;
memset( freeIdent, qtrue, sizeof( freeIdent ) );
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( !level.fireTeams[i].inuse ) {
continue;
}
if ( g_entities[(int)level.fireTeams[i].joinOrder[0]].client->sess.sessionTeam == team ) {
freeIdent[level.fireTeams[i].ident - 1] = qfalse;
}
}
for ( i = 0; i < ( MAX_FIRETEAMS / 2 ); i++ ) {
if ( freeIdent[i] ) {
return i;
}
}
// Gordon: this should never happen
return -1;
}
// Should be the only function that ever creates a fireteam
void G_RegisterFireteam( /*const char* name,*/ int entityNum ) {
fireteamData_t* ft;
gentity_t* leader;
int count, ident;
if ( entityNum < 0 || entityNum >= MAX_CLIENTS ) {
G_Error( "G_RegisterFireteam: invalid client" );
}
leader = &g_entities[entityNum];
if ( !leader->client ) {
G_Error( "G_RegisterFireteam: attempting to register a Fireteam to an entity with no client\n" );
}
if ( G_IsOnFireteam( entityNum, NULL ) ) {
G_ClientPrintAndReturn( entityNum, "You are already on a fireteam, leave it first" );
}
/* if(!name || !*name) {
G_ClientPrintAndReturn(entityNum, "You must choose a name for your fireteam");
}*/
if ( ( ft = G_FindFreeFireteam() ) == NULL ) {
G_ClientPrintAndReturn( entityNum, "No free fireteams available" );
}
if ( leader->client->sess.sessionTeam != TEAM_AXIS && leader->client->sess.sessionTeam != TEAM_ALLIES ) {
G_ClientPrintAndReturn( entityNum, "Only players on a team can create a fireteam" );
}
count = G_CountTeamFireteams( leader->client->sess.sessionTeam );
if ( count >= MAX_FIRETEAMS / 2 ) {
G_ClientPrintAndReturn( entityNum, "Your team already has the maximum number of fireteams allowed" );
}
ident = G_FindFreeFireteamIdent( leader->client->sess.sessionTeam ) + 1;
if ( ident == 0 ) {
G_ClientPrintAndReturn( entityNum, "Um, something is broken, spoink Gordon" );
}
// good to go now, i hope!
ft->inuse = qtrue;
memset( ft->joinOrder, -1, sizeof( level.fireTeams[0].joinOrder ) );
ft->joinOrder[0] = leader - g_entities;
ft->ident = ident;
if ( g_autoFireteams.integer ) {
ft->priv = qfalse;
trap_SendServerCommand( entityNum, "aft -1" );
leader->client->pers.autofireteamEndTime = level.time + 20500;
} else {
ft->priv = qfalse;
}
// Q_strncpyz(ft->name, name, 32);
G_UpdateFireteamConfigString( ft );
}
// only way a client should ever join a fireteam, other than creating one
void G_AddClientToFireteam( int entityNum, int leaderNum ) {
fireteamData_t* ft;
int i;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_AddClientToFireteam: invalid client" );
}
if ( ( leaderNum < 0 || leaderNum >= MAX_CLIENTS ) || !g_entities[leaderNum].client ) {
G_Error( "G_AddClientToFireteam: invalid client" );
}
if ( g_entities[leaderNum].client->sess.sessionTeam != g_entities[entityNum].client->sess.sessionTeam ) {
G_ClientPrintAndReturn( entityNum, "You are not on the same team as that fireteam" );
}
if ( !G_IsFireteamLeader( leaderNum, &ft ) ) {
G_ClientPrintAndReturn( entityNum, "The leader has now left the Fireteam you applied to" );
}
if ( G_IsOnFireteam( entityNum, NULL ) ) {
G_ClientPrintAndReturn( entityNum, "You are already on a fireteam" );
}
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( i >= 6 ) {
G_ClientPrintAndReturn( entityNum, "Too many players already on this Fireteam" );
return;
}
if ( ft->joinOrder[i] == -1 ) {
// found a free position
ft->joinOrder[i] = entityNum;
G_UpdateFireteamConfigString( ft );
return;
}
}
}
// The only way a client should be removed from a fireteam
void G_RemoveClientFromFireteams( int entityNum, qboolean update, qboolean print ) {
fireteamData_t* ft;
int i, j;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_RemoveClientFromFireteams: invalid client" );
}
if ( G_IsOnFireteam( entityNum, &ft ) ) {
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( ft->joinOrder[i] == entityNum ) {
if ( i == 0 ) {
if ( ft->joinOrder[1] == -1 ) {
ft->inuse = qfalse;
ft->ident = -1;
} else {
// TODO: Inform client of promotion to leader
}
}
for ( j = i; j < MAX_CLIENTS - 1; j++ ) {
ft->joinOrder[j] = ft->joinOrder[j + 1];
}
ft->joinOrder[MAX_CLIENTS - 1] = -1;
break;
}
}
} else {
return;
}
if ( ft->joinOrder[0] != -1 ) {
if ( g_entities[(int)ft->joinOrder[0]].r.svFlags & SVF_BOT ) {
G_RemoveClientFromFireteams( ft->joinOrder[0], qfalse, qfalse );
}
}
if ( print ) {
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( ft->joinOrder[i] == -1 ) {
break;
}
trap_SendServerCommand( ft->joinOrder[i], va( "cpm \"%s has left the Fireteam\"\n", level.clients[entityNum].pers.netname ) );
}
}
if ( update ) {
G_UpdateFireteamConfigString( ft );
}
}
// The only way a client should ever be invitied to join a team
void G_InviteToFireTeam( int entityNum, int otherEntityNum ) {
fireteamData_t* ft;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_InviteToFireTeam: invalid client" );
}
if ( ( otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS ) || !g_entities[otherEntityNum].client ) {
G_Error( "G_InviteToFireTeam: invalid client" );
}
if ( !G_IsFireteamLeader( entityNum, &ft ) ) {
G_ClientPrintAndReturn( entityNum, "You are not the leader of a fireteam" );
}
if ( g_entities[entityNum].client->sess.sessionTeam != g_entities[otherEntityNum].client->sess.sessionTeam ) {
G_ClientPrintAndReturn( entityNum, "You are not on the same team as the other player" );
}
if ( G_IsOnFireteam( otherEntityNum, NULL ) ) {
G_ClientPrintAndReturn( entityNum, "The other player is already on a fireteam" );
}
if ( g_entities[otherEntityNum].r.svFlags & SVF_BOT ) {
// Gordon: bots auto join
G_AddClientToFireteam( otherEntityNum, entityNum );
} else {
trap_SendServerCommand( entityNum, va( "invitation -1" ) );
trap_SendServerCommand( otherEntityNum, va( "invitation %i", entityNum ) );
g_entities[otherEntityNum].client->pers.invitationClient = entityNum;
g_entities[otherEntityNum].client->pers.invitationEndTime = level.time + 20500;
}
}
void G_DestroyFireteam( int entityNum ) {
fireteamData_t* ft;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_DestroyFireteam: invalid client" );
}
if ( !G_IsFireteamLeader( entityNum, &ft ) ) {
G_ClientPrintAndReturn( entityNum, "You are not the leader of a fireteam" );
}
while ( ft->joinOrder[0] != -1 ) {
if ( ft->joinOrder[0] != entityNum ) {
trap_SendServerCommand( ft->joinOrder[0], "cpm \"The Fireteam you are on has been disbanded\"\n" );
}
G_RemoveClientFromFireteams( ft->joinOrder[0], qfalse, qfalse );
}
G_UpdateFireteamConfigString( ft );
}
void G_WarnFireTeamPlayer( int entityNum, int otherEntityNum ) {
fireteamData_t *ft, *ft2;
if ( entityNum == otherEntityNum ) {
return; // ok, stop being silly :p
}
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_WarnFireTeamPlayer: invalid client" );
}
if ( ( otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS ) || !g_entities[otherEntityNum].client ) {
G_Error( "G_WarnFireTeamPlayer: invalid client" );
}
if ( !G_IsFireteamLeader( entityNum, &ft ) ) {
G_ClientPrintAndReturn( entityNum, "You are not the leader of a fireteam" );
}
if ( ( !G_IsOnFireteam( otherEntityNum, &ft2 ) ) || ft != ft2 ) {
G_ClientPrintAndReturn( entityNum, "You are not on the same Fireteam as the other player" );
}
trap_SendServerCommand( otherEntityNum, "cpm \"You have been warned by your Fireteam Commander\n\"" );
}
void G_KickFireTeamPlayer( int entityNum, int otherEntityNum ) {
fireteamData_t *ft, *ft2;;
if ( entityNum == otherEntityNum ) {
return; // ok, stop being silly :p
}
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_KickFireTeamPlayer: invalid client" );
}
if ( ( otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS ) || !g_entities[otherEntityNum].client ) {
G_Error( "G_KickFireTeamPlayer: invalid client" );
}
if ( !G_IsFireteamLeader( entityNum, &ft ) ) {
G_ClientPrintAndReturn( entityNum, "You are not the leader of a fireteam" );
}
if ( ( !G_IsOnFireteam( otherEntityNum, &ft2 ) ) || ft != ft2 ) {
G_ClientPrintAndReturn( entityNum, "You are not on the same Fireteam as the other player" );
}
G_RemoveClientFromFireteams( otherEntityNum, qtrue, qfalse );
G_ClientPrintAndReturn( otherEntityNum, "You have been kicked from the fireteam" );
}
// The only way a client should ever apply to join a team
void G_ApplyToFireTeam( int entityNum, int fireteamNum ) {
gentity_t *leader;
fireteamData_t* ft;
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_AddClientToFireteam: invalid client" );
}
if ( G_IsOnFireteam( entityNum, NULL ) ) {
G_ClientPrintAndReturn( entityNum, "You are already on a fireteam" );
}
ft = &level.fireTeams[fireteamNum];
if ( !ft->inuse ) {
G_ClientPrintAndReturn( entityNum, "The Fireteam you requested does not exist" );
}
if ( ft->joinOrder[0] < 0 || ft->joinOrder[0] >= MAX_CLIENTS ) {
G_Error( "G_ApplyToFireTeam: Fireteam leader is invalid\n" );
}
leader = &g_entities[(int)ft->joinOrder[0]];
if ( !leader->client ) {
G_Error( "G_ApplyToFireTeam: Fireteam leader client is NULL\n" );
}
// TEMP
// G_AddClientToFireteam( entityNum, ft->joinOrder[0] );
trap_SendServerCommand( entityNum, va( "application -1" ) );
trap_SendServerCommand( leader - g_entities, va( "application %i", entityNum ) );
leader->client->pers.applicationClient = entityNum;
leader->client->pers.applicationEndTime = level.time + 20000;
}
void G_ProposeFireTeamPlayer( int entityNum, int otherEntityNum ) {
fireteamData_t* ft;
gentity_t* leader;
if ( entityNum == otherEntityNum ) {
return; // ok, stop being silly :p
}
if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
G_Error( "G_ProposeFireTeamPlayer: invalid client" );
}
if ( ( otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS ) || !g_entities[otherEntityNum].client ) {
G_Error( "G_ProposeFireTeamPlayer: invalid client" );
}
if ( G_IsOnFireteam( otherEntityNum, NULL ) ) {
G_ClientPrintAndReturn( entityNum, "The other player is already on a fireteam" );
}
if ( !G_IsOnFireteam( entityNum, &ft ) ) {
G_ClientPrintAndReturn( entityNum, "You are not on a fireteam" );
}
if ( ft->joinOrder[0] == entityNum ) {
// you are the leader so just invite them
G_InviteToFireTeam( entityNum, otherEntityNum );
return;
}
leader = &g_entities[(int)ft->joinOrder[0]];
if ( !leader->client ) {
G_Error( "G_ProposeFireTeamPlayer: invalid client" );
}
trap_SendServerCommand( entityNum, va( "proposition -1" ) );
trap_SendServerCommand( leader - g_entities, va( "proposition %i %i", otherEntityNum, entityNum ) );
leader->client->pers.propositionClient = otherEntityNum;
leader->client->pers.propositionClient2 = entityNum;
leader->client->pers.propositionEndTime = level.time + 20000;
}
int G_FireteamNumberForString( const char* name, team_t team ) {
int i, fireteam = 0;
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( !level.fireTeams[i].inuse ) {
continue;
}
if ( g_entities[(int)level.fireTeams[i].joinOrder[0]].client->sess.sessionTeam != team ) {
continue;
}
if ( !Q_stricmp( bg_fireteamNames[level.fireTeams[i].ident - 1], name ) ) {
fireteam = i + 1;
}
/* if(!Q_stricmp(level.fireTeams[i].name, name)) {
fireteam = i+1;
}*/
}
if ( fireteam <= 0 ) {
fireteam = atoi( name );
}
return fireteam;
}
fireteamData_t* G_FindFreePublicFireteam( team_t team ) {
int i, j;
for ( i = 0; i < MAX_FIRETEAMS; i++ ) {
if ( !level.fireTeams[ i ].inuse ) {
continue;
}
if ( g_entities[ (int)level.fireTeams[i].joinOrder[0] ].client->sess.sessionTeam != team ) {
continue;
}
if ( level.fireTeams[ i ].priv ) {
continue;
}
for ( j = 0; j < MAX_CLIENTS; j++ ) {
if ( j >= 6 || level.fireTeams[i].joinOrder[j] == -1 ) {
break;
}
}
if ( j >= 6 ) {
continue;
}
return &level.fireTeams[ i ];
}
return NULL;
}
// Command handler
void Cmd_FireTeam_MP_f( gentity_t* ent ) {
char command[32];
int i;
if ( trap_Argc() < 2 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam " );
}
trap_Argv( 1, command, 32 );
if ( !Q_stricmp( command, "create" ) ) {
G_RegisterFireteam( ent - g_entities );
} else if ( !Q_stricmp( command, "disband" ) ) {
G_DestroyFireteam( ent - g_entities );
} else if ( !Q_stricmp( command, "leave" ) ) {
G_RemoveClientFromFireteams( ent - g_entities, qtrue, qtrue );
} else if ( !Q_stricmp( command, "apply" ) ) {
char namebuffer[32];
int fireteam;
if ( trap_Argc() < 3 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam apply " );
}
trap_Argv( 2, namebuffer, 32 );
fireteam = G_FireteamNumberForString( namebuffer, ent->client->sess.sessionTeam );
if ( fireteam <= 0 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam apply " );
}
G_ApplyToFireTeam( ent - g_entities, fireteam - 1 );
} else if ( !Q_stricmp( command, "invite" ) ) {
char namebuffer[32];
int clientnum = 0;
if ( trap_Argc() < 3 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam invite " );
}
trap_Argv( 2, namebuffer, 32 );
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( !g_entities[i].inuse || !g_entities[i].client ) {
continue;
}
if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
clientnum = i + 1;
}
}
if ( clientnum <= 0 ) {
clientnum = atoi( namebuffer );
if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
}
}
if ( clientnum <= 0 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam invite " );
}
G_InviteToFireTeam( ent - g_entities, clientnum - 1 );
} else if ( !Q_stricmp( command, "warn" ) ) {
char namebuffer[32];
int clientnum = 0;
if ( trap_Argc() < 3 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam warn " );
}
trap_Argv( 2, namebuffer, 32 );
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( !g_entities[i].inuse || !g_entities[i].client ) {
continue;
}
if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
clientnum = i + 1;
}
}
if ( clientnum <= 0 ) {
clientnum = atoi( namebuffer );
if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
}
}
if ( clientnum <= 0 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam warn " );
}
G_WarnFireTeamPlayer( ent - g_entities, clientnum - 1 );
} else if ( !Q_stricmp( command, "kick" ) ) {
char namebuffer[32];
int clientnum = 0;
if ( trap_Argc() < 3 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam kick " );
}
trap_Argv( 2, namebuffer, 32 );
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( !g_entities[i].inuse || !g_entities[i].client ) {
continue;
}
if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
clientnum = i + 1;
}
}
if ( clientnum <= 0 ) {
clientnum = atoi( namebuffer );
if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
}
}
if ( clientnum <= 0 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam kick " );
}
G_KickFireTeamPlayer( ent - g_entities, clientnum - 1 );
} else if ( !Q_stricmp( command, "propose" ) ) {
char namebuffer[32];
int clientnum = 0;
if ( trap_Argc() < 3 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam propose " );
}
trap_Argv( 2, namebuffer, 32 );
for ( i = 0; i < MAX_CLIENTS; i++ ) {
if ( !g_entities[i].inuse || !g_entities[i].client ) {
continue;
}
if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
clientnum = i + 1;
}
}
if ( clientnum <= 0 ) {
clientnum = atoi( namebuffer );
if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
}
}
if ( clientnum <= 0 ) {
G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam propose " );
}
G_ProposeFireTeamPlayer( ent - g_entities, clientnum - 1 );
}
}