You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Following other local players (split-screen players) is not allowed by follow command. However it is allowed by team follow1 and team follow2 which can be used for displays at game tournaments.
For tournaments I would expect a separate PC to be used for the players and for showing team follow1/2 to the audience so following local players would not occur.
Following local players is buggy. Player is added twice to all viewports, appears to lag behind the real local player, messes with the sound listener position (higher localPlayerNum sets to either first or third person), and may cause duplicate sounds.
Copying real localPlayer_t's predictedPlayerState and predictedPlayerEntity kind of works but there other data in localPlayer_t that is per-player, like chat lines and showing scoreboard, and lots that is derived from the predictedPlayerState which should be copied.
It's kind of a mess to fix it but I'm not sure what the alternative is for team follow1. It would be odd/confusing to show intermission point if it's a local player. As there would be no indication it's due to being a splitscreen player.
Try anyway
Below is my work-in-progress solution. Though view-height for real player gets messed up on stairs (huh?) and possibly other issues. I'm not planning to continue working on it right now.
Patch
diff--gita/code/cgame/cg_ents.cb/code/cgame/cg_ents.cindex5a02e58e..9cdad9bb100644
@@ -1302,6+1304,9 @@ voidCG_AddPacketEntities( void ) {
if ( cg.localPlayers[num].playerNum==-1 ) {
continue;
}
+if ( cg.localPlayers[num].realLocalPlayer!=num ) {
+continue;
+ }
ps=&cg.localPlayers[num].predictedPlayerState;
BG_PlayerStateToEntityState( ps, &cg.localPlayers[num].predictedPlayerEntity.currentState, qfalse );
CG_AddCEntity( &cg.localPlayers[num].predictedPlayerEntity );
diff--gita/code/cgame/cg_local.hb/code/cgame/cg_local.hindexf5a04937..87fce6bf100644---a/code/cgame/cg_local.h+++b/code/cgame/cg_local.h
@@ -543,6+543,8 @@ typedefstruct {
intplayerNum;
+intrealLocalPlayer; // for player following another local player+// prediction stateqbooleanhyperspace; // true if prediction has hit a trigger_teleportplayerState_tpredictedPlayerState;
diff--gita/code/cgame/cg_snapshot.cb/code/cgame/cg_snapshot.cindexd8daf4b2..3ffc6f65100644---a/code/cgame/cg_snapshot.c+++b/code/cgame/cg_snapshot.c
@@ -139,7+139,7 @@ ThetransitionpointfromsnaptonextSnaphaspassedstaticvoidCG_TransitionSnapshot( void ) {
centity_t*cent;
snapshot_t*oldFrame;
-inti;
+inti, j;
if ( !cg.snap ) {
CG_Error( "CG_TransitionSnapshot: NULL cg.snap" );
@@ -178,6+178,18 @@ staticvoidCG_TransitionSnapshot( void ) {
if ( cg.snap->playerNums[i] !=-1 ) {
BG_PlayerStateToEntityState( &cg.snap->pss[i], &cg_entities[ cg.snap->pss[i].playerNum ].currentState, qfalse );
cg_entities[ cg.snap->pss[i].playerNum ].interpolate=qfalse;
++cg.localPlayers[i].realLocalPlayer=i;
+if ( cg.snap->pss[i].pm_flags&PMF_FOLLOW ) {
+for ( j=0 ; j<CG_MaxSplitView() ; j++ ) {
+playerState_t*otherPS=&cg.snap->pss[j];
+if ( cg.snap->pss[i].playerNum==otherPS->playerNum&& !( otherPS->pm_flags&PMF_FOLLOW ) ) {
+// this player is following another local player...+cg.localPlayers[i].realLocalPlayer=j;
+break;
+ }
+ }
+ }
}
}
diff--gita/code/cgame/cg_view.cb/code/cgame/cg_view.cindex5cfec5b0..4426f7de100644---a/code/cgame/cg_view.c+++b/code/cgame/cg_view.c
@@ -1133,6+1140,12 @@ voidCG_DrawActiveFrame( intserverTime, stereoFrame_tstereoView, qbooleandemocg.cur_lc=&cg.localPlayers[i];
cg.cur_ps=&cg.snap->pss[i];
+if ( cg.cur_lc->realLocalPlayer!=cg.cur_localPlayerNum ) {
+memcpy( &cg.cur_lc->predictedPlayerState, &cg.localPlayers[cg.cur_lc->realLocalPlayer].predictedPlayerState, sizeof( cg.cur_lc->predictedPlayerState ) );
++memcpy( &cg.cur_lc->predictedPlayerEntity, &cg.localPlayers[cg.cur_lc->realLocalPlayer].predictedPlayerEntity, sizeof( cg.cur_lc->predictedPlayerEntity ) );
+ }
+// decide on third person viewcg.cur_lc->renderingThirdPerson=cg.cur_ps->persistant[PERS_TEAM] !=TEAM_SPECTATOR&& (cg_thirdPerson[cg.cur_localPlayerNum].integer|| (cg.cur_ps->stats[STAT_HEALTH] <= 0) ||cg.cur_lc->cameraOrbit);
@@ -1169,7+1182,9 @@ voidCG_DrawActiveFrame( intserverTime, stereoFrame_tstereoView, qbooleandemoCG_PowerupTimerSounds();
// update audio positions-trap_S_Respatialize( cg.cur_ps->playerNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater, !cg.cur_lc->renderingThirdPerson );
+if ( cg.cur_lc->realLocalPlayer==cg.cur_localPlayerNum ) {
+trap_S_Respatialize( cg.cur_ps->playerNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater, !cg.cur_lc->renderingThirdPerson );
+ }
// make sure the lagometerSample and frame timing isn't done twice when in stereoif ( stereoView!=STEREO_RIGHT&&cg.viewport==0 ) {
diff--gita/code/game/g_active.cb/code/game/g_active.cindexe2c32917..c405fe14100644---a/code/game/g_active.c+++b/code/game/g_active.c
@@ -1064,6+1064,11 @@ voidSpectatorPlayerEndFrame( gentity_t*ent ) {
ent->player->ps=cl->ps;
ent->player->ps.pm_flags |= PMF_FOLLOW;
ent->player->ps.eFlags=flags;
++// ugh, player is following one of their local players+if ( cl->pers.connectionNum==ent->player->pers.connectionNum ) {
+//G_Printf( "GAME FIXME: don't follow one of their local players\n" );+ }
return;
}
}
The text was updated successfully, but these errors were encountered:
Premise
Following other local players (split-screen players) is not allowed by
follow
command. However it is allowed byteam follow1
andteam follow2
which can be used for displays at game tournaments.For tournaments I would expect a separate PC to be used for the players and for showing
team follow1/2
to the audience so following local players would not occur.The issue found by @77ZaRR77.
Hard to fix
Following local players is buggy. Player is added twice to all viewports, appears to lag behind the real local player, messes with the sound listener position (higher localPlayerNum sets to either first or third person), and may cause duplicate sounds.
Copying real
localPlayer_t
'spredictedPlayerState
andpredictedPlayerEntity
kind of works but there other data inlocalPlayer_t
that is per-player, like chat lines and showing scoreboard, and lots that is derived from the predictedPlayerState which should be copied.It's kind of a mess to fix it but I'm not sure what the alternative is for
team follow1
. It would be odd/confusing to show intermission point if it's a local player. As there would be no indication it's due to being a splitscreen player.Try anyway
Below is my work-in-progress solution. Though view-height for real player gets messed up on stairs (huh?) and possibly other issues. I'm not planning to continue working on it right now.
Patch
The text was updated successfully, but these errors were encountered: