From 2935fcee95246fa3b47002e8687a4ab2826de759 Mon Sep 17 00:00:00 2001 From: Paradox460 Date: Fri, 16 May 2008 02:46:56 +0000 Subject: [PATCH] Added IRC style admin chat team prefixes Added mean turrets and !outlaw Added !tklog Updated wiki page (wiki/flags.wiki) --- src/game/g_active.c | 16 ++ src/game/g_admin.c | 329 ++++++++++++++++++++++++++++++++++++++++- src/game/g_admin.h | 21 +++ src/game/g_buildable.c | 27 +++- src/game/g_client.c | 18 ++- src/game/g_cmds.c | 44 ++++++ src/game/g_combat.c | 21 ++- src/game/g_local.h | 7 + src/game/g_main.c | 11 ++ src/game/g_weapon.c | 3 +- 10 files changed, 489 insertions(+), 8 deletions(-) diff --git a/src/game/g_active.c b/src/game/g_active.c index c27ac9e..017dc39 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -944,6 +944,22 @@ void ClientTimerActions( gentity_t *ent, int msec ) ent->client->pers.statscounters.spreefeeds -= 2; if( ent->client->pers.statscounters.spreekills > 1 ) ent->client->pers.statscounters.spreekills -= 2; + if( ent->client->pers.statscounters.spreebleeds > 3 ) + { + ent->client->pers.statscounters.spreebleeds -= 4; + if( ent->client->pers.bleeder ) + { + if( ent->client->pers.statscounters.spreebleeds > 3 ) + ent->client->pers.statscounters.spreebleeds -= 4; + if( ent->client->pers.statscounters.spreebleeds < 4 ) + { + ent->client->pers.bleeder = qfalse; + trap_SendServerCommand( ent-g_entities, "cp \"^2Your base has forgiven you^7\"" ); + if( level.bleeders ) + level.bleeders--; + } + } + } // turn off life support when a team admits defeat if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && diff --git a/src/game/g_admin.c b/src/game/g_admin.c index bb4464d..236bcf7 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -245,6 +245,12 @@ g_admin_cmd_t g_admin_cmds[ ] = "" }, + {"outlaw", G_admin_outlaw, "O", + "add to a player's bleed counter, making their base turn on them." + " adding a bleed value will add that many points to their bleed counter, 0 will pardon them", + "(^5name|slot^7) (^5bleed value)" + }, + {"passvote", G_admin_passvote, "V", "pass a vote currently taking place", "" @@ -344,8 +350,13 @@ g_admin_cmd_t g_admin_cmds[ ] = {"time", G_admin_time, "C", "show the current local server time", ""}, + + {"tklog", G_admin_tklog, "t", + "list recent teamkill activity", + "(^5start id#|name|-skip#^7) (^5search skip#^7)" + }, - {"trade", G_admin_trade, "t", + {"trade", G_admin_trade, "T", "trade health with another player", "[^3name|slot#^7]" }, @@ -407,6 +418,9 @@ g_admin_namelog_t *g_admin_namelog[ MAX_ADMIN_NAMELOGS ]; static int admin_adminlog_index = 0; g_admin_adminlog_t *g_admin_adminlog[ MAX_ADMIN_ADMINLOGS ]; +static int admin_tklog_index = 0; +g_admin_tklog_t *g_admin_tklog[ MAX_ADMIN_TKLOGS ]; + qboolean G_admin_permission( gentity_t *ent, char flag ) { int i; @@ -6467,6 +6481,250 @@ qboolean G_admin_adminlog( gentity_t *ent, int skiparg ) return qtrue; } +void G_admin_tklog_cleanup( void ) +{ + int i; + + for( i = 0; i < MAX_ADMIN_TKLOGS && g_admin_tklog[ i ]; i++ ) + { + G_Free( g_admin_tklog[ i ] ); + g_admin_tklog[ i ] = NULL; + } + + admin_tklog_index = 0; +} + +void G_admin_tklog_log( gentity_t *attacker, gentity_t *victim, int meansOfDeath ) +{ + g_admin_tklog_t *tklog; + int previous; + int count = 1; + + if( !attacker || !victim ) + return; + + previous = admin_tklog_index - 1; + if( previous < 0 ) + previous = MAX_ADMIN_TKLOGS - 1; + + if( g_admin_tklog[ previous ] ) + count = g_admin_tklog[ previous ]->id + 1; + + if( g_admin_tklog[ admin_tklog_index ] ) + tklog = g_admin_tklog[ admin_tklog_index ]; + else + tklog = G_Alloc( sizeof( g_admin_tklog_t ) ); + + memset( tklog, 0, sizeof( g_admin_tklog_t ) ); + tklog->id = count; + tklog->time = level.time - level.startTime; + Q_strncpyz( tklog->name, attacker->client->pers.netname, sizeof( tklog->name ) ); + Q_strncpyz( tklog->victim, victim->client->pers.netname, sizeof( tklog->victim ) ); + tklog->damage = victim->client->tkcredits[ attacker->s.number ]; + tklog->value = victim->client->ps.stats[ STAT_MAX_HEALTH ]; + tklog->team = attacker->client->ps.stats[ STAT_PTEAM ]; + if( meansOfDeath == MOD_GRENADE ) + tklog->weapon = WP_GRENADE; + else if( tklog->team == PTE_HUMANS ) + tklog->weapon = attacker->s.weapon; + else + tklog->weapon = attacker->client->ps.stats[ STAT_PCLASS ]; + + g_admin_tklog[ admin_tklog_index ] = tklog; + admin_tklog_index++; + if( admin_tklog_index >= MAX_ADMIN_TKLOGS ) + admin_tklog_index = 0; +} + +qboolean G_admin_tklog( gentity_t *ent, int skiparg ) +{ + g_admin_tklog_t *results[ 10 ]; + int result_index = 0; + char *search_name = NULL; + int index; + int skip = 0; + int skipped = 0; + int checked = 0; + char n1[ MAX_NAME_LENGTH ]; + char fmt_name[ 16 ]; + char argbuf[ 32 ]; + char *weaponName; + int name_length = 10; + int max_id = 0; + int i; + qboolean match; + + memset( results, 0, sizeof( results ) ); + + index = admin_tklog_index; + for( i = 0; i < 10; i++ ) + { + int prev; + + prev = index - 1; + if( prev < 0 ) + prev = MAX_ADMIN_TKLOGS - 1; + if( !g_admin_tklog[ prev ] ) + break; + if( g_admin_tklog[ prev ]->id > max_id ) + max_id = g_admin_tklog[ prev ]->id; + index = prev; + } + + if( G_SayArgc() > 1 + skiparg ) + { + G_SayArgv( 1 + skiparg, argbuf, sizeof( argbuf ) ); + if( ( *argbuf >= '0' && *argbuf <= '9' ) || *argbuf == '-' ) + { + int id; + + id = atoi( argbuf ); + if( id < 0 ) + id += ( max_id - 9 ); + else if( id <= max_id - MAX_ADMIN_TKLOGS ) + id = max_id - MAX_ADMIN_TKLOGS + 1; + + if( id + 9 >= max_id ) + id = max_id - 9; + if( id < 1 ) + id = 1; + for( i = 0; i < MAX_ADMIN_TKLOGS; i++ ) + { + if( g_admin_tklog[ i ]->id == id ) + { + index = i; + break; + } + } + } + else + { + search_name = argbuf; + } + + if( G_SayArgc() > 2 + skiparg && ( search_name ) ) + { + char skipbuf[ 4 ]; + G_SayArgv( 2 + skiparg, skipbuf, sizeof( skipbuf ) ); + skip = atoi( skipbuf ); + } + } + + if( search_name ) + { + g_admin_tklog_t *result_swap[ 10 ]; + + memset( &result_swap, 0, sizeof( result_swap ) ); + + index = admin_tklog_index - 1; + if( index < 0 ) + index = MAX_ADMIN_TKLOGS - 1; + + while( g_admin_tklog[ index ] && + checked < MAX_ADMIN_TKLOGS && + result_index < 10 ) + { + match = qfalse; + + G_SanitiseName( g_admin_tklog[ index ]->name, n1 ); + if( strstr( n1, search_name ) ) + match = qtrue; + + if( match && skip > 0 ) + { + match = qfalse; + skip--; + skipped++; + } + if( match ) + { + result_swap[ result_index ] = g_admin_tklog[ index ]; + result_index++; + } + + checked++; + index--; + if( index < 0 ) + index = MAX_ADMIN_TKLOGS - 1; + } + // search runs backwards, turn it around + for( i = 0; i < result_index; i++ ) + results[ i ] = result_swap[ result_index - i - 1 ]; + } + else + { + while( g_admin_tklog[ index ] && result_index < 10 ) + { + results[ result_index ] = g_admin_tklog[ index ]; + result_index++; + index++; + if( index >= MAX_ADMIN_TKLOGS ) + index = 0; + } + } + + for( i = 0; results[ i ] && i < 10; i++ ) + { + int l; + + G_DecolorString( results[ i ]->name, n1 ); + l = strlen( n1 ); + if( l > name_length ) + name_length = l; + } + ADMBP_begin( ); + for( i = 0; results[ i ] && i < 10; i++ ) + { + int t; + + t = results[ i ]->time / 1000; + + G_DecolorString( results[ i ]->name, n1 ); + Com_sprintf( fmt_name, sizeof( fmt_name ), "%%%ds", + ( name_length + strlen( results[ i ]->name ) - strlen( n1 ) ) ); + Com_sprintf( n1, sizeof( n1 ), fmt_name, results[ i ]->name ); + + if( results[ i ]->team == PTE_HUMANS ) + weaponName = BG_FindNameForWeapon( results[ i ]->weapon ); + else + weaponName = BG_FindNameForClassNum( results[ i ]->weapon ); + + ADMBP( va( "^7%3d %3d:%02d %s^7 %3d / %3d %10s %s^7\n", + results[ i ]->id, + t / 60, t % 60, + n1, + results[ i ]->damage, + results[ i ]->value, + weaponName, + results[ i ]->victim ) ); + } + if( search_name ) + { + ADMBP( va( "^3!tklog:^7 Showing %d matches for '%s^7'.", + result_index, + argbuf ) ); + if( checked < MAX_ADMIN_TKLOGS && g_admin_tklog[ checked ] ) + ADMBP( va( " run '!tklog %s^7 %d' to see more", + argbuf, + skipped + result_index ) ); + ADMBP( "\n" ); + } + else if ( results[ 0 ] ) + { + ADMBP( va( "^3!tklog:^7 Showing %d - %d of %d.\n", + results[ 0 ]->id, + results[ result_index - 1 ]->id, + max_id ) ); + } + else + { + ADMBP( "^3!tklog:^7 log is empty.\n" ); + } + ADMBP_end( ); + + return qtrue; +} + void G_admin_maplog_update( void ) { char map[ 64 ]; @@ -7135,6 +7393,75 @@ qboolean G_admin_demo( gentity_t *ent, int skiparg ) return qtrue; } +qboolean G_admin_outlaw( gentity_t *ent, int skiparg ) +{ + int pids[ MAX_CLIENTS ]; + char name[ MAX_NAME_LENGTH ], err[ MAX_STRING_CHARS ]; + char valuebuf[ 8 ]; + gentity_t *vic; + int points; + + if( !g_bleedingSpree.integer ) + { + ADMP( "^3!outlaw: ^7bleeding sprees are disabled\n" ); + return qfalse; + } + + if( G_SayArgc() < 2 + skiparg ) + { + ADMP( "^3!outlaw: ^7usage: !outlaw [name|slot#] (value)\n" ); + return qfalse; + } + G_SayArgv( 1 + skiparg, name, sizeof( name ) ); + if( G_ClientNumbersFromString( name, pids ) != 1 ) + { + G_MatchOnePlayer( pids, err, sizeof( err ) ); + ADMP( va( "^3!mute: ^7%s\n", err ) ); + return qfalse; + } + + if( G_SayArgc() > 2 + skiparg ) + { + G_SayArgv( 2 + skiparg, valuebuf, sizeof( valuebuf ) ); + points = atoi( valuebuf ); + } + else + { + points = ( g_bleedingSpree.integer + 1 ) * 100; + } + + if( !admin_higher( ent, &g_entities[ pids[ 0 ] ] ) ) + { + ADMP( "^3!mute: ^7sorry, but your intended victim has a higher admin" + " level than you\n" ); + return qfalse; + } + vic = &g_entities[ pids[ 0 ] ]; + if( points ) + { + vic->client->pers.statscounters.spreebleeds += points; + if( !vic->client->pers.bleeder ) + { + vic->client->pers.bleeder = qtrue; + level.bleeders++; + + AP( va( "print \"^3!outlaw: ^7%s^7 has been designated an outlaw by ^7%s\n\"", + vic->client->pers.netname, + ( ent ) ? ent->client->pers.netname : "console" ) ); + } + } + else + { + vic->client->pers.statscounters.spreebleeds = 8; + + AP( va( "print \"^3!outlaw: ^7%s^7 has been pardoned by ^7%s\n\"", + vic->client->pers.netname, + ( ent ) ? ent->client->pers.netname : "console" ) ); + } + return qtrue; +} + + qboolean G_admin_mix( gentity_t *ent, int skiparg ) { int pids[ MAX_CLIENTS ]; diff --git a/src/game/g_admin.h b/src/game/g_admin.h index 781acac..d77145b 100644 --- a/src/game/g_admin.h +++ b/src/game/g_admin.h @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define MAX_ADMIN_NAMELOG_NAMES 5 #define MAX_ADMIN_ADMINLOGS 128 #define MAX_ADMIN_ADMINLOG_ARGS 50 +#define MAX_ADMIN_TKLOGS 64 #define MAX_ADMIN_FLAGS 128 #define MAX_ADMIN_COMMANDS 128 #define MAX_ADMIN_CMD_LEN 20 @@ -84,6 +85,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define ADMF_ADMINCHAT '?' #define ADMF_BUILDCHECK ')' +#define ADMF_SHOWOFF '(' + + #define ADMF_BANIMMUNITY '&' #define MAX_ADMIN_LISTITEMS 20 @@ -166,6 +170,19 @@ typedef struct g_admin_adminlog } g_admin_adminlog_t; +typedef struct g_admin_tklog +{ + char name[ MAX_NAME_LENGTH ]; + char victim[ MAX_NAME_LENGTH ]; + int id; + int time; + int damage; + int value; + int team; + int weapon; +} +g_admin_tklog_t; + qboolean G_admin_ban_check( char *userinfo, char *reason, int rlen ); qboolean G_admin_cmd_check( gentity_t *ent, qboolean say ); qboolean G_admin_readconfig( gentity_t *ent, int skiparg ); @@ -230,6 +247,9 @@ qboolean G_admin_demo( gentity_t *ent, int skiparg ); qboolean G_admin_adminlog( gentity_t *ent, int skiparg ); void G_admin_adminlog_cleanup( void ); void G_admin_adminlog_log( gentity_t *ent, char *command, char *args, int skiparg, qboolean success ); +qboolean G_admin_tklog( gentity_t *ent, int skiparg ); +void G_admin_tklog_cleanup( void ); +void G_admin_tklog_log( gentity_t *attacker, gentity_t *victim, int meansOfDeath ); qboolean G_admin_maplog( gentity_t *ent, int skiparg ); void G_admin_maplog_update( void ); void G_admin_maplog_result( char *flag ); @@ -250,6 +270,7 @@ qboolean G_admin_cp( gentity_t *ent, int skiparg ); qboolean G_admin_credits( gentity_t *ent, int skiparg ); qboolean G_admin_customgrav( gentity_t *ent, int skiparg ); qboolean G_admin_explode( gentity_t *ent, int skiparg ); +qboolean G_admin_outlaw( 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_buildable.c b/src/game/g_buildable.c index 9376f92..f1d2076 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -1078,7 +1078,8 @@ void AAcidTube_Think( gentity_t *self ) if( !G_Visible( self, enemy ) ) continue; - if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS && + if( enemy->client && + ( enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS || enemy->client->pers.bleeder ) && !level.paused && !enemy->client->pers.paused ) { @@ -2120,7 +2121,8 @@ qboolean HMGTurret_CheckTarget( gentity_t *self, gentity_t *target, qboolean ign if( !traceEnt->client ) return qfalse; - if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) + if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS + && !traceEnt->client->pers.bleeder ) return qfalse; return qtrue; @@ -2184,6 +2186,24 @@ void HMGTurret_FindEnemy( gentity_t *self ) } } + // bleeder retribution + if( level.bleeders ) + { + for( i = 0; i < num; i++ ) + { + target = &g_entities[ entityList[ i ] ]; + + if( target->client && target->client->pers.bleeder ) + { + if( !HMGTurret_CheckTarget( self, target, qfalse ) ) + continue; + + self->enemy = target; + return; + } + } + } + //couldn't find a target self->enemy = NULL; } @@ -2299,7 +2319,8 @@ void HTeslaGen_Think( gentity_t *self ) if( enemy->flags & FL_NOTARGET ) continue; - if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && + if( enemy->client && + ( enemy->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS || enemy->client->pers.bleeder ) && enemy->health > 0 && !enemy->client->pers.paused && !level.paused && Distance( enemy->s.pos.trBase, self->s.pos.trBase ) <= TESLAGEN_RANGE ) diff --git a/src/game/g_client.c b/src/game/g_client.c index 6ea2b07..9c754ca 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -1496,6 +1496,10 @@ void ClientBegin( int clientNum ) gentity_t *ent; gclient_t *client; int flags; + char flag[6]; + char userinfo[ MAX_INFO_STRING ]; + trap_Cvar_VariableStringBuffer( "g_chatAdminPrefix", flag, sizeof( flag ) ); + ent = g_entities + clientNum; @@ -1526,8 +1530,18 @@ void ClientBegin( int clientNum ) // locate ent at a spawn point ClientSpawn( ent, NULL, NULL, NULL ); - - trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname ) ); + if( G_admin_permission( ent, ADMF_SHOWOFF) ) + { + trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) ); + trap_SendServerCommand( -1, va( "print \"%s^7%s" S_COLOR_WHITE " entered the game\n\"", flag, client->pers.netname ) ); + Info_SetValueForKey( userinfo, "name", va( "%s^7%s", flag, client->pers.netname ) ); + trap_SetUserinfo( clientNum, userinfo ); + ClientUserinfoChanged( clientNum ); + } + else + { + trap_SendServerCommand( -1, va( "print \"%s" S_COLOR_WHITE " entered the game\n\"", client->pers.netname ) ); + } // name can change between ClientConnect() and ClientBegin() G_admin_namelog_update( client, qfalse ); diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 52face6..2092eaf 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -4222,6 +4222,8 @@ void Cmd_PTRCVerify_f( gentity_t *ent ) connectionRecord_t *connection; char s[ MAX_TOKEN_CHARS ] = { 0 }; int code; + int i; + gentity_t *players; trap_Argv( 1, s, sizeof( s ) ); @@ -4229,6 +4231,25 @@ void Cmd_PTRCVerify_f( gentity_t *ent ) return; code = atoi( s ); + + //Some sanity checks...BECAUSE THIS FUNCTION IS INSANE! lol + for( i = 0; i < level.maxclients; i++ ) + { + players = &g_entities[ i ]; + if( !players->client ) + continue; + if( players->client->pers.connected != CON_CONNECTED ) + continue; + if( players == ent ) + continue; + + if( players->client->pers.connection->ptrCode == code ) + { + trap_SendServerCommand( ent - g_entities, + "print \"This PTR code is already in use\n\"" ); + G_AdminsPrintf("%s^7 attempted to use %s^7's PTR code", ent->client->pers.netname, players->client->pers.netname); + } + } if( G_VerifyPTRC( code ) ) { @@ -4266,6 +4287,9 @@ void Cmd_PTRCRestore_f( gentity_t *ent ) char s[ MAX_TOKEN_CHARS ] = { 0 }; int code; connectionRecord_t *connection; + gentity_t *ents; + int i; + gentity_t *players; trap_Argv( 1, s, sizeof( s ) ); @@ -4273,6 +4297,26 @@ void Cmd_PTRCRestore_f( gentity_t *ent ) return; code = atoi( s ); + + //Some sanity checks.. + for( i = 0; i < level.maxclients; i++ ) + { + players = &g_entities[ i ]; + if( !players->client ) + continue; + if( players->client->pers.connected != CON_CONNECTED ) + continue; + if( players == ent ) + continue; + + if( players->client->pers.connection->ptrCode == code ) + { + trap_SendServerCommand( ent - g_entities, + "print \"This PTR code is already in use\n\"" ); + G_AdminsPrintf("%s^7 attempted to use %s^7's PTR code", ent->client->pers.netname, players->client->pers.netname); + } + } + if( G_VerifyPTRC( code ) ) { diff --git a/src/game/g_combat.c b/src/game/g_combat.c index 39903b7..fd0c2e4 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -275,6 +275,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int self->client->pers.netname, attacker->client->pers.netname, self->client->tkcredits[ attacker->s.number ], self->client->ps.stats[ STAT_MAX_HEALTH ] ) ); trap_SendServerCommand( attacker - g_entities, va( "cp \"You killed ^1TEAMMATE^7 %s\"", self->client->pers.netname ) ); + + G_admin_tklog_log( attacker, self, meansOfDeath ); } self->enemy = attacker; @@ -1222,7 +1224,7 @@ dflags these flags are used to control how T_Damage works void G_SelectiveDamage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod, int team ) { - if( targ->client && ( team != targ->client->ps.stats[ STAT_PTEAM ] ) ) + if( targ->client && ( team != targ->client->ps.stats[ STAT_PTEAM ] || targ->client->pers.bleeder ) ) G_Damage( targ, inflictor, attacker, dir, point, damage, dflags, mod ); } @@ -1485,6 +1487,23 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, { level.humanStatsCounters.ffdmgdone+=take; } + + // bleeding spree + if( g_bleedingSpree.integer > 1 ) + { + attacker->client->pers.statscounters.spreebleeds += take; + if( attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 100 && + !attacker->client->pers.bleeder ) + { + attacker->client->pers.bleeder = qtrue; + level.bleeders++; + trap_SendServerCommand( -1, + va( "print \"%s^3 has become an enemy of their own base.\n\"", + attacker->client->pers.netname ) ); + trap_SendServerCommand( attacker - g_entities, + "cp \"^1Your team bleeding has irritated your base^7\"" ); + } + } } else if( targ->s.eType == ET_BUILDABLE ) { diff --git a/src/game/g_local.h b/src/game/g_local.h index 4b19cf0..cb32448 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -340,6 +340,7 @@ typedef struct int hitslocational; int spreekills; int spreefeeds; + int spreebleeds; int teamkills; int dretchbasytime; int jetpackusewallwalkusetime; @@ -389,6 +390,7 @@ typedef struct qboolean denyBuild; int denyHumanWeapons; int denyAlienClasses; + qboolean bleeder; qboolean paused; int adminLevel; qboolean specd; @@ -757,6 +759,8 @@ typedef struct int lastBuildID; int lastTeamUnbalancedTime; int numTeamWarnings; + + int bleeders; statsCounters_t alienStatsCounters; statsCounters_t humanStatsCounters; @@ -1359,6 +1363,7 @@ extern vmCvar_t g_antiSpawnBlock; extern vmCvar_t g_killingSpree; extern vmCvar_t g_feedingSpree; +extern vmCvar_t g_bleedingSpree; extern vmCvar_t g_sayAreaLocations; @@ -1398,6 +1403,8 @@ extern vmCvar_t g_specAspec; extern vmCvar_t g_healShove; +extern vmCvar_t g_chatAdminPrefix; + extern vmCvar_t g_modBuildableHealth; // Buildable health extern vmCvar_t g_modBuildableSpeed; // Buildable fire rate extern vmCvar_t g_modHumanStamina; // Human stamina diff --git a/src/game/g_main.c b/src/game/g_main.c index a360dd1..bf75286 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -170,6 +170,7 @@ vmCvar_t g_antiSpawnBlock; vmCvar_t g_killingSpree; vmCvar_t g_feedingSpree; +vmCvar_t g_bleedingSpree; vmCvar_t g_KillerHP; @@ -219,6 +220,8 @@ vmCvar_t g_specAspec; vmCvar_t g_healShove; +vmCvar_t g_chatAdminPrefix; + vmCvar_t g_modBuildableHealth; vmCvar_t g_modBuildableSpeed; vmCvar_t g_modHumanStamina; @@ -272,6 +275,8 @@ static cvarTable_t gameCvarTable[ ] = { &g_healShove, "g_healShove", "1", CVAR_ARCHIVE, 0, qtrue }, + { &g_chatAdminPrefix, "g_chatAdminPrefix", "^3@", CVAR_ARCHIVE, 0, qtrue }, + { &g_modBuildableHealth, "g_modBuildableHealth", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_modBuildableSpeed, "g_modBuildableSpeed", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_modHumanStamina, "g_modHumanStamina", "0", CVAR_ARCHIVE, 0, qfalse }, @@ -419,6 +424,7 @@ static cvarTable_t gameCvarTable[ ] = { &g_killingSpree, "g_killingSpree", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_feedingSpree, "g_feedingSpree", "0", CVAR_ARCHIVE, 0, qfalse }, + { &g_bleedingSpree, "g_bleedingSpree", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_KillerHP, "g_KillerHP", "0", CVAR_ARCHIVE, 0, qtrue }, @@ -920,6 +926,7 @@ void G_ShutdownGame( int restart ) G_admin_cleanup( ); G_admin_namelog_cleanup( ); G_admin_adminlog_cleanup( ); + G_admin_tklog_cleanup( ); level.restarted = qfalse; level.surrenderTeam = PTE_NONE; @@ -1564,6 +1571,7 @@ void CalculateRanks( void ) level.numHumanClients = 0; level.numLiveAlienClients = 0; level.numLiveHumanClients = 0; + level.bleeders = 0; for( i = 0; i < level.maxclients; i++ ) { @@ -1596,6 +1604,9 @@ void CalculateRanks( void ) if( level.clients[ i ].sess.sessionTeam != TEAM_SPECTATOR ) level.numLiveHumanClients++; } + + if( level.clients[ i ].pers.bleeder ) + level.bleeders++; } } } diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index f68b406..b45ffa7 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -648,7 +648,8 @@ void teslaFire( gentity_t *ent ) if( !traceEnt->client ) return; - if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) + if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS && + !traceEnt->client->pers.bleeder ) return; //so the client side knows