summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony J. White <tjw@tjw.org>2006-09-05 20:55:24 +0000
committerTony J. White <tjw@tjw.org>2006-09-05 20:55:24 +0000
commit666de76f06023edd9069be7494b3e5877d07f3e0 (patch)
tree98ab67f2022a88a1eb68acea13204a44cf1731a7
parent8b4c10560bd6b7b0bc380cf18b0f3b7cf07d2aca (diff)
Bug 2849
* adds g_admin flag '3' which allows the admin/level to always keep cred/evo when switching teams. * adds !lock and !unlock g_admin commands for locking teams. (enable with 'K' flag) * setting an admin's level to 0 immediately free's up that admin's name from the name protection system (g_adminNameProtect) * don't give kills/creds to a spectator in follow mode ('3' flag exposed this)
-rw-r--r--src/game/g_admin.c91
-rw-r--r--src/game/g_admin.h8
-rw-r--r--src/game/g_client.c3
-rw-r--r--src/game/g_cmds.c59
-rw-r--r--src/game/g_combat.c3
-rw-r--r--src/game/g_local.h1
6 files changed, 149 insertions, 16 deletions
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 0fb2975b..018639a7 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -50,8 +50,8 @@ g_admin_cmd_t g_admin_cmds[ ] =
{"ban", G_admin_ban, "b",
"ban a player by IP and GUID with an optional expiration time and reason."
- "time is seconds or suffix with 'w' - weeks, 'd' - days, 'h' - hours, or "
- "'m' - minutes",
+ " time is seconds or suffix with 'w' - weeks, 'd' - days, 'h' - hours, "
+ "or 'm' - minutes",
"[^3name|slot#|IP^7] (^5time^7) (^5reason^7)"
},
@@ -79,6 +79,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
"display a list of players, their client numbers and their levels",
""
},
+
+ {"lock", G_admin_lock, "K",
+ "lock a team to prevent anyone from joining it",
+ "[^3a|h^7]"
+ },
{"mute", G_admin_mute, "m",
"mute a player",
@@ -142,6 +147,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
"unbans a player specified by the slot as seen in showbans",
"[^3ban slot#^7]"
},
+
+ {"unlock", G_admin_unlock, "K",
+ "unlock a locked team",
+ "[^3a|h^7]"
+ },
{"unmute", G_admin_mute, "m",
"unmute a muted player",
@@ -285,6 +295,8 @@ qboolean G_admin_name_check( gentity_t *ent, char *name, char *err, int len )
for( i = 0; i < MAX_ADMIN_ADMINS && g_admin_admins[ i ]; i++ )
{
+ if( g_admin_admins[ i ]->level < 1 )
+ continue;
G_SanitiseName( g_admin_admins[ i ]->name, testName );
if( !Q_stricmp( name2, testName ) &&
Q_stricmp( ent->client->pers.guid, g_admin_admins[ i ]->guid ) )
@@ -914,9 +926,8 @@ qboolean G_admin_cmd_check( gentity_t *ent, qboolean say )
command[ 0 ] = '\0';
G_SayArgv( 0, command, sizeof( command ) );
if( !Q_stricmp( command, "say" ) ||
- ( G_admin_permission( ent, ADMF_TEAMFTCMD ) &&
- ( !Q_stricmp( command, "say_team" ) ||
- !Q_stricmp( command, "say_buddy" ) ) ) )
+ ( G_admin_permission( ent, ADMF_TEAMCHAT_CMD ) &&
+ ( !Q_stricmp( command, "say_team" ) ) ) )
{
skip = 1;
G_SayArgv( 1, command, sizeof( command ) );
@@ -2303,7 +2314,7 @@ qboolean G_admin_help( gentity_t *ent, int skiparg )
ADMBP( va( "^3!help: ^7help for '!%s':\n",
g_admin_cmds[ i ].keyword ) );
ADMBP( va( " ^3Funtion: ^7%s\n", g_admin_cmds[ i ].function ) );
- ADMBP( va( " ^3Syntax: ^7%s %s\n", g_admin_cmds[ i ].keyword,
+ ADMBP( va( " ^3Syntax: ^7!%s %s\n", g_admin_cmds[ i ].keyword,
g_admin_cmds[ i ].syntax ) );
ADMBP( va( " ^3Flag: ^7'%c'\n", g_admin_cmds[ i ].flag[ 0 ] ) );
ADMBP_end();
@@ -2324,7 +2335,7 @@ qboolean G_admin_help( gentity_t *ent, int skiparg )
ADMBP( va( "^3!help: ^7help for '%s':\n",
g_admin_commands[ i ]->command ) );
ADMBP( va( " ^3Description: ^7%s\n", g_admin_commands[ i ]->desc ) );
- ADMBP( va( " ^3Syntax: ^7%s\n", g_admin_commands[ i ]->command ) );
+ ADMBP( va( " ^3Syntax: ^7!%s\n", g_admin_commands[ i ]->command ) );
ADMBP_end();
return qtrue;
}
@@ -2600,6 +2611,72 @@ qboolean G_admin_namelog( gentity_t *ent, int skiparg )
return qtrue;
}
+qboolean G_admin_lock( gentity_t *ent, int skiparg )
+{
+ char teamName[2] = {""};
+ pTeam_t team;
+
+ if( G_SayArgc() < 1 + skiparg )
+ {
+ ADMP( "^3!lock: ^7usage: !lock [a|h]\n" );
+ return qfalse;
+ }
+ G_SayArgv( 1 + skiparg, teamName, sizeof( teamName ) );
+ if( teamName[ 0 ] == 'a' || teamName[ 0 ] == 'A' )
+ team = PTE_ALIENS;
+ else if( teamName[ 0 ] == 'h' || teamName[ 0 ] == 'H' )
+ team = PTE_HUMANS;
+ else
+ {
+ ADMP( va( "^3!lock: ^7invalid team\"%c\"\n", teamName[0] ) );
+ return qfalse;
+ }
+ if( level.teamLocked[ team ] )
+ {
+ ADMP( va( "^3!lock: ^7%s team is already locked\n",
+ ( team == PTE_ALIENS ) ? "Alien" : "Human" ) );
+ return qfalse;
+ }
+ level.teamLocked[ team ] = qtrue;
+ AP( va( "print \"^3!lock: ^7%s team has been locked by %s\n\"",
+ ( team == PTE_ALIENS ) ? "Alien" : "Human",
+ ( ent ) ? ent->client->pers.netname : "console" ) );
+ return qtrue;
+}
+
+qboolean G_admin_unlock( gentity_t *ent, int skiparg )
+{
+ char teamName[2] = {""};
+ pTeam_t team;
+
+ if( G_SayArgc() < 1 + skiparg )
+ {
+ ADMP( "^3!unlock: ^7usage: !unlock [a|h]\n" );
+ return qfalse;
+ }
+ G_SayArgv( 1 + skiparg, teamName, sizeof( teamName ) );
+ if( teamName[ 0 ] == 'a' || teamName[ 0 ] == 'A' )
+ team = PTE_ALIENS;
+ else if( teamName[ 0 ] == 'h' || teamName[ 0 ] == 'H' )
+ team = PTE_HUMANS;
+ else
+ {
+ ADMP( va( "^3!unlock: ^7invalid team\"%c\"\n", teamName[0] ) );
+ return qfalse;
+ }
+ if( !level.teamLocked[ team ] )
+ {
+ ADMP( va( "^3!lock: ^7%s team is not locked\n",
+ ( team == PTE_ALIENS ) ? "Alien" : "Human" ) );
+ return qfalse;
+ }
+ level.teamLocked[ team ] = qfalse;
+ AP( va( "print \"^3!unlock: ^7%s team has been unlocked by %s\n\"",
+ ( team == PTE_ALIENS ) ? "Alien" : "Human",
+ ( ent ) ? ent->client->pers.netname : "console" ) );
+ return qtrue;
+}
+
/*
* This function facilitates the TP define. ADMP() is similar to CP except that
* it prints the message to the server console if ent is not defined.
diff --git a/src/game/g_admin.h b/src/game/g_admin.h
index 0b5c6907..c91fc42a 100644
--- a/src/game/g_admin.h
+++ b/src/game/g_admin.h
@@ -44,7 +44,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/*
* 1 - cannot be vote kicked, vote muted
* 2 - cannot be censored or flood protected TODO
- * 3 - UNUSED
+ * 3 - never loses credits for changing teams
* 4 - can see team chat as a spectator
* 5 - can switch teams any time, regardless of balance
* 6 - does not need to specify a reason for a kick/ban
@@ -58,13 +58,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define ADMF_IMMUNITY '1'
#define ADMF_NOCENSORFLOOD '2' /* TODO */
-
+#define ADMF_TEAMCHANGEFREE '3'
#define ADMF_SPEC_ALLCHAT '4'
#define ADMF_FORCETEAMCHANGE '5'
#define ADMF_UNACCOUNTABLE '6'
#define ADMF_NO_VOTE_LIMIT '7'
#define ADMF_CAN_PERM_BAN '8'
-#define ADMF_TEAMFTCMD '9'
+#define ADMF_TEAMCHAT_CMD '9'
#define ADMF_ACTIVITY '0'
#define ADMF_IMMUTABLE '!'
@@ -161,6 +161,8 @@ qboolean G_admin_rename( gentity_t *ent, int skiparg );
qboolean G_admin_restart( gentity_t *ent, int skiparg );
qboolean G_admin_nextmap( gentity_t *ent, int skiparg );
qboolean G_admin_namelog( gentity_t *ent, int skiparg );
+qboolean G_admin_lock( gentity_t *ent, int skiparg );
+qboolean G_admin_unlock( gentity_t *ent, int skiparg );
void G_admin_print( gentity_t *ent, char *m );
void G_admin_buffer_print( gentity_t *ent, char *m );
diff --git a/src/game/g_client.c b/src/game/g_client.c
index 7350b55c..491a834d 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -89,6 +89,9 @@ void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap )
if( !client )
return;
+ if( client->sess.sessionTeam == TEAM_SPECTATOR )
+ return;
+
//if we're already at the max and trying to add credit then stop
if( cap )
{
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 6cef9201..4f6804ea 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -597,12 +597,26 @@ void G_ChangeTeam( gentity_t *ent, pTeam_t newTeam )
else if( oldTeam == PTE_HUMANS )
G_RemoveFromSpawnQueue( &level.humanSpawnQueue, ent->client->ps.clientNum );
- // Tranfer credits and kills as long as this player has been on the
- // same team for at least 1 minute. This is done to provide
- // a penalty for switching teams for reconnaissance.
- if( ( oldTeam == PTE_HUMANS || oldTeam == PTE_ALIENS )
- && ( level.time - ent->client->pers.teamChangeTime ) > 60000 )
+ if( G_admin_permission( ent, ADMF_TEAMCHANGEFREE ) )
{
+ // always save in human credtis
+ if( oldTeam == PTE_ALIENS )
+ {
+ ent->client->ps.persistant[ PERS_CREDIT ] *=
+ (float)FREEKILL_HUMAN / FREEKILL_ALIEN;
+ }
+ if( newTeam == PTE_ALIENS )
+ {
+ ent->client->ps.persistant[ PERS_CREDIT ] *=
+ (float)FREEKILL_ALIEN / FREEKILL_HUMAN;
+ }
+ }
+ else if( ( oldTeam == PTE_HUMANS || oldTeam == PTE_ALIENS )
+ && ( level.time - ent->client->pers.teamChangeTime ) > 60000 )
+ {
+ // Tranfer credits and kills as long as this player has been on the
+ // same team for at least 1 minute. This is done to provide
+ // a penalty for switching teams for reconnaissance.
if( oldTeam == PTE_HUMANS )
{
ent->client->ps.persistant[ PERS_CREDIT ] *=
@@ -654,6 +668,19 @@ void Cmd_Team_f( gentity_t *ent )
team = PTE_NONE;
else if( !Q_stricmp( s, "aliens" ) )
{
+ if( level.teamLocked[ PTE_ALIENS ] )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"Alien team has been ^1LOCKED\n\"", s ) );
+ return;
+ }
+ else if( level.teamLocked[ PTE_HUMANS ] )
+ {
+ // if only one team has been locked, let people join the other
+ // regardless of balance
+ force = qtrue;
+ }
+
if( !force && g_teamForceBalance.integer
&& ( ( level.numAlienClients > level.numHumanClients ) ||
( ent->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS &&
@@ -667,6 +694,19 @@ void Cmd_Team_f( gentity_t *ent )
}
else if( !Q_stricmp( s, "humans" ) )
{
+ if( level.teamLocked[ PTE_HUMANS ] )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"Human team has been ^1LOCKED\n\"", s ) );
+ return;
+ }
+ else if( level.teamLocked[ PTE_ALIENS ] )
+ {
+ // if only one team has been locked, let people join the other
+ // regardless of balance
+ force = qtrue;
+ }
+
if( !force && g_teamForceBalance.integer &&
( ( level.numHumanClients > level.numAlienClients ) ||
( ent->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS &&
@@ -680,12 +720,19 @@ void Cmd_Team_f( gentity_t *ent )
}
else if( !Q_stricmp( s, "auto" ) )
{
- if( level.numHumanClients > level.numAlienClients )
+ if( level.teamLocked[ PTE_HUMANS ] && level.teamLocked[ PTE_ALIENS ] )
+ team = PTE_NONE;
+ else if( level.numHumanClients > level.numAlienClients )
team = PTE_ALIENS;
else if( level.numHumanClients < level.numAlienClients )
team = PTE_HUMANS;
else
team = PTE_ALIENS + ( rand( ) % 2 );
+
+ if( team == PTE_ALIENS && level.teamLocked[ PTE_ALIENS ] )
+ team = PTE_HUMANS;
+ else if( team == PTE_HUMANS && level.teamLocked[ PTE_HUMANS ] )
+ team = PTE_ALIENS;
}
else
{
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index f457b77e..07643a2e 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -41,6 +41,9 @@ void AddScore( gentity_t *ent, int score )
if( !ent->client )
return;
+ if( ent->client->sess.sessionTeam == TEAM_SPECTATOR )
+ return;
+
// no scoring during pre-match warmup
if( level.warmupTime )
return;
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 54276cea..304c9f62 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -622,6 +622,7 @@ typedef struct
qboolean uncondAlienWin;
qboolean uncondHumanWin;
+ qboolean teamLocked[ TEAM_NUM_TEAMS ];
} level_locals_t;
//