summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/g_cmds.c71
-rw-r--r--src/game/g_local.h7
-rw-r--r--src/game/g_main.c11
3 files changed, 75 insertions, 14 deletions
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 16e2ecd1..69cc677c 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -1162,7 +1162,8 @@ void Cmd_CallVote_f( gentity_t *ent )
{
char cmd[ MAX_TOKEN_CHARS ],
vote[ MAX_TOKEN_CHARS ],
- arg[ MAX_TOKEN_CHARS ];
+ arg[ MAX_TOKEN_CHARS ],
+ extra[ MAX_TOKEN_CHARS ];
char name[ MAX_NAME_LENGTH ] = "";
char caller[ MAX_NAME_LENGTH ] = "";
char reason[ MAX_TOKEN_CHARS ];
@@ -1175,6 +1176,7 @@ void Cmd_CallVote_f( gentity_t *ent )
trap_Argv( 0, cmd, sizeof( cmd ) );
trap_Argv( 1, vote, sizeof( vote ) );
trap_Argv( 2, arg, sizeof( arg ) );
+ trap_Argv( 3, extra, sizeof( extra ) );
creason = ConcatArgs( 3 );
G_DecolorString( creason, reason, sizeof( reason ) );
@@ -1200,6 +1202,7 @@ void Cmd_CallVote_f( gentity_t *ent )
// protect against the dreaded exploit of '\n'-interpretation inside quotes
if( strchr( arg, '\n' ) || strchr( arg, '\r' ) ||
+ strchr( extra, '\n' ) || strchr( extra, '\r' ) ||
strchr( creason, '\n' ) || strchr( creason, '\r' ) )
{
trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string\n\"" );
@@ -1342,9 +1345,29 @@ void Cmd_CallVote_f( gentity_t *ent )
}
else if( !Q_stricmp( vote, "map_restart" ) )
{
+ restartVotePms_t *p = &v->pms.restart;
+
+ if( arg[ 0 ] )
+ {
+ char map[ MAX_QPATH ];
+ trap_Cvar_VariableStringBuffer( "mapname", map, sizeof( map ) );
+
+ if( !G_LayoutExists( map, arg ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: layout '%s' does not exist for map '%s'\n\"",
+ cmd, arg, map ) );
+ return;
+ }
+ }
+
v->cons = VC_RESTART;
- strcpy( level.voteString[ team ], "restart" );
- strcpy( level.voteDisplayString[ team ], "Restart current map" );
+ p->layout = ( arg[ 0 ] ? G_CopyString( arg ) : NULL );
+
+ Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
+ "restart%s", arg[ 0 ] ? va( ", layout: %s", arg ) : "" );
+ Com_sprintf( level.voteDisplayString[ team ], sizeof( level.voteDisplayString[ team ] ),
+ "Restart the current map%s", arg[ 0 ] ? va( " with layout '%s'", arg ) : "" );
// map_restart comes with a default delay
}
else if( !Q_stricmp( vote, "map" ) )
@@ -1359,24 +1382,35 @@ void Cmd_CallVote_f( gentity_t *ent )
return;
}
+ if( extra[ 0 ] && !G_LayoutExists( arg, extra ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: layout '%s' does not exist for map '%s'\n\"",
+ cmd, extra, arg ) );
+ return;
+ }
+
v->cons = VC_MAP;
p->map = G_CopyString( arg );
+ p->layout = ( extra[ 0 ] ? G_CopyString( extra ) : NULL );
+
Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
- "map: %s", arg );
- Com_sprintf( level.voteDisplayString[ team ],
- sizeof( level.voteDisplayString[ team ] ),
- "Change to map '%s'", arg );
+ "map: %s%s", arg, extra[ 0 ] ? va( ", layout: %s", extra ) : "" );
+ Com_sprintf( level.voteDisplayString[ team ], sizeof( level.voteDisplayString[ team ] ),
+ "Change to map '%s'%s", arg, extra[ 0 ] ? va( " with layout '%s'", extra ) : "" );
level.voteDelay[ team ] = 3000;
}
else if( !Q_stricmp( vote, "nextmap" ) )
{
mapVotePms_t *p = &v->pms.map;
- if( G_MapExists( g_nextMap.string ) )
+ if( G_MapExists( g_nextMap.string ) &&
+ ( !g_nextLayout.string[ 0 ] || G_LayoutExists( g_nextMap.string, g_nextLayout.string ) ) )
{
trap_SendServerCommand( ent-g_entities,
- va( "print \"%s: the next map is already set to '%s'\n\"",
- cmd, g_nextMap.string ) );
+ va( "print \"%s: the next map is already set to '%s'%s\n\"",
+ cmd, g_nextMap.string,
+ g_nextLayout.string[ 0 ] ? va( " with layout '%s'", g_nextLayout.string ) : "" ) );
return;
}
@@ -1388,13 +1422,22 @@ void Cmd_CallVote_f( gentity_t *ent )
return;
}
+ if( extra[ 0 ] && !G_LayoutExists( arg, extra ) )
+ {
+ trap_SendServerCommand( ent-g_entities,
+ va( "print \"%s: layout '%s' does not exist for map '%s'\n\"",
+ cmd, extra, arg ) );
+ return;
+ }
+
v->cons = VC_NEXTMAP;
p->map = G_CopyString( arg );
+ p->layout = ( extra[ 0 ] ? G_CopyString( extra ) : NULL );
+
Com_sprintf( level.voteString[ team ], sizeof( level.voteString[ team ] ),
- "nextmap: %s", arg );
- Com_sprintf( level.voteDisplayString[ team ],
- sizeof( level.voteDisplayString[ team ] ),
- "Set the next map to '%s'", arg );
+ "nextmap: %s%s", arg, extra[ 0 ] ? va( ", layout: %s", extra ) : "" );
+ Com_sprintf( level.voteDisplayString[ team ], sizeof( level.voteDisplayString[ team ] ),
+ "Set the next map to '%s'%s", arg, extra[ 0 ] ? va( " with layout '%s'", extra ) : "" );
}
else if( !Q_stricmp( vote, "draw" ) )
{
diff --git a/src/game/g_local.h b/src/game/g_local.h
index a0a03405..1852c783 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -444,11 +444,18 @@ typedef enum
typedef struct
{
+ char *layout;
+} restartVotePms_t;
+
+typedef struct
+{
char *map;
+ char *layout;
} mapVotePms_t;
typedef union
{
+ restartVotePms_t restart;
mapVotePms_t map;
} votePms_t;
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 4fd2a04e..d91b685d 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -2066,12 +2066,23 @@ void G_ExecuteVote( team_t team )
switch( v->cons )
{
case VC_RESTART:
+ {
+ restartVotePms_t *p = &v->pms.restart;
+ trap_Cvar_Set( "g_nextLayout", p->layout ? p->layout : "" );
+ trap_Cvar_Update( &g_nextLayout );
+ if( p->layout )
+ BG_Free( p->layout );
G_PerformMapRestart();
break;
+ }
case VC_MAP:
case VC_NEXTMAP:
{
mapVotePms_t *p = &v->pms.map;
+ trap_Cvar_Set( "g_nextLayout", p->layout ? p->layout : "" );
+ trap_Cvar_Update( &g_nextLayout );
+ if( p->layout )
+ BG_Free( p->layout );
if( v->cons == VC_NEXTMAP )
{
trap_Cvar_Set( "g_nextMap", p->map );