summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
author/dev/humancontroller <devhc@example.com>2017-02-07 10:02:47 +0100
committer/dev/humancontroller <devhc@example.com>2017-03-09 13:51:16 +0100
commitf8a0a02075de58dd8c269d9eef80a84c6bea0f15 (patch)
treeb74fc75914d2377b39d15da80c9cedc508693011 /src/game
parentec2f1dc2f6444d33f3d112be486e9d7675358bd6 (diff)
implement setivo: layout-based overriding of intermission views
Diffstat (limited to 'src/game')
-rw-r--r--src/game/g_admin.c50
-rw-r--r--src/game/g_admin.h1
-rw-r--r--src/game/g_buildable.c88
3 files changed, 127 insertions, 12 deletions
diff --git a/src/game/g_admin.c b/src/game/g_admin.c
index 18f317d4..2f364fb5 100644
--- a/src/game/g_admin.c
+++ b/src/game/g_admin.c
@@ -189,6 +189,11 @@ g_admin_cmd_t g_admin_cmds[ ] =
"[^3on|off^7]"
},
+ {"setivo", G_admin_setivo, qfalse, "setivo",
+ "set an intermission view override",
+ "[^3s|a|h^7]"
+ },
+
{"setlevel", G_admin_setlevel, qfalse, "setlevel",
"sets the admin level of a player",
"[^3name|slot#|admin#^7] [^3level^7]"
@@ -1649,6 +1654,51 @@ qboolean G_admin_kick( gentity_t *ent )
return qtrue;
}
+qboolean G_admin_setivo( gentity_t* ent )
+{
+ char arg[ 3 ];
+ const char *cn;
+ gentity_t *spot;
+
+ if( !ent )
+ {
+ ADMP( "^3setivo: ^7the console can't position intermission view overrides\n" );
+ return qfalse;
+ }
+
+ if( trap_Argc() != 2 )
+ {
+ ADMP( "^3setivo: ^7usage: setivo {s|a|h}\n" );
+ return qfalse;
+ }
+ trap_Argv( 1, arg, sizeof( arg ) );
+ if( !Q_stricmp( arg, "s" ) )
+ cn = "info_player_intermission";
+ else if( !Q_stricmp( arg, "a" ) )
+ cn = "info_alien_intermission";
+ else if( !Q_stricmp( arg, "h" ) )
+ cn = "info_human_intermission";
+ else
+ {
+ ADMP( "^3setivo: ^7the argument must be either s, a or h\n" );
+ return qfalse;
+ }
+
+ spot = G_Find( NULL, FOFS( classname ), cn );
+ if( !spot )
+ {
+ spot = G_Spawn();
+ spot->classname = (char *)cn;
+ }
+ spot->count = 1;
+
+ BG_GetClientViewOrigin( &ent->client->ps, spot->r.currentOrigin );
+ VectorCopy( ent->client->ps.viewangles, spot->r.currentAngles );
+
+ ADMP( "^3setivo: ^7intermission view override positioned\n" );
+ return qtrue;
+}
+
qboolean G_admin_ban( gentity_t *ent )
{
int seconds;
diff --git a/src/game/g_admin.h b/src/game/g_admin.h
index fd9f6b26..a018ea81 100644
--- a/src/game/g_admin.h
+++ b/src/game/g_admin.h
@@ -158,6 +158,7 @@ qboolean G_admin_time( gentity_t *ent );
qboolean G_admin_setlevel( gentity_t *ent );
qboolean G_admin_kick( gentity_t *ent );
qboolean G_admin_addlayout( gentity_t *ent );
+qboolean G_admin_setivo( gentity_t *ent );
qboolean G_admin_adjustban( gentity_t *ent );
qboolean G_admin_ban( gentity_t *ent );
qboolean G_admin_unban( gentity_t *ent );
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index dd984d33..c221af13 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -3974,13 +3974,25 @@ void G_ParseCSVBuildablePlusList( const char *string, int *buildables, int build
buildable_t b;
for( b = BA_A_SPAWN; b <= BA_A_HIVE && i < buildablesSize - 1; ++b )
buildables[ i++ ] = b;
+
+ if( i < buildablesSize - 1 )
+ buildables[ i++ ] = BA_NUM_BUILDABLES + TEAM_ALIENS;
}
else if( !Q_stricmp( q, "human" ) )
{
buildable_t b;
for( b = BA_H_SPAWN; b <= BA_H_REPEATER && i < buildablesSize - 1; ++b )
buildables[ i++ ] = b;
+
+ if( i < buildablesSize - 1 )
+ buildables[ i++ ] = BA_NUM_BUILDABLES + TEAM_HUMANS;
}
+ else if( !Q_stricmp( q, "ivo_spectator" ) )
+ buildables[ i++ ] = BA_NUM_BUILDABLES + TEAM_NONE;
+ else if( !Q_stricmp( q, "ivo_alien" ) )
+ buildables[ i++ ] = BA_NUM_BUILDABLES + TEAM_ALIENS;
+ else if( !Q_stricmp( q, "ivo_human" ) )
+ buildables[ i++ ] = BA_NUM_BUILDABLES + TEAM_HUMANS;
else
{
buildables[ i ] = BG_BuildableByName( q )->number;
@@ -4010,7 +4022,7 @@ G_LayoutSave
void G_LayoutSave( char *lstr )
{
char *lstrPipePtr;
- qboolean bAllowed[ BA_NUM_BUILDABLES ];
+ qboolean bAllowed[ BA_NUM_BUILDABLES + NUM_TEAMS ];
char map[ MAX_QPATH ];
char fileName[ MAX_OSPATH ];
fileHandle_t f;
@@ -4028,7 +4040,7 @@ void G_LayoutSave( char *lstr )
if( ( lstrPipePtr = strchr( lstr, '|' ) ) )
{
- int bList[ BA_NUM_BUILDABLES ];
+ int bList[ BA_NUM_BUILDABLES + NUM_TEAMS ];
*lstrPipePtr = '\0';
G_ParseCSVBuildablePlusList( lstrPipePtr + 1, &bList[ 0 ], sizeof( bList ) / sizeof( bList[ 0 ] ) );
memset( bAllowed, 0, sizeof( bAllowed ) );
@@ -4037,7 +4049,7 @@ void G_LayoutSave( char *lstr )
}
else
{
- for( i = 0; i < BA_NUM_BUILDABLES; i++ )
+ for( i = 0; i < BA_NUM_BUILDABLES + NUM_TEAMS; i++ )
bAllowed[ i ] = qtrue;
}
@@ -4057,15 +4069,38 @@ void G_LayoutSave( char *lstr )
for( i = MAX_CLIENTS; i < level.num_entities; i++ )
{
- ent = &level.gentities[ i ];
- if( ent->s.eType != ET_BUILDABLE )
- continue;
+ const char *name;
- if( !bAllowed[ ent->s.modelindex ] )
+ ent = &level.gentities[ i ];
+ if( ent->s.eType == ET_BUILDABLE )
+ {
+ if( !bAllowed[ ent->s.modelindex ] )
+ continue;
+ name = BG_Buildable( ent->s.modelindex )->name;
+ }
+ else if( ent->count == 1 && !strcmp( ent->classname, "info_player_intermission" ) )
+ {
+ if( !bAllowed[ BA_NUM_BUILDABLES + TEAM_NONE ] )
+ continue;
+ name = "ivo_spectator";
+ }
+ else if( ent->count == 1 && !strcmp( ent->classname, "info_alien_intermission" ) )
+ {
+ if( !bAllowed[ BA_NUM_BUILDABLES + TEAM_ALIENS ] )
+ continue;
+ name = "ivo_alien";
+ }
+ else if( ent->count == 1 && !strcmp( ent->classname, "info_human_intermission" ) )
+ {
+ if( !bAllowed[ BA_NUM_BUILDABLES + TEAM_HUMANS ] )
+ continue;
+ name = "ivo_human";
+ }
+ else
continue;
s = va( "%s %f %f %f %f %f %f %f %f %f %f %f %f\n",
- BG_Buildable( ent->s.modelindex )->name,
+ name,
ent->r.currentOrigin[ 0 ],
ent->r.currentOrigin[ 1 ],
ent->r.currentOrigin[ 2 ],
@@ -4228,6 +4263,20 @@ static void G_LayoutBuildItem( buildable_t buildable, vec3_t origin,
G_SpawnBuildable( builder, buildable );
}
+static void G_SpawnIntermissionViewOverride( char *cn, vec3_t origin, vec3_t angles )
+{
+ gentity_t *spot = G_Find( NULL, FOFS( classname ), cn );
+ if( !spot )
+ {
+ spot = G_Spawn();
+ spot->classname = cn;
+ }
+ spot->count = 1;
+
+ VectorCopy( origin, spot->r.currentOrigin );
+ VectorCopy( angles, spot->r.currentAngles );
+}
+
/*
============
G_LayoutLoad
@@ -4236,7 +4285,7 @@ G_LayoutLoad
void G_LayoutLoad( char *lstr )
{
char *lstrPlusPtr, *lstrPipePtr;
- qboolean bAllowed[ BA_NUM_BUILDABLES ];
+ qboolean bAllowed[ BA_NUM_BUILDABLES + NUM_TEAMS ];
fileHandle_t f;
int len;
char *layout, *layoutHead;
@@ -4260,7 +4309,7 @@ void G_LayoutLoad( char *lstr )
if( ( lstrPipePtr = strchr( lstr, '|' ) ) )
{
- int bList[ BA_NUM_BUILDABLES ];
+ int bList[ BA_NUM_BUILDABLES + NUM_TEAMS ];
*lstrPipePtr = '\0';
G_ParseCSVBuildablePlusList( lstrPipePtr + 1, &bList[ 0 ], sizeof( bList ) / sizeof( bList[ 0 ] ) );
memset( bAllowed, 0, sizeof( bAllowed ) );
@@ -4269,7 +4318,7 @@ void G_LayoutLoad( char *lstr )
}
else
{
- for( i = 0; i < BA_NUM_BUILDABLES; i++ )
+ for( i = 0; i < BA_NUM_BUILDABLES + NUM_TEAMS; i++ )
bAllowed[ i ] = qtrue;
}
@@ -4307,7 +4356,22 @@ void G_LayoutLoad( char *lstr )
&angles2[ 0 ], &angles2[ 1 ], &angles2[ 2 ] );
buildable = BG_BuildableByName( buildName )->number;
- if( buildable <= BA_NONE || buildable >= BA_NUM_BUILDABLES )
+ if( !Q_stricmp( buildName, "ivo_spectator" ) )
+ {
+ if( bAllowed[ BA_NUM_BUILDABLES + TEAM_NONE ] )
+ G_SpawnIntermissionViewOverride( "info_player_intermission", origin, angles );
+ }
+ else if( !Q_stricmp( buildName, "ivo_alien" ) )
+ {
+ if( bAllowed[ BA_NUM_BUILDABLES + TEAM_ALIENS ] )
+ G_SpawnIntermissionViewOverride( "info_alien_intermission", origin, angles );
+ }
+ else if( !Q_stricmp( buildName, "ivo_human" ) )
+ {
+ if( bAllowed[ BA_NUM_BUILDABLES + TEAM_HUMANS ] )
+ G_SpawnIntermissionViewOverride( "info_human_intermission", origin, angles );
+ }
+ else if( buildable <= BA_NONE || buildable >= BA_NUM_BUILDABLES )
G_Printf( S_COLOR_YELLOW "WARNING: bad buildable name (%s) in layout."
" skipping\n", buildName );
else