From d101df463dc56dc9117b8198e27abf891791421a Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Mon, 30 Dec 2019 13:11:39 -0600 Subject: [PATCH] Added ViewAngle/Pitch/Roll properties to actors. - These are offsets for camera angles that allow turning the camera without affecting aim or movement direction. - Added SPF_VIEW flag for A_SetAngle/Pitch/Roll, which will set the view direction instead of the actor's actual facing direction. - Added ABSVIEWANGLES flag, used to make the view absolute instead of an offset. --- src/playsim/actor.h | 8 +-- src/playsim/d_player.h | 1 - src/playsim/p_actionfunctions.cpp | 12 ++--- src/playsim/p_local.h | 7 +++ src/playsim/p_mobj.cpp | 75 ++++++++++++++++++++------- src/rendering/r_utility.cpp | 12 ++++- src/scripting/thingdef_data.cpp | 1 + src/scripting/vmthunks_actors.cpp | 3 ++ src/utility/namedef.h | 3 ++ wadsrc/static/zscript/actors/actor.zs | 1 + wadsrc/static/zscript/constants.zs | 1 + 11 files changed, 90 insertions(+), 34 deletions(-) diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 06e06b385..8df8b8533 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -412,6 +412,7 @@ enum ActorFlag8 MF8_RETARGETAFTERSLAM = 0x00000080, // Forces jumping to the idle state after slamming into something MF8_RECREATELIGHTS = 0x00000100, // Internal flag that signifies that the light attachments need to be recreated at the MF8_STOPRAILS = 0x00000200, // [MC] Prevent rails from going further if an actor has this flag. + MF8_ABSVIEWANGLES = 0x00000400, // [MC] By default view angle/pitch/roll is an offset. This will make it absolute instead. }; // --- mobj.renderflags --- @@ -840,9 +841,9 @@ public: } // These also set CF_INTERPVIEW for players. - void SetPitch(DAngle p, bool interpolate, bool forceclamp = false); - void SetAngle(DAngle ang, bool interpolate); - void SetRoll(DAngle roll, bool interpolate); + void SetPitch(DAngle p, int fflags); + void SetAngle(DAngle ang, int fflags); + void SetRoll(DAngle roll, int fflags); PClassActor *GetBloodType(int type = 0) const; @@ -956,6 +957,7 @@ public: DAngle SpriteAngle; DAngle SpriteRotation; DRotator Angles; + DRotator ViewAngles; // Offsets for cameras DVector2 Scale; // Scaling values; 1 is normal size double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double. diff --git a/src/playsim/d_player.h b/src/playsim/d_player.h index 3bd6431aa..0d7aeb0ba 100644 --- a/src/playsim/d_player.h +++ b/src/playsim/d_player.h @@ -415,7 +415,6 @@ public: return mo->FloatVar(NAME_ViewHeight); } - void Uncrouch() { if (crouchfactor != 1) diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index b8b3ab7da..fec9a4d25 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -2792,12 +2792,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRefire) // Set actor's angle (in degrees). // //=========================================================================== -enum -{ - SPF_FORCECLAMP = 1, // players always clamp - SPF_INTERPOLATE = 2, -}; - DEFINE_ACTION_FUNCTION(AActor, A_SetAngle) { @@ -2809,7 +2803,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetAngle) AActor *ref = COPY_AAPTR(self, ptr); if (ref != NULL) { - ref->SetAngle(angle, !!(flags & SPF_INTERPOLATE)); + ref->SetAngle(angle, flags); } return 0; } @@ -2833,7 +2827,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetPitch) if (ref != NULL) { - ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE), !!(flags & SPF_FORCECLAMP)); + ref->SetPitch(pitch, flags); } return 0; } @@ -2856,7 +2850,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetRoll) if (ref != NULL) { - ref->SetRoll(roll, !!(flags & SPF_INTERPOLATE)); + ref->SetRoll(roll, flags); } return 0; } diff --git a/src/playsim/p_local.h b/src/playsim/p_local.h index 0c7bb1bc7..16a6f2643 100644 --- a/src/playsim/p_local.h +++ b/src/playsim/p_local.h @@ -217,6 +217,13 @@ enum WARPF WARPF_COPYPITCH = 0x8000, }; +enum SPF +{ + SPF_FORCECLAMP = 1, // players always clamp + SPF_INTERPOLATE = 2, + SPF_VIEW = 4, +}; + enum PCM { PCM_DROPOFF = 1, diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 43367fd67..2ff3d7089 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -367,7 +367,8 @@ void AActor::Serialize(FSerializer &arc) A("spawnorder", SpawnOrder) A("friction", Friction) A("userlights", UserLights) - A("SpriteOffset", SpriteOffset); + A("SpriteOffset", SpriteOffset) + A("viewangles", ViewAngles); } #undef A @@ -3349,9 +3350,9 @@ DEFINE_ACTION_FUNCTION(AActor, SetShade) return 0; } -void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp) +void AActor::SetPitch(DAngle p, int fflags) { - if (player != NULL || forceclamp) + if (player != NULL || fflags & SPF_FORCECLAMP) { // clamp the pitch we set DAngle min, max; @@ -3367,37 +3368,71 @@ void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp) } p = clamp(p, min, max); } - if (p != Angles.Pitch) + + bool view = (fflags & SPF_VIEW); + bool changed = false; + if (view) + { + if (p != ViewAngles.Pitch) + { + ViewAngles.Pitch = p; + changed = true; + } + } + else if (p != Angles.Pitch) { Angles.Pitch = p; - if (player != NULL && interpolate) - { - player->cheats |= CF_INTERPVIEW; - } + changed = true; + } + if (changed && player != nullptr && (fflags & SPF_INTERPOLATE)) + { + player->cheats |= CF_INTERPVIEW; } } -void AActor::SetAngle(DAngle ang, bool interpolate) +void AActor::SetAngle(DAngle ang, int fflags) { - if (ang != Angles.Yaw) + bool view = (fflags & SPF_VIEW); + bool changed = false; + if (view) + { + if (ang != ViewAngles.Yaw) + { + ViewAngles.Yaw = ang; + changed = true; + } + } + else if (ang != Angles.Yaw) { Angles.Yaw = ang; - if (player != NULL && interpolate) - { - player->cheats |= CF_INTERPVIEW; - } + changed = true; + } + if (changed && player != nullptr && (fflags & SPF_INTERPOLATE)) + { + player->cheats |= CF_INTERPVIEW; } } -void AActor::SetRoll(DAngle r, bool interpolate) +void AActor::SetRoll(DAngle r, int fflags) { - if (r != Angles.Roll) + bool view = (fflags & SPF_VIEW); + bool changed = false; + if (view) + { + if (r != ViewAngles.Roll) + { + ViewAngles.Roll = r; + changed = true; + } + } + else if (r != Angles.Roll) { Angles.Roll = r; - if (player != NULL && interpolate) - { - player->cheats |= CF_INTERPVIEW; - } + changed = true; + } + if (changed && player != nullptr && (fflags & SPF_INTERPOLATE)) + { + player->cheats |= CF_INTERPVIEW; } } diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 3445c7ac3..eb39dac39 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -804,7 +804,17 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor viewpoint.sector = viewpoint.camera->Sector; viewpoint.showviewer = false; } - iview->New.Angles = viewpoint.camera->Angles; + + // [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; + + 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/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index c308b00e3..0a147e5af 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -324,6 +324,7 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG(MF8, NOFRICTIONBOUNCE, AActor, flags8), DEFINE_FLAG(MF8, RETARGETAFTERSLAM, AActor, flags8), DEFINE_FLAG(MF8, STOPRAILS, AActor, flags8), + DEFINE_FLAG(MF8, ABSVIEWANGLES, AActor, flags8), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), diff --git a/src/scripting/vmthunks_actors.cpp b/src/scripting/vmthunks_actors.cpp index 176d3be19..6cabf7adf 100644 --- a/src/scripting/vmthunks_actors.cpp +++ b/src/scripting/vmthunks_actors.cpp @@ -1902,6 +1902,9 @@ DEFINE_FIELD(AActor, RenderRequired) DEFINE_FIELD(AActor, friendlyseeblocks) DEFINE_FIELD(AActor, SpawnTime) DEFINE_FIELD(AActor, InventoryID) +DEFINE_FIELD_NAMED(AActor, ViewAngles.Yaw, viewangle) +DEFINE_FIELD_NAMED(AActor, ViewAngles.Pitch, viewpitch) +DEFINE_FIELD_NAMED(AActor, ViewAngles.Roll, viewroll) DEFINE_FIELD_X(FCheckPosition, FCheckPosition, thing); DEFINE_FIELD_X(FCheckPosition, FCheckPosition, pos); diff --git a/src/utility/namedef.h b/src/utility/namedef.h index c0d5f82d3..37fbda018 100644 --- a/src/utility/namedef.h +++ b/src/utility/namedef.h @@ -1062,6 +1062,9 @@ xx(AttackZOffset) xx(SpawnMask) xx(ScoreIcon) xx(ViewHeight) +xx(ViewAngle) +xx(ViewPitch) +xx(ViewRoll) xx(FallingScreamMinSpeed) xx(FallingScreamMaxSpeed) xx(GruntSpeed) diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 672746158..37a86a1ad 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -232,6 +232,7 @@ class Actor : Thinker native native uint8 fountaincolor; native double CameraHeight; // Height of camera when used as such native double CameraFOV; + native double ViewAngle, ViewPitch, ViewRoll; native double RadiusDamageFactor; // Radius damage factor native double SelfDamageFactor; native double StealthAlpha; diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 8c91efb09..0bb65366e 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -542,6 +542,7 @@ enum EAngleFlags { SPF_FORCECLAMP = 1, SPF_INTERPOLATE = 2, + SPF_VIEW = 4, }; // flags for A_CheckLOF