summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikko Tiusanen <ams@daug.net>2014-08-19 21:47:12 +0300
committerMikko Tiusanen <ams@daug.net>2014-08-19 21:47:12 +0300
commita7ca0aa8c8a66adce30b8ac21d4849b91e4fc75b (patch)
tree03f08069aaae71ce18dcfd08e32892dd5573977e
parent5618f2bb4b91f4942d6936fdd18b42e354feee9c (diff)
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.
-rw-r--r--src/cgame/cg_scanner.c2
-rw-r--r--src/game/g_buildable.c25
-rw-r--r--src/game/g_cmds.c29
-rw-r--r--src/game/g_local.h1
-rw-r--r--src/game/tremulous.h1
-rw-r--r--src/server/sv_ccmds.c23
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
@@ -5072,6 +5069,28 @@ static void G_LayoutBuildItem( buildable_t buildable, vec3_t origin,
}
/*
+==============
+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++ )