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.
This commit is contained in:
Major Cooke 2019-12-30 13:11:39 -06:00
parent db3b296dfa
commit d101df463d
11 changed files with 90 additions and 34 deletions

View file

@ -412,6 +412,7 @@ enum ActorFlag8
MF8_RETARGETAFTERSLAM = 0x00000080, // Forces jumping to the idle state after slamming into something 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_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_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 --- // --- mobj.renderflags ---
@ -840,9 +841,9 @@ public:
} }
// These also set CF_INTERPVIEW for players. // These also set CF_INTERPVIEW for players.
void SetPitch(DAngle p, bool interpolate, bool forceclamp = false); void SetPitch(DAngle p, int fflags);
void SetAngle(DAngle ang, bool interpolate); void SetAngle(DAngle ang, int fflags);
void SetRoll(DAngle roll, bool interpolate); void SetRoll(DAngle roll, int fflags);
PClassActor *GetBloodType(int type = 0) const; PClassActor *GetBloodType(int type = 0) const;
@ -956,6 +957,7 @@ public:
DAngle SpriteAngle; DAngle SpriteAngle;
DAngle SpriteRotation; DAngle SpriteRotation;
DRotator Angles; DRotator Angles;
DRotator ViewAngles; // Offsets for cameras
DVector2 Scale; // Scaling values; 1 is normal size 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. double Alpha; // Since P_CheckSight makes an alpha check this can't be a float. It has to be a double.

View file

@ -415,7 +415,6 @@ public:
return mo->FloatVar(NAME_ViewHeight); return mo->FloatVar(NAME_ViewHeight);
} }
void Uncrouch() void Uncrouch()
{ {
if (crouchfactor != 1) if (crouchfactor != 1)

View file

@ -2792,12 +2792,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRefire)
// Set actor's angle (in degrees). // Set actor's angle (in degrees).
// //
//=========================================================================== //===========================================================================
enum
{
SPF_FORCECLAMP = 1, // players always clamp
SPF_INTERPOLATE = 2,
};
DEFINE_ACTION_FUNCTION(AActor, A_SetAngle) DEFINE_ACTION_FUNCTION(AActor, A_SetAngle)
{ {
@ -2809,7 +2803,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetAngle)
AActor *ref = COPY_AAPTR(self, ptr); AActor *ref = COPY_AAPTR(self, ptr);
if (ref != NULL) if (ref != NULL)
{ {
ref->SetAngle(angle, !!(flags & SPF_INTERPOLATE)); ref->SetAngle(angle, flags);
} }
return 0; return 0;
} }
@ -2833,7 +2827,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetPitch)
if (ref != NULL) if (ref != NULL)
{ {
ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE), !!(flags & SPF_FORCECLAMP)); ref->SetPitch(pitch, flags);
} }
return 0; return 0;
} }
@ -2856,7 +2850,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetRoll)
if (ref != NULL) if (ref != NULL)
{ {
ref->SetRoll(roll, !!(flags & SPF_INTERPOLATE)); ref->SetRoll(roll, flags);
} }
return 0; return 0;
} }

View file

@ -217,6 +217,13 @@ enum WARPF
WARPF_COPYPITCH = 0x8000, WARPF_COPYPITCH = 0x8000,
}; };
enum SPF
{
SPF_FORCECLAMP = 1, // players always clamp
SPF_INTERPOLATE = 2,
SPF_VIEW = 4,
};
enum PCM enum PCM
{ {
PCM_DROPOFF = 1, PCM_DROPOFF = 1,

View file

@ -367,7 +367,8 @@ void AActor::Serialize(FSerializer &arc)
A("spawnorder", SpawnOrder) A("spawnorder", SpawnOrder)
A("friction", Friction) A("friction", Friction)
A("userlights", UserLights) A("userlights", UserLights)
A("SpriteOffset", SpriteOffset); A("SpriteOffset", SpriteOffset)
A("viewangles", ViewAngles);
} }
#undef A #undef A
@ -3349,9 +3350,9 @@ DEFINE_ACTION_FUNCTION(AActor, SetShade)
return 0; 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 { // clamp the pitch we set
DAngle min, max; DAngle min, max;
@ -3367,37 +3368,71 @@ void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp)
} }
p = clamp(p, min, max); 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; Angles.Pitch = p;
if (player != NULL && interpolate) changed = true;
{ }
player->cheats |= CF_INTERPVIEW; 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; Angles.Yaw = ang;
if (player != NULL && interpolate) changed = true;
{ }
player->cheats |= CF_INTERPVIEW; 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; Angles.Roll = r;
if (player != NULL && interpolate) changed = true;
{ }
player->cheats |= CF_INTERPVIEW; if (changed && player != nullptr && (fflags & SPF_INTERPOLATE))
} {
player->cheats |= CF_INTERPVIEW;
} }
} }

View file

@ -804,7 +804,17 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
viewpoint.sector = viewpoint.camera->Sector; viewpoint.sector = viewpoint.camera->Sector;
viewpoint.showviewer = false; 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) if (viewpoint.camera->player != 0)
{ {
player = viewpoint.camera->player; player = viewpoint.camera->player;

View file

@ -324,6 +324,7 @@ static FFlagDef ActorFlagDefs[]=
DEFINE_FLAG(MF8, NOFRICTIONBOUNCE, AActor, flags8), DEFINE_FLAG(MF8, NOFRICTIONBOUNCE, AActor, flags8),
DEFINE_FLAG(MF8, RETARGETAFTERSLAM, AActor, flags8), DEFINE_FLAG(MF8, RETARGETAFTERSLAM, AActor, flags8),
DEFINE_FLAG(MF8, STOPRAILS, AActor, flags8), DEFINE_FLAG(MF8, STOPRAILS, AActor, flags8),
DEFINE_FLAG(MF8, ABSVIEWANGLES, AActor, flags8),
// Effect flags // Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View file

@ -1902,6 +1902,9 @@ DEFINE_FIELD(AActor, RenderRequired)
DEFINE_FIELD(AActor, friendlyseeblocks) DEFINE_FIELD(AActor, friendlyseeblocks)
DEFINE_FIELD(AActor, SpawnTime) DEFINE_FIELD(AActor, SpawnTime)
DEFINE_FIELD(AActor, InventoryID) 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, thing);
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, pos); DEFINE_FIELD_X(FCheckPosition, FCheckPosition, pos);

View file

@ -1062,6 +1062,9 @@ xx(AttackZOffset)
xx(SpawnMask) xx(SpawnMask)
xx(ScoreIcon) xx(ScoreIcon)
xx(ViewHeight) xx(ViewHeight)
xx(ViewAngle)
xx(ViewPitch)
xx(ViewRoll)
xx(FallingScreamMinSpeed) xx(FallingScreamMinSpeed)
xx(FallingScreamMaxSpeed) xx(FallingScreamMaxSpeed)
xx(GruntSpeed) xx(GruntSpeed)

View file

@ -232,6 +232,7 @@ class Actor : Thinker native
native uint8 fountaincolor; native uint8 fountaincolor;
native double CameraHeight; // Height of camera when used as such native double CameraHeight; // Height of camera when used as such
native double CameraFOV; native double CameraFOV;
native double ViewAngle, ViewPitch, ViewRoll;
native double RadiusDamageFactor; // Radius damage factor native double RadiusDamageFactor; // Radius damage factor
native double SelfDamageFactor; native double SelfDamageFactor;
native double StealthAlpha; native double StealthAlpha;

View file

@ -542,6 +542,7 @@ enum EAngleFlags
{ {
SPF_FORCECLAMP = 1, SPF_FORCECLAMP = 1,
SPF_INTERPOLATE = 2, SPF_INTERPOLATE = 2,
SPF_VIEW = 4,
}; };
// flags for A_CheckLOF // flags for A_CheckLOF