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_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.

View file

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

View file

@ -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;
}

View file

@ -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,

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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),

View file

@ -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);

View file

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

View file

@ -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;

View file

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