mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +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(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)
|
||||||
|
|
|
@ -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 ---
|
||||||
|
@ -845,9 +846,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// These also set CF_INTERPVIEW for players.
|
// These also set CF_INTERPVIEW for players.
|
||||||
void SetPitch(DAngle p, bool interpolate, bool forceclamp = false);
|
DAngle ClampPitch(DAngle p);
|
||||||
void SetAngle(DAngle ang, bool interpolate);
|
void SetPitch(DAngle p, int fflags);
|
||||||
void SetRoll(DAngle roll, bool interpolate);
|
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;
|
PClassActor *GetBloodType(int type = 0) const;
|
||||||
|
|
||||||
|
@ -961,6 +966,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.
|
||||||
|
|
||||||
|
|
|
@ -419,7 +419,6 @@ public:
|
||||||
return mo->FloatVar(NAME_ViewHeight);
|
return mo->FloatVar(NAME_ViewHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Uncrouch()
|
void Uncrouch()
|
||||||
{
|
{
|
||||||
if (crouchfactor != 1)
|
if (crouchfactor != 1)
|
||||||
|
|
|
@ -2793,12 +2793,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)
|
||||||
{
|
{
|
||||||
|
@ -2810,7 +2804,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;
|
||||||
}
|
}
|
||||||
|
@ -2834,7 +2828,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;
|
||||||
}
|
}
|
||||||
|
@ -2857,11 +2851,98 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// 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
|
// A_SetUserVar
|
||||||
|
|
|
@ -217,6 +217,12 @@ enum WARPF
|
||||||
WARPF_COPYPITCH = 0x8000,
|
WARPF_COPYPITCH = 0x8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SPF
|
||||||
|
{
|
||||||
|
SPF_FORCECLAMP = 1, // players always clamp
|
||||||
|
SPF_INTERPOLATE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
enum PCM
|
enum PCM
|
||||||
{
|
{
|
||||||
PCM_DROPOFF = 1,
|
PCM_DROPOFF = 1,
|
||||||
|
|
|
@ -362,6 +362,7 @@ void AActor::Serialize(FSerializer &arc)
|
||||||
A("renderhidden", RenderHidden)
|
A("renderhidden", RenderHidden)
|
||||||
A("renderrequired", RenderRequired)
|
A("renderrequired", RenderRequired)
|
||||||
A("friendlyseeblocks", friendlyseeblocks)
|
A("friendlyseeblocks", friendlyseeblocks)
|
||||||
|
A("viewangles", ViewAngles)
|
||||||
A("spawntime", SpawnTime)
|
A("spawntime", SpawnTime)
|
||||||
A("spawnorder", SpawnOrder)
|
A("spawnorder", SpawnOrder)
|
||||||
A("friction", Friction)
|
A("friction", Friction)
|
||||||
|
@ -3352,13 +3353,13 @@ DEFINE_ACTION_FUNCTION(AActor, SetShade)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp)
|
// [MC] Helper function for Set(View)Pitch.
|
||||||
|
DAngle AActor::ClampPitch(DAngle p)
|
||||||
{
|
{
|
||||||
if (player != NULL || forceclamp)
|
// clamp the pitch we set
|
||||||
{ // clamp the pitch we set
|
|
||||||
DAngle min, max;
|
DAngle min, max;
|
||||||
|
|
||||||
if (player != NULL)
|
if (player != nullptr)
|
||||||
{
|
{
|
||||||
min = player->MinPitch;
|
min = player->MinPitch;
|
||||||
max = player->MaxPitch;
|
max = player->MaxPitch;
|
||||||
|
@ -3369,35 +3370,89 @@ void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp)
|
||||||
max = 89.;
|
max = 89.;
|
||||||
}
|
}
|
||||||
p = clamp(p, min, max);
|
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)
|
if (p != Angles.Pitch)
|
||||||
{
|
{
|
||||||
Angles.Pitch = p;
|
Angles.Pitch = p;
|
||||||
if (player != NULL && interpolate)
|
if (player != nullptr && (fflags & SPF_INTERPOLATE))
|
||||||
{
|
{
|
||||||
player->cheats |= CF_INTERPVIEW;
|
player->cheats |= CF_INTERPVIEW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AActor::SetAngle(DAngle ang, bool interpolate)
|
void AActor::SetAngle(DAngle ang, int fflags)
|
||||||
{
|
{
|
||||||
if (ang != Angles.Yaw)
|
if (ang != Angles.Yaw)
|
||||||
{
|
{
|
||||||
Angles.Yaw = ang;
|
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;
|
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;
|
p = ClampPitch(p);
|
||||||
if (player != NULL && interpolate)
|
}
|
||||||
|
|
||||||
|
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;
|
player->cheats |= CF_INTERPVIEW;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -325,6 +325,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),
|
||||||
|
|
|
@ -1943,6 +1943,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);
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -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_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_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_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_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_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);
|
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