diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 33623ad3d8..271ac78afa 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -923,6 +923,8 @@ public: void SetPitch(DAngle p, int fflags); void SetAngle(DAngle ang, int fflags); void SetRoll(DAngle roll, int fflags); + + // These also set CF_INTERPVIEWANGLES for players. void SetViewPitch(DAngle p, int fflags); void SetViewAngle(DAngle ang, int fflags); void SetViewRoll(DAngle roll, int fflags); diff --git a/src/playsim/d_player.h b/src/playsim/d_player.h index 9d1cc54852..6b1888170c 100644 --- a/src/playsim/d_player.h +++ b/src/playsim/d_player.h @@ -122,6 +122,7 @@ typedef enum CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame + CF_INTERPVIEWANGLES = 1 << 15, // [RH] flag for interpolating view angles without interpolating the entire frame CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths. CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either. CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either. diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 7297e5c3ce..1b4684b8cc 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -3473,7 +3473,7 @@ void AActor::SetViewPitch(DAngle p, int fflags) ViewAngles.Pitch = p; if (player != nullptr && (fflags & SPF_INTERPOLATE)) { - player->cheats |= CF_INTERPVIEW; + player->cheats |= CF_INTERPVIEWANGLES; } } @@ -3486,7 +3486,7 @@ void AActor::SetViewAngle(DAngle ang, int fflags) ViewAngles.Yaw = ang; if (player != nullptr && (fflags & SPF_INTERPOLATE)) { - player->cheats |= CF_INTERPVIEW; + player->cheats |= CF_INTERPVIEWANGLES; } } @@ -3499,7 +3499,7 @@ void AActor::SetViewRoll(DAngle r, int fflags) ViewAngles.Roll = r; if (player != nullptr && (fflags & SPF_INTERPOLATE)) { - player->cheats |= CF_INTERPVIEW; + player->cheats |= CF_INTERPVIEWANGLES; } } } diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 038ae89d1d..a1dfb35c20 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -1258,6 +1258,7 @@ void P_PlayerThink (player_t *player) player->original_cmd = cmd->ucmd; // Don't interpolate the view for more than one tic player->cheats &= ~CF_INTERPVIEW; + player->cheats &= ~CF_INTERPVIEWANGLES; player->mo->FloatVar("prevBob") = player->bob; IFVIRTUALPTRNAME(player->mo, NAME_PlayerPawn, PlayerThink) diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 6572d4ed75..1fba01bea2 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -80,6 +80,7 @@ struct InterpolationViewer { DVector3 Pos; DRotator Angles; + DRotator ViewAngles; }; AActor *ViewActor; @@ -539,7 +540,13 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr viewpoint.Angles.Yaw = (oviewangle + deltaangle(oviewangle, nviewangle) * Frac).Normalized180(); viewpoint.Angles.Roll = (iview->Old.Angles.Roll + deltaangle(iview->Old.Angles.Roll, iview->New.Angles.Roll) * Frac).Normalized180(); } - + + // [MR] Apply the view angles as an offset if ABSVIEWANGLES isn't specified. + if (!(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES)) + { + viewpoint.Angles += (!player || (player->cheats & CF_INTERPVIEWANGLES)) ? interpolatedvalue(iview->Old.ViewAngles, iview->New.ViewAngles, Frac) : iview->New.ViewAngles; + } + // Due to interpolation this is not necessarily the same as the sector the camera is in. viewpoint.sector = Level->PointInRenderSubsector(viewpoint.Pos)->sector; bool moved = false; @@ -898,16 +905,10 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor } } - // [MC] Apply the view angles first, which is the offsets. If the absolute isn't desired, - // add the standard angles on top of it. - viewpoint.Angles = viewpoint.camera->ViewAngles; + // [MR] Apply view angles as the viewpoint angles if asked to do so. + iview->New.Angles = !(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES) ? viewpoint.camera->Angles : viewpoint.camera->ViewAngles; + iview->New.ViewAngles = viewpoint.camera->ViewAngles; - if (!(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES)) - { - viewpoint.Angles += viewpoint.camera->Angles; - } - - iview->New.Angles = viewpoint.Angles; if (viewpoint.camera->player != 0) { player = viewpoint.camera->player; diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 9d5bb19aad..d5ed7c4cdc 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -1137,6 +1137,7 @@ enum EPlayerCheats CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame + CF_INTERPVIEWANGLES = 1 << 15, // [RH] flag for interpolating view angles without interpolating the entire frame CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.