diff options
| -rw-r--r-- | src/game/g_cmds.c | 71 | ||||
| -rw-r--r-- | src/game/g_local.h | 7 | ||||
| -rw-r--r-- | src/game/g_main.c | 11 | 
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 );  | 
