From f8a0a02075de58dd8c269d9eef80a84c6bea0f15 Mon Sep 17 00:00:00 2001 From: /dev/humancontroller Date: Tue, 7 Feb 2017 10:02:47 +0100 Subject: implement setivo: layout-based overriding of intermission views --- src/game/g_admin.c | 50 ++++++++++++++++++++++++++++ src/game/g_admin.h | 1 + src/game/g_buildable.c | 88 +++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 127 insertions(+), 12 deletions(-) (limited to 'src') 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 -- cgit