From 49e3c15ae00891726c30dcbb5b1ffa6b98666d00 Mon Sep 17 00:00:00 2001 From: Paradox460 Date: Thu, 4 Sep 2008 02:46:40 +0000 Subject: [PATCH] * Damage done to self does not raise bleed counter. (Issue 157) * BleedingSpree goes down when damage is done to other team, but at 1/3 the damage done (Issue 157) * Admitdefeat votes cannot be spammed anymore by players, can't be called before `g_admitDefeatTime`, or by admin (Issue 159) * Fixed bug in listplayers and lockname (Issue 161) * Cleans up build near doors code (Issue 163) * Adds `/devolve` command for aliens. Does not give credits back, player must have full health, and is cvar controlled by `g_allowDevolve` (Issue 166) * Added silent specme, when `!specme s` is done by an admin (anyone with kick flag k), they are put to spec team, but it is not announced. (Issue 168) * Increase max registered players. (Issue 177) --- src/game/g_admin.c | 37 ++++++++---- src/game/g_admin.h | 2 +- src/game/g_buildable.c | 18 ++---- src/game/g_cmds.c | 129 ++++++++++++++++++++++++++++++++++++++++- src/game/g_combat.c | 20 ++++++- src/game/g_local.h | 4 +- src/game/g_main.c | 10 ++-- src/qcommon/q_shared.h | 2 +- 8 files changed, 187 insertions(+), 35 deletions(-) diff --git a/src/game/g_admin.c b/src/game/g_admin.c index a50fc2f..8901a32 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -343,8 +343,8 @@ g_admin_cmd_t g_admin_cmds[ ] = //kev: a bit of a hack, but there is no real point to //creating a new admin flag for this, so i stole it from !help {"specme", G_admin_putmespec, "h", - "moves you to the spectators", - "" + "moves you to the spectators (can be done silently with the 's' argument)", + "(^5s^7)" }, {"suspendban", G_admin_suspendban, "B", @@ -3338,7 +3338,7 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) char lname[ MAX_NAME_LENGTH ]; char lname2[ MAX_NAME_LENGTH ]; char guid_stub[ 9 ]; - char muted[ 2 ], denied[ 2 ], dbuilder[ 2 ], immune[ 2 ], nlocked[ 2 ]; + char muted[ 2 ], denied[ 2 ], dbuilder[ 2 ], immune[ 2 ]; int l; char lname_fmt[ 5 ]; @@ -3375,16 +3375,15 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) guid_stub[ j ] = p->pers.guid[ j + 24 ]; guid_stub[ j ] = '\0'; - nlocked[ 0 ] = '\0'; - if( p->pers.nlocked ) - { - Q_strncpyz( nlocked, "N", sizeof( muted ) ); - } muted[ 0 ] = '\0'; if( p->pers.muted ) { Q_strncpyz( muted, "M", sizeof( muted ) ); } + else if( p->pers.nlocked ) + { + Q_strncpyz( muted, "N", sizeof( muted ) ); + } denied[ 0 ] = '\0'; if( p->pers.denyBuild ) { @@ -3474,7 +3473,6 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) ( *lname ) ? lname2 : "", guid_stub, immune, - nlocked, muted, dbuilder, denied, @@ -3490,7 +3488,6 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) i, c, t, - nlocked, muted, dbuilder, denied, @@ -4571,6 +4568,20 @@ qboolean G_admin_putmespec( gentity_t *ent, int skiparg ) } G_ChangeTeam( ent, PTE_NONE ); + + // check for silent '!specme s' - requires !kick permission + if( G_SayArgc() > 1 + skiparg ) + { + char arg[ 2 ]; + + G_SayArgv( 1 + skiparg, arg, sizeof( arg ) ); + if( ( arg[0] == 's' || arg[0] == 'S' ) && G_admin_permission( ent, 'k' ) ) + { + ADMP("^3!specme: ^7 You have silently joined the spectators\n"); + return qtrue; + } + } + AP( va("print \"^3!specme: ^7%s^7 decided to join the spectators\n\"", ent->client->pers.netname ) ); return qtrue; } @@ -7122,7 +7133,11 @@ qboolean G_admin_outlaw( gentity_t *ent, int skiparg ) } else { - vic->client->pers.statscounters.spreebleeds = 1; + vic->client->pers.statscounters.spreebleeds = 0; + if( vic->client->pers.bleeder ) + vic->client->pers.bleeder = qfalse; + if( level.bleeders ) + level.bleeders--; AP( va( "print \"^3!outlaw: ^7%s^7 has been pardoned by ^7%s\n\"", vic->client->pers.netname, diff --git a/src/game/g_admin.h b/src/game/g_admin.h index 4863920..ac6b445 100644 --- a/src/game/g_admin.h +++ b/src/game/g_admin.h @@ -32,7 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define ADMBP_end() G_admin_buffer_end(ent) #define MAX_ADMIN_LEVELS 32 -#define MAX_ADMIN_ADMINS 1024 +#define MAX_ADMIN_ADMINS 2048 #define MAX_ADMIN_BANS 1024 #define MAX_ADMIN_NAMELOGS 128 #define MAX_ADMIN_NAMELOG_NAMES 5 diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index e543155..a89dd24 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -3087,20 +3087,18 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance { gentity_t *tent = &g_entities[ entitylist[ i ] ]; - if( tent->s.eType == ET_MOVER && !g_moverBuild.integer ) - { - reason = IBE_NOROOM; - break; - } - - else if( tent->s.eType == ET_PLAYER ) + if( tent->s.eType == ET_PLAYER ) { reason = IBE_NOROOM; break; } else if( tent->biteam != ent->client->ps.stats[ STAT_PTEAM ] ) { - reason = IBE_NOROOM; + if( tent->r.contents == CONTENTS_BODY && tent->s.eType == ET_BUILDABLE) + { + reason = IBE_NOROOM; + break; + } } else if( tent->s.eType == ET_BUILDABLE && !tent->deconstruct ) { @@ -3131,10 +3129,6 @@ itemBuildError_t G_CanBuild( gentity_t *ent, buildable_t buildable, int distance } level.markedBuildables[ level.numBuildablesForRemoval++ ] = tent; } - if( tent->r.contents != MASK_PLAYERSOLID && tent->s.eType != ET_BUILDABLE && ( normal[ 2 ] >= minNormal || ( invert && normal[ 2 ] <= -minNormal ) ) ) - { - reason = IBE_NONE; - } } if( reason != IBE_NONE ) { diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index dbf0537..d0119fc 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -2419,6 +2419,14 @@ void Cmd_CallTeamVote_f( gentity_t *ent ) trap_SendServerCommand( ent-g_entities, "print \"admitdefeat votes are disabled\n\"" ); return; } + if( g_admitDefeatTime.integer > 0 && + level.time - level.startTime < g_admitDefeatTime.integer * 1000 ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"Cannot call an admitdefeat vote before %d:%02d\n\"", + g_admitDefeatTime.integer / 60, g_admitDefeatTime.integer % 60 ) ); + return; + } level.teamVotePercentToPass[ cs_offset ] = g_admitDefeatVotePercent.integer; Com_sprintf( level.teamVoteString[ cs_offset ], sizeof( level.teamVoteString[ cs_offset ] ), "admitdefeat %i", team ); @@ -2844,6 +2852,124 @@ void Cmd_Class_f( gentity_t *ent ) } } +/* +================= +Cmd_Class_f +================= +*/ +void Cmd_Devolve_f( gentity_t *ent ) +{ + int clientNum; + int i; + vec3_t infestOrigin; + int allowedClasses[ PCL_NUM_CLASSES ]; + int numClasses = 0; + pClass_t currentClass = ent->client->ps.stats[ STAT_PCLASS ]; + pClass_t newClass; + int numLevels; + int entityList[ MAX_GENTITIES ]; + vec3_t range = { AS_OVER_RT3, AS_OVER_RT3, AS_OVER_RT3 }; + vec3_t mins, maxs; + int num; + gentity_t *other; + qboolean nearOM = qfalse; + + if( ent->client->ps.stats[ STAT_HEALTH ] <= 0 ) + return; + + if( !g_allowDevolve.integer ) + { + trap_SendServerCommand( ent-g_entities, "print \"Devolve has been disabled\n\"" ); + return; + } + + clientNum = ent->client - level.clients; + + if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) + allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0; + + if( ent->client->pers.teamSelection == PTE_ALIENS && + !( ent->client->ps.stats[ STAT_STATE ] & SS_INFESTING ) && + !( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) ) + { + newClass = PCL_ALIEN_BUILDER0; + + if( !level.overmindPresent ) + { + G_TriggerMenu( clientNum, MN_A_NOOVMND_EVOLVE ); + return; + } + + // Check if near OM + VectorAdd( ent->client->ps.origin, range, maxs ); + VectorSubtract( ent->client->ps.origin, range, mins ); + + num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); + for( i = 0; i < num; i++ ) + { + other = &g_entities[ entityList[ i ] ]; + + if(other->s.eType == ET_BUILDABLE && other->s.modelindex == BA_A_OVERMIND) + { + nearOM = qtrue; + break; + } + } + + //Don't devolve if already a granger + if( !nearOM ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"Must be near the overmind to devolve\n\"" ) ); + return; + } + + if( ( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBING ) || + ( ent->client->ps.stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) + { + trap_SendServerCommand( ent-g_entities, va( "print \"You cannot devolve while wallwalking\n\"" ) ); + return; + } + + //Don't devolve if already a granger + if( currentClass == PCL_ALIEN_BUILDER0 || currentClass == PCL_ALIEN_BUILDER0_UPG ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"You are already a granger!\n\"" ) ); + return; + } + + //Don't devolve if not full health + if( ent->client->ps.stats[ STAT_HEALTH ] != BG_FindHealthForClass( currentClass ) ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"You have to be at full health to devolve\n\"" ) ); + return; + } + + if( G_RoomForClassChange( ent, newClass, infestOrigin ) ) + { + + G_LogOnlyPrintf("ClientTeamClass: %i alien builder\n", clientNum); + + ent->client->pers.evolveHealthFraction = (float)ent->client->ps.stats[ STAT_HEALTH ] / + (float)BG_FindHealthForClass( currentClass ); + + if( ent->client->pers.evolveHealthFraction < 0.0f ) + ent->client->pers.evolveHealthFraction = 0.0f; + else if( ent->client->pers.evolveHealthFraction > 1.0f ) + ent->client->pers.evolveHealthFraction = 1.0f; + + //remove credit + ent->client->pers.classSelection = newClass; + ClientUserinfoChanged( clientNum ); + VectorCopy( infestOrigin, ent->s.pos.trBase ); + ClientSpawn( ent, ent, ent->s.pos.trBase, ent->s.apos.trBase ); + return; + } + } +} + /* ================= DBCommand @@ -5114,7 +5240,8 @@ commands_t cmds[ ] = { { "where", CMD_TEAM, Cmd_Where_f }, { "teamvote", CMD_TEAM, Cmd_TeamVote_f }, { "class", CMD_TEAM, Cmd_Class_f }, - + { "devolve", CMD_TEAM, Cmd_Devolve_f }, + { "build", CMD_TEAM|CMD_LIVING, Cmd_Build_f }, { "deconstruct", CMD_TEAM|CMD_LIVING, Cmd_Destroy_f }, { "mark", CMD_TEAM|CMD_LIVING, Cmd_Mark_f }, diff --git a/src/game/g_combat.c b/src/game/g_combat.c index f664cef..e3c4b87 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -1518,7 +1518,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, } // bleeding spree - if( g_bleedingSpree.integer > 1 ) + if( g_bleedingSpree.integer > 1 && attacker != targ ) { attacker->client->pers.statscounters.spreebleeds += take; if( attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 100 && @@ -1540,9 +1540,9 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, { attacker->client->pers.bleederLastWarn = level.time; trap_SendServerCommand( attacker - g_entities, - "print \"^3Your bleeding is close to aggravating your base!\"" ); + "print \"^3Your bleeding is close to aggravating your base!\n\"" ); trap_SendServerCommand( attacker - g_entities, - "cp \"^1Your bleeding is close to aggravating your base!\n\"" ); + "cp \"^1Your bleeding is close to aggravating your base!\"" ); } } } @@ -1578,6 +1578,13 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, if( attacker->client->pers.statscounters.spreefeeds < 0 ) attacker->client->pers.statscounters.spreefeeds = 0; } + + if( attacker->client->pers.statscounters.spreebleeds > 10 ) + { + attacker->client->pers.statscounters.spreebleeds -= take / 3; + if( attacker->client->pers.statscounters.spreebleeds < 10 ) + attacker->client->pers.statscounters.spreebleeds = 10; + } } else if( targ->client ) { @@ -1598,6 +1605,13 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, if( attacker->client->pers.statscounters.spreefeeds < 0 ) attacker->client->pers.statscounters.spreefeeds = 0; } + + if( attacker->client->pers.statscounters.spreebleeds > 10 ) + { + attacker->client->pers.statscounters.spreebleeds -= take / 3; + if( attacker->client->pers.statscounters.spreebleeds < 10 ) + attacker->client->pers.statscounters.spreebleeds = 10; + } } } diff --git a/src/game/g_local.h b/src/game/g_local.h index b5ecc72..b5f2996 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -1319,6 +1319,7 @@ extern vmCvar_t g_mapRotationVote; extern vmCvar_t g_layoutVotePercent; extern vmCvar_t g_designateVotes; extern vmCvar_t g_admitDefeatVotePercent; +extern vmCvar_t g_admitDefeatTime; extern vmCvar_t g_teamAutoJoin; extern vmCvar_t g_teamForceBalance; extern vmCvar_t g_banIPs; @@ -1467,9 +1468,8 @@ extern vmCvar_t g_AllStats; extern vmCvar_t g_AllStatsTime; extern vmCvar_t g_wwNoHovelBuild; - -extern vmCvar_t g_moverBuild; extern vmCvar_t g_specNoclip; +extern vmCvar_t g_allowDevolve; void trap_Printf( const char *fmt ); void trap_Error( const char *fmt ); diff --git a/src/game/g_main.c b/src/game/g_main.c index e82733e..81a622b 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -95,6 +95,7 @@ vmCvar_t g_mapRotationVote; vmCvar_t g_layoutVotePercent; vmCvar_t g_designateVotes; vmCvar_t g_admitDefeatVotePercent; +vmCvar_t g_admitDefeatTime; vmCvar_t g_teamAutoJoin; vmCvar_t g_teamForceBalance; vmCvar_t g_banIPs; @@ -255,9 +256,8 @@ vmCvar_t g_AllStatsTime; vmCvar_t g_wwNoHovelBuild; -vmCvar_t g_moverBuild; - vmCvar_t g_specNoclip; +vmCvar_t g_allowDevolve; static cvarTable_t gameCvarTable[ ] = @@ -373,6 +373,8 @@ static cvarTable_t gameCvarTable[ ] = { &g_designateVotes, "g_designateVotes", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_admitDefeatVotePercent, "g_admitDefeatVotePercent", "50", CVAR_ARCHIVE, 0, qfalse }, + { &g_admitDefeatTime, "g_admitDefeatTime", "300", CVAR_ARCHIVE, 0, qtrue }, + { &g_listEntity, "g_listEntity", "0", 0, 0, qfalse }, { &g_minCommandPeriod, "g_minCommandPeriod", "500", 0, 0, qfalse}, { &g_minNameChangePeriod, "g_minNameChangePeriod", "5", 0, 0, qfalse}, @@ -497,10 +499,10 @@ static cvarTable_t gameCvarTable[ ] = { &g_wwNoHovelBuild, "g_wwNoHovelBuild", "0", CVAR_ARCHIVE, 0, qfalse }, + { &g_specNoclip, "g_specNoclip", "0", CVAR_ARCHIVE, 0, qtrue }, - { &g_moverBuild, "g_moverBuild", "0", CVAR_ARCHIVE, 0, qfalse }, + { &g_allowDevolve, "g_allowDevolve", "0", CVAR_ARCHIVE, 0, qtrue }, - { &g_specNoclip, "g_specNoclip", "0", CVAR_ARCHIVE, 0, qtrue } }; static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] ); diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index 6c4feed..de49204 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // q_shared.h -- included first by ALL program modules. // A user mod should never modify this file #define PRODUCT_NAME "p-g-qvm" -#define PRODUCT_VERSION "1.6.2" +#define PRODUCT_VERSION "1.6.5" #ifdef SVN_VERSION # define Q3_VERSION PRODUCT_NAME " v" PRODUCT_VERSION " SVN r" SVN_VERSION