Applied patches for issues

issue 22: Teamvote changes, poll vote fixes
issue 23: Falling out of map breaks spawns
issue 24: Adds messages to !drop
issue 25: Adds extensions to !register
issue 26: Credit overflow

Wiki pages updated as well.
This commit is contained in:
Paradox460 committed 2008-01-24 01:59:10 +00:00
1 parent 148d25a7d5
commit d8cbb160d3
6 files changed
+253 -34

No files matched your search

+64 -10
View File
@@ -111,7 +111,7 @@ g_admin_cmd_t g_admin_cmds[ ] =
{"drop", G_admin_drop, "o",
"kick a client from the server without log",
"[^3name|slot#^7]"
"[^3name|slot#^7] [^3message^7]"
},
{"drug", G_admin_drug, "Q",
@@ -242,7 +242,7 @@ g_admin_cmd_t g_admin_cmds[ ] =
{"register", G_admin_register, "R",
"Registers your name to protect it from being used by others or updates your admin name to your current name.",
""
"[^3level^7] [^3password^7]"
},
{"rename", G_admin_rename, "N",
@@ -3488,17 +3488,59 @@ qboolean G_admin_spec999( gentity_t *ent, int skiparg )
qboolean G_admin_register(gentity_t *ent, int skiparg ){
int level = 0;
int max = 0;
char buffer [ 64 ];
level = G_admin_level(ent);
if( !ent )
{
ADMP( "!register: sorry, but console isn't allowed to register.\n");
return qfalse;
}
if( level == 0 )
level = 1;
level = G_admin_level(ent);
if( G_SayArgc() > 1 + skiparg )
{
G_SayArgv( 1 + skiparg, buffer, sizeof( buffer ) );
max = atoi( buffer );
if( G_SayArgc() > 2 + skiparg )
{
G_SayArgv( 2 + skiparg, buffer, sizeof( buffer ) );
if( g_adminRegisterAdminPass.string[ 0 ] && Q_stricmp( g_adminRegisterAdminPass.string, "none" ) &&
Q_stricmp( g_adminRegisterAdminPass.string, buffer) )
{
ADMP( "Invalid password.\n" );
return qfalse;
}
if (max > g_adminRegisterAdminLevel.integer)
max = g_adminRegisterAdminLevel.integer;
if( level <= g_adminRegisterAdminLevel.integer )
level = max;
}
else
{
if( max > g_adminRegisterLevel.integer )
max = g_adminRegisterLevel.integer;
if( level > 0 &&
level <= g_adminRegisterLevel.integer )
{
level = max;
}
}
if( max < -1 )
max = -1;
}
else
{
if( max == 0 )
max = 1;
}
if( level < max )
level = max;
if( !Q_stricmp( ent->client->pers.guid, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) )
{
@@ -5166,12 +5208,13 @@ qboolean G_admin_drop( gentity_t *ent, int skiparg )
int pids[ MAX_CLIENTS ];
char name[ MAX_NAME_LENGTH ], err[ MAX_STRING_CHARS ];
int minargc;
char msg[ MAX_STRING_CHARS ];
minargc = 2 + skiparg;
if( G_SayArgc() < minargc )
{
ADMP( "^3!drop: ^7usage: !drop [name|slot#]\n" );
ADMP( "^3!drop: ^7usage: !drop [name|slot#] [message]\n" );
return qfalse;
}
G_SayArgv( 1 + skiparg, name, sizeof( name ) );
@@ -5189,11 +5232,22 @@ qboolean G_admin_drop( gentity_t *ent, int skiparg )
" level than you\n" );
return qfalse;
}
minargc = 3 + skiparg;
G_SayArgv( 2 + skiparg, msg, sizeof( msg ) );
//what they get
trap_SendServerCommand( pids[ 0 ], va( "disconnect" ) );
if( G_SayArgc() < minargc )
{
trap_SendServerCommand( pids[ 0 ], va( "disconnected" ) );
}
else
{
trap_SendServerCommand( pids[ 0 ], va( "disconnected \"Disconnected.\n\n%s^7\n\"", msg ) );
}
//what people get
trap_DropClient( pids[ 0 ], va( "disconnect" ) );
trap_DropClient( pids[ 0 ], va( "disconnected" ) );
+103
View File
@@ -79,6 +79,97 @@ void SP_info_human_intermission( gentity_t *ent )
{
}
/*
===============
G_OverflowCredits
===============
*/
void G_OverflowCredits( gclient_t *doner, int credits )
{
int i;
int maxCredits;
int clientNum;
if( !g_creditOverflow.integer )
return;
if( doner->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
{
maxCredits = ALIEN_MAX_KILLS;
clientNum = level.lastCreditedAlien;
}
else if( doner->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
{
maxCredits = HUMAN_MAX_CREDITS;
clientNum = level.lastCreditedHuman;
}
else
{
return;
}
if( g_creditOverflow.integer == 1 )
{
// distribute to everyone on team
gentity_t *vic;
i = 0;
while( credits > 0 && i < level.maxclients )
{
i++;
clientNum++;
if( clientNum >= level.maxclients )
clientNum = 0;
vic = &g_entities[ clientNum ];
if( vic->client->ps.stats[ STAT_PTEAM ] != doner->ps.stats[ STAT_PTEAM ] ||
vic->client->ps.persistant[ PERS_CREDIT ] >= maxCredits )
continue;
if( vic->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
level.lastCreditedAlien = clientNum;
else
level.lastCreditedHuman = clientNum;
if( vic->client->ps.persistant[ PERS_CREDIT ] + credits > maxCredits )
{
credits -= maxCredits - vic->client->ps.persistant[ PERS_CREDIT ];
vic->client->ps.persistant[ PERS_CREDIT ] = maxCredits;
}
else
{
vic->client->ps.persistant[ PERS_CREDIT ] += credits;
return;
}
}
}
else if( g_creditOverflow.integer == 2 )
{
// distribute by team rank
gclient_t *cl;
for( i = 0; i < level.numPlayingClients && credits > 0; i++ )
{
// get the client list sorted by rank
cl = &level.clients[ level.sortedClients[ i ] ];
if( cl->ps.stats[ STAT_PTEAM ] != doner->ps.stats[ STAT_PTEAM ] ||
cl->ps.persistant[ PERS_CREDIT ] >= maxCredits )
continue;
if( cl->ps.persistant[ PERS_CREDIT ] + credits > maxCredits )
{
credits -= maxCredits - cl->ps.persistant[ PERS_CREDIT ];
cl->ps.persistant[ PERS_CREDIT ] = maxCredits;
}
else
{
cl->ps.persistant[ PERS_CREDIT ] += credits;
return;
}
}
}
}
/*
===============
G_AddCreditToClient
@@ -96,13 +187,19 @@ void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap )
{
if( client->ps.persistant[ PERS_CREDIT ] >= ALIEN_MAX_KILLS &&
credit > 0 )
{
G_OverflowCredits( client, credit );
return;
}
}
else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
{
if( client->ps.persistant[ PERS_CREDIT ] >= HUMAN_MAX_CREDITS &&
credit > 0 )
{
G_OverflowCredits( client, credit );
return;
}
}
}
@@ -113,12 +210,18 @@ void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap )
if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
{
if( client->ps.persistant[ PERS_CREDIT ] > ALIEN_MAX_KILLS )
{
G_OverflowCredits( client, client->ps.persistant[ PERS_CREDIT ] - ALIEN_MAX_KILLS );
client->ps.persistant[ PERS_CREDIT ] = ALIEN_MAX_KILLS;
}
}
else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
{
if( client->ps.persistant[ PERS_CREDIT ] > HUMAN_MAX_CREDITS )
{
G_OverflowCredits( client, client->ps.persistant[ PERS_CREDIT ] - HUMAN_MAX_CREDITS );
client->ps.persistant[ PERS_CREDIT ] = HUMAN_MAX_CREDITS;
}
}
}
+30 -6
View File
@@ -1711,15 +1711,20 @@ void Cmd_CallVote_f( gentity_t *ent )
ent->client->pers.voteCount++;
// start the voting, the caller autoamtically votes yes
// start the voting
level.voteTime = level.time;
level.voteYes = 1;
level.voteYes = 0;
level.voteNo = 0;
for( i = 0 ; i < level.maxclients ; i++ )
level.clients[i].ps.eFlags &= ~EF_VOTED;
ent->client->ps.eFlags |= EF_VOTED;
// the caller always votes yes, except for polls
if( Q_stricmp( arg1, "poll" ) )
{
level.voteYes++;
ent->client->ps.eFlags |= EF_VOTED;
}
trap_SetConfigstring( CS_VOTE_TIME, va( "%i", level.voteTime ) );
trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString );
@@ -1861,6 +1866,8 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
trap_SendServerCommand( ent-g_entities, "print \"Invalid team vote string\n\"" );
return;
}
level.teamVotePercentToPass[ cs_offset ] = 50;
// detect clientNum for partial name match votes
if( !Q_stricmp( arg1, "kick" ) ||
@@ -2034,6 +2041,12 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
}
else if( !Q_stricmp( arg1, "admitdefeat" ) )
{
if( !g_admitDefeatVotePercent.integer )
{
trap_SendServerCommand( ent-g_entities, "print \"admitdefeat votes are disabled\n\"" );
return;
}
level.teamVotePercentToPass[ cs_offset ] = g_admitDefeatVotePercent.integer;
Com_sprintf( level.teamVoteString[ cs_offset ],
sizeof( level.teamVoteString[ cs_offset ] ), "admitdefeat %i", team );
Com_sprintf( level.teamVoteDisplayString[ cs_offset ],
@@ -2056,6 +2069,12 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
}
ent->client->pers.voteCount++;
if( level.teamVotePercentToPass[ cs_offset ] != 50 )
{
Q_strcat( level.teamVoteDisplayString[ cs_offset ], sizeof( level.teamVoteDisplayString[ cs_offset ] ),
va( " (Needs %d percent)", level.teamVotePercentToPass[ cs_offset ] ) );
}
for( i = 0 ; i < level.maxclients ; i++ )
{
if( level.clients[ i ].pers.connected == CON_DISCONNECTED )
@@ -2066,9 +2085,9 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
"called a team vote: %s \n\"", ent->client->pers.netname, level.teamVoteDisplayString[ cs_offset ] ) );
}
// start the voting, the caller autoamtically votes yes
// start the voting
level.teamVoteTime[ cs_offset ] = level.time;
level.teamVoteYes[ cs_offset ] = 1;
level.teamVoteYes[ cs_offset ] = 0;
level.teamVoteNo[ cs_offset ] = 0;
for( i = 0 ; i < level.maxclients ; i++ )
@@ -2077,7 +2096,12 @@ void Cmd_CallTeamVote_f( gentity_t *ent )
level.clients[ i ].ps.eFlags &= ~EF_TEAMVOTED;
}
ent->client->ps.eFlags |= EF_TEAMVOTED;
// the caller always votes yes, except for polls
if( Q_stricmp( arg1, "poll" ) )
{
level.teamVoteYes[ cs_offset ]++;
ent->client->ps.eFlags |= EF_TEAMVOTED;
}
trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, va( "%i", level.teamVoteTime[ cs_offset ] ) );
trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, level.teamVoteDisplayString[ cs_offset ] );
+9
View File
@@ -640,6 +640,7 @@ typedef struct
// team voting state
char teamVoteString[ 2 ][ MAX_STRING_CHARS ];
char teamVoteDisplayString[ 2 ][ MAX_STRING_CHARS ];
int teamVotePercentToPass[ 2 ];
int teamVoteTime[ 2 ]; // level.time vote was called
int teamVoteYes[ 2 ];
int teamVoteNo[ 2 ];
@@ -727,6 +728,9 @@ typedef struct
int pause_ff;
int pause_ffb;
int lastCreditedAlien;
int lastCreditedHuman;
int unlaggedIndex;
int unlaggedTimes[ MAX_UNLAGGED_MARKERS ];
@@ -1250,6 +1254,7 @@ extern vmCvar_t g_extendVotesTime;
extern vmCvar_t g_extendVotesCount;
extern vmCvar_t g_mapVotesPercent;
extern vmCvar_t g_designateVotes;
extern vmCvar_t g_admitDefeatVotePercent;
extern vmCvar_t g_teamAutoJoin;
extern vmCvar_t g_teamForceBalance;
extern vmCvar_t g_banIPs;
@@ -1260,6 +1265,7 @@ extern vmCvar_t pmove_fixed;
extern vmCvar_t pmove_msec;
extern vmCvar_t g_rankings;
extern vmCvar_t g_allowShare;
extern vmCvar_t g_creditOverflow;
extern vmCvar_t g_enableDust;
extern vmCvar_t g_enableBreath;
extern vmCvar_t g_singlePlayer;
@@ -1309,6 +1315,9 @@ extern vmCvar_t g_adminSayFilter;
extern vmCvar_t g_adminNameProtect;
extern vmCvar_t g_adminTempBan;
extern vmCvar_t g_adminMapLog;
extern vmCvar_t g_adminRegisterLevel;
extern vmCvar_t g_adminRegisterAdminPass;
extern vmCvar_t g_adminRegisterAdminLevel;
extern vmCvar_t g_minLevelToJoinTeam;
extern vmCvar_t g_minLevelToSpecMM1;
+46 -17
View File
@@ -88,6 +88,7 @@ vmCvar_t g_extendVotesTime;
vmCvar_t g_extendVotesCount;
vmCvar_t g_mapVotesPercent;
vmCvar_t g_designateVotes;
vmCvar_t g_admitDefeatVotePercent;
vmCvar_t g_teamAutoJoin;
vmCvar_t g_teamForceBalance;
vmCvar_t g_banIPs;
@@ -149,6 +150,9 @@ vmCvar_t g_adminSayFilter;
vmCvar_t g_adminNameProtect;
vmCvar_t g_adminTempBan;
vmCvar_t g_adminMapLog;
vmCvar_t g_adminRegisterLevel;
vmCvar_t g_adminRegisterAdminPass;
vmCvar_t g_adminRegisterAdminLevel;
vmCvar_t g_minLevelToJoinTeam;
vmCvar_t g_privateMessages;
@@ -173,6 +177,7 @@ vmCvar_t g_allowActions;
vmCvar_t g_actionPrefix;
vmCvar_t g_allowShare;
vmCvar_t g_creditOverflow;
vmCvar_t g_devmapNoGod;
vmCvar_t g_devmapNoStructDmg;
@@ -270,6 +275,7 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_extendVotesCount, "g_extendVotesCount", "3", CVAR_ARCHIVE, 0, qfalse },
{ &g_mapVotesPercent, "g_mapVotesPercent", "50", CVAR_ARCHIVE, 0, qfalse },
{ &g_designateVotes, "g_designateVotes", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_admitDefeatVotePercent, "g_admitDefeatVotePercent", "50", CVAR_ARCHIVE, 0, qfalse },
{ &g_listEntity, "g_listEntity", "0", 0, 0, qfalse },
{ &g_minCommandPeriod, "g_minCommandPeriod", "500", 0, 0, qfalse},
@@ -330,6 +336,9 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_adminTempBan, "g_adminTempBan", "120", CVAR_ARCHIVE, 0, qfalse },
{ &g_minLevelToJoinTeam, "g_minLevelToJoinTeam", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminMapLog, "g_adminMapLog", "", CVAR_ROM, 0, qfalse },
{ &g_adminRegisterLevel, "g_adminRegisterLevel", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminRegisterAdminPass, "g_adminRegisterAdminPass", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminRegisterAdminLevel, "g_adminRegisterAdminLevel", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_privateMessages, "g_privateMessages", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_radiationDamage, "g_radiationDamage", "1", CVAR_ARCHIVE, 0, qfalse },
@@ -357,6 +366,7 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_rankings, "g_rankings", "0", 0, 0, qfalse },
{ &g_allowShare, "g_allowShare", "1", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse},
{ &g_creditOverflow, "g_creditOverflow", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse},
{ &g_allowActions, "g_allowActions", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_actionPrefix, "g_actionPrefix", "***", CVAR_ARCHIVE, 0, qfalse },
{ &g_banNotice, "g_banNotice", "", CVAR_ARCHIVE, 0, qtrue },
@@ -2187,7 +2197,8 @@ CheckVote
void CheckVote( void )
{
int votePercentToPass=level.votePercentToPass;
int voteYesPercent;
int voteYesPercent = 0;
char *result = "";
if( level.voteExecuteTime && level.voteExecuteTime < level.time )
{
@@ -2213,19 +2224,21 @@ void CheckVote( void )
if( !level.voteTime )
return;
voteYesPercent = (int)(100* (level.voteYes)/(level.voteYes + level.voteNo));
if( level.voteYes || level.voteNo )
{
voteYesPercent = (int)(100* (level.voteYes)/(level.voteYes + level.voteNo));
}
if( level.time - level.voteTime >= VOTE_TIME || ( level.voteYes + level.voteNo == level.numConnectedClients ) )
{
if( voteYesPercent> votePercentToPass || level.voteNo == 0 )
{
// execute the command, then remove the vote
trap_SendServerCommand(-1, va("print \"Vote ^2passed^7 (^2Y:%d^7-^1N:%d^7) [%s]\n\"", level.voteYes, level.voteNo, level.voteDisplayString ));
result = "^2passed";
level.voteExecuteTime = level.time + 3000;
}
else
{
// same behavior as a timeout
trap_SendServerCommand(-1, va("print \"Vote ^1failed^7 (^4Y:%d^7-^1N:%d^7) [%s]\n\"", level.voteYes, level.voteNo, level.voteDisplayString ));
result = "^1failed";
}
}
else
@@ -2233,13 +2246,13 @@ void CheckVote( void )
if( level.voteYes > (int)((double)level.numConnectedClients * ((double)votePercentToPass/100.0)) )
{
// execute the command, then remove the vote
trap_SendServerCommand(-1, va("print \"Vote ^2passed^7 (^2Y:%d^7-^1N:%d^7) [%s]\n\"", level.voteYes, level.voteNo, level.voteDisplayString ));
result = "^2passed";
level.voteExecuteTime = level.time + 3000;
}
else if( level.voteNo > (int)((double)level.numConnectedClients * ((double)(100.0-votePercentToPass)/100.0)) )
{
// same behavior as a timeout
trap_SendServerCommand(-1, va("print \"Vote ^1failed^7 (^2Y:%d^7-^1N:%d^7) [%s]\n\"", level.voteYes, level.voteNo, level.voteDisplayString ));
result = "^1failed";
}
else
{
@@ -2248,6 +2261,9 @@ void CheckVote( void )
}
}
trap_SendServerCommand(-1, va("print \"Vote %s^7 (^2Y:%d^7-^1N:%d^7) [%s]\n\"",
result, level.voteYes, level.voteNo, level.voteDisplayString ) );
level.voteTime = 0;
trap_SetConfigstring( CS_VOTE_TIME, "" );
}
@@ -2261,6 +2277,9 @@ CheckTeamVote
void CheckTeamVote( int team )
{
int cs_offset;
int votePercentToPass;
int voteYesPercent = 0;
char *result = "";
if ( team == PTE_HUMANS )
cs_offset = 0;
@@ -2272,32 +2291,39 @@ void CheckTeamVote( int team )
if( !level.teamVoteTime[ cs_offset ] )
return;
if( level.time - level.teamVoteTime[ cs_offset ] >= VOTE_TIME )
votePercentToPass = level.teamVotePercentToPass[ cs_offset ];
if( level.teamVoteYes[ cs_offset ] || level.teamVoteNo[ cs_offset ] )
{
if( level.teamVoteYes[ cs_offset ] > level.teamVoteNo[ cs_offset ] && level.teamVoteYes[ cs_offset ] >= 2 )
voteYesPercent = (int)(100* (level.teamVoteYes[ cs_offset ])/(level.teamVoteYes[ cs_offset ] + level.teamVoteNo[ cs_offset ]));
}
if( level.time - level.teamVoteTime[ cs_offset ] >= VOTE_TIME ||
level.teamVoteYes[ cs_offset ] + level.teamVoteNo[ cs_offset ] == level.numteamVotingClients[ cs_offset ] )
{
if( voteYesPercent > votePercentToPass &&
level.teamVoteYes[ cs_offset ] + level.teamVoteNo[ cs_offset ] > level.numteamVotingClients[ cs_offset ] / 2 )
{
// execute the command, then remove the vote
trap_SendServerCommand( -1, "print \"Team vote passed\n\"" );
result = "^2passed";
trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.teamVoteString[ cs_offset ] ) );
}
else
{
trap_SendServerCommand( -1, "print \"Team vote failed\n\"" );
{
result = "^1failed";
}
}
else
{
if( level.teamVoteYes[ cs_offset ] > level.numteamVotingClients[ cs_offset ] / 2 )
if( level.teamVoteYes[ cs_offset ] > (int)((double)level.numteamVotingClients[ cs_offset ] * ((double)votePercentToPass/100.0)) )
{
// execute the command, then remove the vote
trap_SendServerCommand( -1, "print \"Team vote passed\n\"" );
//
result = "^2passed";
trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.teamVoteString[ cs_offset ] ) );
}
else if( level.teamVoteNo[ cs_offset ] >= level.numteamVotingClients[ cs_offset ] / 2 )
else if( level.teamVoteNo[ cs_offset ] > (int)((double)level.numteamVotingClients[ cs_offset ] * ((double)(100.0-votePercentToPass)/100.0)) )
{
// same behavior as a timeout
trap_SendServerCommand( -1, "print \"Team vote failed\n\"" );
result = "^1Failed";
}
else
{
@@ -2306,6 +2332,9 @@ void CheckTeamVote( int team )
}
}
trap_SendServerCommand( -1, va( "print \"Team vote %s^7 (^2Y:%d^7-^1N:%d^7)\n\"",
result, level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] ) );
level.teamVoteTime[ cs_offset ] = 0;
trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, "" );
}
+1 -1
View File
@@ -806,7 +806,7 @@ gentity_t *G_ClosestEnt( vec3_t origin, gentity_t **entities, int numEntities )
{
gentity_t *ent = entities[ i ];
if( ( nd = Distance( origin, ent->s.origin ) ) < d )
if( ( nd = Distance( origin, ent->s.origin ) ) < d || !closestEnt )
{
d = nd;
closestEnt = ent;