From a7ca0aa8c8a66adce30b8ac21d4849b91e4fc75b Mon Sep 17 00:00:00 2001 From: Mikko Tiusanen Date: Tue, 19 Aug 2014 21:47:12 +0300 Subject: Added support for selecting layout with map vote. Removed outdated comments and moved trapper accuracy to tremulous header. Disabled map votes during first minute even when there's only one player connected. --- src/cgame/cg_scanner.c | 2 +- src/game/g_buildable.c | 25 ++++++++++++++++++++++--- src/game/g_cmds.c | 29 ++++++++++++++++++++++------- src/game/g_local.h | 1 + src/game/tremulous.h | 1 + src/server/sv_ccmds.c | 23 +++++++++++++++++++++++ 6 files changed, 70 insertions(+), 11 deletions(-) diff --git a/src/cgame/cg_scanner.c b/src/cgame/cg_scanner.c index ad3d47d..43348b3 100644 --- a/src/cgame/cg_scanner.c +++ b/src/cgame/cg_scanner.c @@ -57,7 +57,7 @@ void CG_UpdateEntityPositions( void ) for( i = 0; i < cg.snap->numEntities; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; - //make adv basilisk invisble to human helmet if invisble + if( cent->currentState.eType == ET_BUILDABLE && !( cent->currentState.eFlags & EF_DEAD )) { diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index 3783053..61a3460 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -2091,9 +2091,6 @@ void HNone_Think( gentity_t *self ) self->nextthink = level.time + 1000; } - -#define TRAPPER_ACCURACY 9 // lower is better - /* ================ ATrapper_FireOnEnemy @@ -5071,6 +5068,28 @@ static void G_LayoutBuildItem( buildable_t buildable, vec3_t origin, G_SpawnBuildable( builder, buildable ); } +/* +============== +G_LayoutExists + +Check if a layout with the given name exists for the given map. +============== +*/ +qboolean G_LayoutExists( char *mapName, char *layoutName ) +{ + fileHandle_t f; + int len; + if( !layoutName[ 0 ] || !Q_stricmp( layoutName, "*BUILTIN*" ) ) + return qtrue; + + len = trap_FS_FOpenFile( va( "layouts/%s/%s.dat", mapName, layoutName ), &f, FS_READ ); + if( len < 0 ) + return qfalse; + + trap_FS_FCloseFile( f ); + return qtrue; +} + /* ============ G_LayoutLoad diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index f876553..77c6f82 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1426,8 +1426,7 @@ void Cmd_CallVote_f( gentity_t *ent ) } else if( !Q_stricmp( vote, "map" ) ) { - if( (( level.time - level.startTime ) < 60 * 1000 ) - && ( level.numPlayingClients > 0 && level.numConnectedClients > 1 ) ) + if( (( level.time - level.startTime ) < 60 * 1000 ) ) { trap_SendServerCommand( ent-g_entities, "print \"You cannot call for a map change in the first minute.\n\"" ); return; @@ -1449,11 +1448,27 @@ void Cmd_CallVote_f( gentity_t *ent ) return; } - Com_sprintf( level.voteString[ team ], sizeof( level.voteString ), - "%s \"%s\"", vote, arg ); - Com_sprintf( level.voteDisplayString[ team ], - sizeof( level.voteDisplayString[ team ] ), - "Change to map '%s'", arg ); + if( reason[0] ) + { + if( !G_LayoutExists( arg, reason ) ) + { + trap_SendServerCommand( ent-g_entities, + va( "print \"%s: 'layouts/%s/%s.dat' could not be found on the server\n\"", + cmd, arg, reason ) ); + return; + } + Com_sprintf( level.voteString[ team ], sizeof( level.voteString ), + "%s \"%s\" \"%s\"", vote, arg, reason ); + Com_sprintf( level.voteDisplayString[ team ], + sizeof( level.voteDisplayString[ team ] ), + "Change to map '%s' (layout: '%s')", arg, reason ); + } else { + Com_sprintf( level.voteString[ team ], sizeof( level.voteString ), + "%s \"%s\"", vote, arg ); + Com_sprintf( level.voteDisplayString[ team ], + sizeof( level.voteDisplayString[ team ] ), + "Change to map '%s'", arg ); + } level.voteDelay[ team ] = 3000; } else if( !Q_stricmp( vote, "nextmap" ) ) diff --git a/src/game/g_local.h b/src/game/g_local.h index 37971ed..2683ac5 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -834,6 +834,7 @@ void FinishSpawningBuildable( gentity_t *ent ); void G_LayoutSave( char *name ); int G_LayoutList( const char *map, char *list, int len ); void G_LayoutSelect( void ); +qboolean G_LayoutExists( char *mapName, char *layoutName ); void G_LayoutLoad( void ); void G_BaseSelfDestruct( team_t team ); int G_NextQueueTime( int queuedBP, int totalBP, int queueBaseRate ); diff --git a/src/game/tremulous.h b/src/game/tremulous.h index 40c0823..f76f968 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -694,6 +694,7 @@ TREMULOUS EDGE MOD SRC FILE #define LOCKBLOB_LOCKTIME 5000 #define LOCKBLOB_DOT 0.85f // max angle = acos( LOCKBLOB_DOT ) #define LOCKBLOB_K_SCALE 1.0f +#define TRAPPER_ACCURACY 9 // lower is better #define OVERMIND_BP 0 #define OVERMIND_BT 30000 diff --git a/src/server/sv_ccmds.c b/src/server/sv_ccmds.c index 8e76fa1..bfcc75c 100644 --- a/src/server/sv_ccmds.c +++ b/src/server/sv_ccmds.c @@ -42,9 +42,11 @@ Restart the server on a different map static void SV_Map_f( void ) { char *cmd; char *map; + char *layout; qboolean killBots, cheat; char expanded[MAX_QPATH]; char mapname[MAX_QPATH]; + char layoutname[MAX_QPATH]; int i; map = Cmd_Argv(1); @@ -73,6 +75,23 @@ static void SV_Map_f( void ) { // and thus nuke the arguments of the map command Q_strncpyz(mapname, map, sizeof(mapname)); + // save the layout name as well + if ( Cmd_Argc() > 2 ) { + layout = Cmd_Argv(2); + if( Q_stricmp( layout, "" ) ) { + Com_sprintf (expanded, sizeof(expanded), "layouts/%s/%s.dat", map, layout); + if ( FS_ReadFile (expanded, NULL) == -1 ) { + Com_Printf ("Can't find layout %s\n", expanded); + return; + } + Q_strncpyz(layoutname, layout, sizeof(layoutname)); + } else { + layoutname[0] = '\0'; + } + } else { + layoutname[0] = '\0'; + } + // start up the map SV_SpawnServer( mapname, killBots ); @@ -86,6 +105,10 @@ static void SV_Map_f( void ) { Cvar_Set( "sv_cheats", "0" ); } + if ( layoutname[0] ) { + Cvar_Set( "g_layouts", layoutname ); + } + // This forces the local master server IP address cache // to be updated on sending the next heartbeat for( i = 0; i < MAX_MASTER_SERVERS; i++ ) -- cgit