Skip to content

Commit

Permalink
improved spectator navigation
Browse files Browse the repository at this point in the history
Use new method to allow spectators to pass through entities such as doors without the potential to get stuck.
  • Loading branch information
Chomenor committed Apr 27, 2022
1 parent d890394 commit 81c9df8
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/msvc_2019/game.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@
<ClCompile Include="..\..\code\game\g_weapon.c" />
<ClCompile Include="..\..\code\game\mods\features\feature_altswap_handler.c" />
<ClCompile Include="..\..\code\game\mods\features\feature_player_move.c" />
<ClCompile Include="..\..\code\game\mods\features\feature_spect_passthrough.c" />
<ClCompile Include="..\..\code\game\mods\features\pingcomp\pc_client_predict.c" />
<ClCompile Include="..\..\code\game\mods\features\pingcomp\pc_dead_move.c" />
<ClCompile Include="..\..\code\game\mods\features\pingcomp\pc_instant_weapons.c" />
Expand Down
3 changes: 3 additions & 0 deletions build/msvc_2019/game.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@
<ClCompile Include="..\..\code\game\mods\features\feature_player_move.c">
<Filter>game\mods\features</Filter>
</ClCompile>
<ClCompile Include="..\..\code\game\mods\features\feature_spect_passthrough.c">
<Filter>game\mods\features</Filter>
</ClCompile>
<ClCompile Include="..\..\code\game\mods\features\pingcomp\pc_client_predict.c">
<Filter>game\mods\features\pingcomp</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions build/qvm_build/build_game.bat
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ set src=game\mods&set name=g_mod_stubs&call :compile
set src=game\mods&set name=g_mod_utils&call :compile
set src=game\mods\features&set name=feature_altswap_handler&call :compile
set src=game\mods\features&set name=feature_player_move&call :compile
set src=game\mods\features&set name=feature_spect_passthrough&call :compile
set src=game\mods\features\pingcomp&set name=pc_client_predict&call :compile
set src=game\mods\features\pingcomp&set name=pc_dead_move&call :compile
set src=game\mods\features\pingcomp&set name=pc_instant_weapons&call :compile
Expand Down
4 changes: 4 additions & 0 deletions code/game/g_mover.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,10 @@ static void Touch_DoorTriggerSpectator( gentity_t *ent, gentity_t *other, trace_
int i, axis;
vec3_t origin, dir, angles;

if ( modfn.AdjustGeneralConstant( GC_SKIP_SPECTATOR_DOOR_TELEPORT, 0 ) ) {
return;
}

axis = ent->count;
VectorClear(dir);
if (fabs(other->s.origin[axis] - ent->r.absmax[axis]) <
Expand Down
97 changes: 97 additions & 0 deletions code/game/mods/features/feature_spect_passthrough.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Spectator Pass-Through
*
* This module changes free-roaming spectator behavior to allow clipping through all dynamic
* entities. It replaces the standard method of auto-teleporting through doors, which is very
* unreliable and prone to getting stuck.
*/

#include "mods/g_mod_local.h"

#define PREFIX( x ) ModSpectPassThrough_##x
#define MOD_STATE PREFIX( state )

static struct {
void ( *Prev_Trace )( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs,
const vec3_t end, int passEntityNum, int contentMask );

// For mod function stacking
ModFNType_PmoveInit Prev_PmoveInit;
ModFNType_AdjustGeneralConstant Prev_AdjustGeneralConstant;
} *MOD_STATE;

/*
================
ModSpectPassThrough_Trace
Trace with entities ignored so everything except the main map is pass-through.
================
*/
static void ModSpectPassThrough_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs,
const vec3_t end, int passEntityNum, int contentMask ) {
int entityNum;
MOD_STATE->Prev_Trace( results, start, mins, maxs, end, passEntityNum, contentMask );
entityNum = results->entityNum;

if ( entityNum >= 0 && entityNum < ENTITYNUM_MAX_NORMAL && EF_WARN_ASSERT( g_entities[entityNum].r.contents ) ) {
// Repeat trace with contacted entity temporarily set to empty contents.
int oldContents = g_entities[entityNum].r.contents;
g_entities[entityNum].r.contents = 0;
ModSpectPassThrough_Trace( results, start, mins, maxs, end, passEntityNum, contentMask );
g_entities[entityNum].r.contents = oldContents;
}
}

/*
================
(ModFN) PmoveInit
Override trace function for spectators.
================
*/
LOGFUNCTION_SVOID( PREFIX(PmoveInit), ( int clientNum, pmove_t *pmove ),
( clientNum, pmove ), "G_MODFN_PMOVEINIT" ) {
const gclient_t *client = &level.clients[clientNum];

MOD_STATE->Prev_PmoveInit( clientNum, pmove );

if ( client->sess.sessionTeam == TEAM_SPECTATOR || ( client->ps.eFlags & EF_ELIMINATED ) ) {
MOD_STATE->Prev_Trace = pmove->trace;
pmove->trace = ModSpectPassThrough_Trace;
}
}

/*
================
(ModFN) AdjustGeneralConstant
================
*/
int PREFIX(AdjustGeneralConstant)( generalConstant_t gcType, int defaultValue ) {
if ( gcType == GC_SKIP_SPECTATOR_DOOR_TELEPORT ) {
return 1;
}

return MOD_STATE->Prev_AdjustGeneralConstant( gcType, defaultValue );
}

/*
================
ModSpectPassThrough_Init
================
*/

#define INIT_FN_STACKABLE( name ) \
MOD_STATE->Prev_##name = modfn.name; \
modfn.name = PREFIX(name);

#define INIT_FN_OVERRIDE( name ) \
modfn.name = PREFIX(name);

LOGFUNCTION_VOID( ModSpectPassThrough_Init, ( void ), (), "G_MOD_INIT" ) {
if ( !MOD_STATE ) {
MOD_STATE = G_Alloc( sizeof( *MOD_STATE ) );

INIT_FN_STACKABLE( PmoveInit );
INIT_FN_STACKABLE( AdjustGeneralConstant );
}
}
1 change: 1 addition & 0 deletions code/game/mods/g_mod_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ int G_ModUtils_GetLatchedValue( const char *cvar_name, const char *default_value
void ModAltSwapHandler_Init( void );
void ModPingcomp_Init( void );
void ModPlayerMove_Init( void );
void ModSpectPassThrough_Init( void );

//
// Ping Compensation (pc_main.c)
Expand Down
1 change: 1 addition & 0 deletions code/game/mods/g_mod_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ LOGFUNCTION_VOID( G_ModsInit, ( void ), (), "G_MOD_INIT" ) {
ModPlayerMove_Init();
ModAltSwapHandler_Init();
ModPingcomp_Init();
ModSpectPassThrough_Init();
}
}
1 change: 1 addition & 0 deletions code/game/mods/g_mod_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ typedef enum {
GC_NONE,
GC_SKIP_RUN_MISSILE,
GC_EVENT_TIME_OFFSET,
GC_SKIP_SPECTATOR_DOOR_TELEPORT,
} generalConstant_t;

typedef enum {
Expand Down

0 comments on commit 81c9df8

Please sign in to comment.