* 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)
This commit is contained in:
1 parent
2e5b254639
commit
49e3c15ae0
8 files changed
+187
-35
No files matched your search
+26
-11
@@ -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,
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+6
-12
@@ -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 )
|
||||
{
|
||||
|
||||
+128
-1
@@ -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 },
|
||||
|
||||
+17
-3
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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 );
|
||||
|
||||
+6
-4
@@ -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 ] );
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user