mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
View Angles (Part 1 - Redux) (#1002)
* 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 A_SetView<Angle/Pitch/Roll>, which will set the view direction. - Added ABSVIEWANGLES flag, used to make the view absolute instead of an offset. * Converted functions to be direct-native.
This commit is contained in:
parent
c57e669044
commit
eaba63e13b
10 changed files with 205 additions and 37 deletions
|
@ -1039,6 +1039,9 @@ xx(AttackZOffset)
|
|||
xx(SpawnMask)
|
||||
xx(ScoreIcon)
|
||||
xx(ViewHeight)
|
||||
xx(ViewAngle)
|
||||
xx(ViewPitch)
|
||||
xx(ViewRoll)
|
||||
xx(FallingScreamMinSpeed)
|
||||
xx(FallingScreamMaxSpeed)
|
||||
xx(GruntSpeed)
|
||||
|
|
|
@ -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 ---
|
||||
|
@ -845,9 +846,13 @@ 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);
|
||||
DAngle ClampPitch(DAngle p);
|
||||
void SetPitch(DAngle p, int fflags);
|
||||
void SetAngle(DAngle ang, int fflags);
|
||||
void SetRoll(DAngle roll, int fflags);
|
||||
void SetViewPitch(DAngle p, int fflags);
|
||||
void SetViewAngle(DAngle ang, int fflags);
|
||||
void SetViewRoll(DAngle roll, int fflags);
|
||||
|
||||
PClassActor *GetBloodType(int type = 0) const;
|
||||
|
||||
|
@ -961,6 +966,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.
|
||||
|
||||
|
|
|
@ -419,7 +419,6 @@ public:
|
|||
return mo->FloatVar(NAME_ViewHeight);
|
||||
}
|
||||
|
||||
|
||||
void Uncrouch()
|
||||
{
|
||||
if (crouchfactor != 1)
|
||||
|
|
|
@ -2793,12 +2793,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)
|
||||
{
|
||||
|
@ -2810,7 +2804,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;
|
||||
}
|
||||
|
@ -2834,7 +2828,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;
|
||||
}
|
||||
|
@ -2857,11 +2851,98 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetRoll)
|
|||
|
||||
if (ref != NULL)
|
||||
{
|
||||
ref->SetRoll(roll, !!(flags & SPF_INTERPOLATE));
|
||||
ref->SetRoll(roll, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetViewAngle
|
||||
//
|
||||
// Set actor's viewangle (in degrees).
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void SetViewAngleNative(AActor* self, double angle, int flags, int ptr)
|
||||
{
|
||||
AActor *ref = COPY_AAPTR(self, ptr);
|
||||
if (ref != nullptr)
|
||||
{
|
||||
ref->SetViewAngle(angle, flags);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SetViewAngle, SetViewAngleNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(angle);
|
||||
PARAM_INT(flags);
|
||||
PARAM_INT(ptr);
|
||||
|
||||
SetViewAngleNative(self, angle, flags, ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetViewPitch
|
||||
//
|
||||
// Set actor's viewpitch (in degrees).
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void SetViewPitchNative(AActor* self, double pitch, int flags, int ptr)
|
||||
{
|
||||
AActor *ref = COPY_AAPTR(self, ptr);
|
||||
if (ref != nullptr)
|
||||
{
|
||||
ref->SetViewPitch(pitch, flags);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SetViewPitch, SetViewPitchNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(pitch);
|
||||
PARAM_INT(flags);
|
||||
PARAM_INT(ptr);
|
||||
|
||||
SetViewPitchNative(self, pitch, flags, ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// [MC] A_SetViewRoll
|
||||
//
|
||||
// Set actor's viewroll (in degrees).
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void SetViewRollNative(AActor* self, double roll, int flags, int ptr)
|
||||
{
|
||||
AActor *ref = COPY_AAPTR(self, ptr);
|
||||
if (ref != nullptr)
|
||||
{
|
||||
ref->SetViewRoll(roll, flags);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_SetViewRoll, SetViewRollNative)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(roll);
|
||||
PARAM_INT(flags);
|
||||
PARAM_INT(ptr);
|
||||
|
||||
SetViewRollNative(self, roll, flags, ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetUserVar
|
||||
|
|
|
@ -217,6 +217,12 @@ enum WARPF
|
|||
WARPF_COPYPITCH = 0x8000,
|
||||
};
|
||||
|
||||
enum SPF
|
||||
{
|
||||
SPF_FORCECLAMP = 1, // players always clamp
|
||||
SPF_INTERPOLATE = 2,
|
||||
};
|
||||
|
||||
enum PCM
|
||||
{
|
||||
PCM_DROPOFF = 1,
|
||||
|
|
|
@ -362,6 +362,7 @@ void AActor::Serialize(FSerializer &arc)
|
|||
A("renderhidden", RenderHidden)
|
||||
A("renderrequired", RenderRequired)
|
||||
A("friendlyseeblocks", friendlyseeblocks)
|
||||
A("viewangles", ViewAngles)
|
||||
A("spawntime", SpawnTime)
|
||||
A("spawnorder", SpawnOrder)
|
||||
A("friction", Friction)
|
||||
|
@ -3352,52 +3353,106 @@ DEFINE_ACTION_FUNCTION(AActor, SetShade)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp)
|
||||
{
|
||||
if (player != NULL || forceclamp)
|
||||
{ // clamp the pitch we set
|
||||
DAngle min, max;
|
||||
// [MC] Helper function for Set(View)Pitch.
|
||||
DAngle AActor::ClampPitch(DAngle p)
|
||||
{
|
||||
// clamp the pitch we set
|
||||
DAngle min, max;
|
||||
|
||||
if (player != NULL)
|
||||
{
|
||||
min = player->MinPitch;
|
||||
max = player->MaxPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = -89.;
|
||||
max = 89.;
|
||||
}
|
||||
p = clamp(p, min, max);
|
||||
if (player != nullptr)
|
||||
{
|
||||
min = player->MinPitch;
|
||||
max = player->MaxPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = -89.;
|
||||
max = 89.;
|
||||
}
|
||||
p = clamp(p, min, max);
|
||||
return p;
|
||||
}
|
||||
|
||||
void AActor::SetPitch(DAngle p, int fflags)
|
||||
{
|
||||
if (player != nullptr || (fflags & SPF_FORCECLAMP))
|
||||
{
|
||||
p = ClampPitch(p);
|
||||
}
|
||||
|
||||
if (p != Angles.Pitch)
|
||||
{
|
||||
Angles.Pitch = p;
|
||||
if (player != NULL && interpolate)
|
||||
if (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)
|
||||
{
|
||||
Angles.Yaw = ang;
|
||||
if (player != NULL && interpolate)
|
||||
if (player != nullptr && (fflags & SPF_INTERPOLATE))
|
||||
{
|
||||
player->cheats |= CF_INTERPVIEW;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AActor::SetRoll(DAngle r, int fflags)
|
||||
{
|
||||
if (r != Angles.Roll)
|
||||
{
|
||||
Angles.Roll = r;
|
||||
if (player != nullptr && (fflags & SPF_INTERPOLATE))
|
||||
{
|
||||
player->cheats |= CF_INTERPVIEW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AActor::SetRoll(DAngle r, bool interpolate)
|
||||
void AActor::SetViewPitch(DAngle p, int fflags)
|
||||
{
|
||||
if (r != Angles.Roll)
|
||||
if (player != NULL || (fflags & SPF_FORCECLAMP))
|
||||
{
|
||||
Angles.Roll = r;
|
||||
if (player != NULL && interpolate)
|
||||
p = ClampPitch(p);
|
||||
}
|
||||
|
||||
if (p != ViewAngles.Pitch)
|
||||
{
|
||||
ViewAngles.Pitch = p;
|
||||
if (player != nullptr && (fflags & SPF_INTERPOLATE))
|
||||
{
|
||||
player->cheats |= CF_INTERPVIEW;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AActor::SetViewAngle(DAngle ang, int fflags)
|
||||
{
|
||||
if (ang != ViewAngles.Yaw)
|
||||
{
|
||||
ViewAngles.Yaw = ang;
|
||||
if (player != nullptr && (fflags & SPF_INTERPOLATE))
|
||||
{
|
||||
player->cheats |= CF_INTERPVIEW;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AActor::SetViewRoll(DAngle r, int fflags)
|
||||
{
|
||||
if (r != ViewAngles.Roll)
|
||||
{
|
||||
ViewAngles.Roll = r;
|
||||
if (player != nullptr && (fflags & SPF_INTERPOLATE))
|
||||
{
|
||||
player->cheats |= CF_INTERPVIEW;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -325,6 +325,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),
|
||||
|
|
|
@ -1943,6 +1943,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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -1122,6 +1123,9 @@ class Actor : Thinker native
|
|||
native void A_SetAngle(double angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetPitch(double pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetRoll(double roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetViewAngle(double angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetViewPitch(double pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetViewRoll(double roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
deprecated("2.3", "User variables are deprecated in ZScript. Actor variables are directly accessible") native void A_SetUserVar(name varname, int value);
|
||||
deprecated("2.3", "User variables are deprecated in ZScript. Actor variables are directly accessible") native void A_SetUserArray(name varname, int index, int value);
|
||||
deprecated("2.3", "User variables are deprecated in ZScript. Actor variables are directly accessible") native void A_SetUserVarFloat(name varname, double value);
|
||||
|
|
Loading…
Reference in a new issue