summaryrefslogtreecommitdiff
path: root/src/game/g_cmds.c
diff options
context:
space:
mode:
authorPaweł Redman <pawel@redman.xyz>2017-04-13 11:30:00 +0000
committer/dev/humancontroller <devhc@example.com>2017-04-15 12:06:43 +0200
commit5ad9e26c3be1f2ebc6cdb340b685aef30ae16db7 (patch)
tree5ee97c52196122bd8356ad8e09403332e7712fcd /src/game/g_cmds.c
parent45973dc48641365b31475733bce7af9c3b8603a6 (diff)
import the cQVM game module
replacing the existing one
Diffstat (limited to 'src/game/g_cmds.c')
-rw-r--r--src/game/g_cmds.c1040
1 files changed, 661 insertions, 379 deletions
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 3857ef1..b9cca49 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -760,19 +760,47 @@ void Cmd_Team_f( gentity_t *ent )
// stop team join spam
if( level.time - ent->client->pers.teamChangeTime < 1000 )
return;
+
+ if( ent->client->pers.teamSelection != PTE_NONE )
+ {
+ int cs_offset;
+
+ if( ent->client->pers.teamSelection == PTE_ALIENS )
+ cs_offset = 1;
+ else
+ cs_offset = 0;
+ if( level.teamVoteTime[ cs_offset ] )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Can not leave team during a team vote\n\"" );
+ return;
+ }
+ }
+
// Prevent invisible players from joining a team
- if ( ent->client->sess.invisible == qtrue )
+ if( ent->client->sess.invisible == qtrue )
{
trap_SendServerCommand( ent-g_entities,
- va( "print \"You cannot join a team while invisible\n\"" ) );
+ va( "print \"You cannot join a team while invisible\n\"" ) );
return;
}
-
+
if( oldteam == PTE_ALIENS )
aliens--;
else if( oldteam == PTE_HUMANS )
humans--;
+ // practice mode
+ if( !force && g_practiceCount.integer )
+ {
+ char name[ MAX_NAME_LENGTH ];
+
+ G_DecolorString( ent->client->pers.netname, name );
+ if( strstr( name, g_practiceText.string ) )
+ {
+ force = qtrue;
+ }
+ }
+
// do warm up
if( g_doWarmup.integer && g_warmupMode.integer == 1 &&
level.time - level.startTime < g_warmup.integer * 1000 )
@@ -938,6 +966,10 @@ void Cmd_Team_f( gentity_t *ent )
Com_sprintf( buf, sizeof( buf ), "%s^7 abandoned humans and joined the aliens.", ent->client->pers.netname );
else
Com_sprintf( buf, sizeof( buf ), "%s^7 joined the aliens.", ent->client->pers.netname );
+
+ if( g_modAlienRegenRange.integer )
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"Reminder: aliens must be near base to regenerate health.\n\"" ) );
}
else if( team == PTE_HUMANS ) {
if ( oldteam == PTE_ALIENS )
@@ -991,15 +1023,12 @@ static void G_SayTo( gentity_t *ent, gentity_t *other, int mode, int color, cons
}
if( mode == SAY_ADMINS &&
- (!G_admin_permission( other, ADMF_ADMINCHAT ) || other->client->pers.ignoreAdminWarnings ) )
+ (!G_admin_permission( other, ADMF_ADMINCHAT) || other->client->pers.ignoreAdminWarnings ) )
return;
if( BG_ClientListTest( &other->client->sess.ignoreList, ent-g_entities ) )
ignore = qtrue;
-
- if ( ignore && g_fullIgnore.integer )
- return;
-
+
trap_SendServerCommand( other-g_entities, va( "%s \"%s%s%s%c%c%s\"",
( mode == SAY_TEAM || mode == SAY_ACTION_T ) ? "tchat" : "chat",
( ignore ) ? "[skipnotify]" : "",
@@ -1032,24 +1061,6 @@ void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText )
return;
}
- // Spam limit: If they said this message recently, ignore it.
- if( g_spamTime.integer )
- if ( ( level.time - ent->client->pers.lastMessageTime ) < ( g_spamTime.integer * 1000 ) &&
- !Q_stricmp( ent->client->pers.lastMessage, chatText) &&
- !G_admin_permission( ent, ADMF_NOCENSORFLOOD ) &&
- ent->client->pers.floodDemerits <= g_floodMaxDemerits.integer )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Your message has been ignored to prevent spam\n\"" );
- return;
- }
- else
- {
- ent->client->pers.lastMessageTime = level.time;
-
- Q_strncpyz( ent->client->pers.lastMessage, chatText,
- sizeof( ent->client->pers.lastMessage ) );
- }
-
// Flood limit. If they're talking too fast, determine that and return.
if( g_floodMinTime.integer )
if ( G_Flood_Limited( ent ) )
@@ -1057,7 +1068,7 @@ void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText )
trap_SendServerCommand( ent-g_entities, "print \"Your chat is flood-limited; wait before chatting again\n\"" );
return;
}
-
+
if (g_chatTeamPrefix.integer && ent && ent->client )
{
switch( ent->client->pers.teamSelection)
@@ -1158,16 +1169,6 @@ void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText )
Com_sprintf( text, sizeof( text ), "%s^7", chatText );
- if( ent && ent->client && g_aimbotAdvertBan.integer && ( Q_stricmp( text, "^1N^7ullify for ^1T^7remulous [beta] | Get it at CheatersUtopia.com^7" ) == 0 ) )
- {
- trap_SendConsoleCommand( 0,
- va( "!ban %s %s %s\n",
- ent->client->pers.ip,
- ( g_aimbotAdvertBanTime.string && Q_stricmp( g_aimbotAdvertBanTime.string, "0" ) == 1 ) ? g_aimbotAdvertBanTime.string : "" ,
- g_aimbotAdvertBanReason.string ) );
- Q_strncpyz( text, "^7has been caught hacking and will be dealt with.", sizeof( text ) );
- }
-
if( target )
{
G_SayTo( ent, target, mode, color, name, text, prefix );
@@ -1215,11 +1216,14 @@ static void Cmd_SayArea_f( gentity_t *ent )
int num, i;
int color = COLOR_BLUE;
const char *prefix;
- vec3_t range = { HELMET_RANGE, HELMET_RANGE, HELMET_RANGE };
+ vec3_t range = { 1000.0f, 1000.0f, 1000.0f };
vec3_t mins, maxs;
char *msg = ConcatArgs( 1 );
char name[ 64 ];
+ for(i = 0; i < 3; i++ )
+ range[ i ] = g_sayAreaRange.value;
+
if( g_floodMinTime.integer )
if ( G_Flood_Limited( ent ) )
{
@@ -1373,6 +1377,31 @@ static void Cmd_Say_f( gentity_t *ent )
}
}
+ args = G_SayConcatArgs(0);
+ if( !Q_stricmpn( args, "say /join", 9 ) )
+ {
+ Cmd_Join_f( ent );
+ return;
+ }
+ if( !Q_stricmpn( args, "say /part", 9 ) )
+ {
+ Cmd_Part_f( ent );
+ return;
+ }
+ if( !Q_stricmpn( args, "say /0", 6 ) ||
+ !Q_stricmpn( args, "say /1", 6 ) ||
+ !Q_stricmpn( args, "say /2", 6 ) ||
+ !Q_stricmpn( args, "say /3", 6 ) ||
+ !Q_stricmpn( args, "say /4", 6 ) ||
+ !Q_stricmpn( args, "say /5", 6 ) ||
+ !Q_stricmpn( args, "say /6", 6 ) ||
+ !Q_stricmpn( args, "say /7", 6 ) ||
+ !Q_stricmpn( args, "say /8", 6 ) ||
+ !Q_stricmpn( args, "say /9", 6 ) )
+ {
+ Cmd_Channel_f( ent );
+ return;
+ }
if( trap_Argc( ) < 2 )
return;
@@ -1417,6 +1446,244 @@ static void Cmd_Tell_f( gentity_t *ent )
G_Say( ent, ent, SAY_TELL, p );
}
+void Cmd_Join_f( gentity_t *ent )
+{
+ char pass[CHAT_MAXPASS];
+ char arg[MAX_TOKEN_CHARS];
+ int skipargs = 0;
+ int chan;
+ int i;
+ gentity_t *target;
+
+ if( g_floodMinTime.integer &&
+ G_Flood_Limited( ent ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Your chat is flood-limited; wait before chatting again\n\"" );
+ return;
+ }
+
+ G_SayArgv( skipargs, arg, sizeof( arg ) );
+ if( !Q_stricmp( arg, "say" ) )
+ skipargs++;
+
+ if( G_SayArgc( ) < 2 + skipargs )
+ {
+ char message[ 64 ];
+ int n;
+
+ n = 0;
+ for( i = 0; i < CHAT_MAXCHAN && n < 64 - 3; i++ )
+ {
+ if( ent->client->pers.chat[i][0] )
+ {
+ message[ n ] = ' '; n++;
+ message[ n ] = '0' + i; n++;
+ }
+ }
+ if( n == 0)
+ Com_sprintf( message, sizeof( message ), " no channels, use: /join [0-%d] (password)", CHAT_MAXCHAN - 1 );
+ else
+ message[ n ] = '\0';
+
+ trap_SendServerCommand( ent-g_entities, va( "print \"joined in:%s\n\"", message ) );
+ return;
+ }
+
+ G_SayArgv( 1 + skipargs, arg, sizeof( arg ) );
+ chan = atoi( arg );
+ if( chan < 0 || chan >= CHAT_MAXCHAN )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"^3/join^7: invalid channel, usage: /join [0-%d] (password)\n\"", CHAT_MAXCHAN - 1 ) );
+ return;
+ }
+
+ pass[ 0 ] = '\0';
+ if ( G_SayArgc( ) >= 2 + skipargs )
+ G_SayArgv( 2 + skipargs, pass, sizeof( pass ) );
+ if( pass[ 0 ] == '\0' )
+ Q_strncpyz( pass, "default", sizeof( pass ) );
+
+ if( !Q_stricmp( ent->client->pers.chat[chan], pass ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"^3/join^7: already join to channel %d\n\"", chan ) );
+ return;
+ }
+
+ G_LogPrintf( "join: channel %d %s^7\n", chan, ent->client->pers.netname );
+ Q_strncpyz( ent->client->pers.chat[chan], pass, sizeof( ent->client->pers.chat[chan] ) );
+ G_admin_chat_update( ent, chan );
+
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ target = &g_entities[ i ];
+ if( target && target->client &&
+ target->client->pers.connected == CON_CONNECTED &&
+ !Q_stricmp( target->client->pers.chat[ chan ], pass ) )
+ {
+ trap_SendServerCommand( i, va( "print \"join: %s^7 has joined channel #%d\n\"",
+ ent->client->pers.netname, chan ) );
+ }
+ }
+}
+
+void Cmd_Part_f( gentity_t *ent )
+{
+ char arg[MAX_TOKEN_CHARS];
+ int skipargs = 0;
+ int chan;
+ int i;
+ gentity_t *target;
+
+ G_SayArgv( skipargs, arg, sizeof( arg ) );
+ if( !Q_stricmp( arg, "say" ) )
+ skipargs++;
+
+ if( G_SayArgc( ) < 2 + skipargs )
+ {
+ trap_SendServerCommand( ent-g_entities, va( "print \"^3/part^7 usage: /part [0-%d]\n\"", CHAT_MAXCHAN - 1 ) );
+ return;
+ }
+
+ if( g_floodMinTime.integer &&
+ G_Flood_Limited( ent ) )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Your chat is flood-limited; wait before chatting again\n\"" );
+ return;
+ }
+
+ G_SayArgv( 1 + skipargs, arg, sizeof( arg ) );
+ chan = atoi( arg );
+ if( chan < 0 || chan >= CHAT_MAXCHAN )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"^3/part^7: invalid channel, available channels are 0 to %d\n\"", CHAT_MAXCHAN - 1 ) );
+ return;
+ }
+
+ if( ent->client->pers.chat[chan][0] == '\0' )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"^3/part^7: not in that channel\n\"" );
+ return;
+ }
+
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ target = &g_entities[ i ];
+ if( target && target->client &&
+ target->client->pers.connected == CON_CONNECTED &&
+ !Q_stricmp( target->client->pers.chat[ chan ], ent->client->pers.chat[ chan ] ) )
+ {
+ trap_SendServerCommand( i, va( "print \"part: %s^7 has left channel #%d\n\"",
+ ent->client->pers.netname, chan ) );
+ }
+ }
+
+ G_LogPrintf( "part: channel %d %s^7\n", chan, ent->client->pers.netname );
+ Q_strncpyz( ent->client->pers.chat[chan], "", sizeof( ent->client->pers.chat[chan] ) );
+ G_admin_chat_update( ent, chan );
+}
+
+void Cmd_Channel_f( gentity_t *ent )
+{
+ char arg[MAX_TOKEN_CHARS];
+ char str[MAX_STRING_CHARS];
+ char *cmd, *p;
+ char location[ 64 ];
+ char escaped[ 64 ];
+ int chan;
+ int i;
+ int num = 0;
+ int skipargs = 0;
+ qboolean who = qfalse;
+ gentity_t *target;
+
+ if( g_floodMinTime.integer &&
+ G_Flood_Limited( ent ) )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Your chat is flood-limited; wait before chatting again\n\"" );
+ return;
+ }
+
+ G_SayArgv( skipargs, arg, sizeof( arg ) );
+ if( !Q_stricmp( arg, "say" ) )
+ {
+ skipargs++;
+ G_SayArgv( skipargs, arg, sizeof( arg ) );
+ }
+ cmd = arg;
+ if( *cmd == '/' )
+ cmd++;
+ chan = atoi( cmd );
+ if( chan < 0 || chan >= CHAT_MAXCHAN ||
+ ent->client->pers.chat[chan][0] == '\0' )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"^3/%s^7: you are not joined to that channel, use /join\n\"", cmd ) );
+ return;
+ }
+
+ p = G_SayConcatArgs( 1 + skipargs );
+ if( !p || p[0] == '\0' )
+ who = qtrue;
+
+ if( Team_GetLocationMsg( ent, location, sizeof( location ) ) )
+ {
+ Com_sprintf( escaped, sizeof( escaped ), " (^4%s^7)", location );
+ }
+ else
+ {
+ escaped[ 0 ] = '\0';
+ }
+
+ str[ 0 ] = '\0';
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ target = &g_entities[ i ];
+ if( target && target->client &&
+ target->client->pers.connected == CON_CONNECTED &&
+ !Q_stricmp( target->client->pers.chat[ chan ], ent->client->pers.chat[ chan ] ) )
+ {
+ if( num > 0 )
+ Q_strcat( str, sizeof( str ), "^7, " );
+ Q_strcat( str, sizeof( str ), target->client->pers.netname );
+ num++;
+ }
+ }
+
+ if( who )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"channel ^3%d^7 has %s%s and contains %d player%s%s%s\n\"",
+ chan,
+ ( !Q_stricmp( ent->client->pers.chat[ chan ], "default" ) ) ? "no password" : "password ",
+ ( !Q_stricmp( ent->client->pers.chat[ chan ], "default" ) ) ? "" : ent->client->pers.chat[ chan ],
+ num,
+ ( num == 1 ) ? "" : "s",
+ ( num ) ? ": " : "",
+ str ) );
+ return;
+ }
+
+ G_LogPrintf( "channel%d: %s^7 %s\n", chan, ent->client->pers.netname, p );
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ target = &g_entities[ i ];
+ if( target && target->client &&
+ target->client->pers.connected == CON_CONNECTED &&
+ !Q_stricmp( target->client->pers.chat[ chan ], ent->client->pers.chat[ chan ] ) )
+ {
+ trap_SendServerCommand( i, va( "chat \"(^1#%d^7 %d) [%s^7]%s: ^1%s^7\"",
+ chan, num, ent->client->pers.netname,
+ ( OnSameTeam( target, ent ) ) ? escaped : "",
+ p ) );
+ }
+ }
+}
+
/*
==================
Cmd_Where_f
@@ -1427,6 +1694,24 @@ void Cmd_Where_f( gentity_t *ent )
trap_SendServerCommand( ent-g_entities, va( "print \"%s\n\"", vtos( ent->s.origin ) ) );
}
+static int map_vote_percent( const char *map, int fallback )
+{
+ char maps[ MAX_CVAR_VALUE_STRING ];
+ char *token, *token_p;
+
+ if( !g_popularMapsVotePercent.integer )
+ return fallback;
+
+ Q_strncpyz( maps, g_popularMaps.string, sizeof( maps ) );
+ token_p = maps;
+ while( *( token = COM_Parse( &token_p ) ) )
+ {
+ if( !Q_stricmp( token, map ) )
+ return g_popularMapsVotePercent.integer;
+ }
+
+ return fallback;
+}
static qboolean map_is_votable( const char *map )
{
@@ -1469,7 +1754,7 @@ void Cmd_CallVote_f( gentity_t *ent )
arg1plus = G_SayConcatArgs( 1 );
arg2plus = G_SayConcatArgs( 2 );
-
+
// Invisible players cannot call votes
if( ent->client->sess.invisible == qtrue )
{
@@ -1483,6 +1768,12 @@ void Cmd_CallVote_f( gentity_t *ent )
return;
}
+ if( G_admin_permission( ent, ADMF_NO_VOTE ) )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"You have no voting rights\n\"" );
+ return;
+ }
+
// Flood limit. If they're talking too fast, determine that and return.
if( g_floodMinTime.integer )
if ( G_Flood_Limited( ent ) )
@@ -1491,13 +1782,6 @@ void Cmd_CallVote_f( gentity_t *ent )
return;
}
- //see if they can vote
- if( G_admin_permission( ent, ADMF_NO_VOTE ) )
- {
- trap_SendServerCommand( ent-g_entities, "print \"You have no voting rights\n\"" );
- return;
- }
-
if( g_voteMinTime.integer
&& ent->client->pers.firstConnect
&& level.time - ent->client->pers.enterTime < g_voteMinTime.integer * 1000
@@ -1554,6 +1838,10 @@ void Cmd_CallVote_f( gentity_t *ent )
{
G_admin_maplog_result( "m" );
}
+ else if( !Q_stricmpn( level.voteString, "!restart", 8 ) )
+ {
+ G_admin_maplog_result( "l" );
+ }
level.voteExecuteTime = 0;
trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.voteString ) );
@@ -1628,7 +1916,7 @@ void Cmd_CallVote_f( gentity_t *ent )
}
if( clientNum != -1 &&
- level.clients[ clientNum ].pers.connected != CON_CONNECTED )
+ level.clients[ clientNum ].pers.connected == CON_DISCONNECTED )
{
clientNum = -1;
}
@@ -1659,6 +1947,8 @@ void Cmd_CallVote_f( gentity_t *ent )
if( !Q_stricmp( arg1, "kick" ) )
{
+ char n1[ MAX_NAME_LENGTH ];
+
if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
{
trap_SendServerCommand( ent-g_entities,
@@ -1673,9 +1963,13 @@ void Cmd_CallVote_f( gentity_t *ent )
"!ban %s \"%s\" vote kick", level.clients[ clientNum ].pers.ip,
g_adminTempBan.string );
if ( reason[0]!='\0' )
- Q_strcat( level.voteString, sizeof( level.voteDisplayString ), va( "(%s^7)", reason ) );
+ Q_strcat( level.voteString, sizeof( level.voteString ), va( ": %s^7", reason ) );
+ G_SanitiseString( ent->client->pers.netname, n1, sizeof( n1 ) );
+ Q_strcat( level.voteString, sizeof( level.voteString ), va( ", %s", n1 ) );
Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
"Kick player \'%s\'", name );
+
+ level.votePassThreshold = g_kickVotesPercent.integer;
}
else if( !Q_stricmp( arg1, "spec" ) )
{
@@ -1772,7 +2066,7 @@ void Cmd_CallVote_f( gentity_t *ent )
Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
Com_sprintf( level.voteDisplayString,
sizeof( level.voteDisplayString ), "Change to map '%s'", arg2 );
- level.votePassThreshold = g_mapVotesPercent.integer;
+ level.votePassThreshold = map_vote_percent( arg2, g_mapVotesPercent.integer );
}
else if( !Q_stricmp( arg1, "nextmap" ) )
{
@@ -1808,7 +2102,7 @@ void Cmd_CallVote_f( gentity_t *ent )
"set g_nextMap %s", arg2 );
Com_sprintf( level.voteDisplayString,
sizeof( level.voteDisplayString ), "Set the next map to '%s^7'", arg2 );
- level.votePassThreshold = g_mapVotesPercent.integer;
+ level.votePassThreshold = map_vote_percent( arg2, g_mapVotesPercent.integer );
}
else if( !Q_stricmp( arg1, "draw" ) )
{
@@ -1817,16 +2111,53 @@ void Cmd_CallVote_f( gentity_t *ent )
"End match in a draw" );
level.votePassThreshold = g_mapVotesPercent.integer;
}
+ else if( !Q_stricmp( arg1, "layout" ) )
+ {
+ char map[ 64 ];
+
+ if( g_mapvoteMaxTime.integer
+ && (( level.time - level.startTime ) >= g_mapvoteMaxTime.integer * 1000 )
+ && !G_admin_permission( ent, ADMF_NO_VOTE_LIMIT )
+ && (level.numPlayingClients > 0 && level.numConnectedClients>1) )
+ {
+ trap_SendServerCommand( ent-g_entities, va(
+ "print \"You cannot call for a layout change after %d seconds\n\"",
+ g_mapvoteMaxTime.integer ) );
+ G_admin_adminlog_log( ent, "vote", NULL, 0, qfalse );
+ return;
+ }
+
+ trap_Cvar_VariableStringBuffer( "mapname", map, sizeof( map ) );
+ if( Q_stricmp( arg2, "*BUILTIN*" ) &&
+ !trap_FS_FOpenFile( va( "layouts/%s/%s.dat", map, arg2 ), NULL, FS_READ ) )
+ {
+ trap_SendServerCommand( ent - g_entities, va( "print \"callvote: "
+ "layout '%s' could not be found on the server\n\"", arg2 ) );
+ return;
+ }
+ Com_sprintf( level.voteString, sizeof( level.voteString ), "!restart %s", arg2 );
+ Com_sprintf( level.voteDisplayString,
+ sizeof( level.voteDisplayString ), "Change to map layout '%s'", arg2 );
+ level.votePassThreshold = g_mapVotesPercent.integer;
+ }
else if( !Q_stricmp( arg1, "poll" ) )
{
- if( arg2plus[ 0 ] == '\0' )
+ if(!g_pollVotes.integer)
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Poll Votes have been disabled\n\"" );
+ return;
+ }
+ else if( arg2plus[ 0 ] == '\0' )
{
trap_SendServerCommand( ent-g_entities, "print \"callvote: You forgot to specify what people should vote on.\n\"" );
return;
}
- Com_sprintf( level.voteString, sizeof( level.voteString ), nullstring);
- Com_sprintf( level.voteDisplayString,
- sizeof( level.voteDisplayString ), "[Poll] \'%s\'", arg2plus );
+ else
+ {
+ Com_sprintf( level.voteString, sizeof( level.voteString ), nullstring);
+ Com_sprintf( level.voteDisplayString,
+ sizeof( level.voteDisplayString ), "[Poll] \'%s" S_COLOR_WHITE "\'", arg2plus );
+ }
}
else if( !Q_stricmp( arg1, "sudden_death" ) ||
!Q_stricmp( arg1, "suddendeath" ) )
@@ -1858,41 +2189,36 @@ void Cmd_CallVote_f( gentity_t *ent )
}
}
- else if( !Q_stricmp( arg1, "extend" ) )
- {
- if( !g_extendVotesPercent.integer )
- {
- trap_SendServerCommand( ent-g_entities, "print \"Extend votes have been disabled\n\"" );
- return;
- }
- if( g_extendVotesCount.integer
- && level.extend_vote_count >= g_extendVotesCount.integer )
- {
- trap_SendServerCommand( ent-g_entities,
- va( "print \"callvote: Maximum number of %d extend votes has been reached\n\"",
- g_extendVotesCount.integer ) );
- return;
- }
- if( !g_timelimit.integer ) {
- trap_SendServerCommand( ent-g_entities,
- "print \"This match has no timelimit so extend votes wont work\n\"" );
- return;
- }
- if( level.time - level.startTime <
- ( g_timelimit.integer - g_extendVotesTime.integer / 2 ) * 60000 )
- {
- trap_SendServerCommand( ent-g_entities,
- va( "print \"callvote: Extend votes only allowed with less than %d minutes remaining\n\"",
- g_extendVotesTime.integer / 2 ) );
- return;
- }
- level.extend_vote_count++;
- level.votePassThreshold = g_extendVotesPercent.integer;
- Com_sprintf( level.voteString, sizeof( level.voteString ),
- "timelimit %i", g_timelimit.integer + g_extendVotesTime.integer );
- Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
- "Extend the timelimit by %d minutes", g_extendVotesTime.integer );
- }
+ else if( !Q_stricmp( arg1, "extend" ) )
+ {
+ if( !g_extendVotesPercent.integer )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Extend votes have been disabled\n\"" );
+ return;
+ }
+ if( g_extendVotesCount.integer
+ && level.extend_vote_count >= g_extendVotesCount.integer )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"callvote: Maximum number of %d extend votes has been reached\n\"",
+ g_extendVotesCount.integer ) );
+ return;
+ }
+ if( level.time - level.startTime <
+ ( g_timelimit.integer - g_extendVotesTime.integer / 2 ) * 60000 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"callvote: Extend votes only allowed with less than %d minutes remaining\n\"",
+ g_extendVotesTime.integer / 2 ) );
+ return;
+ }
+ level.extend_vote_count++;
+ level.votePassThreshold = g_extendVotesPercent.integer;
+ Com_sprintf( level.voteString, sizeof( level.voteString ),
+ "timelimit %i", g_timelimit.integer + g_extendVotesTime.integer );
+ Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ),
+ "Extend the timelimit by %d minutes", g_extendVotesTime.integer );
+ }
else
{
qboolean match = qfalse;
@@ -1976,13 +2302,13 @@ void Cmd_CallVote_f( gentity_t *ent )
match = qtrue;
break;
}
- }
+ }
if( !match )
{
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
trap_SendServerCommand( ent-g_entities, "print \"Valid vote commands are: "
- "map, map_restart, draw, extend, nextmap, kick, spec, mute, unmute, poll, and sudden_death\n" );
+ "map, map_restart, nextmap, layout, draw, extend, kick, spec, mute, unmute, poll, and sudden_death\n" );
if( customVoteKeys[ 0 ] != '\0' )
trap_SendServerCommand( ent-g_entities,
va( "print \"Additional custom vote commands: %s\n\"", customVoteKeys ) );
@@ -1992,7 +2318,7 @@ void Cmd_CallVote_f( gentity_t *ent )
if( level.votePassThreshold!=50 )
{
- Q_strcat( level.voteDisplayString, sizeof( level.voteDisplayString ), va( "^7 (Needs > %d percent)", level.votePassThreshold ) );
+ Q_strcat( level.voteDisplayString, sizeof( level.voteDisplayString ), va( " (Needs > %d percent)", level.votePassThreshold ) );
}
if ( reason[0]!='\0' )
@@ -2002,6 +2328,7 @@ void Cmd_CallVote_f( gentity_t *ent )
trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE
" called a vote: %s" S_COLOR_WHITE "\n\"", ent->client->pers.netname, level.voteDisplayString ) );
+ trap_SendServerCommand( -1, "cp \"A vote has been called\n^2F1: Yes^7, ^1F2: No^7\"" );
G_LogPrintf("Vote: %s^7 called a vote: %s^7\n", ent->client->pers.netname, level.voteDisplayString );
@@ -2138,22 +2465,21 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
else if(team==PTE_HUMANS)
numVoters = level.numHumanClients;
- if( !g_allowVote.integer )
+ if( !g_allowVote.integer || g_allowVote.integer == 2 )
{
- trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"Team voting not allowed here\n\"" );
return;
}
- if( level.teamVoteTime[ cs_offset ] )
+ if( G_admin_permission( ent, ADMF_NO_VOTE ) )
{
- trap_SendServerCommand( ent-g_entities, "print \"A team vote is already in progress\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"You have no voting rights\n\"" );
return;
}
- //see if they can vote
- if( G_admin_permission( ent, ADMF_NO_VOTE ) )
+ if( level.teamVoteTime[ cs_offset ] )
{
- trap_SendServerCommand( ent-g_entities, "print \"You have no voting rights\n\"" );
+ trap_SendServerCommand( ent-g_entities, "print \"A team vote is already in progress\n\"" );
return;
}
@@ -2300,8 +2626,12 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
}
}
+ level.teamVotePassThreshold[ cs_offset ] = 50;
+
if( !Q_stricmp( arg1, "kick" ) )
{
+ char n1[ MAX_NAME_LENGTH ];
+
if( G_admin_permission( &g_entities[ clientNum ], ADMF_IMMUNITY ) )
{
trap_SendServerCommand( ent-g_entities,
@@ -2311,15 +2641,28 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
return;
}
+ if( g_allowVote.integer == 3 )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"Team kick votes are disabled\n\"" );
+ return;
+ }
// use ip in case this player disconnects before the vote ends
Com_sprintf( level.teamVoteString[ cs_offset ],
sizeof( level.teamVoteString[ cs_offset ] ),
"!ban %s \"%s\" team vote kick", level.clients[ clientNum ].pers.ip,
g_adminTempBan.string );
+ if( reason[0] )
+ Q_strcat( level.teamVoteString[ cs_offset ], sizeof( level.teamVoteString[ cs_offset ] ),
+ va( ": %s", reason ) );
+ G_SanitiseString( ent->client->pers.netname, n1, sizeof( n1 ) );
+ Q_strcat( level.teamVoteString[ cs_offset ], sizeof( level.teamVoteString[ cs_offset ] ),
+ va( ", %s", n1 ) );
Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
sizeof( level.teamVoteDisplayString[ cs_offset ] ),
"Kick player '%s'", name );
+
+ level.teamVotePassThreshold[ cs_offset ] = g_kickVotesPercent.integer;
}
else if( !Q_stricmp( arg1, "denybuild" ) )
{
@@ -2405,6 +2748,16 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
}
else if( !Q_stricmp( arg1, "admitdefeat" ) )
{
+ if( g_defeatVoteMinTime.integer &&
+ level.time - level.startTime < abs( g_defeatVoteMinTime.integer ) * 1000 &&
+ ( !G_admin_permission( ent, ADMF_NO_VOTE_LIMIT ) || g_defeatVoteMinTime.integer < 0 ) )
+ {
+ trap_SendServerCommand( ent-g_entities, va(
+ "print \"You cannot admit defeat until after %d seconds\n\"",
+ g_defeatVoteMinTime.integer ) );
+ G_admin_adminlog_log( ent, "vote", NULL, 0, qfalse );
+ return;
+ }
if( numVoters <=1 )
{
trap_SendServerCommand( ent-g_entities,
@@ -2440,6 +2793,12 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
ent->client->pers.voteCount++;
G_admin_adminlog_log( ent, "teamvote", arg1, 0, qtrue );
+
+ if( level.teamVotePassThreshold[ cs_offset ] != 50 )
+ {
+ Q_strcat( level.teamVoteDisplayString[ cs_offset ], sizeof( level.teamVoteDisplayString[ cs_offset ] ),
+ va( " (Needs > %d percent)", level.teamVotePassThreshold[ cs_offset ] ) );
+ }
if ( reason[0]!='\0' )
Q_strcat( level.teamVoteDisplayString[ cs_offset ], sizeof( level.teamVoteDisplayString[ cs_offset ] ), va( " Reason: '%s'^7", reason ) );
@@ -2453,6 +2812,7 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
{
trap_SendServerCommand( i, va("print \"%s " S_COLOR_WHITE
"called a team vote: %s^7 \n\"", ent->client->pers.netname, level.teamVoteDisplayString[ cs_offset ] ) );
+ trap_SendServerCommand( i, "cp \"A team vote has been called\n^2F1: Yes^7, ^1F2: No^7\"" );
}
else if( G_admin_permission( &g_entities[ i ], ADMF_ADMINCHAT ) &&
( ( !Q_stricmp( arg1, "kick" ) || !Q_stricmp( arg1, "denybuild" ) ) ||
@@ -2656,7 +3016,6 @@ void Cmd_Class_f( gentity_t *ent )
vec3_t mins, maxs;
int num;
gentity_t *other;
- qboolean humanNear = qfalse;
clientNum = ent->client - level.clients;
@@ -2779,21 +3138,11 @@ void Cmd_Class_f( gentity_t *ent )
if( ( other->client && other->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) ||
( other->s.eType == ET_BUILDABLE && other->biteam == BIT_HUMANS ) )
{
- humanNear = qtrue;
- }
- //If its the OM, then ignore all humans.
- if(other->s.eType == ET_BUILDABLE && other->s.modelindex == BA_A_OVERMIND)
- {
- humanNear = qfalse;
- break;
+ G_TriggerMenu( clientNum, MN_A_TOOCLOSE );
+ return;
}
}
- if(humanNear == qtrue) {
- G_TriggerMenu( clientNum, MN_A_TOOCLOSE );
- return;
- }
-
if( !level.overmindPresent )
{
G_TriggerMenu( clientNum, MN_A_NOOVMND_EVOLVE );
@@ -2902,19 +3251,33 @@ DBCommand
Send command to all designated builders of selected team
=================
*/
-void DBCommand( pTeam_t team, const char *text )
+void DBCommand( gentity_t *builder, pTeam_t team, const char *text )
{
int i;
gentity_t *ent;
+ if( g_floodMinTime.integer && G_Flood_Limited( builder ) )
+ {
+ trap_SendServerCommand( builder-g_entities,
+ "print \"Your deconstruct attempt is flood-limited; wait before trying again\n\"" );
+ return;
+ }
+
+ trap_SendServerCommand( builder-g_entities,
+ "print \"This structure is protected by designated builder\n\"" );
+
for( i = 0, ent = g_entities + i; i < level.maxclients; i++, ent++ )
{
- if( !ent->client || ( ent->client->pers.connected != CON_CONNECTED ) ||
- ( ent->client->pers.teamSelection != team ) ||
- !ent->client->pers.designatedBuilder )
+ if( !ent->client || ent->client->pers.connected != CON_CONNECTED )
continue;
- trap_SendServerCommand( i, text );
+ if( ( ent->client->pers.teamSelection == team &&
+ ent->client->pers.designatedBuilder ) ||
+ ( ent->client->pers.teamSelection == PTE_NONE &&
+ G_admin_permission( ent, ADMF_SPEC_ALLCHAT ) ) )
+ {
+ trap_SendServerCommand( i, text );
+ }
}
}
@@ -2937,6 +3300,23 @@ void Cmd_Destroy_f( gentity_t *ent )
"print \"Your building rights have been revoked\n\"" );
return;
}
+ if( ent->client->pers.paused )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"You may not deconstruct while paused\n\"" );
+ return;
+ }
+
+ if( g_newbieNoBuild.integer
+ && g_newbieNamePrefix.string[ 0 ]
+ && Q_stricmpn ( ent->client->pers.netname, g_newbieNamePrefix.string, strlen(g_newbieNamePrefix.string ) ) == 0 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"You cannot build until you set a name\n%s%s\"",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? g_newbieNoBuildMessage.string : "",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? "\n" : "" ) );
+ return;
+ }
trap_Argv( 0, cmd, sizeof( cmd ) );
if( Q_stricmp( cmd, "destroy" ) == 0 )
@@ -2947,11 +3327,10 @@ void Cmd_Destroy_f( gentity_t *ent )
if( ( ent->client->hovel->s.eFlags & EF_DBUILDER ) &&
!ent->client->pers.designatedBuilder )
{
- trap_SendServerCommand( ent-g_entities,
- "print \"This structure is protected by designated builder\n\"" );
- DBCommand( ent->client->pers.teamSelection,
- va( "print \"%s^3 has attempted to decon a protected structure!\n\"",
- ent->client->pers.netname ) );
+ DBCommand( ent, ent->client->pers.teamSelection,
+ va( "print \"%s^3 has attempted to decon a protected %s!\n\"",
+ ent->client->pers.netname,
+ BG_FindHumanNameForBuildable( ent->client->hovel->s.modelindex ) ) );
return;
}
G_Damage( ent->client->hovel, ent, ent, forward, ent->s.origin,
@@ -2981,21 +3360,13 @@ void Cmd_Destroy_f( gentity_t *ent )
if( ( traceEnt->s.eFlags & EF_DBUILDER ) &&
!ent->client->pers.designatedBuilder )
{
- trap_SendServerCommand( ent-g_entities,
- "print \"This structure is protected by designated builder\n\"" );
- DBCommand( ent->client->pers.teamSelection,
- va( "print \"%s^3 has attempted to decon a protected structure!\n\"",
- ent->client->pers.netname ) );
+ DBCommand( ent, ent->client->pers.teamSelection,
+ va( "print \"%s^3 has attempted to decon a protected %s!\n\"",
+ ent->client->pers.netname,
+ BG_FindHumanNameForBuildable( traceEnt->s.modelindex ) ) );
return;
}
- // Check the minimum level to deconstruct
- if ( G_admin_level( ent ) < g_minDeconLevel.integer && !ent->client->pers.designatedBuilder )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"You do not have deconstructuction rights.\n\"" );
- return;
- }
// Prevent destruction of the last spawn
if( g_markDeconstruct.integer != 1 && !g_cheats.integer )
@@ -3024,8 +3395,7 @@ void Cmd_Destroy_f( gentity_t *ent )
!BG_FindReplaceableTestForBuildable( traceEnt->s.modelindex ) ) ||
( g_suddenDeathMode.integer == SDMODE_BP &&
BG_FindBuildPointsForBuildable( traceEnt->s.modelindex ) ) ||
- g_suddenDeathMode.integer == SDMODE_NO_BUILD ||
- g_suddenDeathMode.integer == SDMODE_NO_DECON ) )
+ g_suddenDeathMode.integer == SDMODE_NO_BUILD ) )
{
trap_SendServerCommand( ent-g_entities,
"print \"During Sudden Death you can only decon buildings that "
@@ -3055,6 +3425,7 @@ void Cmd_Destroy_f( gentity_t *ent )
new = G_Alloc( sizeof( buildHistory_t ) );
new->ID = ( ++level.lastBuildID > 1000 )
? ( level.lastBuildID = 1 ) : level.lastBuildID;
+ new->time = level.time;
new->ent = ent;
new->name[ 0 ] = 0;
new->buildable = traceEnt->s.modelindex;
@@ -3078,6 +3449,8 @@ void Cmd_Destroy_f( gentity_t *ent )
ent->client->pers.netname,
BG_FindNameForBuildable( traceEnt->s.modelindex ) );
}
+ else if( deconstruct )
+ G_RecoverBuildPoints( traceEnt );
if( !deconstruct )
G_Damage( traceEnt, ent, ent, forward, tr.endpos, 10000, 0, MOD_SUICIDE );
@@ -3112,12 +3485,21 @@ void Cmd_Mark_f( gentity_t *ent )
"print \"Your building rights have been revoked\n\"" );
return;
}
+ if( ent->client->pers.paused )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"You may not mark while paused\n\"" );
+ return;
+ }
- // Check the minimum level to deconstruct
- if ( G_admin_level( ent ) < g_minDeconLevel.integer && !ent->client->pers.designatedBuilder && g_minDeconAffectsMark.integer > 0 )
+ if( g_newbieNoBuild.integer
+ && g_newbieNamePrefix.string[ 0 ]
+ && Q_stricmpn ( ent->client->pers.netname, g_newbieNamePrefix.string, strlen(g_newbieNamePrefix.string ) ) == 0 )
{
trap_SendServerCommand( ent-g_entities,
- "print \"You do not have deconstructuction rights.\n\"" );
+ va( "print \"You cannot build until you set a name\n%s%s\"",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? g_newbieNoBuildMessage.string : "",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? "\n" : "" ) );
return;
}
@@ -3164,8 +3546,7 @@ void Cmd_Mark_f( gentity_t *ent )
!BG_FindReplaceableTestForBuildable( traceEnt->s.modelindex ) ) ||
( g_suddenDeathMode.integer == SDMODE_BP &&
BG_FindBuildPointsForBuildable( traceEnt->s.modelindex ) ) ||
- g_suddenDeathMode.integer == SDMODE_NO_BUILD ||
- g_suddenDeathMode.integer == SDMODE_NO_DECON ) )
+ g_suddenDeathMode.integer == SDMODE_NO_BUILD ) )
{
trap_SendServerCommand( ent-g_entities,
"print \"During Sudden Death you can only mark buildings that "
@@ -3186,6 +3567,65 @@ void Cmd_Mark_f( gentity_t *ent )
}
}
+void Cmd_Aim_f( gentity_t *ent )
+{
+ vec3_t forward, end;
+ trace_t tr;
+ gentity_t *traceEnt;
+
+ if( !g_turretAim.integer )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Turret aim is disabled\n\"" );
+ return;
+ }
+
+ if( ent->client->pers.denyBuild ||
+ ent->client->pers.paused )
+ return;
+
+ if( g_newbieNoBuild.integer &&
+ g_newbieNamePrefix.string[ 0 ] &&
+ !Q_stricmpn ( ent->client->pers.netname, g_newbieNamePrefix.string, strlen(g_newbieNamePrefix.string ) ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"You cannot use /aim until you set a name\n%s%s\"",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? g_newbieNoBuildMessage.string : "",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? "\n" : "" ) );
+ return;
+ }
+
+ if( !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) )
+ {
+ AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
+ VectorMA( ent->client->ps.origin, 100, forward, end );
+
+ trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID );
+ traceEnt = &g_entities[ tr.entityNum ];
+
+ if( tr.fraction < 1.0f &&
+ ( traceEnt->s.eType == ET_BUILDABLE ) &&
+ ( traceEnt->s.modelindex == BA_H_MGTURRET ) &&
+ ( traceEnt->biteam == ent->client->pers.teamSelection ) &&
+ ( ( ent->client->ps.weapon >= WP_ABUILD ) &&
+ ( ent->client->ps.weapon <= WP_HBUILD ) ) )
+ {
+ if( traceEnt->rotatorAngle >= 360.0f )
+ {
+ traceEnt->rotatorAngle = 0.0f;
+ trap_SendServerCommand( ent-g_entities, "print \"Turret aim direction disabled\n\"" );
+ }
+ else
+ {
+ traceEnt->rotatorAngle = ent->client->ps.viewangles[ YAW ];
+ while( traceEnt->rotatorAngle < 360.0f )
+ traceEnt->rotatorAngle += 360.0f;
+ trap_SendServerCommand( ent-g_entities, "print \"Turret aim direction enabled\n\"" );
+ }
+ }
+ }
+}
+
/*
=================
@@ -3507,12 +3947,6 @@ void Cmd_Buy_f( gentity_t *ent )
if( !Q_stricmp( s, "retrigger" ) )
ent->client->retriggerArmouryMenu = level.framenum + RAM_FRAMES;
}
- if( ent->client->pers.paused )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"You may not deconstruct while paused\n\"" );
- return;
- }
//update ClientInfo
ClientUserinfoChanged( ent->client->ps.clientNum, qfalse );
@@ -3688,7 +4122,18 @@ void Cmd_Build_f( gentity_t *ent )
if( ent->client->pers.paused )
{
trap_SendServerCommand( ent-g_entities,
- "print \"You may not mark while paused\n\"" );
+ "print \"You may not build while paused\n\"" );
+ return;
+ }
+
+ if( g_newbieNoBuild.integer
+ && g_newbieNamePrefix.string[ 0 ]
+ && Q_stricmpn ( ent->client->pers.netname, g_newbieNamePrefix.string, strlen(g_newbieNamePrefix.string ) ) == 0 )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"You cannot build until you set a name\n%s%s\"",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? g_newbieNoBuildMessage.string : "",
+ ( g_newbieNoBuildMessage.string[ 0 ] ) ? "\n" : "" ) );
return;
}
@@ -3722,6 +4167,13 @@ void Cmd_Build_f( gentity_t *ent )
}
}
+ if( g_vampireDeath.integer )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ "print \"Building is not allowed during Vampire Sudden Death\n\"" );
+ return;
+ }
+
team = ent->client->ps.stats[ STAT_PTEAM ];
if( buildable != BA_NONE &&
@@ -4005,113 +4457,6 @@ char *G_statsString( statsCounters_t *sc, pTeam_t *pt )
return s;
}
- /*
- =================
- Cmd_AllStats_f
- =================
- */
- void Cmd_AllStats_f( gentity_t *ent )
- {
- int i;
- int NextViewTime;
- int NumResults = 0;
- int Teamcolor = 3;
- gentity_t *tmpent;
-
- //check if ent exists
- if(!ent) return;
-
- NextViewTime = ent->client->pers.statscounters.AllstatstimeLastViewed + g_AllStatsTime.integer * 1000;
- //check if you can use the cmd at this time
- if( !level.intermissiontime && level.time < NextViewTime)
- {
- ADMP( va("You may only check your stats every %i Seconds and during intermission. Next valid time is %d:%02d\n",( g_AllStatsTime.integer ) ? ( g_AllStatsTime.integer ) : 60, ( NextViewTime / 60000 ), ( NextViewTime / 1000 ) % 60 ) );
- return;
- }
- //see if allstats is enabled
- if( !g_AllStats.integer )
- {
- ADMP( "AllStats has been disabled\n");
- return;
- }
- ADMP("^3K^2=^7Kills ^3A^2=^7Assists ^3SK^2=^7StructKills\n^3D^2=^7Deaths ^3F^2=^7Feeds ^3S^2=^7Suicides ^3TK^2=^7Teamkills\n^3DD^2=^7Damage done ^3TDD^2=^7Team Damage done\n^3SB^2=^7Structs Built\n\n" );
- //display a header describing the data
- ADMP( "^3 #| K A SK| D F S TK| DD TDD| SB| Name\n" );
-
- //loop through the clients that are connected
- for( i = 0; i < level.numConnectedClients; i++ )
- {
- //assign a tempent 4 the hell of it
- tmpent = &g_entities[ level.sortedClients[ i ] ];
-
- //check for what mode we are working in and display relevent data
- if( g_AllStats.integer == 1 )
- {
- //check if client is connected and on same team
- if( tmpent->client && tmpent->client->pers.connected == CON_CONNECTED && tmpent->client->pers.teamSelection == ent->client->pers.teamSelection && tmpent->client->pers.teamSelection != PTE_NONE )
- {
- NumResults++;
- if( tmpent->client->pers.teamSelection == PTE_ALIENS ) Teamcolor = 1;
- if( tmpent->client->pers.teamSelection == PTE_HUMANS ) Teamcolor = 5;
- ADMP( va( "^%i%2i^3|^%i%3i %3i %3i^3|^%i%3i %3i %3i %3i^3|^%i%5i %5i^3|^%i%3i^3|^7 %s\n",
- Teamcolor,
- NumResults,
- Teamcolor,
- ( tmpent->client->pers.statscounters.kills ) ? tmpent->client->pers.statscounters.kills : 0,
- ( tmpent->client->pers.statscounters.assists ) ? tmpent->client->pers.statscounters.assists : 0,
- ( tmpent->client->pers.statscounters.structskilled ) ? tmpent->client->pers.statscounters.structskilled : 0,
- Teamcolor,
- ( tmpent->client->pers.statscounters.deaths ) ? tmpent->client->pers.statscounters.deaths : 0,
- ( tmpent->client->pers.statscounters.feeds ) ? tmpent->client->pers.statscounters.feeds : 0,
- ( tmpent->client->pers.statscounters.suicides ) ? tmpent->client->pers.statscounters.suicides : 0,
- ( tmpent->client->pers.statscounters.teamkills ) ? tmpent->client->pers.statscounters.teamkills : 0,
- Teamcolor,
- ( tmpent->client->pers.statscounters.dmgdone ) ? tmpent->client->pers.statscounters.dmgdone : 0,
- ( tmpent->client->pers.statscounters.ffdmgdone ) ? tmpent->client->pers.statscounters.ffdmgdone : 0,
- Teamcolor,
- ( tmpent->client->pers.statscounters.structsbuilt ) ? tmpent->client->pers.statscounters.structsbuilt : 0,
- ( tmpent->client->pers.netname ) ? tmpent->client->pers.netname : "Unknown" ) );
- }
- }
- else if( g_AllStats.integer == 2 )
- {
- //check if client is connected and has some stats or atleast is on a team
- if( tmpent->client && tmpent->client->pers.connected == CON_CONNECTED && ( tmpent->client->pers.teamSelection != PTE_NONE ) )
- {
- NumResults++;
- if( tmpent->client->pers.teamSelection == PTE_ALIENS ) Teamcolor = 1;
- if( tmpent->client->pers.teamSelection == PTE_HUMANS ) Teamcolor = 5;
- ADMP( va( "^%i%2i^3|^%i%3i %3i %3i^3|^%i%3i %3i %3i %3i^3|^%i%5i %5i^3|^%i%3i^3|^7 %s\n",
- Teamcolor,
- NumResults,
- Teamcolor,
- ( tmpent->client->pers.statscounters.kills ) ? tmpent->client->pers.statscounters.kills : 0,
- ( tmpent->client->pers.statscounters.assists ) ? tmpent->client->pers.statscounters.assists : 0,
- ( tmpent->client->pers.statscounters.structskilled ) ? tmpent->client->pers.statscounters.structskilled : 0,
- Teamcolor,
- ( tmpent->client->pers.statscounters.deaths ) ? tmpent->client->pers.statscounters.deaths : 0,
- ( tmpent->client->pers.statscounters.feeds ) ? tmpent->client->pers.statscounters.feeds : 0,
- ( tmpent->client->pers.statscounters.suicides ) ? tmpent->client->pers.statscounters.suicides : 0,
- ( tmpent->client->pers.statscounters.teamkills ) ? tmpent->client->pers.statscounters.teamkills : 0,
- Teamcolor,
- ( tmpent->client->pers.statscounters.dmgdone ) ? tmpent->client->pers.statscounters.dmgdone : 0,
- ( tmpent->client->pers.statscounters.ffdmgdone ) ? tmpent->client->pers.statscounters.ffdmgdone : 0,
- Teamcolor,
- ( tmpent->client->pers.statscounters.structsbuilt ) ? tmpent->client->pers.statscounters.structsbuilt : 0,
- ( tmpent->client->pers.netname ) ? tmpent->client->pers.netname : "Unknown" ) );
- }
- }
- }
- if( NumResults == 0 ) {
- ADMP( " ^3EMPTY!\n" );
- } else {
- ADMP( va( "^7 %i Players found!\n", NumResults ) );
- }
- //update time last viewed
-
- ent->client->pers.statscounters.AllstatstimeLastViewed = level.time;
- return;
-}
/*
=================
@@ -4412,12 +4757,6 @@ void Cmd_Follow_f( gentity_t *ent )
trap_SendServerCommand( ent - g_entities, "print \"follow: You cannot follow unless you are dead or on the spectators.\n\"" );
return;
}
- if( ent->client->pers.paused )
- {
- trap_SendServerCommand( ent-g_entities,
- "print \"You may not build while paused\n\"" );
- return;
- }
if( trap_Argc( ) != 2 )
{
@@ -4569,30 +4908,8 @@ void Cmd_PTRCRestore_f( gentity_t *ent )
connection = ent->client->pers.connection;
if( connection && connection->ptrCode == code )
{
- // Set the correct team
- if( !( ent->client->pers.specExpires > level.time ) )
- {
- // Check if the alien team is full
- if( connection->clientTeam == PTE_ALIENS &&
- !G_admin_permission(ent, ADMF_FORCETEAMCHANGE) &&
- g_teamForceBalance.integer &&
- level.numAlienClients > level.numHumanClients )
- {
- G_TriggerMenu( ent - g_entities, MN_A_TEAMFULL );
- }
- // Check if the human team is full
- else if( connection->clientTeam == PTE_HUMANS &&
- !G_admin_permission(ent, ADMF_FORCETEAMCHANGE) &&
- g_teamForceBalance.integer &&
- level.numHumanClients > level.numAlienClients )
- {
- G_TriggerMenu( ent - g_entities, MN_H_TEAMFULL );
- }
- else
- {
- G_ChangeTeam( ent, connection->clientTeam );
- }
- }
+ // set the correct team
+ G_ChangeTeam( ent, connection->clientTeam );
// set the correct credit etc.
ent->client->ps.persistant[ PERS_CREDIT ] = 0;
@@ -4688,39 +5005,39 @@ static void Cmd_Ignore_f( gentity_t *ent )
char arg1[ MAX_STRING_TOKENS ];
char arg2[ MAX_STRING_TOKENS ];
pTeam_t team;
-
+
if( !ent || !ent->client || ( ent->client->pers.teamSelection == PTE_NONE ) )
{
return;
}
-
+
if( !g_allowShare.integer )
{
trap_SendServerCommand( ent-g_entities, "print \"Share has been disabled.\n\"" );
return;
}
-
+
if( g_floodMinTime.integer )
if ( G_Flood_Limited( ent ) )
{
trap_SendServerCommand( ent-g_entities, "print \"Your chat is flood-limited; wait before chatting again\n\"" );
return;
}
-
+
team = ent->client->pers.teamSelection;
-
+
G_SayArgv( 0, cmd, sizeof( cmd ) );
if( !Q_stricmp( cmd, "say" ) || !Q_stricmp( cmd, "say_team" ) )
{
skipargs = 1;
G_SayArgv( 1, cmd, sizeof( cmd ) );
}
-
+
// target player name is in arg1
G_SayArgv( 1+skipargs, arg1, sizeof( arg1 ) );
// amount to be shared is in arg2
G_SayArgv( 2+skipargs, arg2, sizeof( arg2 ) );
-
+
if( arg1[0] && !strchr( arg1, ';' ) && Q_stricmp( arg1, "target_in_aim" ) )
{
//check arg1 is a number
@@ -4732,7 +5049,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
break;
}
}
-
+
if( clientNum >= 0 )
{
clientNum = atoi( arg1 );
@@ -4759,14 +5076,15 @@ static void Cmd_Ignore_f( gentity_t *ent )
vec3_t forward, end;
trace_t tr;
gentity_t *traceEnt;
-
+
+
// trace a teammate
AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
VectorMA( ent->client->ps.origin, 8192 * 16, forward, end );
-
+
trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID );
traceEnt = &g_entities[ tr.entityNum ];
-
+
if( tr.fraction < 1.0f && traceEnt->client &&
( traceEnt->client->pers.teamSelection == team ) )
{
@@ -4780,7 +5098,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
return;
}
}
-
+
// verify target player team
if( ( clientNum < 0 ) || ( clientNum >= level.maxclients ) ||
( level.clients[ clientNum ].pers.teamSelection != team ) )
@@ -4789,7 +5107,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
"print \"share: not a valid player of your team.\n\"" );
return;
}
-
+
if( !arg2[0] || strchr( arg2, ';' ) )
{
// default credit count
@@ -4814,11 +5132,11 @@ static void Cmd_Ignore_f( gentity_t *ent )
return;
}
}
-
+
// credit count from parameter
creds = atoi( arg2 );
}
-
+
// player specified "0" to transfer
if( creds <= 0 )
{
@@ -4826,13 +5144,13 @@ static void Cmd_Ignore_f( gentity_t *ent )
"print \"Ooh, you are a generous one, indeed!\n\"" );
return;
}
-
+
// transfer only credits the player really has
if( creds > ent->client->pers.credit )
{
creds = ent->client->pers.credit;
}
-
+
// player has no credits
if( creds <= 0 )
{
@@ -4840,7 +5158,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
"print \"Earn some first, lazy gal!\n\"" );
return;
}
-
+
// allow transfers only up to the credit/evo limit
if( ( team == PTE_HUMANS ) &&
( creds > HUMAN_MAX_CREDITS - level.clients[ clientNum ].pers.credit ) )
@@ -4852,7 +5170,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
{
creds = ALIEN_MAX_KILLS - level.clients[ clientNum ].pers.credit;
}
-
+
// target cannot take any more credits
if( creds <= 0 )
{
@@ -4861,7 +5179,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
( team == PTE_HUMANS ) ? "credits" : "evolvepoints" ) );
return;
}
-
+
// transfer credits
G_AddCreditToClient( ent->client, -creds, qfalse );
trap_SendServerCommand( ent-g_entities,
@@ -4873,7 +5191,7 @@ static void Cmd_Ignore_f( gentity_t *ent )
va( "print \"You have received %d %s from %s^7.\n\"", creds,
( team == PTE_HUMANS ) ? "credits" : "evolvepoints",
ent->client->pers.netname ) );
-
+
G_LogPrintf( "Share: %i %i %i %d: %s^7 transferred %d%s to %s^7\n",
ent->client->ps.clientNum,
clientNum,
@@ -4884,35 +5202,36 @@ static void Cmd_Ignore_f( gentity_t *ent )
( team == PTE_HUMANS ) ? "c" : "e",
level.clients[ clientNum ].pers.netname );
}
-
+
/*
=================
Cmd_Donate_f
-
+
Alms for the poor
=================
*/
void Cmd_Donate_f( gentity_t *ent ) {
char s[ MAX_TOKEN_CHARS ] = "", *type = "evo(s)";
int i, value, divisor, portion, new_credits, total=0,
- max = ALIEN_MAX_KILLS, *amounts, *totals;
+ max = ALIEN_MAX_KILLS, *amounts;
qboolean donated = qtrue;
-
+
if( !ent->client ) return;
-
+
if( !g_allowShare.integer )
{
trap_SendServerCommand( ent-g_entities, "print \"Donate has been disabled.\n\"" );
return;
}
-
+
if( g_floodMinTime.integer )
if ( G_Flood_Limited( ent ) )
{
trap_SendServerCommand( ent-g_entities, "print \"Your chat is flood-limited; wait before chatting again\n\"" );
return;
}
-
+
+
if( ent->client->pers.teamSelection == PTE_ALIENS )
divisor = level.numAlienClients-1;
else if( ent->client->pers.teamSelection == PTE_HUMANS ) {
@@ -4924,13 +5243,13 @@ static void Cmd_Ignore_f( gentity_t *ent )
va( "print \"donate: spectators cannot be so gracious\n\"" ) );
return;
}
-
+
if( divisor < 1 ) {
trap_SendServerCommand( ent-g_entities,
"print \"donate: get yourself some teammates first\n\"" );
return;
}
-
+
trap_Argv( 1, s, sizeof( s ) );
value = atoi(s);
if( value <= 0 ) {
@@ -4940,15 +5259,11 @@ static void Cmd_Ignore_f( gentity_t *ent )
}
if( value > ent->client->pers.credit)
value = ent->client->pers.credit;
-
+
// allocate memory for distribution amounts
amounts = G_Alloc( level.maxclients * sizeof( int ) );
- totals = G_Alloc( level.maxclients * sizeof( int ) );
- for( i = 0; i < level.maxclients; i++ ) {
- amounts[ i ] = 0;
- totals[ i ] = 0;
- }
-
+ for( i = 0; i < level.maxclients; i++ ) amounts[ i ] = 0;
+
// determine donation amounts for each client
total = value;
while( donated && value ) {
@@ -4962,10 +5277,8 @@ static void Cmd_Ignore_f( gentity_t *ent )
ent->client->pers.teamSelection ) {
new_credits = level.clients[ i ].pers.credit + portion;
amounts[ i ] = portion;
- totals[ i ] += portion;
if( new_credits > max ) {
amounts[ i ] -= new_credits - max;
- totals[ i ] -= new_credits - max;
new_credits = max;
}
if( amounts[ i ] ) {
@@ -4976,23 +5289,23 @@ static void Cmd_Ignore_f( gentity_t *ent )
}
}
}
-
+
// transfer funds
G_AddCreditToClient( ent->client, value - total, qtrue );
for( i = 0; i < level.maxclients; i++ )
- if( totals[ i ] ) {
+ if( amounts[ i ] ) {
trap_SendServerCommand( i,
va( "print \"%s^7 donated %d %s to you, don't forget to say 'thank you'!\n\"",
- ent->client->pers.netname, totals[ i ], type ) );
+ ent->client->pers.netname, amounts[ i ], type ) );
}
-
+
G_Free( amounts );
- G_Free( totals );
-
+
trap_SendServerCommand( ent-g_entities,
va( "print \"Donated %d %s to the cause.\n\"",
total-value, type ) );
}
+
commands_t cmds[ ] = {
// normal commands
@@ -5016,9 +5329,22 @@ commands_t cmds[ ] = {
{ "me", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f },
{ "me_team", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Say_f },
+ // channel chat
+ { "join", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Join_f },
+ { "part", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Part_f },
+ { "0", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "1", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "2", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "3", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "4", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "5", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "6", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "7", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "8", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+ { "9", CMD_MESSAGE|CMD_INTERMISSION, Cmd_Channel_f },
+
{ "score", CMD_INTERMISSION, ScoreboardMessage },
{ "mystats", CMD_TEAM|CMD_INTERMISSION, Cmd_MyStats_f },
- { "allstats", 0|CMD_INTERMISSION, Cmd_AllStats_f },
{ "teamstatus", CMD_TEAM, Cmd_TeamStatus_f },
// cheats
@@ -5047,6 +5373,7 @@ commands_t cmds[ ] = {
{ "build", CMD_TEAM|CMD_LIVING, Cmd_Build_f },
{ "deconstruct", CMD_TEAM|CMD_LIVING, Cmd_Destroy_f },
{ "mark", CMD_TEAM|CMD_LIVING, Cmd_Mark_f },
+ { "aim", CMD_HUMAN|CMD_LIVING, Cmd_Aim_f },
{ "buy", CMD_HUMAN|CMD_LIVING, Cmd_Buy_f },
{ "sell", CMD_HUMAN|CMD_LIVING, Cmd_Sell_f },
@@ -5403,15 +5730,15 @@ void G_PrivateMessage( gentity_t *ent )
if( teamonly && !OnSameTeam( ent, tmpent ) )
continue;
-
+
// Ignore sending to invisible players
if( tmpent->client->sess.invisible == qtrue && !G_admin_permission( ent, "invisible" ) )
continue;
-
+
// Ignore sending to non-invisible-capable players while invisible
if( ent->client->sess.invisible == qtrue && !G_admin_permission( tmpent, "invisible" ) )
continue;
-
+
if( BG_ClientListTest( &tmpent->client->sess.ignoreList,
ent-g_entities ) )
{
@@ -5662,48 +5989,3 @@ qboolean G_IsMuted( gclient_t *client )
return muteState;
}
-
-/*
-==================
-G_TeamKill_Repent
-
-Determine whether a players team kill activity is high
-==================
-*/
-
-qboolean G_TeamKill_Repent( gentity_t *ent )
-{
- int millisSinceLastTeamKill;
-
- // Doesn't work if g_teamKillThreshold isn't set
- if( !g_teamKillThreshold.integer ||
- g_teamKillThreshold.integer == 0 )
- return qfalse;
-
- // Doesn't work when game is paused
- if( level.paused )
- return qfalse;
-
- millisSinceLastTeamKill = level.time - ent->client->pers.lastTeamKillTime;
- if( millisSinceLastTeamKill < 30000 )
- ent->client->pers.teamKillDemerits++;
- else
- {
- ent->client->pers.teamKillDemerits--;
- if( ent->client->pers.teamKillDemerits < 0 )
- ent->client->pers.teamKillDemerits = 0;
- }
-
- ent->client->pers.lastTeamKillTime = level.time;
-
- if ( ent->client->pers.teamKillDemerits >= ( g_teamKillThreshold.integer + 2 ) )
- trap_SendConsoleCommand( 0, va( "!ban %s 30m team killing\n", ent->client->pers.ip ) );
- else if ( ent->client->pers.teamKillDemerits == ( g_teamKillThreshold.integer + 1 ) )
- trap_SendConsoleCommand( 0, va( "!warn %i team killing\n", ent->client->ps.clientNum ) );
- else if ( ent->client->pers.teamKillDemerits == g_teamKillThreshold.integer )
- G_AdminsPrintf( "Team killer %s^7 has team killed ^6%i^7 times.\n",
- ent->client->pers.netname,
- ent->client->pers.statscounters.teamkills );
-
- return qfalse;
-}