diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 806db50fc8..967ddb660a 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -156,6 +156,12 @@ static TArray PredictionPortalSectors_sprev_Backup; static TArray PredictionPortalLinesBackup; static TArray PredictionPortalLines_sprev_Backup; +struct +{ + DVector3 Pos = {}; + int Flags = 0; +} static PredictionViewPosBackup; + // [GRB] Custom player classes TArray PlayerClasses; @@ -1443,6 +1449,14 @@ void P_PredictPlayer (player_t *player) PredictionActorBackupArray.Resize(act->GetClass()->Size); memcpy(PredictionActorBackupArray.Data(), &act->snext, act->GetClass()->Size - ((uint8_t *)&act->snext - (uint8_t *)act)); + // Since this is a DObject it needs to have its fields backed up manually for restore, otherwise any changes + // to it will be permanent while predicting. This is now auto-created on pawns to prevent creation spam. + if (act->ViewPos != nullptr) + { + PredictionViewPosBackup.Pos = act->ViewPos->Offset; + PredictionViewPosBackup.Flags = act->ViewPos->Flags; + } + act->flags &= ~MF_PICKUP; act->flags2 &= ~MF2_PUSHWALL; player->cheats |= CF_PREDICTING; @@ -1580,6 +1594,12 @@ void P_UnPredictPlayer () act->UnlinkFromWorld(&ctx); memcpy(&act->snext, PredictionActorBackupArray.Data(), PredictionActorBackupArray.Size() - ((uint8_t *)&act->snext - (uint8_t *)act)); + if (act->ViewPos != nullptr) + { + act->ViewPos->Offset = PredictionViewPosBackup.Pos; + act->ViewPos->Flags = PredictionViewPosBackup.Flags; + } + // The blockmap ordering needs to remain unchanged, too. // Restore sector links and refrences. // [ED850] This is somewhat of a duplicate of LinkToWorld(), but we need to keep every thing the same, diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index f2d7213f45..fe56805d79 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -179,6 +179,9 @@ class PlayerPawn : Actor override void BeginPlay() { + // Force create this since players can predict. + SetViewPos((0.0, 0.0, 0.0)); + Super.BeginPlay (); ChangeStatNum (STAT_PLAYER); FullHeight = Height;