diff --git a/CMakeLists.txt b/CMakeLists.txt index 813560be1..b52bafccf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,7 +164,7 @@ if( MSVC ) string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ) else() set( REL_LINKER_FLAGS "" ) - set( ALL_C_FLAGS "" ) + set( ALL_C_FLAGS "-ffp-contract=off" ) set( REL_C_FLAGS "" ) set( DEB_C_FLAGS "" ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc42f81e1..9fb4b2499 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1284,7 +1284,22 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE g_shared/sbar_mugshot.cpp g_shared/shared_hud.cpp g_shared/shared_sbar.cpp - oplsynth/fmopl.cpp + math/asin.c + math/atan.c + math/const.c + math/cosh.c + math/exp.c + math/isnan.c + math/log.c + math/log10.c + math/mtherr.c + math/polevl.c + math/sin.c + math/sinh.c + math/sqrt.c + math/tan.c + math/tanh.c + math/fastsin.cpp resourcefiles/ancientzip.cpp resourcefiles/file_7z.cpp resourcefiles/file_grp.cpp @@ -1481,6 +1496,7 @@ source_group("Games\\Hexen Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR source_group("Games\\Raven Shared" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_raven/.+") source_group("Games\\Strife Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_strife/.+") source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+") +source_group("Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+") source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+") source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+") source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+") diff --git a/src/actor.h b/src/actor.h index 12d912155..564681917 100644 --- a/src/actor.h +++ b/src/actor.h @@ -25,6 +25,7 @@ // Basics. #include "tables.h" +#include "templates.h" // We need the thinker_t stuff. #include "dthinker.h" @@ -533,6 +534,10 @@ enum EThingSpecialActivationType THINGSPEC_Switch = 1<<10, // The thing is alternatively activated and deactivated when triggered }; +#define ONFLOORZ FIXED_MIN +#define ONCEILINGZ FIXED_MAX +#define FLOATRANDZ (FIXED_MAX-1) + class FDecalBase; class AInventory; @@ -571,6 +576,7 @@ public: fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here... angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h +const double MinVel = 1. / 65536; // Map Object definition. class AActor : public DThinker @@ -600,7 +606,7 @@ public: // Adjusts the angle for deflection/reflection of incoming missiles // Returns true if the missile should be allowed to explode anyway - bool AdjustReflectionAngle (AActor *thing, angle_t &angle); + bool AdjustReflectionAngle (AActor *thing, DAngle &angle); // Returns true if this actor is within melee range of its target bool CheckMeleeRange(); @@ -763,7 +769,7 @@ public: // Return starting health adjusted by skill level int SpawnHealth() const; int GetGibHealth() const; - fixed_t GetCameraHeight() const; + double GetCameraHeight() const; inline bool isMissile(bool precise=true) { @@ -782,9 +788,9 @@ public: } // These also set CF_INTERPVIEW for players. - void SetPitch(int p, bool interpolate, bool forceclamp = false); - void SetAngle(angle_t ang, bool interpolate); - void SetRoll(angle_t roll, bool interpolate); + void SetPitch(DAngle p, bool interpolate, bool forceclamp = false); + void SetAngle(DAngle ang, bool interpolate); + void SetRoll(DAngle roll, bool interpolate); PClassActor *GetBloodType(int type = 0) const { @@ -815,135 +821,225 @@ public: fixed_t AproxDistance(fixed_t otherx, fixed_t othery) { - return P_AproxDistance(X() - otherx, Y() - othery); + return P_AproxDistance(_f_X() - otherx, _f_Y() - othery); } - fixed_t AngleTo(fixed_t otherx, fixed_t othery) + fixed_t __f_AngleTo(fixed_t otherx, fixed_t othery) { - return R_PointToAngle2(X(), Y(), otherx, othery); + return R_PointToAngle2(_f_X(), _f_Y(), otherx, othery); } - fixed_t AngleTo(fixedvec2 other) + fixed_t __f_AngleTo(fixedvec2 other) { - return R_PointToAngle2(X(), Y(), other.x, other.y); + return R_PointToAngle2(_f_X(), _f_Y(), other.x, other.y); } // 'absolute' is reserved for a linked portal implementation which needs // to distinguish between portal-aware and portal-unaware distance calculation. fixed_t AproxDistance(AActor *other, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return P_AproxDistance(X() - otherpos.x, Y() - otherpos.y); + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return P_AproxDistance(_f_X() - otherpos.x, _f_Y() - otherpos.y); } fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return P_AproxDistance(X() - otherpos.x + xadd, Y() - otherpos.y + yadd); + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return P_AproxDistance(_f_X() - otherpos.x + xadd, _f_Y() - otherpos.y + yadd); } fixed_t AproxDistance3D(AActor *other, bool absolute = false) { - return P_AproxDistance(AproxDistance(other), Z() - other->Z()); + return P_AproxDistance(AproxDistance(other), _f_Z() - other->_f_Z()); } // more precise, but slower version, being used in a few places - fixed_t Distance2D(AActor *other, bool absolute = false) + double Distance2D(AActor *other, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return xs_RoundToInt(DVector2(X() - otherpos.x, Y() - otherpos.y).Length()); + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return (DVector2(_f_X() - otherpos.x, _f_Y() - otherpos.y).Length())/FRACUNIT; + } + + double Distance2D(double x, double y) const + { + return DVector2(X() - x, Y() - y).Length(); } // a full 3D version of the above fixed_t Distance3D(AActor *other, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return xs_RoundToInt(DVector3(X() - otherpos.x, Y() - otherpos.y, Z() - otherpos.z).Length()); + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return xs_RoundToInt(DVector3(_f_X() - otherpos.x, _f_Y() - otherpos.y, _f_Z() - otherpos.z).Length()); } - angle_t AngleTo(AActor *other, bool absolute = false) + angle_t __f_AngleTo(AActor *other, bool absolute = false) { - fixedvec3 otherpos = absolute ? other->Pos() : other->PosRelative(this); - return R_PointToAngle2(X(), Y(), otherpos.x, otherpos.y); + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return R_PointToAngle2(_f_X(), _f_Y(), otherpos.x, otherpos.y); } - angle_t AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const + angle_t __f_AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const { - return R_PointToAngle2(X(), Y(), other->X() + oxofs, other->Y() + oyofs); + return R_PointToAngle2(_f_X(), _f_Y(), other->_f_X() + oxofs, other->_f_Y() + oyofs); } - fixedvec2 Vec2To(AActor *other) const + DAngle AngleTo(AActor *other, bool absolute = false) + { + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return VecToAngle(otherpos.x - _f_X(), otherpos.y - _f_Y()); + } + + DAngle AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const + { + fixedvec3 otherpos = absolute ? other->_f_Pos() : other->PosRelative(this); + return VecToAngle(otherpos.y + oxofs - _f_Y(), otherpos.x + oyofs - _f_X()); + } + + DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const + { + return FIXED2DBL(AngleTo(other, FLOAT2FIXED(oxofs), FLOAT2FIXED(oyofs), absolute)); + } + + fixedvec2 _f_Vec2To(AActor *other) const { fixedvec3 otherpos = other->PosRelative(this); - fixedvec2 ret = { otherpos.x - X(), otherpos.y - Y() }; + fixedvec2 ret = { otherpos.x - _f_X(), otherpos.y - _f_Y() }; return ret; } - fixedvec3 Vec3To(AActor *other) const + fixedvec3 _f_Vec3To(AActor *other) const { fixedvec3 otherpos = other->PosRelative(this); - fixedvec3 ret = { otherpos.x - X(), otherpos.y - Y(), otherpos.z - Z() }; + fixedvec3 ret = { otherpos.x - _f_X(), otherpos.y - _f_Y(), otherpos.z - _f_Z() }; return ret; } + DVector2 Vec2To(AActor *other) const + { + fixedvec3 otherpos = other->PosRelative(this); + return{ FIXED2DBL(otherpos.x - _f_X()), FIXED2DBL(otherpos.y - _f_Y()) }; + } + + DVector3 Vec3To(AActor *other) const + { + fixedvec3 otherpos = other->PosRelative(this); + return { FIXED2DBL(otherpos.x - _f_X()), FIXED2DBL(otherpos.y - _f_Y()), FIXED2DBL(otherpos.z - _f_Z()) }; + } + fixedvec2 Vec2Offset(fixed_t dx, fixed_t dy, bool absolute = false) { if (absolute) { - fixedvec2 ret = { X() + dx, Y() + dy }; + fixedvec2 ret = { _f_X() + dx, _f_Y() + dy }; return ret; } - else return P_GetOffsetPosition(X(), Y(), dx, dy); + else return P_GetOffsetPosition(_f_X(), _f_Y(), dx, dy); } + DVector2 Vec2Offset(double dx, double dy, bool absolute = false) + { + if (absolute) + { + return { X() + dx, Y() + dy }; + } + else + { + fixedvec2 v = P_GetOffsetPosition(_f_X(), _f_Y(), FLOAT2FIXED(dx), FLOAT2FIXED(dy)); + return{ FIXED2DBL(v.x), FIXED2DBL(v.y) }; + } + } + + DVector3 Vec2OffsetZ(double dx, double dy, double atz, bool absolute = false) + { + if (absolute) + { + return{ X() + dx, Y() + dy, atz }; + } + else + { + fixedvec2 v = P_GetOffsetPosition(_f_X(), _f_Y(), FLOAT2FIXED(dx), FLOAT2FIXED(dy)); + return{ FIXED2DBL(v.x), FIXED2DBL(v.y), atz }; + } + } fixedvec2 Vec2Angle(fixed_t length, angle_t angle, bool absolute = false) { if (absolute) { - fixedvec2 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), - Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) }; + fixedvec2 ret = { _f_X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), + _f_Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) }; return ret; } - else return P_GetOffsetPosition(X(), Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT])); + else return P_GetOffsetPosition(_f_X(), _f_Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT])); } fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false) { if (absolute) { - fixedvec3 ret = { X() + dx, Y() + dy, Z() + dz }; + fixedvec3 ret = { _f_X() + dx, _f_Y() + dy, _f_Z() + dz }; return ret; } else { - fixedvec2 op = P_GetOffsetPosition(X(), Y(), dx, dy); - fixedvec3 pos = { op.x, op.y, Z() + dz }; + fixedvec2 op = P_GetOffsetPosition(_f_X(), _f_Y(), dx, dy); + fixedvec3 pos = { op.x, op.y, _f_Z() + dz }; return pos; } } - fixedvec3 Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false) + DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false) { if (absolute) { - fixedvec3 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), - Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), Z() + dz }; + return { X() + dx, Y() + dy, Z() + dz }; + } + else + { + fixedvec2 v = P_GetOffsetPosition(_f_X(), _f_Y(), FLOAT2FIXED(dx), FLOAT2FIXED(dy)); + return{ FIXED2DBL(v.x), FIXED2DBL(v.y), Z() + dz }; + } + } + + fixedvec3 _f_Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false) + { + if (absolute) + { + fixedvec3 ret = { _f_X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), + _f_Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), _f_Z() + dz }; return ret; } else { - fixedvec2 op = P_GetOffsetPosition(X(), Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT])); - fixedvec3 pos = { op.x, op.y, Z() + dz }; + fixedvec2 op = P_GetOffsetPosition(_f_X(), _f_Y(), FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT])); + fixedvec3 pos = { op.x, op.y, _f_Z() + dz }; return pos; } } + DVector3 Vec3Angle(double length, DAngle angle, double dz, bool absolute = false) + { + if (absolute) + { + return{ X() + length * angle.Cos(), Y() + length * angle.Sin(), Z() + dz }; + } + else + { + fixedvec2 op = P_GetOffsetPosition(_f_X(), _f_Y(), FLOAT2FIXED(length*angle.Cos()), FLOAT2FIXED(length*angle.Sin())); + return{ FIXED2DBL(op.x), FIXED2DBL(op.y), Z() + dz }; + } + } + + double AccuracyFactor() + { + return 1. / (1 << (accuracy * 5 / 100)); + } + void ClearInterpolation(); void Move(fixed_t dx, fixed_t dy, fixed_t dz) { - SetOrigin(X() + dx, Y() + dy, Z() + dz, true); + SetOrigin(_f_X() + dx, _f_Y() + dy, _f_Z() + dz, true); } void SetOrigin(const fixedvec3 & npos, bool moving) @@ -951,6 +1047,11 @@ public: SetOrigin(npos.x, npos.y, npos.z, moving); } + void SetOrigin(const DVector3 & npos, bool moving) + { + SetOrigin(FLOAT2FIXED(npos.X), FLOAT2FIXED(npos.Y), FLOAT2FIXED(npos.Z), moving); + } + inline void SetFriendPlayer(player_t *player); bool IsVisibleToPlayer() const; @@ -960,7 +1061,7 @@ public: bool CanSeek(AActor *target) const; - fixed_t GetGravity() const; + double GetGravity() const; bool IsSentient() const; const char *GetTag(const char *def = NULL) const; void SetTag(const char *def); @@ -973,10 +1074,32 @@ public: AActor *snext, **sprev; // links in sector (if needed) fixedvec3 __pos; // double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions. + /* angle_t angle; + fixed_t pitch; + angle_t roll; // This was fixed_t before, which is probably wrong + fixedvec3 vel; + */ + + DRotator Angles; + DVector3 Vel; + double Speed; + double FloatSpeed; + + // intentionally stange names so that searching for them is easier. + angle_t _f_angle() { return FLOAT2ANGLE(Angles.Yaw.Degrees); } + int _f_pitch() { return FLOAT2ANGLE(Angles.Pitch.Degrees); } + angle_t _f_roll() { return FLOAT2ANGLE(Angles.Roll.Degrees); } + fixed_t _f_velx() { return FLOAT2FIXED(Vel.X); } + fixed_t _f_vely() { return FLOAT2FIXED(Vel.Y); } + fixed_t _f_velz() { return FLOAT2FIXED(Vel.Z); } + fixed_t _f_speed() { return FLOAT2FIXED(Speed); } + fixed_t _f_floatspeed() { return FLOAT2FIXED(FloatSpeed); } + + WORD sprite; // used to find patch_t and flip value BYTE frame; // sprite frame to draw - fixed_t scaleX, scaleY; // Scaling values; FRACUNIT is normal size + DVector2 Scale; // Scaling values; 1 is normal size FRenderStyle RenderStyle; // Style to draw this actor with ActorRenderFlags renderflags; // Different rendering flags FTextureID picnum; // Draw this instead of sprite if valid @@ -985,12 +1108,20 @@ public: DWORD fillcolor; // Color to draw when STYLE_Shaded // interaction info - fixed_t pitch; - angle_t roll; // This was fixed_t before, which is probably wrong FBlockNode *BlockNode; // links in blocks (if needed) struct sector_t *Sector; subsector_t * subsector; - fixed_t floorz, ceilingz; // closest together of contacted secs + double floorz, ceilingz; // closest together of contacted secs + + inline fixed_t _f_ceilingz() + { + return FLOAT2FIXED(ceilingz); + } + inline fixed_t _f_floorz() + { + return FLOAT2FIXED(floorz); + } + fixed_t dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. struct sector_t *floorsector; @@ -998,9 +1129,19 @@ public: int floorterrain; struct sector_t *ceilingsector; FTextureID ceilingpic; // contacted sec ceilingpic - fixed_t radius, height; // for movement checking - fixed_t projectilepassheight; // height for clipping projectile movement against this actor - fixedvec3 vel; + double radius, Height; // for movement checking + + inline fixed_t _f_radius() const + { + return FLOAT2FIXED(radius); + } + inline fixed_t _f_height() const + { + return FLOAT2FIXED(Height); + } + + double projectilepassheight; // height for clipping projectile movement against this actor + SDWORD tics; // state tic counter FState *state; VMFunction *Damage; // For missiles and monster railgun @@ -1018,6 +1159,9 @@ public: int special1; // Special info int special2; // Special info + double specialf1; // With floats we cannot use the int versions for storing position or angle data without reverting to fixed point (which we do not want.) + double specialf2; + int weaponspecial; // Special info for weapons. int health; BYTE movedir; // 0-7 @@ -1045,7 +1189,12 @@ public: FNameNoInit Species; // For monster families TObjPtr tracer; // Thing being chased/attacked for tracers TObjPtr master; // Thing which spawned this one (prevents mutual attacks) - fixed_t floorclip; // value to use for floor clipping + double Floorclip; // value to use for floor clipping + fixed_t _f_floorclip() + { + return FLOAT2FIXED(Floorclip); + } + int tid; // thing identifier int special; // special int args[5]; // special arguments @@ -1068,7 +1217,7 @@ public: fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. fixed_t wallbouncefactor; // The bounce factor for walls can be different. int bouncecount; // Strife's grenades only bounce twice before exploding - fixed_t gravity; // [GRB] Gravity factor + double Gravity; // [GRB] Gravity factor fixed_t Friction; int FastChaseStrafeCount; fixed_t pushfactor; @@ -1115,8 +1264,6 @@ public: FSoundIDNoInit WallBounceSound; FSoundIDNoInit CrushPainSound; - fixed_t Speed; - fixed_t FloatSpeed; fixed_t MaxDropOffHeight, MaxStepHeight; SDWORD Mass; SWORD PainChance; @@ -1148,7 +1295,8 @@ public: // [RH] Used to interpolate the view to get >35 FPS fixed_t PrevX, PrevY, PrevZ; - angle_t PrevAngle; + //angle_t PrevAngle; + DRotator PrevAngles; int PrevPortalGroup; // ThingIDs @@ -1156,6 +1304,7 @@ public: void AddToHash (); void RemoveFromHash (); + private: static AActor *TIDHash[128]; static inline int TIDHASH (int key) { return key & 127; } @@ -1200,23 +1349,40 @@ public: bool HasSpecialDeathStates () const; - fixed_t X() const + fixed_t _f_X() const { return __pos.x; } - fixed_t Y() const + fixed_t _f_Y() const { return __pos.y; } - fixed_t Z() const + fixed_t _f_Z() const { return __pos.z; } - fixedvec3 Pos() const + fixedvec3 _f_Pos() const { return __pos; } + double X() const + { + return FIXED2DBL(__pos.x); + } + double Y() const + { + return FIXED2DBL(__pos.y); + } + double Z() const + { + return FIXED2DBL(__pos.z); + } + DVector3 Pos() const + { + return DVector3(X(), Y(), Z()); + } + fixedvec3 PosRelative(int grp) const; fixedvec3 PosRelative(const AActor *other) const; fixedvec3 PosRelative(sector_t *sec) const; @@ -1224,42 +1390,75 @@ public: fixed_t SoundX() const { - return X(); + return _f_X(); } fixed_t SoundY() const { - return Y(); + return _f_Y(); } fixed_t SoundZ() const { - return Z(); + return _f_Z(); } fixedvec3 InterpolatedPosition(fixed_t ticFrac) const { fixedvec3 ret; - ret.x = PrevX + FixedMul (ticFrac, X() - PrevX); - ret.y = PrevY + FixedMul (ticFrac, Y() - PrevY); - ret.z = PrevZ + FixedMul (ticFrac, Z() - PrevZ); + ret.x = PrevX + FixedMul (ticFrac, _f_X() - PrevX); + ret.y = PrevY + FixedMul (ticFrac, _f_Y() - PrevY); + ret.z = PrevZ + FixedMul (ticFrac, _f_Z() - PrevZ); return ret; } fixedvec3 PosPlusZ(fixed_t zadd) const { - fixedvec3 ret = { X(), Y(), Z() + zadd }; + fixedvec3 ret = { _f_X(), _f_Y(), _f_Z() + zadd }; return ret; } - fixed_t Top() const + DVector3 PosPlusZ(double zadd) const { - return Z() + height; + return { X(), Y(), Z() + zadd }; } - void SetZ(fixed_t newz, bool moving = true) + DVector3 PosAtZ(double zadd) const + { + return{ X(), Y(), zadd }; + } + fixed_t _f_Top() const + { + return _f_Z() + FLOAT2FIXED(Height); + } + void _f_SetZ(fixed_t newz, bool moving = true) { __pos.z = newz; } - void AddZ(fixed_t newz, bool moving = true) + void _f_AddZ(fixed_t newz, bool moving = true) { __pos.z += newz; } + double Top() const + { + return Z() + Height; + } + double Center() const + { + return Z() + Height/2; + } + double _pushfactor() const + { + return FIXED2DBL(pushfactor); + } + double _bouncefactor() const + { + return FIXED2DBL(bouncefactor); + } + void SetZ(double newz, bool moving = true) + { + __pos.z = FLOAT2FIXED(newz); + } + void AddZ(double newz, bool moving = true) + { + __pos.z += FLOAT2FIXED(newz); + if (!moving) PrevZ = __pos.z; + } // These are not for general use as they do not link the actor into the world! void SetXY(fixed_t xx, fixed_t yy) @@ -1273,6 +1472,12 @@ public: __pos.y = yy; __pos.z = zz; } + void SetXYZ(double xx, double yy, double zz) + { + __pos.x = FLOAT2FIXED(xx); + __pos.y = FLOAT2FIXED(yy); + __pos.z = FLOAT2FIXED(zz); + } void SetXY(const fixedvec2 &npos) { __pos.x = npos.x; @@ -1284,6 +1489,87 @@ public: __pos.y = npos.y; __pos.z = npos.z; } + void SetXYZ(const DVector3 &npos) + { + __pos.x = FLOAT2FIXED(npos.X); + __pos.y = FLOAT2FIXED(npos.Y); + __pos.z = FLOAT2FIXED(npos.Z); + } + + double VelXYToSpeed() const + { + return DVector2(Vel.X, Vel.Y).Length(); + } + + double VelToSpeed() const + { + return Vel.Length(); + } + + void AngleFromVel() + { + Angles.Yaw = VecToAngle(Vel.X, Vel.Y); + } + + void VelFromAngle() + { + Vel.X = Speed * Angles.Yaw.Cos(); + Vel.Y = Speed * Angles.Yaw.Sin(); + } + + void VelFromAngle(double speed) + { + Vel.X = speed * Angles.Yaw.Cos(); + Vel.Y = speed * Angles.Yaw.Sin(); + } + + void VelFromAngle(DAngle angle, double speed) + { + Vel.X = speed * angle.Cos(); + Vel.Y = speed * angle.Sin(); + } + + void Thrust() + { + Vel.X += Speed * Angles.Yaw.Cos(); + Vel.Y += Speed * Angles.Yaw.Sin(); + } + + void Thrust(double speed) + { + Vel.X += speed * Angles.Yaw.Cos(); + Vel.Y += speed * Angles.Yaw.Sin(); + } + + void Thrust(DAngle angle, double speed) + { + Vel.X += speed * angle.Cos(); + Vel.Y += speed * angle.Sin(); + } + + void Vel3DFromAngle(DAngle angle, DAngle pitch, double speed) + { + double cospitch = pitch.Cos(); + Vel.X = speed * cospitch * angle.Cos(); + Vel.Y = speed * cospitch * angle.Sin(); + Vel.Z = speed * -pitch.Sin(); + } + + void Vel3DFromAngle(DAngle pitch, double speed) + { + double cospitch = pitch.Cos(); + Vel.X = speed * cospitch * Angles.Yaw.Cos(); + Vel.Y = speed * cospitch * Angles.Yaw.Sin(); + Vel.Z = speed * -pitch.Sin(); + } + + // This is used by many vertical velocity calculations. + // Better have it in one place, if something needs to be changed about the formula. + double DistanceBySpeed(AActor *dest, double speed) + { + return MAX(1., Distance2D(dest) / speed); + } + // begin of GZDoom specific additions TArray > dynamiclights; @@ -1369,6 +1655,14 @@ inline AActor *Spawn (PClassActor *type, const fixedvec3 &pos, replace_t allowre return AActor::StaticSpawn (type, pos.x, pos.y, pos.z, allowreplacement); } +inline AActor *Spawn(PClassActor *type, const DVector3 &pos, replace_t allowreplacement) +{ + fixed_t zz; + if (pos.Z != ONFLOORZ && pos.Z != ONCEILINGZ && pos.Z != FLOATRANDZ) zz = FLOAT2FIXED(pos.Z); + else zz = (int)pos.Z; + return Spawn(type, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), zz, allowreplacement); +} + AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement); AActor *Spawn (FName classname, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement); @@ -1377,11 +1671,27 @@ inline AActor *Spawn (const char *type, const fixedvec3 &pos, replace_t allowrep return Spawn (type, pos.x, pos.y, pos.z, allowreplacement); } +inline AActor *Spawn(const char *type, const DVector3 &pos, replace_t allowreplacement) +{ + fixed_t zz; + if (pos.Z != ONFLOORZ && pos.Z != ONCEILINGZ && pos.Z != FLOATRANDZ) zz = FLOAT2FIXED(pos.Z); + else zz = (int)pos.Z; + return Spawn(type, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), zz, allowreplacement); +} + inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowreplacement) { return Spawn (classname, pos.x, pos.y, pos.z, allowreplacement); } +inline AActor *Spawn(FName type, const DVector3 &pos, replace_t allowreplacement) +{ + fixed_t zz; + if (pos.Z != ONFLOORZ && pos.Z != ONCEILINGZ && pos.Z != FLOATRANDZ) zz = FLOAT2FIXED(pos.Z); + else zz = (int)pos.Z; + return Spawn(type, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), zz, allowreplacement); +} + template inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) @@ -1395,13 +1705,27 @@ inline T *Spawn (const fixedvec3 &pos, replace_t allowreplacement) return static_cast(AActor::StaticSpawn (RUNTIME_TEMPLATE_CLASS(T), pos.x, pos.y, pos.z, allowreplacement)); } -inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle) +template +inline T *Spawn(const DVector3 &pos, replace_t allowreplacement) +{ + fixed_t zz; + if (pos.Z != ONFLOORZ && pos.Z != ONCEILINGZ && pos.Z != FLOATRANDZ) zz = FLOAT2FIXED(pos.Z); + else zz = (int)pos.Z; + return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), zz, allowreplacement)); +} + +inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle) { fixedvec2 ret = { FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]), FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) }; return ret; } +inline fixedvec2 Vec2Angle(fixed_t length, DAngle angle) +{ + return { xs_CRoundToInt(length * angle.Cos()), xs_CRoundToInt(length * angle.Sin()) }; +} + void PrintMiscActorInfo(AActor * query); AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, ActorFlags actorMask, DWORD wallMask); @@ -1409,7 +1733,7 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, struct FTranslatedLineTarget { AActor *linetarget; - angle_t angleFromSource; + DAngle angleFromSource; bool unlinked; // found by a trace that went through an unlinked portal. }; diff --git a/src/am_map.cpp b/src/am_map.cpp index 8fab7e5ac..d0caf9f28 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -648,7 +648,7 @@ CUSTOM_CVAR (Int, am_cheat, 0, 0) #define AM_NUMMARKPOINTS 10 -// player radius for automap checking +// player _f_radius() for automap checking #define PLAYERRADIUS 16*MAPUNIT // how much the automap moves window per tic in frame-buffer coordinates @@ -1012,8 +1012,8 @@ void AM_restoreScaleAndLoc () } else { - m_x = (players[consoleplayer].camera->X() >> FRACTOMAPBITS) - m_w/2; - m_y = (players[consoleplayer].camera->Y() >> FRACTOMAPBITS)- m_h/2; + m_x = (players[consoleplayer].camera->_f_X() >> FRACTOMAPBITS) - m_w/2; + m_y = (players[consoleplayer].camera->_f_Y() >> FRACTOMAPBITS)- m_h/2; } m_x2 = m_x + m_w; m_y2 = m_y + m_h; @@ -1129,7 +1129,7 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) { xs[i] -= pivotx; ys[i] -= pivoty; - AM_rotate (&xs[i], &ys[i], ANG90 - players[consoleplayer].camera->angle); + AM_rotate (&xs[i], &ys[i], ANG90 - players[consoleplayer].camera->_f_angle()); if (i == 5) break; @@ -1150,7 +1150,7 @@ static void AM_ClipRotatedExtents (fixed_t pivotx, fixed_t pivoty) // ys[4] = rmax_y; // else if (ys[4] < rmin_y) // ys[4] = rmin_y; - AM_rotate (&xs[4], &ys[4], ANG270 - players[consoleplayer].camera->angle); + AM_rotate (&xs[4], &ys[4], ANG270 - players[consoleplayer].camera->_f_angle()); m_x = xs[4] + pivotx - m_w/2; m_y = ys[4] + pivoty - m_h/2; #endif @@ -1216,7 +1216,7 @@ void AM_changeWindowLoc () oincy = incy = Scale(m_paninc.y, SCREENHEIGHT, 200); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - AM_rotate(&incx, &incy, players[consoleplayer].camera->angle - ANG90); + AM_rotate(&incx, &incy, players[consoleplayer].camera->_f_angle() - ANG90); } m_x += incx; @@ -1263,8 +1263,8 @@ void AM_initVariables () if (playeringame[pnum]) break; assert(pnum >= 0 && pnum < MAXPLAYERS); - m_x = (players[pnum].camera->X() >> FRACTOMAPBITS) - m_w/2; - m_y = (players[pnum].camera->Y() >> FRACTOMAPBITS) - m_h/2; + m_x = (players[pnum].camera->_f_X() >> FRACTOMAPBITS) - m_w/2; + m_y = (players[pnum].camera->_f_Y() >> FRACTOMAPBITS) - m_h/2; AM_changeWindowLoc(); // for saving & restoring @@ -1585,25 +1585,25 @@ void AM_doFollowPlayer () fixed_t sx, sy; if (players[consoleplayer].camera != NULL && - (f_oldloc.x != players[consoleplayer].camera->X() || - f_oldloc.y != players[consoleplayer].camera->Y())) + (f_oldloc.x != players[consoleplayer].camera->_f_X() || + f_oldloc.y != players[consoleplayer].camera->_f_Y())) { - m_x = (players[consoleplayer].camera->X() >> FRACTOMAPBITS) - m_w/2; - m_y = (players[consoleplayer].camera->Y() >> FRACTOMAPBITS) - m_h/2; + m_x = (players[consoleplayer].camera->_f_X() >> FRACTOMAPBITS) - m_w/2; + m_y = (players[consoleplayer].camera->_f_Y() >> FRACTOMAPBITS) - m_h/2; m_x2 = m_x + m_w; m_y2 = m_y + m_h; // do the parallax parchment scrolling. - sx = (players[consoleplayer].camera->X() - f_oldloc.x) >> FRACTOMAPBITS; - sy = (f_oldloc.y - players[consoleplayer].camera->Y()) >> FRACTOMAPBITS; + sx = (players[consoleplayer].camera->_f_X() - f_oldloc.x) >> FRACTOMAPBITS; + sy = (f_oldloc.y - players[consoleplayer].camera->_f_Y()) >> FRACTOMAPBITS; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - AM_rotate (&sx, &sy, players[consoleplayer].camera->angle - ANG90); + AM_rotate (&sx, &sy, players[consoleplayer].camera->_f_angle() - ANG90); } AM_ScrollParchment (sx, sy); - f_oldloc.x = players[consoleplayer].camera->X(); - f_oldloc.y = players[consoleplayer].camera->Y(); + f_oldloc.x = players[consoleplayer].camera->_f_X(); + f_oldloc.y = players[consoleplayer].camera->_f_Y(); } } @@ -2042,7 +2042,7 @@ void AM_drawSubsectors() // Apply the automap's rotation to the texture origin. if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - rotation += ANG90 - players[consoleplayer].camera->angle; + rotation += ANG90 - players[consoleplayer].camera->_f_angle(); AM_rotatePoint(&originpt.x, &originpt.y); } originx = f_x + ((originpt.x - m_x) * scale / float(1 << 24)); @@ -2588,7 +2588,7 @@ void AM_rotatePoint (fixed_t *x, fixed_t *y) fixed_t pivoty = m_y + m_h/2; *x -= pivotx; *y -= pivoty; - AM_rotate (x, y, ANG90 - players[consoleplayer].camera->angle); + AM_rotate (x, y, ANG90 - players[consoleplayer].camera->_f_angle()); *x += pivotx; *y += pivoty; } @@ -2668,7 +2668,7 @@ void AM_drawPlayers () mline_t *arrow; int numarrowlines; - fixedvec2 pos = am_portaloverlay? players[consoleplayer].camera->GetPortalTransition(players[consoleplayer].viewheight) : (fixedvec2)players[consoleplayer].camera->Pos(); + fixedvec2 pos = am_portaloverlay? players[consoleplayer].camera->GetPortalTransition(players[consoleplayer].viewheight) : (fixedvec2)players[consoleplayer].camera->_f_Pos(); pt.x = pos.x >> FRACTOMAPBITS; pt.y = pos.y >> FRACTOMAPBITS; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) @@ -2678,7 +2678,7 @@ void AM_drawPlayers () } else { - angle = players[consoleplayer].camera->angle; + angle = players[consoleplayer].camera->_f_angle(); } if (am_cheat != 0 && CheatMapArrow.Size() > 0) @@ -2736,12 +2736,12 @@ void AM_drawPlayers () pt.x = pos.x >> FRACTOMAPBITS; pt.y = pos.y >> FRACTOMAPBITS; - angle = p->mo->angle; + angle = p->mo->_f_angle(); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint (&pt.x, &pt.y); - angle -= players[consoleplayer].camera->angle - ANG90; + angle -= players[consoleplayer].camera->_f_angle() - ANG90; } AM_drawLineCharacter(&MapArrow[0], MapArrow.Size(), 0, angle, color, pt.x, pt.y); @@ -2770,12 +2770,12 @@ void AM_drawKeys () p.x = pos.x >> FRACTOMAPBITS; p.y = pos.y >> FRACTOMAPBITS; - angle = key->angle; + angle = key->_f_angle(); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint (&p.x, &p.y); - angle += ANG90 - players[consoleplayer].camera->angle; + angle += ANG90 - players[consoleplayer].camera->_f_angle(); } if (key->flags & MF_SPECIAL) @@ -2830,11 +2830,11 @@ void AM_drawThings () const size_t spriteIndex = sprite.spriteframes + (show > 1 ? t->frame : 0); frame = &SpriteFrames[spriteIndex]; - angle_t angle = ANGLE_270 - t->angle; + angle_t angle = ANGLE_270 - t->_f_angle(); if (frame->Texture[0] != frame->Texture[1]) angle += (ANGLE_180 / 16); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { - angle += players[consoleplayer].camera->angle - ANGLE_90; + angle += players[consoleplayer].camera->_f_angle() - ANGLE_90; } rotation = angle >> 28; @@ -2844,8 +2844,8 @@ void AM_drawThings () if (texture == NULL) goto drawTriangle; // fall back to standard display if no sprite can be found. - const fixed_t spriteXScale = FixedMul(t->scaleX, 10 * scale_mtof); - const fixed_t spriteYScale = FixedMul(t->scaleY, 10 * scale_mtof); + const fixed_t spriteXScale = fixed_t(t->Scale.X * 10 * scale_mtof); + const fixed_t spriteYScale = fixed_t(t->Scale.Y * 10 * scale_mtof); DrawMarker (texture, p.x, p.y, 0, !!(frame->Flip & (1 << rotation)), spriteXScale, spriteYScale, t->Translation, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]); @@ -2853,12 +2853,12 @@ void AM_drawThings () else { drawTriangle: - angle = t->angle; + angle = t->_f_angle(); if (am_rotate == 1 || (am_rotate == 2 && viewactive)) { AM_rotatePoint (&p.x, &p.y); - angle += ANG90 - players[consoleplayer].camera->angle; + angle += ANG90 - players[consoleplayer].camera->_f_angle(); } color = AMColors[AMColors.ThingColor]; @@ -2920,7 +2920,7 @@ void AM_drawThings () { { -MAPUNIT, MAPUNIT }, { -MAPUNIT, -MAPUNIT } }, }; - AM_drawLineCharacter (box, 4, t->radius >> FRACTOMAPBITS, angle - t->angle, color, p.x, p.y); + AM_drawLineCharacter (box, 4, t->_f_radius() >> FRACTOMAPBITS, angle - t->_f_angle(), color, p.x, p.y); } } } @@ -3041,8 +3041,8 @@ void AM_drawAuthorMarkers () marked->subsector->flags & SSECF_DRAWN : marked->Sector->MoreFlags & SECF_DRAWN))) { - DrawMarker (tex, marked->X() >> FRACTOMAPBITS, marked->Y() >> FRACTOMAPBITS, 0, - flip, mark->scaleX, mark->scaleY, mark->Translation, + DrawMarker (tex, marked->_f_X() >> FRACTOMAPBITS, marked->_f_Y() >> FRACTOMAPBITS, 0, + flip, FLOAT2FIXED(mark->Scale.X), FLOAT2FIXED(mark->Scale.Y), mark->Translation, mark->alpha, mark->fillcolor, mark->RenderStyle); } marked = mark->args[0] != 0 ? it.Next() : NULL; diff --git a/src/b_func.cpp b/src/b_func.cpp index 70ffadce8..98653ca9e 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -36,7 +36,7 @@ bool DBot::Reachable (AActor *rtarget) if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget) - rtarget->Sector->floorplane.ZatPoint (rtarget)) - < player->mo->height) //Where rtarget is, player->mo can't be. + < player->mo->_f_height()) //Where rtarget is, player->mo can't be. return false; sector_t *last_s = player->mo->Sector; @@ -44,7 +44,7 @@ bool DBot::Reachable (AActor *rtarget) fixed_t estimated_dist = player->mo->AproxDistance(rtarget); bool reachable = true; - FPathTraverse it(player->mo->X()+player->mo->vel.x, player->mo->Y()+player->mo->vel.y, rtarget->X(), rtarget->Y(), PT_ADDLINES|PT_ADDTHINGS); + FPathTraverse it(player->mo->_f_X()+player->mo->_f_velx(), player->mo->_f_Y()+player->mo->_f_vely(), rtarget->_f_X(), rtarget->_f_Y(), PT_ADDLINES|PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) { @@ -58,8 +58,8 @@ bool DBot::Reachable (AActor *rtarget) frac = in->frac - FixedDiv (4*FRACUNIT, MAX_TRAVERSE_DIST); dist = FixedMul (frac, MAX_TRAVERSE_DIST); - hitx = it.Trace().x + FixedMul (player->mo->vel.x, frac); - hity = it.Trace().y + FixedMul (player->mo->vel.y, frac); + hitx = it.Trace().x + FixedMul (player->mo->_f_velx(), frac); + hity = it.Trace().y + FixedMul (player->mo->_f_vely(), frac); if (in->isaline) { @@ -79,7 +79,7 @@ bool DBot::Reachable (AActor *rtarget) if (!bglobal.IsDangerous (s) && //Any nukage/lava? (floorheight <= (last_z+MAXMOVEHEIGHT) && ((ceilingheight == floorheight && line->special) - || (ceilingheight - floorheight) >= player->mo->height))) //Does it fit? + || (ceilingheight - floorheight) >= player->mo->_f_height()))) //Does it fit? { last_z = floorheight; last_s = s; @@ -127,7 +127,7 @@ bool DBot::Check_LOS (AActor *to, angle_t vangle) if (vangle == 0) return false; //Looker seems to be blind. - return absangle(player->mo->AngleTo(to) - player->mo->angle) <= vangle/2; + return absangle(player->mo->__f_AngleTo(to) - player->mo->_f_angle()) <= vangle/2; } //------------------------------------- @@ -170,7 +170,7 @@ void DBot::Dofire (ticcmd_t *cmd) no_fire = true; //Distance to enemy. - dist = player->mo->AproxDistance(enemy, player->mo->vel.x - enemy->vel.x, player->mo->vel.y - enemy->vel.y); + dist = player->mo->AproxDistance(enemy, player->mo->_f_velx() - enemy->_f_velx(), player->mo->_f_vely() - enemy->_f_vely()); //FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go. if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) @@ -192,7 +192,7 @@ void DBot::Dofire (ticcmd_t *cmd) else { //*4 is for atmosphere, the chainsaws sounding and all.. - no_fire = (dist > (MELEERANGE*4)); + no_fire = (dist > (FLOAT2FIXED(MELEERANGE)*4)); } } else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG) @@ -212,7 +212,7 @@ void DBot::Dofire (ticcmd_t *cmd) { angle = an; //have to be somewhat precise. to avoid suicide. - if (absangle(angle - player->mo->angle) < 12*ANGLE_1) + if (absangle(angle - player->mo->_f_angle()) < 12*ANGLE_1) { t_rocket = 9; no_fire = false; @@ -222,16 +222,16 @@ void DBot::Dofire (ticcmd_t *cmd) // prediction aiming shootmissile: dist = player->mo->AproxDistance (enemy); - m = dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; - bglobal.SetBodyAt (enemy->X() + enemy->vel.x*m*2, enemy->Y() + enemy->vel.y*m*2, enemy->Z(), 1); - angle = player->mo->AngleTo(bglobal.body1); + m = dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->_f_speed(); + bglobal.SetBodyAt (enemy->_f_X() + enemy->_f_velx()*m*2, enemy->_f_Y() + enemy->_f_vely()*m*2, enemy->_f_Z(), 1); + angle = player->mo->__f_AngleTo(bglobal.body1); if (Check_LOS (enemy, SHOOTFOV)) no_fire = false; } else { //Other weapons, mostly instant hit stuff. - angle = player->mo->AngleTo(enemy); + angle = player->mo->__f_AngleTo(enemy); aiming_penalty = 0; if (enemy->flags & MF_SHADOW) aiming_penalty += (pr_botdofire()%25)+10; @@ -254,7 +254,7 @@ shootmissile: angle -= m; } - if (absangle(angle - player->mo->angle) < 4*ANGLE_1) + if (absangle(angle - player->mo->_f_angle()) < 4*ANGLE_1) { increase = !increase; } @@ -456,7 +456,7 @@ void FCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum) // //Returns NULL if shouldn't fire //else an angle (in degrees) are given -//This function assumes actor->player->angle +//This function assumes actor->player->_f_angle() //has been set an is the main aiming angle. @@ -467,22 +467,16 @@ fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) th->target = source; // where it came from - float speed = (float)th->Speed; - fixedvec3 fixvel = source->Vec3To(dest); - DVector3 velocity(fixvel.x, fixvel.y, fixvel.z); - velocity.MakeUnit(); - th->vel.x = FLOAT2FIXED(velocity[0] * speed); - th->vel.y = FLOAT2FIXED(velocity[1] * speed); - th->vel.z = FLOAT2FIXED(velocity[2] * speed); + th->Vel = source->Vec3To(dest).Resized(th->Speed); fixed_t dist = 0; while (dist < SAFE_SELF_MISDIST) { - dist += th->Speed; - th->Move(th->vel.x, th->vel.y, th->vel.z); - if (!CleanAhead (th, th->X(), th->Y(), cmd)) + dist += th->_f_speed(); + th->Move(th->_f_velx(), th->_f_vely(), th->_f_velz()); + if (!CleanAhead (th, th->_f_X(), th->_f_Y(), cmd)) break; } th->Destroy (); @@ -496,9 +490,9 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) AActor *actor; int m; - bglobal.SetBodyAt (player->mo->X() + FixedMul(player->mo->vel.x, 5*FRACUNIT), - player->mo->Y() + FixedMul(player->mo->vel.y, 5*FRACUNIT), - player->mo->Z() + (player->mo->height / 2), 2); + bglobal.SetBodyAt (player->mo->_f_X() + FixedMul(player->mo->_f_velx(), 5*FRACUNIT), + player->mo->_f_Y() + FixedMul(player->mo->_f_vely(), 5*FRACUNIT), + player->mo->_f_Z() + (player->mo->_f_height() / 2), 2); actor = bglobal.body2; @@ -506,20 +500,20 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) if (dist < SAFE_SELF_MISDIST) return 0; //Predict. - m = (((dist+1)/FRACUNIT) / GetDefaultByName("Rocket")->Speed); + m = (((dist+1)/FRACUNIT) / GetDefaultByName("Rocket")->_f_speed()); - bglobal.SetBodyAt (enemy->X() + FixedMul(enemy->vel.x, (m+2*FRACUNIT)), - enemy->Y() + FixedMul(enemy->vel.y, (m+2*FRACUNIT)), ONFLOORZ, 1); + bglobal.SetBodyAt (enemy->_f_X() + FixedMul(enemy->_f_velx(), (m+2*FRACUNIT)), + enemy->_f_Y() + FixedMul(enemy->_f_vely(), (m+2*FRACUNIT)), ONFLOORZ, 1); //try the predicted location if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile { FCheckPosition tm; - if (bglobal.SafeCheckPosition (player->mo, actor->X(), actor->Y(), tm)) + if (bglobal.SafeCheckPosition (player->mo, actor->_f_X(), actor->_f_Y(), tm)) { if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST) { - ang = actor->AngleTo(bglobal.body1); + ang = actor->__f_AngleTo(bglobal.body1); return ang; } } @@ -529,7 +523,7 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) { - ang = player->mo->AngleTo(enemy); + ang = player->mo->__f_AngleTo(enemy); return ang; } } diff --git a/src/b_move.cpp b/src/b_move.cpp index 6138ba3ad..63a0bc623 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -21,6 +21,7 @@ #include "d_player.h" #include "p_spec.h" #include "p_checkposition.h" +#include "math/cmath.h" static FRandom pr_botopendoor ("BotOpenDoor"); static FRandom pr_bottrywalk ("BotTryWalk"); @@ -38,7 +39,7 @@ void DBot::Roam (ticcmd_t *cmd) if (Reachable(dest)) { // Straight towards it. - angle = player->mo->AngleTo(dest); + angle = player->mo->__f_AngleTo(dest); } else if (player->mo->movedir < 8) // turn towards movement direction if not there yet { @@ -70,8 +71,8 @@ bool DBot::Move (ticcmd_t *cmd) if ((unsigned)player->mo->movedir >= 8) I_Error ("Weird bot movedir!"); - tryx = player->mo->X() + 8*xspeed[player->mo->movedir]; - tryy = player->mo->Y() + 8*yspeed[player->mo->movedir]; + tryx = player->mo->_f_X() + 8*xspeed[player->mo->movedir]; + tryy = player->mo->_f_Y() + 8*yspeed[player->mo->movedir]; try_ok = bglobal.CleanAhead (player->mo, tryx, tryy, cmd); @@ -147,7 +148,7 @@ void DBot::NewChaseDir (ticcmd_t *cmd) olddir = (dirtype_t)player->mo->movedir; turnaround = opposite[olddir]; - fixedvec2 delta = player->mo->Vec2To(dest); + fixedvec2 delta = player->mo->_f_Vec2To(dest); if (delta.x > 10*FRACUNIT) d[1] = DI_EAST; @@ -269,21 +270,21 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm if (!(thing->flags & MF_NOCLIP) ) { fixed_t maxstep = thing->MaxStepHeight; - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) return false; // doesn't fit if (!(thing->flags&MF_MISSILE)) { - if(tm.floorz > (thing->Sector->floorplane.ZatPoint (x, y)+MAXMOVEHEIGHT)) //Too high wall + if(tm._f_floorz() > (thing->Sector->floorplane.ZatPoint (x, y)+MAXMOVEHEIGHT)) //Too high wall return false; //Jumpable - if(tm.floorz>(thing->Sector->floorplane.ZatPoint (x, y)+thing->MaxStepHeight)) + if(tm._f_floorz()>(thing->Sector->floorplane.ZatPoint (x, y)+thing->MaxStepHeight)) cmd->ucmd.buttons |= BT_JUMP; if ( !(thing->flags & MF_TELEPORT) && - tm.ceilingz - thing->Z() < thing->height) + tm.ceilingz < thing->Top()) return false; // mobj must lower itself to fit // jump out of water @@ -291,12 +292,12 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm // maxstep=37*FRACUNIT; if ( !(thing->flags & MF_TELEPORT) && - (tm.floorz - thing->Z() > maxstep ) ) + (tm._f_floorz() - thing->_f_Z() > maxstep ) ) return false; // too big a step up if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT)) - && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight ) + && tm._f_floorz() - tm.dropoffz > thing->MaxDropOffHeight ) return false; // don't stand over a dropoff } @@ -304,13 +305,13 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm return true; } -#define OKAYRANGE (5*ANGLE_1) //counts *2, when angle is in range, turning is not executed. -#define MAXTURN (15*ANGLE_1) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash +#define OKAYRANGE (5) //counts *2, when angle is in range, turning is not executed. +#define MAXTURN (15) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash #define TURNSENS 3 //Higher is smoother but slower turn. void DBot::TurnToAng () { - int maxturn = MAXTURN; + double maxturn = MAXTURN; if (player->ReadyWeapon != NULL) { @@ -330,16 +331,16 @@ void DBot::TurnToAng () maxturn = 3; } - int distance = angle - player->mo->angle; + DAngle distance = deltaangle(player->mo->Angles.Yaw, ANGLE2DBL(angle)); - if (abs (distance) < OKAYRANGE && !enemy) + if (fabs (distance) < OKAYRANGE && !enemy) return; distance /= TURNSENS; - if (abs (distance) > maxturn) + if (fabs (distance) > maxturn) distance = distance < 0 ? -maxturn : maxturn; - player->mo->angle += distance; + player->mo->Angles.Yaw += distance; } void DBot::Pitch (AActor *target) @@ -347,9 +348,9 @@ void DBot::Pitch (AActor *target) double aim; double diff; - diff = target->Z() - player->mo->Z(); - aim = atan(diff / (double)player->mo->AproxDistance(target)); - player->mo->pitch = -(int)(aim * ANGLE_180/M_PI); + diff = target->_f_Z() - player->mo->_f_Z(); + aim = g_atan(diff / (double)player->mo->AproxDistance(target)); + player->mo->Angles.Pitch = ToDegrees(aim); } //Checks if a sector is dangerous. diff --git a/src/b_think.cpp b/src/b_think.cpp index 88c17fd87..0d02f76f8 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -20,6 +20,7 @@ #include "d_net.h" #include "d_event.h" #include "d_player.h" +#include "vectors.h" static FRandom pr_botmove ("BotMove"); @@ -39,20 +40,21 @@ void DBot::Think () if (teamplay || !deathmatch) mate = Choose_Mate (); - angle_t oldyaw = player->mo->angle; - int oldpitch = player->mo->pitch; + AActor *actor = player->mo; + DAngle oldyaw = actor->Angles.Yaw; + DAngle oldpitch = actor->Angles.Pitch; Set_enemy (); ThinkForMove (cmd); TurnToAng (); - cmd->ucmd.yaw = (short)((player->mo->angle - oldyaw) >> 16) / ticdup; - cmd->ucmd.pitch = (short)((oldpitch - player->mo->pitch) >> 16); + cmd->ucmd.yaw = (short)((actor->Angles.Yaw - oldyaw).Degrees * (65536 / 360.f)) / ticdup; + cmd->ucmd.pitch = (short)((oldpitch - actor->Angles.Pitch).Degrees * (65536 / 360.f)); if (cmd->ucmd.pitch == -32768) cmd->ucmd.pitch = -32767; cmd->ucmd.pitch /= ticdup; - player->mo->angle = oldyaw + (cmd->ucmd.yaw << 16) * ticdup; - player->mo->pitch = oldpitch - (cmd->ucmd.pitch << 16) * ticdup; + actor->Angles.Yaw = oldyaw + DAngle(cmd->ucmd.yaw * ticdup * (360 / 65536.f)); + actor->Angles.Pitch = oldpitch - DAngle(cmd->ucmd.pitch * ticdup * (360 / 65536.f)); } if (t_active) t_active--; @@ -85,22 +87,22 @@ void DBot::ThinkForMove (ticcmd_t *cmd) dist = dest ? player->mo->AproxDistance(dest) : 0; if (missile && - ((!missile->vel.x || !missile->vel.y) || !Check_LOS(missile, SHOOTFOV*3/2))) + ((!missile->_f_velx() || !missile->_f_vely()) || !Check_LOS(missile, SHOOTFOV*3/2))) { sleft = !sleft; missile = NULL; //Probably ended its travel. } - if (player->mo->pitch > 0) - player->mo->pitch -= 80; - else if (player->mo->pitch <= -60) - player->mo->pitch += 80; + if (player->mo->Angles.Pitch > 0) + player->mo->Angles.Pitch -= 80; + else if (player->mo->Angles.Pitch <= -60) + player->mo->Angles.Pitch += 80; //HOW TO MOVE: if (missile && (player->mo->AproxDistance(missile)mo->AngleTo(missile); + angle = player->mo->__f_AngleTo(missile); cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN; cmd->ucmd.forwardmove = -FORWARDRUN; //Back IS best. @@ -166,7 +168,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) sleft = !sleft; } - angle = player->mo->AngleTo(enemy); + angle = player->mo->__f_AngleTo(enemy); if (player->ReadyWeapon == NULL || player->mo->AproxDistance(enemy) > @@ -207,7 +209,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) goto roam; } - angle = player->mo->AngleTo(mate); + angle = player->mo->__f_AngleTo(mate); matedist = player->mo->AproxDistance(mate); if (matedist > (FRIEND_DIST*2)) @@ -242,7 +244,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) (pr_botmove()%100)>skill.isp) && player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) dest = enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy. else //hide while t_fight, but keep view at enemy. - angle = player->mo->AngleTo(enemy); + angle = player->mo->__f_AngleTo(enemy); } //Just a monster, so kill it. else dest = enemy; @@ -304,8 +306,8 @@ void DBot::ThinkForMove (ticcmd_t *cmd) if (t_fight<(AFTERTICS/2)) player->mo->flags |= MF_DROPOFF; - oldx = player->mo->X(); - oldy = player->mo->Y(); + oldx = player->mo->_f_X(); + oldy = player->mo->_f_Y(); } //BOT_WhatToGet diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 810411609..44c37336f 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -875,7 +875,7 @@ CCMD(linetarget) FTranslatedLineTarget t; if (CheckCheatmode () || players[consoleplayer].mo == NULL) return; - P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &t, 0); + P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->Angles.Yaw, MISSILERANGE, &t, 0.); if (t.linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", @@ -892,8 +892,8 @@ CCMD(info) FTranslatedLineTarget t; if (CheckCheatmode () || players[consoleplayer].mo == NULL) return; - P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, - &t, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); + P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->Angles.Yaw, MISSILERANGE, + &t, 0., ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); if (t.linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", @@ -903,7 +903,7 @@ CCMD(info) PrintMiscActorInfo(t.linetarget); } else Printf("No target found. Info cannot find actors that have " - "the NOBLOCKMAP flag or have height/radius of 0.\n"); + "the NOBLOCKMAP flag or have height/_f_radius() of 0.\n"); } typedef bool (*ActorTypeChecker) (AActor *); @@ -943,9 +943,8 @@ static void PrintFilteredActorList(const ActorTypeChecker IsActorType, const cha { if ((FilterClass == NULL || mo->IsA(FilterClass)) && IsActorType(mo)) { - Printf ("%s at (%d,%d,%d)\n", - mo->GetClass()->TypeName.GetChars(), - mo->X() >> FRACBITS, mo->Y() >> FRACBITS, mo->Z() >> FRACBITS); + Printf ("%s at (%f,%f,%f)\n", + mo->GetClass()->TypeName.GetChars(), mo->X(), mo->Y(), mo->Z()); } } } @@ -1087,7 +1086,7 @@ CCMD(currentpos) if(mo) { Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n", - FIXED2DBL(mo->X()), FIXED2DBL(mo->Y()), FIXED2DBL(mo->Z()), ANGLE2DBL(mo->angle), FIXED2DBL(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel); + mo->X(), mo->Y(), mo->Z(), mo->Angles.Yaw, mo->floorz, mo->Sector->sectornum, mo->Sector->lightlevel); } else { diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 8c456517e..7a0ce0d88 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -903,7 +903,7 @@ static int PatchThing (int thingy) } else if (linelen == 6 && stricmp (Line1, "Height") == 0) { - info->height = val; + info->Height = FIXED2DBL(val); info->projectilepassheight = 0; // needs to be disabled hadHeight = true; } @@ -915,11 +915,11 @@ static int PatchThing (int thingy) { if (stricmp (Line1, "Speed") == 0) { - info->Speed = val; + info->Speed = val; // handle fixed point later. } else if (stricmp (Line1, "Width") == 0) { - info->radius = val; + info->radius = FIXED2FLOAT(val); } else if (stricmp (Line1, "Alpha") == 0) { @@ -928,7 +928,7 @@ static int PatchThing (int thingy) } else if (stricmp (Line1, "Scale") == 0) { - info->scaleY = info->scaleX = clamp (FLOAT2FIXED(atof (Line2)), 1, 256*FRACUNIT); + info->Scale.Y = info->Scale.X = clamp(atof (Line2), 1./65536, 256.); } else if (stricmp (Line1, "Decal") == 0) { @@ -1215,7 +1215,7 @@ static int PatchThing (int thingy) } if (value[1] & 0x00000001) { - info->gravity = FRACUNIT/4; + info->Gravity = 1./4; value[1] &= ~0x00000001; } info->flags2 = ActorFlags2::FromInt (value[1]); @@ -1257,7 +1257,7 @@ static int PatchThing (int thingy) !hadHeight && thingy <= (int)OrgHeights.Size() && thingy > 0) { - info->height = OrgHeights[thingy - 1] * FRACUNIT; + info->Height = OrgHeights[thingy - 1]; info->projectilepassheight = 0; } // If the thing's shadow changed, change its fuzziness if not already specified @@ -1278,9 +1278,9 @@ static int PatchThing (int thingy) } // If this thing's speed is really low (i.e. meant to be a monster), // bump it up, because all speeds are fixed point now. - if (abs(info->Speed) < 256) + if (fabs(info->Speed) >= 256) { - info->Speed <<= FRACBITS; + info->Speed /= FRACUNIT; } if (info->flags & MF_SPECIAL) @@ -1342,7 +1342,7 @@ static int PatchSound (int soundNum) else CHECKKEY ("Zero/One", info->singularity) else CHECKKEY ("Value", info->priority) else CHECKKEY ("Zero 1", info->link) - else CHECKKEY ("Neg. One 1", info->pitch) + else CHECKKEY ("Neg. One 1", info->_f_pitch()) else CHECKKEY ("Neg. One 2", info->volume) else CHECKKEY ("Zero 2", info->data) else CHECKKEY ("Zero 3", info->usefulness) diff --git a/src/d_net.cpp b/src/d_net.cpp index 4d8e33d3d..e6ad65800 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2321,7 +2321,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) else { const AActor *def = GetDefaultByType (typeinfo); - fixedvec3 spawnpos = source->Vec3Angle(def->radius * 2 + source->radius, source->angle, 8 * FRACUNIT); + fixedvec3 spawnpos = source->_f_Vec3Angle(def->_f_radius() * 2 + source->_f_radius(), source->_f_angle(), 8 * FRACUNIT); AActor *spawned = Spawn (typeinfo, spawnpos, ALLOW_REPLACE); if (spawned != NULL) @@ -2348,7 +2348,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) } if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2) { - spawned->angle = source->angle - (ANGLE_1 * angle); + spawned->Angles.Yaw = source->Angles.Yaw - angle; spawned->tid = tid; spawned->special = special; for(i = 0; i < 5; i++) { @@ -2366,16 +2366,16 @@ void Net_DoCommand (int type, BYTE **stream, int player) { FTraceResults trace; - angle_t ang = players[player].mo->angle >> ANGLETOFINESHIFT; - angle_t pitch = (angle_t)(players[player].mo->pitch) >> ANGLETOFINESHIFT; + angle_t ang = players[player].mo->_f_angle() >> ANGLETOFINESHIFT; + angle_t pitch = (angle_t)(players[player].mo->_f_pitch()) >> ANGLETOFINESHIFT; fixed_t vx = FixedMul (finecosine[pitch], finecosine[ang]); fixed_t vy = FixedMul (finecosine[pitch], finesine[ang]); fixed_t vz = -finesine[pitch]; s = ReadString (stream); - if (Trace (players[player].mo->X(), players[player].mo->Y(), - players[player].mo->Top() - (players[player].mo->height>>2), + if (Trace (players[player].mo->_f_X(), players[player].mo->_f_Y(), + players[player].mo->_f_Top() - (players[player].mo->_f_height()>>2), players[player].mo->Sector, vx, vy, vz, 172*FRACUNIT, 0, ML_BLOCKEVERYTHING, players[player].mo, trace, TRACE_NoSky)) @@ -2656,8 +2656,8 @@ void Net_DoCommand (int type, BYTE **stream, int player) break; case DEM_SETPITCHLIMIT: - players[player].MinPitch = ReadByte(stream) * -ANGLE_1; // up - players[player].MaxPitch = ReadByte(stream) * ANGLE_1; // down + players[player].MinPitch = -(double)ReadByte(stream); // up + players[player].MaxPitch = (double)ReadByte(stream); // down break; case DEM_ADVANCEINTER: diff --git a/src/d_player.h b/src/d_player.h index 749736996..8e7a47077 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -114,7 +114,7 @@ public: virtual void PlayIdle (); virtual void PlayRunning (); virtual void ThrowPoisonBag (); - virtual void TweakSpeeds (int &forwardmove, int &sidemove); + virtual void TweakSpeeds (double &forwardmove, double &sidemove); virtual void MorphPlayerThink (); virtual void ActivateMorphWeapon (); AWeapon *PickNewWeapon (PClassAmmo *ammotype); @@ -149,12 +149,12 @@ public: TObjPtr InvSel; // selected inventory item // [GRB] Player class properties - fixed_t JumpZ; + double JumpZ; fixed_t GruntSpeed; fixed_t FallingScreamMinSpeed, FallingScreamMaxSpeed; fixed_t ViewHeight; - fixed_t ForwardMove1, ForwardMove2; - fixed_t SideMove1, SideMove2; + double ForwardMove1, ForwardMove2; + double SideMove1, SideMove2; FTextureID ScoreIcon; int SpawnMask; FNameNoInit MorphWeapon; @@ -292,7 +292,7 @@ struct userinfo_t : TMap { ~userinfo_t(); - int GetAimDist() const + double GetAimDist() const { if (dmflags2 & DF2_NOAUTOAIM) { @@ -302,11 +302,11 @@ struct userinfo_t : TMap float aim = *static_cast(*CheckKey(NAME_Autoaim)); if (aim > 35 || aim < 0) { - return ANGLE_1*35; + return 35.; } else { - return xs_RoundToInt(fabs(aim * ANGLE_1)); + return aim; } } const char *GetName() const @@ -329,13 +329,13 @@ struct userinfo_t : TMap { return *static_cast(*CheckKey(NAME_NeverSwitchOnPickup)); } - fixed_t GetMoveBob() const + double GetMoveBob() const { - return FLOAT2FIXED(*static_cast(*CheckKey(NAME_MoveBob))); + return *static_cast(*CheckKey(NAME_MoveBob)); } - fixed_t GetStillBob() const + double GetStillBob() const { - return FLOAT2FIXED(*static_cast(*CheckKey(NAME_StillBob))); + return *static_cast(*CheckKey(NAME_StillBob)); } int GetPlayerClassNum() const { @@ -405,13 +405,13 @@ public: fixed_t viewz; // focal origin above r.z fixed_t viewheight; // base height above floor for viewz fixed_t deltaviewheight; // squat speed. - fixed_t bob; // bounded/scaled total velocity + double bob; // bounded/scaled total velocity // killough 10/98: used for realistic bobbing (i.e. not simply overall speed) - // mo->vel.x and mo->vel.y represent true velocity experienced by player. + // mo->velx and mo->vely represent true velocity experienced by player. // This only represents the thrust that the player applies himself. // This avoids anomalies with such things as Boom ice and conveyors. - fixedvec2 vel; + DVector2 Vel; bool centering; BYTE turnticks; @@ -488,10 +488,10 @@ public: FString LogText; // [RH] Log for Strife - int MinPitch; // Viewpitch limits (negative is up, positive is down) - int MaxPitch; + DAngle MinPitch; // Viewpitch limits (negative is up, positive is down) + DAngle MaxPitch; - fixed_t crouchfactor; + double crouchfactor; fixed_t crouchoffset; fixed_t crouchviewdelta; @@ -499,7 +499,7 @@ public: // [CW] I moved these here for multiplayer conversation support. TObjPtr ConversationNPC, ConversationPC; - angle_t ConversationNPCAngle; + DAngle ConversationNPCAngle; bool ConversationFaceTalker; fixed_t GetDeltaViewHeight() const @@ -509,9 +509,9 @@ public: void Uncrouch() { - if (crouchfactor != FRACUNIT) + if (crouchfactor != 1) { - crouchfactor = FRACUNIT; + crouchfactor = 1; crouchoffset = 0; crouchdir = 0; crouching = 0; @@ -533,7 +533,7 @@ extern player_t players[MAXPLAYERS]; FArchive &operator<< (FArchive &arc, player_t *&p); -void P_CheckPlayerSprite(AActor *mo, int &spritenum, fixed_t &scalex, fixed_t &scaley); +void P_CheckPlayerSprite(AActor *mo, int &spritenum, DVector2 &scale); inline void AActor::SetFriendPlayer(player_t *player) { @@ -556,7 +556,7 @@ inline bool AActor::IsNoClip2() const return false; } -#define CROUCHSPEED (FRACUNIT/12) +#define CROUCHSPEED (1./12) bool P_IsPlayerTotallyFrozen(const player_t *player); diff --git a/src/doomdata.h b/src/doomdata.h index 4d8254757..ddbf899d5 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -26,6 +26,7 @@ // The most basic types we use, portability. #include "doomtype.h" +#include "vectors.h" // Some global defines, that configure the game. #include "doomdef.h" @@ -357,11 +358,10 @@ struct FMapThing int special; int args[5]; int Conversation; - fixed_t gravity; + double Gravity; fixed_t alpha; DWORD fillcolor; - fixed_t scaleX; - fixed_t scaleY; + DVector2 Scale; int health; int score; short pitch; diff --git a/src/doomdef.h b/src/doomdef.h index 627efe391..346a73f0f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -350,7 +350,7 @@ enum { BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps - BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected. + BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' _f_radius() and height aren't restored properly when resurrected. BCOMPATF_BADTELEPORTERS = 1 << 3, // Ignore tags on Teleport specials BCOMPATF_BADPORTALS = 1 << 4, // Restores the old unstable portal behavior BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild @@ -365,11 +365,14 @@ enum // linedefs. More friction can create mud, sludge, // magnetized floors, etc. Less friction can create ice. -#define MORE_FRICTION_VELOCITY 15000 // mud factor based on velocity +#define MORE_FRICTION_VELOCITY (15000/65536.) // mud factor based on velocity #define ORIG_FRICTION 0xE800 // original value +#define fORIG_FRICTION (ORIG_FRICTION/65536.) #define ORIG_FRICTION_FACTOR 2048 // original value +#define fORIG_FRICTION_FACTOR (2048/65536.) // original value #define FRICTION_LOW 0xf900 #define FRICTION_FLY 0xeb00 +#define fFRICTION_FLY (0xeb00/65536.) #define BLINKTHRESHOLD (4*32) diff --git a/src/doomtype.h b/src/doomtype.h index db4bc7e5d..fa84824f2 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -44,7 +44,6 @@ #include "tarray.h" #include "name.h" #include "zstring.h" -#include "vectors.h" class PClassActor; typedef TMap FClassMap; @@ -252,10 +251,13 @@ enum ESSType SS_BGRA }; -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +// always use our own definition for consistency. +#ifdef M_PI +#undef M_PI #endif +const double M_PI = 3.14159265358979323846; // matches value in gcc v2 math.h + template char ( &_ArraySizeHelper( T (&array)[N] ))[N]; diff --git a/src/farchive.cpp b/src/farchive.cpp index 8fd647fd2..93ec269d7 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1532,3 +1532,21 @@ FArchive &operator<< (FArchive &arc, side_t *&side) { return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides)); } + +FArchive &operator<<(FArchive &arc, DAngle &ang) +{ + arc << ang.Degrees; + return arc; +} + +FArchive &operator<<(FArchive &arc, DVector3 &vec) +{ + arc << vec.X << vec.Y << vec.Z; + return arc; +} + +FArchive &operator<<(FArchive &arc, DVector2 &vec) +{ + arc << vec.X << vec.Y; + return arc; +} diff --git a/src/farchive.h b/src/farchive.h index b646827de..a3f38ff47 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -324,6 +324,10 @@ FArchive &operator<< (FArchive &arc, line_t *&line); FArchive &operator<< (FArchive &arc, vertex_t *&vert); FArchive &operator<< (FArchive &arc, side_t *&side); +FArchive &operator<<(FArchive &arc, DAngle &ang); +FArchive &operator<<(FArchive &arc, DVector3 &vec); +FArchive &operator<<(FArchive &arc, DVector2 &vec); + template diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 953297b31..0e9216d80 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -69,6 +69,7 @@ #include "farchive.h" #include "p_setup.h" #include "p_spec.h" +#include "math/cmath.h" static FRandom pr_script("FScript"); @@ -863,7 +864,7 @@ void FParser::SF_Spawn(void) { int x, y, z; PClassActor *pclass; - angle_t angle = 0; + DAngle angle = 0.; if (CheckArgs(3)) { @@ -889,7 +890,7 @@ void FParser::SF_Spawn(void) if(t_argc >= 4) { - angle = intvalue(t_argv[3]) * (SQWORD)ANG45 / 45; + angle = floatvalue(t_argv[3]); } t_return.type = svt_mobj; @@ -897,7 +898,7 @@ void FParser::SF_Spawn(void) if (t_return.value.mobj) { - t_return.value.mobj->angle = angle; + t_return.value.mobj->Angles.Yaw = angle; if (!DFraggleThinker::ActiveThinker->nocheckposition) { @@ -982,8 +983,7 @@ void FParser::SF_ObjX(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd: SoM's fixed-point fix - t_return.value.f = mo ? mo->X() : 0; // null ptr check + t_return.setDouble(mo ? mo->X() : 0.); } //========================================================================== @@ -1005,8 +1005,7 @@ void FParser::SF_ObjY(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd - t_return.value.f = mo ? mo->Y() : 0; // null ptr check + t_return.setDouble(mo ? mo->Y() : 0.); } //========================================================================== @@ -1028,8 +1027,7 @@ void FParser::SF_ObjZ(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd - t_return.value.f = mo ? mo->Z() : 0; // null ptr check + t_return.setDouble(mo ? mo->Z() : 0.); } @@ -1052,8 +1050,7 @@ void FParser::SF_ObjAngle(void) mo = Script->trigger; } - t_return.type = svt_fixed; // haleyjd: fixed-point -- SoM again :) - t_return.value.f = mo ? (fixed_t)AngleToFixed(mo->angle) : 0; // null ptr check + t_return.setDouble(mo ? mo->Angles.Yaw.Degrees : 0.); } @@ -1257,10 +1254,9 @@ void FParser::SF_PushThing(void) AActor * mo = actorvalue(t_argv[0]); if(!mo) return; - angle_t angle = (angle_t)FixedToAngle(fixedvalue(t_argv[1])); - fixed_t force = fixedvalue(t_argv[2]); - - P_ThrustMobj(mo, angle, force); + DAngle angle = floatvalue(t_argv[1]); + double force = floatvalue(t_argv[2]); + mo->Thrust(angle, force); } } @@ -1334,11 +1330,10 @@ void FParser::SF_MobjMomx(void) if(t_argc > 1) { if(mo) - mo->vel.x = fixedvalue(t_argv[1]); + mo->Vel.X = floatvalue(t_argv[1]); } - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->vel.x : 0; + t_return.setDouble(mo ? mo->Vel.X : 0.); } } @@ -1357,12 +1352,11 @@ void FParser::SF_MobjMomy(void) mo = actorvalue(t_argv[0]); if(t_argc > 1) { - if(mo) - mo->vel.y = fixedvalue(t_argv[1]); + if(mo) + mo->Vel.Y = floatvalue(t_argv[1]); } - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->vel.y : 0; + t_return.setDouble(mo ? mo->Vel.Y : 0.); } } @@ -1379,14 +1373,13 @@ void FParser::SF_MobjMomz(void) if (CheckArgs(1)) { mo = actorvalue(t_argv[0]); - if(t_argc > 1) + if (t_argc > 1) { - if(mo) - mo->vel.z = fixedvalue(t_argv[1]); + if (mo) + mo->Vel.Z = floatvalue(t_argv[1]); } - - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->vel.z : 0; + + t_return.setDouble(mo ? mo->Vel.Z : 0.); } } @@ -1431,7 +1424,7 @@ void FParser::SF_PointToDist(void) double y = floatvalue(t_argv[3]) - floatvalue(t_argv[1]); t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(sqrt(x*x+y*y)); + t_return.value.f = FLOAT2FIXED(g_sqrt(x*x+y*y)); } } @@ -1448,7 +1441,7 @@ void FParser::SF_PointToDist(void) void FParser::SF_SetCamera(void) { - angle_t angle; + DAngle angle; player_t * player; AActor * newcamera; @@ -1464,20 +1457,14 @@ void FParser::SF_SetCamera(void) return; // nullptr check } - angle = t_argc < 2 ? newcamera->angle : (fixed_t)FixedToAngle(fixedvalue(t_argv[1])); + angle = t_argc < 2 ? newcamera->Angles.Yaw : floatvalue(t_argv[1]); - newcamera->special1=newcamera->angle; - newcamera->special2=newcamera->Z(); - newcamera->SetZ(t_argc < 3 ? (newcamera->Z() + (41 << FRACBITS)) : (intvalue(t_argv[2]) << FRACBITS)); - newcamera->angle = angle; - if(t_argc < 4) newcamera->pitch = 0; - else - { - fixed_t pitch = fixedvalue(t_argv[3]); - if (pitch < -50 * FRACUNIT) pitch = -50 * FRACUNIT; - if (pitch > 50 * FRACUNIT) pitch = 50 * FRACUNIT; - newcamera->pitch = xs_CRoundToUInt((pitch / 65536.0f)*(ANGLE_45 / 45.0f)*(20.0f / 32.0f)); - } + newcamera->specialf1 = newcamera->Angles.Yaw.Degrees; + newcamera->specialf2 = newcamera->Z(); + newcamera->SetZ(t_argc < 3 ? newcamera->Z() + 41 : floatvalue(t_argv[2])); + newcamera->Angles.Yaw = angle; + if (t_argc < 4) newcamera->Angles.Pitch = 0.; + else newcamera->Angles.Pitch = clamp(floatvalue(t_argv[3]), -50., 50.) * (20. / 32.); player->camera=newcamera; } } @@ -1498,8 +1485,8 @@ void FParser::SF_ClearCamera(void) if (cam) { player->camera=player->mo; - cam->angle=cam->special1; - cam->SetZ(cam->special2); + cam->Angles.Yaw = cam->specialf1; + cam->SetZ(cam->specialf2); } } @@ -3076,7 +3063,8 @@ void FParser::SF_MoveCamera(void) fixed_t zdist, xydist, movespeed; fixed_t xstep, ystep, zstep, targetheight; angle_t anglespeed, anglestep, angledist, targetangle, - mobjangle, bigangle, smallangle; + bigangle, smallangle; + DAngle mobjangle; // I have to use floats for the math where angles are divided // by fixed values. @@ -3105,8 +3093,8 @@ void FParser::SF_MoveCamera(void) anglespeed = (angle_t)FixedToAngle(fixedvalue(t_argv[5])); // figure out how big one step will be - fixedvec2 dist = cam->Vec2To(target); - zdist = targetheight - cam->Z(); + fixedvec2 dist = cam->_f_Vec2To(target); + zdist = targetheight - cam->_f_Z(); // Angle checking... // 90 @@ -3114,15 +3102,16 @@ void FParser::SF_MoveCamera(void) //180--+--0 // Q2|Q3 // 270 + angle_t camangle = cam->Angles.Yaw.BAMs(); quad1 = targetangle / ANG90; - quad2 = cam->angle / ANG90; - bigangle = targetangle > cam->angle ? targetangle : cam->angle; - smallangle = targetangle < cam->angle ? targetangle : cam->angle; + quad2 = camangle / ANG90; + bigangle = targetangle > camangle ? targetangle : camangle; + smallangle = targetangle < camangle ? targetangle : camangle; if((quad1 > quad2 && quad1 - 1 == quad2) || (quad2 > quad1 && quad2 - 1 == quad1) || quad1 == quad2) { angledist = bigangle - smallangle; - angledir = targetangle > cam->angle ? 1 : -1; + angledir = targetangle > camangle ? 1 : -1; } else { @@ -3144,19 +3133,19 @@ void FParser::SF_MoveCamera(void) if(angledist > ANG180) { angledist = diff180; - angledir = targetangle > cam->angle ? -1 : 1; + angledir = targetangle > camangle ? -1 : 1; } else - angledir = targetangle > cam->angle ? 1 : -1; + angledir = targetangle > camangle ? 1 : -1; } } // set step variables based on distance and speed mobjangle = cam->AngleTo(target); - xydist = cam->Distance2D(target); + xydist = FLOAT2FIXED(cam->Distance2D(target, true)); - xstep = FixedMul(finecosine[mobjangle >> ANGLETOFINESHIFT], movespeed); - ystep = FixedMul(finesine[mobjangle >> ANGLETOFINESHIFT], movespeed); + xstep = (fixed_t)(movespeed * mobjangle.Cos()); + ystep = (fixed_t)(movespeed * mobjangle.Sin()); if(xydist && movespeed) zstep = FixedDiv(zdist, FixedDiv(xydist, movespeed)); @@ -3178,18 +3167,18 @@ void FParser::SF_MoveCamera(void) anglestep = anglespeed; if(abs(xstep) >= (abs(dist.x) - 1)) - x = cam->X() + dist.x; + x = cam->_f_X() + dist.x; else { - x = cam->X() + xstep; + x = cam->_f_X() + xstep; moved = 1; } if(abs(ystep) >= (abs(dist.y) - 1)) - y = cam->Y() + dist.y; + y = cam->_f_Y() + dist.y; else { - y = cam->Y() + ystep; + y = cam->_f_Y() + ystep; moved = 1; } @@ -3197,34 +3186,34 @@ void FParser::SF_MoveCamera(void) z = targetheight; else { - z = cam->Z() + zstep; + z = cam->_f_Z() + zstep; moved = 1; } if(anglestep >= angledist) - cam->angle = targetangle; + cam->Angles.Yaw = ANGLE2DBL(targetangle); else { if(angledir == 1) { - cam->angle += anglestep; + cam->Angles.Yaw += ANGLE2DBL(anglestep); moved = 1; } else if(angledir == -1) { - cam->angle -= anglestep; + cam->Angles.Yaw -= ANGLE2DBL(anglestep); moved = 1; } } - cam->radius=8; - cam->height=8; - if ((x != cam->X() || y != cam->Y()) && !P_TryMove(cam, x, y, true)) + cam->radius = 1 / 8192.; + cam->Height = 1 / 8192.; + if ((x != cam->_f_X() || y != cam->_f_Y()) && !P_TryMove(cam, x, y, true)) { Printf("Illegal camera move to (%f, %f)\n", x/65536.f, y/65536.f); return; } - cam->SetZ(z); + cam->_f_SetZ(z); t_return.type = svt_int; t_return.value.i = moved; @@ -3419,8 +3408,8 @@ void FParser::SF_SetObjPosition() mobj->SetOrigin( fixedvalue(t_argv[1]), - (t_argc >= 3)? fixedvalue(t_argv[2]) : mobj->Y(), - (t_argc >= 4)? fixedvalue(t_argv[3]) : mobj->Z(), false); + (t_argc >= 3)? fixedvalue(t_argv[2]) : mobj->_f_Y(), + (t_argc >= 4)? fixedvalue(t_argv[3]) : mobj->_f_Z(), false); } } @@ -3751,7 +3740,7 @@ void FParser::SF_Resurrect() return; mo->SetState(state); - mo->height = mo->GetDefault()->height; + mo->Height = mo->GetDefault()->Height; mo->radius = mo->GetDefault()->radius; mo->flags = mo->GetDefault()->flags; mo->flags2 = mo->GetDefault()->flags2; @@ -3772,14 +3761,15 @@ void FParser::SF_Resurrect() void FParser::SF_LineAttack() { AActor *mo; - int damage, angle, slope; + int damage; + DAngle angle, slope; if (CheckArgs(3)) { mo = actorvalue(t_argv[0]); damage = intvalue(t_argv[2]); - angle = (intvalue(t_argv[1]) * (ANG45 / 45)); + angle = floatvalue(t_argv[1]); slope = P_AimLineAttack(mo, angle, MISSILERANGE); P_LineAttack(mo, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); @@ -3830,7 +3820,7 @@ void FParser::SF_Sin() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(sin(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_sin(floatvalue(t_argv[0]))); } } @@ -3840,7 +3830,7 @@ void FParser::SF_ASin() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(asin(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_asin(floatvalue(t_argv[0]))); } } @@ -3850,7 +3840,7 @@ void FParser::SF_Cos() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(cos(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_cos(floatvalue(t_argv[0]))); } } @@ -3860,7 +3850,7 @@ void FParser::SF_ACos() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(acos(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_acos(floatvalue(t_argv[0]))); } } @@ -3870,7 +3860,8 @@ void FParser::SF_Tan() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(tan(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED( + g_tan(floatvalue(t_argv[0]))); } } @@ -3880,7 +3871,7 @@ void FParser::SF_ATan() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(atan(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_atan(floatvalue(t_argv[0]))); } } @@ -3890,7 +3881,7 @@ void FParser::SF_Exp() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(exp(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_exp(floatvalue(t_argv[0]))); } } @@ -3899,7 +3890,7 @@ void FParser::SF_Log() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(log(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_log(floatvalue(t_argv[0]))); } } @@ -3909,7 +3900,7 @@ void FParser::SF_Sqrt() if (CheckArgs(1)) { t_return.type = svt_fixed; - t_return.value.f = FLOAT2FIXED(sqrt(floatvalue(t_argv[0]))); + t_return.value.f = FLOAT2FIXED(g_sqrt(floatvalue(t_argv[0]))); } } @@ -4043,7 +4034,7 @@ void FParser::SF_SetCorona(void) break; case 6: lspr[num].dynamic_radius = fval; - lspr[num].dynamic_sqrradius = sqrt(lspr[num].dynamic_radius); + lspr[num].dynamic_sqrradius = g_sqrt(lspr[num].dynamic_radius); break; default: CONS_Printf("Error in setcorona\n"); @@ -4109,11 +4100,9 @@ void FParser::SF_MobjRadius(void) if(t_argc > 1) { if(mo) - mo->radius = fixedvalue(t_argv[1]); + mo->radius = floatvalue(t_argv[1]); } - - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->radius : 0; + t_return.setDouble(mo ? mo->radius : 0.); } } @@ -4134,11 +4123,9 @@ void FParser::SF_MobjHeight(void) if(t_argc > 1) { if(mo) - mo->height = fixedvalue(t_argv[1]); + mo->Height = floatvalue(t_argv[1]); } - - t_return.type = svt_fixed; - t_return.value.f = mo ? mo->height : 0; + t_return.setDouble(mo ? mo->Height : 0.); } } @@ -4287,7 +4274,8 @@ void FParser::SF_SpawnShot2(void) { S_Sound (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM); mo->target = source; - P_ThrustMobj(mo, mo->angle = source->angle, mo->Speed); + mo->Angles.Yaw = source->Angles.Yaw; + mo->Thrust(); if (!P_CheckMissileSpawn(mo, source->radius)) mo = NULL; } t_return.value.mobj = mo; diff --git a/src/fragglescript/t_script.h b/src/fragglescript/t_script.h index a5159d038..0cbeb446f 100644 --- a/src/fragglescript/t_script.h +++ b/src/fragglescript/t_script.h @@ -106,6 +106,24 @@ struct svalue_t string = other.string; value = other.value; } + + void setInt(int ip) + { + value.i = ip; + type = svt_int; + } + + void setFixed(fixed_t fp) + { + value.f = fp; + type = svt_fixed; + } + + void setDouble(double dp) + { + value.f = FLOAT2FIXED(dp); + type = svt_fixed; + } }; int intvalue(const svalue_t & v); diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp index 11cbcf15d..84481e5f6 100644 --- a/src/g_doom/a_archvile.cpp +++ b/src/g_doom/a_archvile.cpp @@ -13,7 +13,7 @@ // PIT_VileCheck // Detect a corpse that could be raised. // -void A_Fire(AActor *self, int height); +void A_Fire(AActor *self, double height); // @@ -50,13 +50,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrackle) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(height) { height = 0; } + PARAM_FLOAT_OPT(height) { height = 0; } A_Fire(self, height); return 0; } -void A_Fire(AActor *self, int height) +void A_Fire(AActor *self, double height) { AActor *dest; @@ -68,7 +68,7 @@ void A_Fire(AActor *self, int height) if (!P_CheckSight (self->target, dest, 0) ) return; - fixedvec3 newpos = dest->Vec3Angle(24 * FRACUNIT, dest->angle, height); + DVector3 newpos = dest->Vec3Angle(24., dest->Angles.Yaw, height); self->SetOrigin(newpos, true); } @@ -116,7 +116,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) PARAM_INT_OPT (dmg) { dmg = 20; } PARAM_INT_OPT (blastdmg) { blastdmg = 70; } PARAM_INT_OPT (blastrad) { blastrad = 70; } - PARAM_FIXED_OPT (thrust) { thrust = FRACUNIT; } + PARAM_FLOAT_OPT (thrust) { thrust = 1; } PARAM_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; } PARAM_INT_OPT (flags) { flags = 0; } @@ -147,14 +147,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) if (fire != NULL) { // move the fire between the vile and the player - fixedvec3 pos = target->Vec3Angle(-24 * FRACUNIT, self->angle, 0); + DVector3 pos = target->Vec3Angle(-24., self->Angles.Yaw, 0); fire->SetOrigin (pos, true); P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0); } if (!(target->flags7 & MF7_DONTTHRUST)) { - target->vel.z = Scale(thrust, 1000, target->Mass); + target->Vel.Z = thrust * 1000 / MAX(1, target->Mass); } return 0; } diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index f752b7334..51ee77ff8 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -31,13 +31,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainPain) return 0; } -static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z) +static void BrainishExplosion (const DVector3 &pos) { - AActor *boom = Spawn("Rocket", x, y, z, NO_REPLACE); + AActor *boom = Spawn("Rocket", pos, NO_REPLACE); if (boom != NULL) { boom->DeathSound = "misc/brainexplode"; - boom->vel.z = pr_brainscream() << 9; + boom->Vel.Z = pr_brainscream() /128.; PClassActor *cls = PClass::FindActor("BossBrain"); if (cls != NULL) @@ -57,12 +57,11 @@ static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z) DEFINE_ACTION_FUNCTION(AActor, A_BrainScream) { PARAM_ACTION_PROLOGUE; - fixed_t x; - - for (x = self->X() - 196*FRACUNIT; x < self->X() + 320*FRACUNIT; x += 8*FRACUNIT) + + for (double x = -196; x < +320; x += 8) { - BrainishExplosion (x, self->Y() - 320*FRACUNIT, - 128 + (pr_brainscream() << (FRACBITS + 1))); + // (1 / 512.) is actually what the original value of 128 did, even though it probably meant 128 map units. + BrainishExplosion(self->Vec2OffsetZ(x, -320, (1 / 512.) + pr_brainexplode() * 2)); } S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE); return 0; @@ -71,9 +70,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainScream) DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode) { PARAM_ACTION_PROLOGUE; - fixed_t x = self->X() + pr_brainexplode.Random2()*2048; - fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT; - BrainishExplosion (x, self->Y(), z); + double x = pr_brainexplode.Random2() / 32.; + DVector3 pos = self->Vec2OffsetZ(x, 0, 1 / 512. + pr_brainexplode() * 2); + BrainishExplosion(pos); return 0; } @@ -144,17 +143,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) spit->master = self; // [RH] Do this correctly for any trajectory. Doom would divide by 0 // if the target had the same y coordinate as the spitter. - if ((spit->vel.x | spit->vel.y) == 0) + if (spit->Vel.X == 0 && spit->Vel.Y == 0) { spit->special2 = 0; } - else if (abs(spit->vel.y) > abs(spit->vel.x)) + else if (fabs(spit->Vel.X) > fabs(spit->Vel.Y)) { - spit->special2 = (targ->Y() - self->Y()) / spit->vel.y; + spit->special2 = int((targ->Y() - self->Y()) / spit->Vel.Y); } else { - spit->special2 = (targ->X() - self->X()) / spit->vel.x; + spit->special2 = int((targ->X() - self->X()) / spit->Vel.X); } // [GZ] Calculates when the projectile will have reached destination spit->special2 += level.maptime; diff --git a/src/g_doom/a_doommisc.cpp b/src/g_doom/a_doommisc.cpp index 66f7cc7e9..93e7abdaa 100644 --- a/src/g_doom/a_doommisc.cpp +++ b/src/g_doom/a_doommisc.cpp @@ -47,7 +47,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BarrelDestroy) if (dmflags2 & DF2_BARRELS_RESPAWN) { - self->height = self->GetDefault()->height; + self->Height = self->GetDefault()->Height; self->renderflags |= RF_INVISIBLE; self->flags &= ~MF_SOLID; } diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index b43b5a1d5..22f471482 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -30,9 +30,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int pitch; + DAngle pitch; FTranslatedLineTarget t; if (self->player != NULL) @@ -50,9 +50,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) if (self->FindInventory()) damage *= 10; - angle = self->angle; - - angle += pr_punch.Random2() << 18; + angle = self->Angles.Yaw + pr_punch.Random2() * (5.625 / 256); pitch = P_AimLineAttack (self, angle, MELEERANGE); P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, LAF_ISMELEEATTACK, &t); @@ -61,7 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch) if (t.linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } return 0; } @@ -123,15 +121,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) PARAM_INT_OPT (damage) { damage = 2; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (range) { range = 0; } - PARAM_ANGLE_OPT(spread_xy) { spread_xy = 33554432; /*angle_t(2.8125 * (ANGLE_90 / 90.0));*/ } // The floating point expression does not get optimized away. - PARAM_ANGLE_OPT (spread_z) { spread_z = 0; } - PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } + PARAM_DANGLE_OPT(spread_xy) { spread_xy = 2.8125; } + PARAM_DANGLE_OPT(spread_z) { spread_z = 0.; } + PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; } PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } - angle_t angle; - angle_t slope; + DAngle angle; + DAngle slope; player_t *player; FTranslatedLineTarget t; int actualdamage; @@ -154,12 +152,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) damage *= (pr_saw()%10+1); } if (range == 0) - { // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) - range = MELEERANGE+1; + { + range = SAWRANGE; } - angle = self->angle + (pr_saw.Random2() * (spread_xy / 255)); - slope = P_AimLineAttack (self, angle, range, &t) + (pr_saw.Random2() * (spread_z / 255)); + angle = self->Angles.Yaw + spread_xy * (pr_saw.Random2() / 255.); + slope = P_AimLineAttack (self, angle, range, &t) + spread_z * (pr_saw.Random2() / 255.); AWeapon *weapon = self->player->ReadyWeapon; if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON()) @@ -209,7 +207,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) { assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))); ABasicArmorBonus *armorbonus = static_cast(Spawn(armorbonustype, 0,0,0, NO_REPLACE)); - armorbonus->SaveAmount *= (actualdamage * lifesteal) >> FRACBITS; + armorbonus->SaveAmount = int(armorbonus->SaveAmount * actualdamage * lifesteal); armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax; armorbonus->flags |= MF_DROPPED; armorbonus->ClearCounters(); @@ -223,7 +221,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) else { - P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax); + P_GiveBody (self, int(actualdamage * lifesteal), lifestealmax); } } @@ -232,20 +230,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) // turn to face target if (!(flags & SF_NOTURN)) { - angle = t.angleFromSource; - if (angle - self->angle > ANG180) + DAngle anglediff = deltaangle(self->Angles.Yaw, t.angleFromSource); + + if (anglediff < 0.0) { - if (angle - self->angle < (angle_t)(-ANG90 / 20)) - self->angle = angle + ANG90 / 21; + if (anglediff < -4.5) + self->Angles.Yaw = angle + 90.0 / 21; else - self->angle -= ANG90 / 20; + self->Angles.Yaw -= 4.5; } else { - if (angle - self->angle > ANG90 / 20) - self->angle = angle - ANG90 / 21; + if (anglediff > 4.5) + self->Angles.Yaw = angle - 90.0 / 21; else - self->angle += ANG90 / 20; + self->Angles.Yaw += 4.5; } } if (!(flags & SF_NOPULLIN)) @@ -278,7 +277,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun) } player->mo->PlayAttacking2 (); - angle_t pitch = P_BulletSlope (self); + DAngle pitch = P_BulletSlope (self); for (i = 0; i < 7; i++) { @@ -295,7 +294,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) PARAM_ACTION_PROLOGUE; int i; - angle_t angle; + DAngle angle; int damage; player_t *player; @@ -315,13 +314,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) player->mo->PlayAttacking2 (); - angle_t pitch = P_BulletSlope (self); + DAngle pitch = P_BulletSlope (self); for (i=0 ; i<20 ; i++) { damage = 5*(pr_fireshotgun2()%3+1); - angle = self->angle; - angle += pr_fireshotgun2.Random2() << 19; + angle = self->Angles.Yaw + pr_fireshotgun2.Random2() * (11.25 / 256); // Doom adjusts the bullet slope by shifting a random number [-255,255] // left 5 places. At 2048 units away, this means the vertical position @@ -332,7 +330,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2) P_LineAttack (self, angle, PLAYERMISSILERANGE, - pitch + (pr_fireshotgun2.Random2() * 332063), damage, + pitch + pr_fireshotgun2.Random2() * (7.097 / 256), damage, NAME_Hitscan, NAME_BulletPuff); } return 0; @@ -501,10 +499,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade) } // Temporarily raise the pitch to send the grenade slightly upwards - fixed_t SavedPlayerPitch = self->pitch; - self->pitch -= (1152 << FRACBITS); + DAngle SavedPlayerPitch = self->Angles.Pitch; + self->Angles.Pitch -= 6.328125; //(1152 << F RACBITS); P_SpawnPlayerMissile(self, grenade); - self->pitch = SavedPlayerPitch; + self->Angles.Pitch = SavedPlayerPitch; return 0; } @@ -619,7 +617,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG) return 0; } - P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->angle, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); + P_SpawnPlayerMissile (self, 0, 0, 0, PClass::FindActor("BFGBall"), self->Angles.Yaw, NULL, NULL, !!(dmflags2 & DF2_NO_FREEAIMBFG)); return 0; } @@ -632,25 +630,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) { PARAM_ACTION_PROLOGUE; PARAM_CLASS_OPT (spraytype, AActor) { spraytype = NULL; } - PARAM_INT_OPT (numrays) { numrays = 40; } - PARAM_INT_OPT (damagecnt) { damagecnt = 15; } - PARAM_ANGLE_OPT (angle) { angle = ANGLE_90; } - PARAM_FIXED_OPT (distance) { distance = 16*64*FRACUNIT; } - PARAM_ANGLE_OPT (vrange) { vrange = 32*ANGLE_1; } + PARAM_INT_OPT (numrays) { numrays = 0; } + PARAM_INT_OPT (damagecnt) { damagecnt = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } + PARAM_FLOAT_OPT (distance) { distance = 0; } + PARAM_DANGLE_OPT(vrange) { vrange = 0.; } PARAM_INT_OPT (defdamage) { defdamage = 0; } int i; int j; int damage; - angle_t an; + DAngle an; FTranslatedLineTarget t; if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra"); if (numrays <= 0) numrays = 40; if (damagecnt <= 0) damagecnt = 15; - if (angle == 0) angle = ANG90; - if (distance <= 0) distance = 16 * 64 * FRACUNIT; - if (vrange == 0) vrange = ANGLE_1 * 32; + if (angle == 0) angle = 90.; + if (distance <= 0) distance = 16 * 64; + if (vrange == 0) vrange = 32.; // [RH] Don't crash if no target if (!self->target) @@ -659,14 +657,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) // offset angles from its attack angle for (i = 0; i < numrays; i++) { - an = self->angle - angle / 2 + angle / numrays*i; + an = self->Angles.Yaw - angle / 2 + angle / numrays*i; // self->target is the originator (player) of the missile P_AimLineAttack(self->target, an, distance, &t, vrange); if (t.linetarget != NULL) { - AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->height >> 2), ALLOW_REPLACE); + AActor *spray = Spawn(spraytype, t.linetarget->PosPlusZ(t.linetarget->Height / 4), ALLOW_REPLACE); int dmgFlags = 0; FName dmgType = NAME_BFGSplash; @@ -696,7 +694,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) damage = defdamage; } - int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource); + int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees); P_TraceBleed(newdam > 0 ? newdam : damage, &t, self); } } @@ -749,16 +747,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG) self->player->extralight = 2; // Save values temporarily - angle_t SavedPlayerAngle = self->angle; - fixed_t SavedPlayerPitch = self->pitch; + DAngle SavedPlayerAngle = self->Angles.Yaw; + DAngle SavedPlayerPitch = self->Angles.Pitch; for (int i = 0; i < 2; i++) // Spawn two plasma balls in sequence { - self->angle += ((pr_oldbfg()&127) - 64) * (ANG90/768); - self->pitch += ((pr_oldbfg()&127) - 64) * (ANG90/640); + self->Angles.Yaw += ((pr_oldbfg()&127) - 64) * (90./768); + self->Angles.Pitch += ((pr_oldbfg()&127) - 64) * (90./640); mo = P_SpawnPlayerMissile (self, plasma[i]); // Restore saved values - self->angle = SavedPlayerAngle; - self->pitch = SavedPlayerPitch; + self->Angles.Yaw = SavedPlayerAngle; + self->Angles.Pitch = SavedPlayerPitch; } if (doesautoaim && weapon != NULL) { // Restore autoaim setting diff --git a/src/g_doom/a_fatso.cpp b/src/g_doom/a_fatso.cpp index e79362316..872e1982d 100644 --- a/src/g_doom/a_fatso.cpp +++ b/src/g_doom/a_fatso.cpp @@ -15,7 +15,7 @@ // firing three missiles in three different directions? // Doesn't look like it. // -#define FATSPREAD (ANG90/8) +#define FATSPREAD (90./8) DEFINE_ACTION_FUNCTION(AActor, A_FatRaise) { @@ -32,7 +32,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; } AActor *missile; - angle_t an; if (!self->target) return 0; @@ -41,16 +40,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) A_FaceTarget (self); // Change direction to ... - self->angle += FATSPREAD; + self->Angles.Yaw += FATSPREAD; P_SpawnMissile (self, self->target, spawntype); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle += FATSPREAD; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw += FATSPREAD; + missile->VelFromAngle(); } return 0; } @@ -61,7 +58,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2) PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; } AActor *missile; - angle_t an; if (!self->target) return 0; @@ -70,16 +66,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack2) A_FaceTarget (self); // Now here choose opposite deviation. - self->angle -= FATSPREAD; + self->Angles.Yaw -= FATSPREAD; P_SpawnMissile (self, self->target, spawntype); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle -= FATSPREAD*2; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw -= FATSPREAD*2; + missile->VelFromAngle(); } return 0; } @@ -90,7 +84,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3) PARAM_CLASS_OPT(spawntype, AActor) { spawntype = NULL; } AActor *missile; - angle_t an; if (!self->target) return 0; @@ -102,19 +95,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack3) missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle -= FATSPREAD/2; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw -= FATSPREAD/2; + missile->VelFromAngle(); } missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { - missile->angle += FATSPREAD/2; - an = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul (missile->Speed, finecosine[an]); - missile->vel.y = FixedMul (missile->Speed, finesine[an]); + missile->Angles.Yaw += FATSPREAD/2; + missile->VelFromAngle(); } return 0; } @@ -137,8 +126,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; } PARAM_INT_OPT (n) { n = 0; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (vrange) { vrange = 4*FRACUNIT; } - PARAM_FIXED_OPT (hrange) { hrange = FRACUNIT/2; } + PARAM_FLOAT_OPT (vrange) { vrange = 4; } + PARAM_FLOAT_OPT (hrange) { hrange = 0.5; } int i, j; @@ -152,20 +141,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) } P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE); - P_CheckSplash(self, 128<Pos(), NO_REPLACE); // We need something to aim at. AActor *master = (flags & MSF_DontHurt) ? (AActor*)(self->target) : self; - target->height = self->height; + target->Height = self->Height; for (i = -n; i <= n; i += 8) { for (j = -n; j <= n; j += 8) { AActor *mo; target->SetXYZ( - self->X() + (i << FRACBITS), // Aim in many directions from source - self->Y() + (j << FRACBITS), + self->X() + i, // Aim in many directions from source + self->Y() + j, self->Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options (flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM))) @@ -178,9 +167,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) } if (mo != NULL) { // Slow it down a bit - mo->vel.x = FixedMul(mo->vel.x, hrange); - mo->vel.y = FixedMul(mo->vel.y, hrange); - mo->vel.z = FixedMul(mo->vel.z, hrange); + mo->Vel *= hrange; mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity } } diff --git a/src/g_doom/a_keen.cpp b/src/g_doom/a_keen.cpp index bb73d2015..d0a10da58 100644 --- a/src/g_doom/a_keen.cpp +++ b/src/g_doom/a_keen.cpp @@ -35,7 +35,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KeenDie) } } - EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2*FRACUNIT, 0, 0, 0); + EV_DoDoor (DDoor::doorOpen, NULL, NULL, doortag, 2., 0, 0, 0); return 0; } diff --git a/src/g_doom/a_lostsoul.cpp b/src/g_doom/a_lostsoul.cpp index 8aa7108cf..056802fe0 100644 --- a/src/g_doom/a_lostsoul.cpp +++ b/src/g_doom/a_lostsoul.cpp @@ -19,12 +19,9 @@ // Fly at the player like a missile. // -void A_SkullAttack(AActor *self, fixed_t speed) +void A_SkullAttack(AActor *self, double speed) { AActor *dest; - angle_t an; - int dist; - if (!self->target) return; @@ -33,21 +30,14 @@ void A_SkullAttack(AActor *self, fixed_t speed) S_Sound (self, CHAN_VOICE, self->AttackSound, 1, ATTN_NORM); A_FaceTarget (self); - an = self->angle >> ANGLETOFINESHIFT; - self->vel.x = FixedMul (speed, finecosine[an]); - self->vel.y = FixedMul (speed, finesine[an]); - dist = self->AproxDistance (dest); - dist = dist / speed; - - if (dist < 1) - dist = 1; - self->vel.z = (dest->Z() + (dest->height>>1) - self->Z()) / dist; + self->VelFromAngle(speed); + self->Vel.Z = (dest->Center() - self->Z()) / self->DistanceBySpeed(dest, speed); } DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT(speed) { speed = SKULLSPEED; } + PARAM_FLOAT_OPT(speed) { speed = SKULLSPEED; } if (speed <= 0) speed = SKULLSPEED; diff --git a/src/g_doom/a_painelemental.cpp b/src/g_doom/a_painelemental.cpp index acdfdb04d..ead3ed91d 100644 --- a/src/g_doom/a_painelemental.cpp +++ b/src/g_doom/a_painelemental.cpp @@ -10,8 +10,6 @@ #include "doomstat.h" */ -DECLARE_ACTION(A_SkullAttack) - enum PA_Flags { PAF_NOSKULLATTACK = 1, @@ -23,21 +21,21 @@ enum PA_Flags // A_PainShootSkull // Spawn a lost soul and launch it at the target // -void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int flags = 0, int limit = -1) +void A_PainShootSkull (AActor *self, DAngle Angle, PClassActor *spawntype, int flags = 0, int limit = -1) { AActor *other; - int prestep; + double prestep; if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul"); assert(spawntype != NULL); if (self->DamageType == NAME_Massacre) return; // [RH] check to make sure it's not too close to the ceiling - if (self->Top() + 8*FRACUNIT > self->ceilingz) + if (self->Top() + 8 > self->ceilingz) { if (self->flags & MF_FLOAT) { - self->vel.z -= 2*FRACUNIT; + self->Vel.Z -= 2; self->flags |= MF_INFLOAT; self->flags4 |= MF4_VFRICTION; } @@ -64,14 +62,13 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int } // okay, there's room for another one - prestep = 4*FRACUNIT + - 3*(self->radius + GetDefaultByType(spawntype)->radius)/2; + prestep = 4 + (self->radius + GetDefaultByType(spawntype)->radius) * 1.5; // NOTE: The following code contains some advance work for line-to-line portals which is currenty inactive. - fixedvec2 dist = Vec2Angle(prestep, angle); - fixedvec3 pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT, true); - fixedvec3 src = self->Pos(); + DVector2 dist = Angle.ToVector(prestep); + DVector3 pos = self->Vec3Offset(dist.X, dist.Y, 8., true); + DVector3 src = self->Pos(); for (int i = 0; i < 2; i++) { @@ -79,7 +76,7 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int // wall or an impassible line, or a "monsters can't cross" line.// | // If it is, then we don't allow the spawn. // V - FBoundingBox box(MIN(src.x, pos.x), MIN(src.y, pos.y), MAX(src.x, pos.x), MAX(src.y, pos.y)); + FBoundingBox box(MIN(src.X, pos.X), MIN(src.Y, pos.Y), MAX(src.X, pos.X), MAX(src.Y, pos.Y)); FBlockLinesIterator it(box); line_t *ld; bool inportal = false; @@ -88,8 +85,8 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int { if (ld->isLinePortal() && i == 0) { - if (P_PointOnLineSidePrecise(src.x, src.y, ld) == 0 && - P_PointOnLineSidePrecise(pos.x, pos.y, ld) == 1) + if (P_PointOnLineSidePrecise(src, ld) == 0 && + P_PointOnLineSidePrecise(pos, ld) == 1) { // crossed a portal line from front to back, we need to repeat the check on the other side as well. inportal = true; @@ -98,12 +95,9 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int else if (!(ld->flags & ML_TWOSIDED) || (ld->flags & (ML_BLOCKING | ML_BLOCKMONSTERS | ML_BLOCKEVERYTHING))) { - if (!(box.Left() > ld->bbox[BOXRIGHT] || - box.Right() < ld->bbox[BOXLEFT] || - box.Top() < ld->bbox[BOXBOTTOM] || - box.Bottom() > ld->bbox[BOXTOP])) + if (box.inRange(ld)) { - if (P_PointOnLineSidePrecise(src.x, src.y, ld) != P_PointOnLineSidePrecise(pos.x, pos.y, ld)) + if (P_PointOnLineSidePrecise(src, ld) != P_PointOnLineSidePrecise(pos, ld)) return; // line blocks trajectory // ^ } } @@ -111,20 +105,19 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int if (!inportal) break; // recalculate position and redo the check on the other side of the portal - pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT); - src.x = pos.x - dist.x; - src.y = pos.y - dist.y; + pos = self->Vec3Offset(dist.X, dist.Y, 8.); + src.X = pos.X - dist.X; + src.Y = pos.Y - dist.Y; } - other = Spawn (spawntype, pos.x, pos.y, pos.z, ALLOW_REPLACE); + other = Spawn (spawntype, pos, ALLOW_REPLACE); // Check to see if the new Lost Soul's z value is above the // ceiling of its new sector, or below the floor. If so, kill it. - if ((other->Top() > - (other->Sector->HighestCeilingAt(other))) || - (other->Z() < other->Sector->LowestFloorAt(other))) + if (other->Top() > other->Sector->HighestCeilingAt(other) || + other->Z() < other->Sector->LowestFloorAt(other)) { // kill it immediately P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);// ^ @@ -160,13 +153,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack) return 0; PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; } - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_DANGLE_OPT (angle) { angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (limit) { limit = -1; } if (!(flags & PAF_AIMFACING)) A_FaceTarget (self); - A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit); + A_PainShootSkull (self, self->Angles.Yaw + angle, spawntype, flags, limit); return 0; } @@ -179,8 +172,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack) return 0; A_FaceTarget (self); - A_PainShootSkull (self, self->angle + ANG45, spawntype); - A_PainShootSkull (self, self->angle - ANG45, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 45., spawntype); + A_PainShootSkull (self, self->Angles.Yaw - 45., spawntype); return 0; } @@ -194,8 +187,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie) self->flags &= ~MF_FRIENDLY; } A_Unblock(self, true); - A_PainShootSkull (self, self->angle + ANG90, spawntype); - A_PainShootSkull (self, self->angle + ANG180, spawntype); - A_PainShootSkull (self, self->angle + ANG270, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 90, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 180, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 270, spawntype); return 0; } diff --git a/src/g_doom/a_possessed.cpp b/src/g_doom/a_possessed.cpp index 5fc2e6b89..f6b559c4b 100644 --- a/src/g_doom/a_possessed.cpp +++ b/src/g_doom/a_possessed.cpp @@ -22,19 +22,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack) { PARAM_ACTION_PROLOGUE; - int angle; int damage; - int slope; + DAngle angle; + DAngle slope; if (!self->target) return 0; A_FaceTarget (self); - angle = self->angle; + angle = self->Angles.Yaw; slope = P_AimLineAttack (self, angle, MISSILERANGE); S_Sound (self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM); - angle += pr_posattack.Random2() << 20; + angle += pr_posattack.Random2() * (22.5 / 256); damage = ((pr_posattack()%5)+1)*3; P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); return 0; @@ -43,16 +43,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_PosAttack) static void A_SPosAttack2 (AActor *self) { int i; - int bangle; - int slope; + DAngle bangle; + DAngle slope; A_FaceTarget (self); - bangle = self->angle; + bangle = self->Angles.Yaw; slope = P_AimLineAttack (self, bangle, MISSILERANGE); for (i=0 ; i<3 ; i++) { - int angle = bangle + (pr_sposattack.Random2() << 20); + DAngle angle = bangle + pr_sposattack.Random2() * (22.5 / 256); int damage = ((pr_sposattack()%5)+1)*3; P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); } @@ -88,10 +88,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack) { PARAM_ACTION_PROLOGUE; - int angle; - int bangle; + DAngle angle; + DAngle bangle; int damage; - int slope; + DAngle slope; if (!self->target) return 0; @@ -104,10 +104,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosAttack) S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); A_FaceTarget (self); - bangle = self->angle; + bangle = self->Angles.Yaw; slope = P_AimLineAttack (self, bangle, MISSILERANGE); - angle = bangle + (pr_cposattack.Random2() << 20); + angle = bangle + pr_cposattack.Random2() * (22.5 / 256); damage = ((pr_cposattack()%5)+1)*3; P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); return 0; diff --git a/src/g_doom/a_revenant.cpp b/src/g_doom/a_revenant.cpp index 1b36d6cb2..9c8a38602 100644 --- a/src/g_doom/a_revenant.cpp +++ b/src/g_doom/a_revenant.cpp @@ -28,27 +28,26 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile) return 0; A_FaceTarget (self); - self->AddZ(16*FRACUNIT); - missile = P_SpawnMissile (self, self->target, PClass::FindActor("RevenantTracer")); - self->AddZ(-16*FRACUNIT); + self->AddZ(16.); + missile = P_SpawnMissile(self, self->target, PClass::FindActor("RevenantTracer")); + self->AddZ(-16.); if (missile != NULL) { - missile->SetOrigin(missile->Vec3Offset(missile->vel.x, missile->vel.y, 0), false); + missile->SetOrigin(missile->Vec3Offset(missile->Vel.X, missile->Vel.Y, 0.), false); missile->tracer = self->target; } return 0; } -#define TRACEANGLE (0xc000000) +#define TRACEANGLE (16.875) DEFINE_ACTION_FUNCTION(AActor, A_Tracer) { PARAM_ACTION_PROLOGUE; - angle_t exact; - fixed_t dist; - fixed_t slope; + double dist; + double slope; AActor *dest; AActor *smoke; @@ -65,11 +64,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // spawn a puff of smoke behind the rocket - P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->angle, self->angle, 3); + P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->Angles.Yaw, self->Angles.Yaw, 3); - smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE); + smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE); - smoke->vel.z = FRACUNIT; + smoke->Vel.Z = 1.; smoke->tics -= pr_tracer()&3; if (smoke->tics < 1) smoke->tics = 1; @@ -81,49 +80,42 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // change angle - exact = self->AngleTo(dest); + DAngle exact = self->AngleTo(dest); + DAngle diff = deltaangle(self->Angles.Yaw, exact); - if (exact != self->angle) + if (diff < 0) { - if (exact - self->angle > 0x80000000) - { - self->angle -= TRACEANGLE; - if (exact - self->angle < 0x80000000) - self->angle = exact; - } - else - { - self->angle += TRACEANGLE; - if (exact - self->angle > 0x80000000) - self->angle = exact; - } + self->Angles.Yaw -= TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) > 0) + self->Angles.Yaw = exact; } - - exact = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[exact]); - self->vel.y = FixedMul (self->Speed, finesine[exact]); + else if (diff > 0) + { + self->Angles.Yaw += TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) < 0.) + self->Angles.Yaw = exact; + } + + self->VelFromAngle(); if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // change slope - dist = self->AproxDistance (dest) / self->Speed; + dist = self->DistanceBySpeed(dest, self->Speed); - if (dist < 1) - dist = 1; - - if (dest->height >= 56*FRACUNIT) + if (dest->Height >= 56.) { - slope = (dest->Z()+40*FRACUNIT - self->Z()) / dist; + slope = (dest->Z() + 40. - self->Z()) / dist; } else { - slope = (dest->Z() + self->height*2/3 - self->Z()) / dist; + slope = (dest->Z() + self->Height*(2./3) - self->Z()) / dist; } - if (slope < self->vel.z) - self->vel.z -= FRACUNIT/8; + if (slope < self->Vel.Z) + self->Vel.Z -= 1. / 8; else - self->vel.z += FRACUNIT/8; + self->Vel.Z += 1. / 8; } return 0; } diff --git a/src/g_doom/a_scriptedmarine.cpp b/src/g_doom/a_scriptedmarine.cpp index 0f9e48e59..a3d33f555 100644 --- a/src/g_doom/a_scriptedmarine.cpp +++ b/src/g_doom/a_scriptedmarine.cpp @@ -275,14 +275,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) A_FaceTarget (self); if (self->CheckMeleeRange ()) { - angle_t angle; + DAngle angle; FTranslatedLineTarget t; damage *= (pr_m_saw()%10+1); - angle = self->angle + (pr_m_saw.Random2() << 18); + angle = self->Angles.Yaw + pr_m_saw.Random2() * (5.625 / 256); - P_LineAttack (self, angle, MELEERANGE+1, - P_AimLineAttack (self, angle, MELEERANGE+1), damage, + P_LineAttack (self, angle, SAWRANGE, + P_AimLineAttack (self, angle, SAWRANGE), damage, NAME_Melee, pufftype, false, &t); if (!t.linetarget) @@ -294,19 +294,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) // turn to face target angle = t.angleFromSource; - if (angle - self->angle > ANG180) + DAngle anglediff = deltaangle(self->Angles.Yaw, angle); + + if (anglediff < 0.0) { - if (angle - self->angle < (angle_t)(-ANG90/20)) - self->angle = angle + ANG90/21; + if (anglediff < -4.5) + self->Angles.Yaw = angle + 90.0 / 21; else - self->angle -= ANG90/20; + self->Angles.Yaw -= 4.5; } else { - if (angle - self->angle > ANG90/20) - self->angle = angle - ANG90/21; + if (anglediff > 4.5) + self->Angles.Yaw = angle - 90.0 / 21; else - self->angle += ANG90/20; + self->Angles.Yaw += 4.5; } } else @@ -325,9 +327,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Saw) static void MarinePunch(AActor *self, int damagemul) { - angle_t angle; + DAngle angle; int damage; - int pitch; + DAngle pitch; FTranslatedLineTarget t; if (self->target == NULL) @@ -336,7 +338,7 @@ static void MarinePunch(AActor *self, int damagemul) damage = ((pr_m_punch()%10+1) << 1) * damagemul; A_FaceTarget (self); - angle = self->angle + (pr_m_punch.Random2() << 18); + angle = self->Angles.Yaw + pr_m_punch.Random2() * (5.625 / 256); pitch = P_AimLineAttack (self, angle, MELEERANGE); P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff, true, &t); @@ -344,7 +346,7 @@ static void MarinePunch(AActor *self, int damagemul) if (t.linetarget) { S_Sound (self, CHAN_WEAPON, "*fist", 1, ATTN_NORM); - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } } @@ -363,17 +365,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch) // //============================================================================ -void P_GunShot2 (AActor *mo, bool accurate, int pitch, PClassActor *pufftype) +void P_GunShot2 (AActor *mo, bool accurate, DAngle pitch, PClassActor *pufftype) { - angle_t angle; + DAngle angle; int damage; damage = 5*(pr_m_gunshot()%3+1); - angle = mo->angle; + angle = mo->Angles.Yaw; if (!accurate) { - angle += pr_m_gunshot.Random2 () << 18; + angle += pr_m_gunshot.Random2() * (5.625 / 256); } P_LineAttack (mo, angle, MISSILERANGE, pitch, damage, NAME_Hitscan, pufftype); @@ -395,7 +397,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FirePistol) S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM); A_FaceTarget (self); - P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), + P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE), PClass::FindActor(NAME_BulletPuff)); return 0; } @@ -410,14 +412,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun) { PARAM_ACTION_PROLOGUE; - int pitch; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); for (int i = 0; i < 7; ++i) { P_GunShot2 (self, false, pitch, PClass::FindActor(NAME_BulletPuff)); @@ -457,21 +459,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_M_FireShotgun2) { PARAM_ACTION_PROLOGUE; - int pitch; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); for (int i = 0; i < 20; ++i) { int damage = 5*(pr_m_fireshotgun2()%3+1); - angle_t angle = self->angle + (pr_m_fireshotgun2.Random2() << 19); + DAngle angle = self->Angles.Yaw + pr_m_fireshotgun2.Random2() * (11.25 / 256); P_LineAttack (self, angle, MISSILERANGE, - pitch + (pr_m_fireshotgun2.Random2() * 332063), damage, + pitch + pr_m_fireshotgun2.Random2() * (7.097 / 256), damage, NAME_Hitscan, NAME_BulletPuff); } self->special1 = level.maptime; @@ -494,7 +496,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun) S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM); A_FaceTarget (self); - P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), + P_GunShot2 (self, accurate, P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE), PClass::FindActor(NAME_BulletPuff)); return 0; } @@ -647,13 +649,11 @@ void AScriptedMarine::SetSprite (PClassActor *source) { // A valid actor class wasn't passed, so use the standard sprite SpriteOverride = sprite = GetClass()->OwnedStates[0].sprite; // Copy the standard scaling - scaleX = GetDefault()->scaleX; - scaleY = GetDefault()->scaleY; + Scale = GetDefault()->Scale; } else { // Use the same sprite and scaling the passed class spawns with SpriteOverride = sprite = GetDefaultByType (source)->SpawnState->sprite; - scaleX = GetDefaultByType(source)->scaleX; - scaleY = GetDefaultByType(source)->scaleY; + Scale = GetDefaultByType(source)->Scale; } } diff --git a/src/g_game.cpp b/src/g_game.cpp index 627853acb..869a521f5 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1182,8 +1182,8 @@ void G_Ticker () } if (players[i].mo) { - DWORD sum = rngsum + players[i].mo->X() + players[i].mo->Y() + players[i].mo->Z() - + players[i].mo->angle + players[i].mo->pitch; + DWORD sum = rngsum + players[i].mo->_f_X() + players[i].mo->_f_Y() + players[i].mo->_f_Z() + + players[i].mo->_f_angle() + players[i].mo->_f_pitch(); sum ^= players[i].health; consistancy[i][buf] = sum; } @@ -1443,13 +1443,13 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) if (!players[playernum].mo) { // first spawn of level, before corpses for (i = 0; i < playernum; i++) - if (players[i].mo && players[i].mo->X() == x && players[i].mo->Y() == y) + if (players[i].mo && players[i].mo->_f_X() == x && players[i].mo->_f_Y() == y) return false; return true; } - oldz = players[playernum].mo->Z(); // [RH] Need to save corpse's z-height - players[playernum].mo->SetZ(z); // [RH] Checks are now full 3-D + oldz = players[playernum].mo->_f_Z(); // [RH] Need to save corpse's z-height + players[playernum].mo->_f_SetZ(z); // [RH] Checks are now full 3-D // killough 4/2/98: fix bug where P_CheckPosition() uses a non-solid // corpse to detect collisions with other players in DM starts @@ -1461,7 +1461,7 @@ bool G_CheckSpot (int playernum, FPlayerStart *mthing) players[playernum].mo->flags |= MF_SOLID; i = P_CheckPosition(players[playernum].mo, x, y); players[playernum].mo->flags &= ~MF_SOLID; - players[playernum].mo->SetZ(oldz); // [RH] Restore corpse's height + players[playernum].mo->_f_SetZ(oldz); // [RH] Restore corpse's height if (!i) return false; @@ -1645,8 +1645,8 @@ static void G_QueueBody (AActor *body) const AActor *const defaultActor = body->GetDefault(); const FPlayerSkin &skin = skins[skinidx]; - body->scaleX = Scale(body->scaleX, skin.ScaleX, defaultActor->scaleX); - body->scaleY = Scale(body->scaleY, skin.ScaleY, defaultActor->scaleY); + body->Scale.X *= skin.Scale.X / defaultActor->Scale.X; + body->Scale.Y *= skin.Scale.Y / defaultActor->Scale.Y; } bodyqueslot++; diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index 80c5d215a..3251e3812 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -41,13 +41,13 @@ void AChickenPlayer::MorphPlayerThink () { return; } - if (!(vel.x | vel.y) && pr_chickenplayerthink () < 160) + if (Vel.X == 0 && Vel.Y == 0 && pr_chickenplayerthink () < 160) { // Twitch view angle - angle += pr_chickenplayerthink.Random2 () << 19; + Angles.Yaw += pr_chickenplayerthink.Random2() * (360. / 256. / 32.); } if ((Z() <= floorz) && (pr_chickenplayerthink() < 32)) { // Jump and noise - vel.z += JumpZ; + Vel.Z += JumpZ; FState * painstate = FindState(NAME_Pain); if (painstate != NULL) SetState (painstate); @@ -105,11 +105,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers) } for (i = 0; i < count; i++) { - mo = Spawn("Feather", self->PosPlusZ(20*FRACUNIT), NO_REPLACE); + mo = Spawn("Feather", self->PosPlusZ(20.), NO_REPLACE); mo->target = self; - mo->vel.x = pr_feathers.Random2() << 8; - mo->vel.y = pr_feathers.Random2() << 8; - mo->vel.z = FRACUNIT + (pr_feathers() << 9); + mo->Vel.X = pr_feathers.Random2() / 256.; + mo->Vel.Y = pr_feathers.Random2() / 256.; + mo->Vel.Z = 1. + pr_feathers() / 128.; mo->SetState (mo->SpawnState + (pr_feathers()&7)); } return 0; @@ -125,8 +125,7 @@ void P_UpdateBeak (AActor *self) { if (self->player != NULL) { - self->player->psprites[ps_weapon].sy = WEAPONTOP + - (self->player->chickenPeck << (FRACBITS-1)); + self->player->psprites[ps_weapon].sy = WEAPONTOP + self->player->chickenPeck / 2; } } @@ -172,9 +171,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; player_t *player; FTranslatedLineTarget t; @@ -184,12 +183,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1) } damage = 1 + (pr_beakatkpl1()&3); - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t); if (t.linetarget) { - player->mo->angle = t.angleFromSource; + player->mo->Angles.Yaw = t.angleFromSource; } P_PlayPeck (player->mo); player->chickenPeck = 12; @@ -207,9 +206,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; player_t *player; FTranslatedLineTarget t; @@ -219,12 +218,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2) } damage = pr_beakatkpl2.HitDice (4); - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t); if (t.linetarget) { - player->mo->angle = t.angleFromSource; + player->mo->Angles.Yaw = t.angleFromSource; } P_PlayPeck (player->mo); player->chickenPeck = 12; diff --git a/src/g_heretic/a_dsparil.cpp b/src/g_heretic/a_dsparil.cpp index ed2b97321..a978f3097 100644 --- a/src/g_heretic/a_dsparil.cpp +++ b/src/g_heretic/a_dsparil.cpp @@ -67,8 +67,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack) PARAM_ACTION_PROLOGUE; AActor *mo; - fixed_t vz; - angle_t angle; + DAngle angle; if (!self->target) { @@ -86,17 +85,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr1Attack) PClassActor *fx = PClass::FindActor("SorcererFX1"); if (self->health > (self->SpawnHealth()/3)*2) { // Spit one fireball - P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx ); + P_SpawnMissileZ (self, self->Z() + 48, self->target, fx ); } else { // Spit three fireballs - mo = P_SpawnMissileZ (self, self->Z() + 48*FRACUNIT, self->target, fx); + mo = P_SpawnMissileZ (self, self->Z() + 48, self->target, fx); if (mo != NULL) { - vz = mo->vel.z; - angle = mo->angle; - P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle-ANGLE_1*3, vz); - P_SpawnMissileAngleZ (self, self->Z() + 48*FRACUNIT, fx, angle+ANGLE_1*3, vz); + angle = mo->Angles.Yaw; + P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle - 3, mo->Vel.Z); + P_SpawnMissileAngleZ(self, self->Z() + 48, fx, angle + 3, mo->Vel.Z); } if (self->health < self->SpawnHealth()/3) { // Maybe attack again @@ -130,7 +128,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise) mo = Spawn("Sorcerer2", self->Pos(), ALLOW_REPLACE); mo->Translation = self->Translation; mo->SetState (mo->FindState("Rise")); - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; mo->CopyFriendliness (self, true); return 0; } @@ -143,31 +141,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcererRise) void P_DSparilTeleport (AActor *actor) { - fixed_t prevX; - fixed_t prevY; - fixed_t prevZ; + DVector3 prev; AActor *mo; AActor *spot; DSpotState *state = DSpotState::GetSpotState(); if (state == NULL) return; - spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128*FRACUNIT, 0); + spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128, 0); if (spot == NULL) return; - prevX = actor->X(); - prevY = actor->Y(); - prevZ = actor->Z(); + prev = actor->Pos(); if (P_TeleportMove (actor, spot->Pos(), false)) { - mo = Spawn("Sorcerer2Telefade", prevX, prevY, prevZ, ALLOW_REPLACE); + mo = Spawn("Sorcerer2Telefade", prev, ALLOW_REPLACE); if (mo) mo->Translation = actor->Translation; S_Sound (mo, CHAN_BODY, "misc/teleport", 1, ATTN_NORM); actor->SetState (actor->FindState("Teleport")); S_Sound (actor, CHAN_BODY, "misc/teleport", 1, ATTN_NORM); - actor->SetZ(actor->floorz, false); - actor->angle = spot->angle; - actor->vel.x = actor->vel.y = actor->vel.z = 0; + actor->SetZ(actor->floorz); + actor->Angles.Yaw = spot->Angles.Yaw; + actor->Vel.Zero(); } } @@ -230,8 +224,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Srcr2Attack) PClassActor *fx = PClass::FindActor("Sorcerer2FX2"); if (fx) { - P_SpawnMissileAngle (self, fx, self->angle-ANG45, FRACUNIT/2); - P_SpawnMissileAngle (self, fx, self->angle+ANG45, FRACUNIT/2); + P_SpawnMissileAngle(self, fx, self->Angles.Yaw - 45, 0.5); + P_SpawnMissileAngle(self, fx, self->Angles.Yaw + 45, 0.5); } } else @@ -257,9 +251,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BlueSpark) for (i = 0; i < 2; i++) { mo = Spawn("Sorcerer2FXSpark", self->Pos(), ALLOW_REPLACE); - mo->vel.x = pr_bluespark.Random2() << 9; - mo->vel.y = pr_bluespark.Random2() << 9; - mo->vel.z = FRACUNIT + (pr_bluespark()<<8); + mo->Vel.X = pr_bluespark.Random2() / 128.; + mo->Vel.Y = pr_bluespark.Random2() / 128.; + mo->Vel.Z = 1. + pr_bluespark() / 256.; } return 0; } @@ -279,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard) mo = Spawn("Wizard", self->Pos(), ALLOW_REPLACE); if (mo != NULL) { - mo->AddZ(-mo->GetDefault()->height / 2, false); + mo->AddZ(-mo->GetDefault()->Height / 2, false); if (!P_TestMobjLocation (mo)) { // Didn't fit mo->ClearCounters(); @@ -289,7 +283,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard) { // [RH] Make the new wizards inherit D'Sparil's target mo->CopyFriendliness (self->target, true); - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->SetState (self->FindState(NAME_Death)); self->flags &= ~MF_MISSILE; mo->master = self->target; diff --git a/src/g_heretic/a_hereticartifacts.cpp b/src/g_heretic/a_hereticartifacts.cpp index 2ed4da34c..860644eee 100644 --- a/src/g_heretic/a_hereticartifacts.cpp +++ b/src/g_heretic/a_hereticartifacts.cpp @@ -49,12 +49,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_TimeBomb) { PARAM_ACTION_PROLOGUE; - self->AddZ(32*FRACUNIT, false); - self->PrevZ = self->Z(); // no interpolation! + self->AddZ(32, false); self->RenderStyle = STYLE_Add; self->alpha = FRACUNIT; P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE); - P_CheckSplash(self, 128<angle >> ANGLETOFINESHIFT; AActor *mo = Spawn("ActivatedTimeBomb", - Owner->Vec3Angle(24*FRACUNIT, Owner->angle, - Owner->floorclip), ALLOW_REPLACE); + Owner->Vec3Angle(24., Owner->Angles.Yaw, - Owner->Floorclip), ALLOW_REPLACE); mo->target = Owner; return true; } diff --git a/src/g_heretic/a_hereticimp.cpp b/src/g_heretic/a_hereticimp.cpp index d2d40bed4..81185c0c1 100644 --- a/src/g_heretic/a_hereticimp.cpp +++ b/src/g_heretic/a_hereticimp.cpp @@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpMsAttack) self->SetState (self->SeeState); return 0; } - A_SkullAttack(self, 12 * FRACUNIT); + A_SkullAttack(self, 12.); return 0; } @@ -47,14 +47,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ImpExplode) self->flags &= ~MF_NOGRAVITY; chunk = Spawn("HereticImpChunk1", self->Pos(), ALLOW_REPLACE); - chunk->vel.x = pr_imp.Random2 () << 10; - chunk->vel.y = pr_imp.Random2 () << 10; - chunk->vel.z = 9*FRACUNIT; + chunk->Vel.X = pr_imp.Random2() / 64.; + chunk->Vel.Y = pr_imp.Random2() / 64.; + chunk->Vel.Z = 9; chunk = Spawn("HereticImpChunk2", self->Pos(), ALLOW_REPLACE); - chunk->vel.x = pr_imp.Random2 () << 10; - chunk->vel.y = pr_imp.Random2 () << 10; - chunk->vel.z = 9*FRACUNIT; + chunk->Vel.X = pr_imp.Random2() / 64.; + chunk->Vel.Y = pr_imp.Random2() / 64.; + chunk->Vel.Z = 9; if (self->special1 == 666) { // Extreme death crash self->SetState (self->FindState("XCrash")); diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index af8431a95..927d13dc4 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -59,11 +59,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain) } for (count = chance > 240 ? 2 : 1; count; count--) { - goo = Spawn(gootype, self->PosPlusZ(48*FRACUNIT), ALLOW_REPLACE); + goo = Spawn(gootype, self->PosPlusZ(48.), ALLOW_REPLACE); goo->target = self; - goo->vel.x = pr_podpain.Random2() << 9; - goo->vel.y = pr_podpain.Random2() << 9; - goo->vel.z = FRACUNIT/2 + (pr_podpain() << 9); + goo->Vel.X = pr_podpain.Random2() / 128.; + goo->Vel.Y = pr_podpain.Random2() / 128.; + goo->Vel.Z = 0.5 + pr_podpain() / 128.; } return 0; } @@ -104,23 +104,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod) PARAM_CLASS_OPT(podtype, AActor) { podtype = PClass::FindActor("Pod"); } AActor *mo; - fixed_t x; - fixed_t y; if (self->special1 == MAX_GEN_PODS) { // Too many generated pods return 0; } - x = self->X(); - y = self->Y(); - mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE); - if (!P_CheckPosition (mo, x, y)) + mo = Spawn(podtype, self->PosAtZ(ONFLOORZ), ALLOW_REPLACE); + if (!P_CheckPosition (mo, mo->Pos())) { // Didn't fit mo->Destroy (); return 0; } mo->SetState (mo->FindState("Grow")); - P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT)); + mo->Thrust(pr_makepod() * (360. / 256), 4.5); S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE); self->special1++; // Increment generated pod count mo->master = self; // Link the generator to the pod @@ -139,7 +135,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AccTeleGlitter) if (++self->health > 35) { - self->vel.z += self->vel.z/2; + self->Vel.Z *= 1.5; } return 0; } @@ -172,19 +168,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcanoBlast) int i; int count; AActor *blast; - angle_t angle; count = 1 + (pr_blast() % 3); for (i = 0; i < count; i++) { blast = Spawn("VolcanoBlast", self->PosPlusZ(44*FRACUNIT), ALLOW_REPLACE); blast->target = self; - angle = pr_blast () << 24; - blast->angle = angle; - angle >>= ANGLETOFINESHIFT; - blast->vel.x = FixedMul (1*FRACUNIT, finecosine[angle]); - blast->vel.y = FixedMul (1*FRACUNIT, finesine[angle]); - blast->vel.z = (FRACUNIT*5/2) + (pr_blast() << 10); + blast->Angles.Yaw = pr_blast() * (360 / 256.f); + blast->VelFromAngle(1.); + blast->Vel.Z = 2.5 + pr_blast() / 64.; S_Sound (blast, CHAN_BODY, "world/volcano/shoot", 1, ATTN_NORM); P_CheckMissileSpawn (blast, self->radius); } @@ -203,26 +195,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_VolcBallImpact) unsigned int i; AActor *tiny; - angle_t angle; if (self->Z() <= self->floorz) { self->flags |= MF_NOGRAVITY; - self->gravity = FRACUNIT; - self->AddZ(28*FRACUNIT); - //self->vel.z = 3*FRACUNIT; + self->Gravity = 1; + self->AddZ(28); + //self->Vel.Z = 3; } P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE); for (i = 0; i < 4; i++) { tiny = Spawn("VolcanoTBlast", self->Pos(), ALLOW_REPLACE); tiny->target = self; - angle = i*ANG90; - tiny->angle = angle; - angle >>= ANGLETOFINESHIFT; - tiny->vel.x = FixedMul (FRACUNIT*7/10, finecosine[angle]); - tiny->vel.y = FixedMul (FRACUNIT*7/10, finesine[angle]); - tiny->vel.z = FRACUNIT + (pr_volcimpact() << 9); + tiny->Angles.Yaw = 90.*i; + tiny->VelFromAngle(0.7); + tiny->Vel.Z = 1. + pr_volcimpact() / 128.; P_CheckMissileSpawn (tiny, self->radius); } return 0; diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 814a80bf5..f36ea54b5 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -63,8 +63,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; - int slope; + DAngle angle; + DAngle slope; player_t *player; FTranslatedLineTarget t; @@ -86,15 +86,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_StaffAttack) { puff = PClass::FindActor(NAME_BulletPuff); // just to be sure } - angle = self->angle; - angle += pr_sap.Random2() << 18; + angle = self->Angles.Yaw + pr_sap.Random2() * (5.625 / 256); slope = P_AimLineAttack (self, angle, MELEERANGE); P_LineAttack (self, angle, MELEERANGE, slope, damage, NAME_Melee, puff, true, &t); if (t.linetarget) { //S_StartSound(player->mo, sfx_stfhit); // turn to face target - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } return 0; } @@ -110,7 +109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; player_t *player; @@ -122,18 +121,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL1) AWeapon *weapon = player->ReadyWeapon; if (weapon != NULL) { - if (!weapon->DepleteAmmo (weapon->bAltFire)) + if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; } - angle_t pitch = P_BulletSlope(self); - damage = 7+(pr_fgw()&7); - angle = self->angle; + DAngle pitch = P_BulletSlope(self); + damage = 7 + (pr_fgw() & 7); + angle = self->Angles.Yaw; if (player->refire) { - angle += pr_fgw.Random2() << 18; + angle += pr_fgw.Random2() * (5.625 / 256); } - P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1"); - S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); + P_LineAttack(self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff1"); + S_Sound(self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); return 0; } @@ -148,9 +147,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2) PARAM_ACTION_PROLOGUE; int i; - angle_t angle; + DAngle angle; int damage; - fixed_t vz; + double vz; player_t *player; if (NULL == (player = self->player)) @@ -164,17 +163,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireGoldWandPL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - angle_t pitch = P_BulletSlope(self); - vz = FixedMul (GetDefaultByName("GoldWandFX2")->Speed, - finetangent[FINEANGLES/4-((signed)pitch>>ANGLETOFINESHIFT)]); - P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle-(ANG45/8), vz); - P_SpawnMissileAngle (self, PClass::FindActor("GoldWandFX2"), self->angle+(ANG45/8), vz); - angle = self->angle-(ANG45/8); + DAngle pitch = P_BulletSlope(self); + + vz = -GetDefaultByName("GoldWandFX2")->Speed * pitch.TanClamped(); + P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw - (45. / 8), vz); + P_SpawnMissileAngle(self, PClass::FindActor("GoldWandFX2"), self->Angles.Yaw + (45. / 8), vz); + angle = self->Angles.Yaw - (45. / 8); for(i = 0; i < 5; i++) { damage = 1+(pr_fgw2()&7); P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "GoldWandPuff2"); - angle += ((ANG45/8)*2)/4; + angle += ((45. / 8) * 2) / 4; } S_Sound (self, CHAN_WEAPON, "weapons/wandhit", 1, ATTN_NORM); return 0; @@ -204,8 +203,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL1) return 0; } P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX1")); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/10)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 4.5); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 4.5); return 0; } @@ -233,10 +232,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCrossbowPL2) return 0; } P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2")); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle-(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->angle+(ANG45/10)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle-(ANG45/5)); - P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->angle+(ANG45/5)); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw - 4.5); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX2"), self->Angles.Yaw + 4.5); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw - 9.); + P_SpawnPlayerMissile (self, PClass::FindActor("CrossbowFX3"), self->Angles.Yaw + 9.); return 0; } @@ -250,11 +249,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle Angle; int damage; - int slope; + DAngle slope; int randVal; - fixed_t dist; + double dist; player_t *player; PClassActor *pufftype; FTranslatedLineTarget t; @@ -273,25 +272,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2) * FRACUNIT; - player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3) * FRACUNIT; - angle = self->angle; + player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2); + player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3); + Angle = self->Angles.Yaw; if (power) { damage = pr_gatk.HitDice (2); dist = 4*MELEERANGE; - angle += pr_gatk.Random2() << 17; + Angle += pr_gatk.Random2() * (2.8125 / 256); pufftype = PClass::FindActor("GauntletPuff2"); } else { damage = pr_gatk.HitDice (2); - dist = MELEERANGE+1; - angle += pr_gatk.Random2() << 18; + dist = SAWRANGE; + Angle += pr_gatk.Random2() * (5.625 / 256); pufftype = PClass::FindActor("GauntletPuff1"); } - slope = P_AimLineAttack (self, angle, dist); - P_LineAttack (self, angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); + slope = P_AimLineAttack (self, Angle, dist); + P_LineAttack (self, Angle, dist, slope, damage, NAME_Melee, pufftype, false, &t, &actualdamage); if (!t.linetarget) { if (pr_gatk() > 64) @@ -324,20 +323,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack) S_Sound (self, CHAN_AUTO, "weapons/gauntletshit", 1, ATTN_NORM); } // turn to face target - angle = t.angleFromSource; - if (angle-self->angle > ANG180) + DAngle angle = t.angleFromSource; + DAngle anglediff = deltaangle(self->Angles.Yaw, angle); + + if (anglediff < 0.0) { - if ((int)(angle-self->angle) < -ANG90/20) - self->angle = angle+ANG90/21; + if (anglediff < -4.5) + self->Angles.Yaw = angle + 90.0 / 21; else - self->angle -= ANG90/20; + self->Angles.Yaw -= 4.5; } else { - if (angle-self->angle > ANG90/20) - self->angle = angle-ANG90/21; + if (anglediff > 4.5) + self->Angles.Yaw = angle - 90.0 / 21; else - self->angle += ANG90/20; + self->Angles.Yaw += 4.5; } self->flags |= MF_JUSTATTACKED; return 0; @@ -387,7 +388,6 @@ int AMaceFX4::DoSpecialDamage (AActor *target, int damage, FName damagetype) void FireMacePL1B (AActor *actor) { AActor *ball; - angle_t angle; player_t *player; if (NULL == (player = actor->player)) @@ -401,16 +401,13 @@ void FireMacePL1B (AActor *actor) if (!weapon->DepleteAmmo (weapon->bAltFire)) return; } - ball = Spawn("MaceFX2", actor->PosPlusZ(28*FRACUNIT - actor->floorclip), ALLOW_REPLACE); - ball->vel.z = 2*FRACUNIT+/*((player->lookdir)<<(FRACBITS-5))*/ - finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)]; - angle = actor->angle; + ball = Spawn("MaceFX2", actor->PosPlusZ(28 - actor->Floorclip), ALLOW_REPLACE); + ball->Vel.Z = 2 - player->mo->Angles.Pitch.TanClamped(); ball->target = actor; - ball->angle = angle; - ball->AddZ(2*finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)]); - angle >>= ANGLETOFINESHIFT; - ball->vel.x = (actor->vel.x>>1) + FixedMul(ball->Speed, finecosine[angle]); - ball->vel.y = (actor->vel.y>>1) + FixedMul(ball->Speed, finesine[angle]); + ball->Angles.Yaw = actor->Angles.Yaw; + ball->AddZ(ball->Vel.Z); + ball->VelFromAngle(); + ball->Vel += actor->Vel.XY()/2; S_Sound (ball, CHAN_BODY, "weapons/maceshoot", 1, ATTN_NORM); P_CheckMissileSpawn (ball, actor->radius); } @@ -435,19 +432,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1) if (pr_maceatk() < 28) { - FireMacePL1B (self); + FireMacePL1B(self); return 0; } AWeapon *weapon = player->ReadyWeapon; if (weapon != NULL) { - if (!weapon->DepleteAmmo (weapon->bAltFire)) + if (!weapon->DepleteAmmo(weapon->bAltFire)) return 0; } - player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT; - player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*FRACUNIT; - ball = P_SpawnPlayerMissile (self, PClass::FindActor("MaceFX1"), - self->angle+(((pr_maceatk()&7)-4)<<24)); + player->psprites[ps_weapon].sx = ((pr_maceatk() & 3) - 2); + player->psprites[ps_weapon].sy = WEAPONTOP + (pr_maceatk() & 3); + ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256))); if (ball) { ball->special1 = 16; // tics till dropoff @@ -476,21 +472,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_MacePL1Check) } self->special1 = 0; self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT/8; + self->Gravity = 1. / 8;; // [RH] Avoid some precision loss by scaling the velocity directly #if 0 // This is the original code, for reference. - angle_t angle = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul(7*FRACUNIT, finecosine[angle]); - self->vel.y = FixedMul(7*FRACUNIT, finesine[angle]); + a.ngle_t angle = self->angle>>ANGLETOF.INESHIFT; + self->velx = F.ixedMul(7*F.RACUNIT, f.inecosine[angle]); + self->vely = F.ixedMul(7*F.RACUNIT, f.inesine[angle]); #else - double velscale = sqrt ((double)self->vel.x * (double)self->vel.x + - (double)self->vel.y * (double)self->vel.y); - velscale = 458752 / velscale; - self->vel.x = (int)(self->vel.x * velscale); - self->vel.y = (int)(self->vel.y * velscale); + double velscale = 7 / self->Vel.XY().Length(); + self->Vel.X *= velscale; + self->Vel.Y *= velscale; #endif - self->vel.z -= self->vel.z >> 1; + self->Vel.Z *= 0.5; return 0; } @@ -507,16 +501,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact) if ((self->health != MAGIC_JUNK) && (self->flags & MF_INBOUNCE)) { // Bounce self->health = MAGIC_JUNK; - self->vel.z = (self->vel.z * 192) >> 8; + self->Vel.Z *= 0.75; self->BounceFlags = BOUNCE_None; self->SetState (self->SpawnState); S_Sound (self, CHAN_BODY, "weapons/macebounce", 1, ATTN_NORM); } else { // Explode - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->flags |= MF_NOGRAVITY; - self->gravity = FRACUNIT; + self->Gravity = 1; S_Sound (self, CHAN_BODY, "weapons/macehit", 1, ATTN_NORM); } return 0; @@ -533,7 +527,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) PARAM_ACTION_PROLOGUE; AActor *tiny; - angle_t angle; if ((self->Z() <= self->floorz) && P_HitFloor (self)) { // Landed in some sort of liquid @@ -542,42 +535,36 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) } if (self->flags & MF_INBOUNCE) { - if (self->vel.z < 2*FRACUNIT) + if (self->Vel.Z < 2) { goto boom; } // Bounce - self->vel.z = (self->vel.z * 192) >> 8; + self->Vel.Z *= 0.75; self->SetState (self->SpawnState); tiny = Spawn("MaceFX3", self->Pos(), ALLOW_REPLACE); - angle = self->angle+ANG90; tiny->target = self->target; - tiny->angle = angle; - angle >>= ANGLETOFINESHIFT; - tiny->vel.x = (self->vel.x>>1) + FixedMul(self->vel.z-FRACUNIT, finecosine[angle]); - tiny->vel.y = (self->vel.y>>1) + FixedMul(self->vel.z-FRACUNIT, finesine[angle]); - tiny->vel.z = self->vel.z; + tiny->Angles.Yaw = self->Angles.Yaw + 90.; + tiny->VelFromAngle(self->Vel.Z - 1.); + tiny->Vel += { self->Vel.X * .5, self->Vel.Y * .5, self->Vel.Z }; P_CheckMissileSpawn (tiny, self->radius); tiny = Spawn("MaceFX3", self->Pos(), ALLOW_REPLACE); - angle = self->angle-ANG90; tiny->target = self->target; - tiny->angle = angle; - angle >>= ANGLETOFINESHIFT; - tiny->vel.x = (self->vel.x>>1) + FixedMul(self->vel.z-FRACUNIT, finecosine[angle]); - tiny->vel.y = (self->vel.y>>1) + FixedMul(self->vel.z-FRACUNIT, finesine[angle]); - tiny->vel.z = self->vel.z; + tiny->Angles.Yaw = self->Angles.Yaw - 90.; + tiny->VelFromAngle(self->Vel.Z - 1.); + tiny->Vel += { self->Vel.X * .5, self->Vel.Y * .5, self->Vel.Z }; P_CheckMissileSpawn (tiny, self->radius); } else { // Explode boom: - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->flags |= MF_NOGRAVITY; self->BounceFlags = BOUNCE_None; - self->gravity = FRACUNIT; + self->Gravity = 1; } return 0; } @@ -607,13 +594,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->angle, &t); + mo = P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AMaceFX4), self->Angles.Yaw, &t); if (mo) { - mo->vel.x += self->vel.x; - mo->vel.y += self->vel.y; - mo->vel.z = 2*FRACUNIT+ - clamp(finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], -5*FRACUNIT, 5*FRACUNIT); + mo->Vel += self->Vel.XY(); + mo->Vel.Z = 2 - player->mo->Angles.Pitch.TanClamped(); if (t.linetarget && !t.unlinked) { mo->tracer = t.linetarget; @@ -635,7 +620,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) int i; AActor *target; - angle_t angle = 0; + DAngle angle = 0.; bool newAngle; FTranslatedLineTarget t; @@ -646,7 +631,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) } if (self->flags & MF_INBOUNCE) { - if (self->vel.z < 2*FRACUNIT) + if (self->Vel.Z < 2) { goto boom; } @@ -668,10 +653,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) } else { // Find new target - angle = 0; + angle = 0.; for (i = 0; i < 16; i++) { - P_AimLineAttack (self, angle, 10*64*FRACUNIT, &t, 0, ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target); + P_AimLineAttack (self, angle, 640., &t, 0., ALF_NOFRIENDS|ALF_PORTALRESTRICT, NULL, self->target); if (t.linetarget && self->target != t.linetarget) { self->tracer = t.linetarget; @@ -679,15 +664,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) newAngle = true; break; } - angle += ANGLE_45/2; + angle += 22.5; } } if (newAngle) { - self->angle = angle; - angle >>= ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[angle]); - self->vel.y = FixedMul (self->Speed, finesine[angle]); + self->Angles.Yaw = angle; + self->VelFromAngle(); } self->SetState (self->SpawnState); S_Sound (self, CHAN_BODY, "weapons/macestop", 1, ATTN_NORM); @@ -695,9 +678,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) else { // Explode boom: - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); self->flags |= MF_NOGRAVITY; - self->gravity = FRACUNIT; + self->Gravity = 1; S_Sound (self, CHAN_BODY, "weapons/maceexplode", 1, ATTN_NORM); } return 0; @@ -737,7 +720,7 @@ void ABlasterFX1::Effect () { if (pr_bfx1t() < 64) { - Spawn("BlasterSmoke", X(), Y(), MAX (Z() - 8 * FRACUNIT, floorz), ALLOW_REPLACE); + Spawn("BlasterSmoke", PosAtZ(MAX(Z() - 8., floorz)), ALLOW_REPLACE); } } @@ -778,7 +761,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; player_t *player; @@ -793,12 +776,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBlasterPL1) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - angle_t pitch = P_BulletSlope(self); + DAngle pitch = P_BulletSlope(self); damage = pr_fb1.HitDice (4); - angle = self->angle; + angle = self->Angles.Yaw; if (player->refire) { - angle += pr_fb1.Random2() << 18; + angle += pr_fb1.Random2() * (5.625 / 256); } P_LineAttack (self, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, "BlasterPuff"); S_Sound (self, CHAN_WEAPON, "weapons/blastershoot", 1, ATTN_NORM); @@ -816,18 +799,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers) PARAM_ACTION_PROLOGUE; unsigned int i; - angle_t angle; + DAngle angle; AActor *ripper; for(i = 0; i < 8; i++) { ripper = Spawn (self->Pos(), ALLOW_REPLACE); - angle = i*ANG45; + angle = i*45.; ripper->target = self->target; - ripper->angle = angle; - angle >>= ANGLETOFINESHIFT; - ripper->vel.x = FixedMul (ripper->Speed, finecosine[angle]); - ripper->vel.y = FixedMul (ripper->Speed, finesine[angle]); + ripper->Angles.Yaw = angle; + ripper->VelFromAngle(); P_CheckMissileSpawn (ripper, self->radius); } return 0; @@ -955,7 +936,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSkullRodPL2) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->angle, &t, &MissileActor); + P_SpawnPlayerMissile (self, 0,0,0, RUNTIME_CLASS(AHornRodFX2), self->Angles.Yaw, &t, &MissileActor); // Use MissileActor instead of the return value from // P_SpawnPlayerMissile because we need to give info to the mobj // even if it exploded immediately. @@ -1071,10 +1052,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) { // Fudge rain frequency return 0; } - fixedvec2 pos = self->Vec2Offset( - ((pr_storm()&127) - 64) * FRACUNIT, - ((pr_storm()&127) - 64) * FRACUNIT); - mo = Spawn (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE); + double xo = ((pr_storm() & 127) - 64); + double yo = ((pr_storm() & 127) - 64); + DVector3 pos = self->Vec2OffsetZ(xo, yo, ONCEILINGZ); + mo = Spawn (pos, ALLOW_REPLACE); // We used bouncecount to store the 3D floor index in A_HideInCeiling if (!mo) return 0; if (mo->Sector->PortalGroup != self->Sector->PortalGroup) @@ -1083,19 +1064,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) mo->Destroy(); return 0; } - fixed_t newz; if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size()) - newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT; + pos.Z = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPointF(mo); else - newz = self->Sector->ceilingplane.ZatPoint(mo); - int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz); - if (moceiling >= 0) - mo->SetZ(newz - mo->height, false); - mo->Translation = multiplayer ? - TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0; + pos.Z = self->Sector->ceilingplane.ZatPointF(mo); + int moceiling = P_Find3DFloor(NULL, pos, false, false, pos.Z); + if (moceiling >= 0) mo->SetZ(pos.Z - mo->Height); + mo->Translation = multiplayer ? TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0; mo->target = self->target; - mo->vel.x = 1; // Force collision detection - mo->vel.z = -mo->Speed; + mo->Vel.X = MinVel; // Force collision detection + mo->Vel.Z = -mo->Speed; mo->special2 = self->special2; // Transfer player number P_CheckMissileSpawn (mo, self->radius); if (self->special1 != -1 && !S_IsActorPlayingSomething (self, CHAN_BODY, -1)) @@ -1136,21 +1114,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_HideInCeiling) PARAM_ACTION_PROLOGUE; // We use bouncecount to store the 3D floor index - fixed_t foo; - for (unsigned int i=0; i< self->Sector->e->XFloor.ffloors.Size(); i++) + double foo; + for (int i = self->Sector->e->XFloor.ffloors.Size() - 1; i >= 0; i--) { F3DFloor * rover = self->Sector->e->XFloor.ffloors[i]; - if(!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; - - if ((foo = rover->bottom.plane->ZatPoint(self)) >= (self->Top())) + if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue; + + if ((foo = rover->bottom.plane->ZatPointF(self)) >= self->Top()) { - self->SetZ(foo + 4*FRACUNIT, false); + self->SetZ(foo + 4, false); self->bouncecount = i; return 0; } } self->bouncecount = -1; - self->SetZ(self->ceilingz + 4*FRACUNIT, false); + self->SetZ(self->ceilingz + 4, false); return 0; } @@ -1237,7 +1215,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; player_t *player; if (NULL == (player = self->player)) @@ -1252,10 +1229,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL1) return 0; } P_SpawnPlayerMissile (self, RUNTIME_CLASS(APhoenixFX1)); - angle = self->angle + ANG180; - angle >>= ANGLETOFINESHIFT; - self->vel.x += FixedMul (4*FRACUNIT, finecosine[angle]); - self->vel.y += FixedMul (4*FRACUNIT, finesine[angle]); + self->Thrust(self->Angles.Yaw + 180, 4); return 0; } @@ -1270,22 +1244,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_PhoenixPuff) PARAM_ACTION_PROLOGUE; AActor *puff; - angle_t angle; + DAngle angle; //[RH] Heretic never sets the target for seeking //P_SeekerMissile (self, ANGLE_1*5, ANGLE_1*10); puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE); - angle = self->angle + ANG90; - angle >>= ANGLETOFINESHIFT; - puff->vel.x = FixedMul (FRACUNIT*13/10, finecosine[angle]); - puff->vel.y = FixedMul (FRACUNIT*13/10, finesine[angle]); - puff->vel.z = 0; + angle = self->Angles.Yaw + 90; + puff->Vel = DVector3(angle.ToVector(1.3), 0); + puff = Spawn("PhoenixPuff", self->Pos(), ALLOW_REPLACE); - angle = self->angle - ANG90; - angle >>= ANGLETOFINESHIFT; - puff->vel.x = FixedMul (FRACUNIT*13/10, finecosine[angle]); - puff->vel.y = FixedMul (FRACUNIT*13/10, finesine[angle]); - puff->vel.z = 0; + angle = self->Angles.Yaw - 90; + puff->Vel = DVector3(angle.ToVector(1.3), 0); return 0; } @@ -1323,9 +1292,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) PARAM_ACTION_PROLOGUE; AActor *mo; - angle_t angle; - fixed_t slope; + double slope; FSoundID soundid; player_t *player; APhoenixRod *flamethrower; @@ -1345,20 +1313,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) S_StopSound (self, CHAN_WEAPON); return 0; } - angle = self->angle; - fixed_t xo = (pr_fp2.Random2() << 9); - fixed_t yo = (pr_fp2.Random2() << 9); - fixedvec3 pos = self->Vec3Offset(xo, yo, - 26*FRACUNIT + finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] - self->floorclip); + slope = -self->Angles.Pitch.TanClamped(); + double xo = pr_fp2.Random2() / 128.; + double yo = pr_fp2.Random2() / 128.; + DVector3 pos = self->Vec3Offset(xo, yo, 26 + slope - self->Floorclip); - slope = finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] + (FRACUNIT/10); + slope += 0.1; mo = Spawn("PhoenixFX2", pos, ALLOW_REPLACE); mo->target = self; - mo->angle = angle; - mo->vel.x = self->vel.x + FixedMul (mo->Speed, finecosine[angle>>ANGLETOFINESHIFT]); - mo->vel.y = self->vel.y + FixedMul (mo->Speed, finesine[angle>>ANGLETOFINESHIFT]); - mo->vel.z = FixedMul (mo->Speed, slope); + mo->Angles.Yaw = self->Angles.Yaw; + mo->VelFromAngle(); + mo->Vel += self->Vel.XY(); + mo->Vel.Z = mo->Speed * slope; if (!player->refire || !S_IsActorPlayingSomething (self, CHAN_WEAPON, -1)) { S_Sound (self, CHAN_WEAPON|CHAN_LOOP, soundid, 1, ATTN_NORM); @@ -1403,7 +1370,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameEnd) { PARAM_ACTION_PROLOGUE; - self->vel.z += FRACUNIT*3/2; + self->Vel.Z += 1.5; return 0; } @@ -1417,7 +1384,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatPuff) { PARAM_ACTION_PROLOGUE; - self->vel.z += FRACUNIT*18/10; + self->Vel.Z += 1.8; return 0; } diff --git a/src/g_heretic/a_ironlich.cpp b/src/g_heretic/a_ironlich.cpp index 5c7746e82..820d650f9 100644 --- a/src/g_heretic/a_ironlich.cpp +++ b/src/g_heretic/a_ironlich.cpp @@ -30,9 +30,9 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype) if (!(target->flags7 & MF7_DONTTHRUST)) { - target->angle += pr_foo.Random2() << 20; - target->vel.x += pr_foo.Random2() << 10; - target->vel.y += pr_foo.Random2() << 10; + target->Angles.Yaw += pr_foo.Random2() * (360 / 4096.); + target->Vel.X += pr_foo.Random2() / 64.; + target->Vel.Y += pr_foo.Random2() / 64.; } if ((level.time & 16) && !(target->flags2 & MF2_BOSS) && !(target->flags7 & MF7_DONTTHRUST)) @@ -42,10 +42,10 @@ int AWhirlwind::DoSpecialDamage (AActor *target, int damage, FName damagetype) { randVal = 160; } - target->vel.z += randVal << 11; - if (target->vel.z > 12*FRACUNIT) + target->Vel.Z += randVal / 32.; + if (target->Vel.Z > 12) { - target->vel.z = 12*FRACUNIT; + target->Vel.Z = 12; } } if (!(level.time & 7)) @@ -73,7 +73,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) int randAttack; static const int atkResolve1[] = { 50, 150 }; static const int atkResolve2[] = { 150, 200 }; - int dist; // Ice ball (close 20% : far 60%) // Fire column (close 40% : far 20%) @@ -93,7 +92,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) P_TraceBleed (newdam > 0 ? newdam : damage, target, self); return 0; } - dist = self->AproxDistance (target) > 8*64*FRACUNIT; + int dist = self->Distance2D(target) > 8 * 64; randAttack = pr_atk (); if (randAttack < atkResolve1[dist]) { // Ice ball @@ -114,10 +113,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) S_Sound (self, CHAN_BODY, "ironlich/attack1", 1, ATTN_NORM); } fire->target = baseFire->target; - fire->angle = baseFire->angle; - fire->vel.x = baseFire->vel.x; - fire->vel.y = baseFire->vel.y; - fire->vel.z = baseFire->vel.z; + fire->Angles.Yaw = baseFire->Angles.Yaw; + fire->Vel = baseFire->Vel; fire->Damage = NULL; fire->health = (i+1) * 2; P_CheckMissileSpawn (fire, self->radius); @@ -129,7 +126,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichAttack) mo = P_SpawnMissile (self, target, RUNTIME_CLASS(AWhirlwind)); if (mo != NULL) { - mo->AddZ(-32*FRACUNIT, false); + mo->AddZ(-32); mo->tracer = target; mo->health = 20*TICRATE; // Duration S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM); @@ -151,21 +148,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_WhirlwindSeek) self->health -= 3; if (self->health < 0) { - self->vel.x = self->vel.y = self->vel.z = 0; - self->SetState (self->FindState(NAME_Death)); + self->Vel.Zero(); + self->SetState(self->FindState(NAME_Death)); self->flags &= ~MF_MISSILE; return 0; } if ((self->threshold -= 3) < 0) { self->threshold = 58 + (pr_seek() & 31); - S_Sound (self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM); + S_Sound(self, CHAN_BODY, "ironlich/attack3", 1, ATTN_NORM); } if (self->tracer && self->tracer->flags&MF_SHADOW) { return 0; } - P_SeekerMissile (self, ANGLE_1*10, ANGLE_1*30); + P_SeekerMissile(self, ANGLE_1 * 10, ANGLE_1 * 30); return 0; } @@ -180,19 +177,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichIceImpact) PARAM_ACTION_PROLOGUE; unsigned int i; - angle_t angle; AActor *shard; for (i = 0; i < 8; i++) { shard = Spawn("HeadFX2", self->Pos(), ALLOW_REPLACE); - angle = i*ANG45; shard->target = self->target; - shard->angle = angle; - angle >>= ANGLETOFINESHIFT; - shard->vel.x = FixedMul (shard->Speed, finecosine[angle]); - shard->vel.y = FixedMul (shard->Speed, finesine[angle]); - shard->vel.z = -FRACUNIT*6/10; + shard->Angles.Yaw = i*45.; + shard->VelFromAngle(); + shard->Vel.Z = -.6; P_CheckMissileSpawn (shard, self->radius); } return 0; @@ -209,7 +202,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LichFireGrow) PARAM_ACTION_PROLOGUE; self->health--; - self->AddZ(9*FRACUNIT); + self->AddZ(9.); if (self->health == 0) { self->Damage = self->GetDefault()->Damage; diff --git a/src/g_heretic/a_knight.cpp b/src/g_heretic/a_knight.cpp index a2b2cc45b..9f42a328a 100644 --- a/src/g_heretic/a_knight.cpp +++ b/src/g_heretic/a_knight.cpp @@ -25,12 +25,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood) AActor *mo; - fixed_t xo = (pr_dripblood.Random2() << 11); - fixed_t yo = (pr_dripblood.Random2() << 11); - mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0), ALLOW_REPLACE); - mo->vel.x = pr_dripblood.Random2 () << 10; - mo->vel.y = pr_dripblood.Random2 () << 10; - mo->gravity = FRACUNIT/8; + double xo = pr_dripblood.Random2() / 32.; + double yo = pr_dripblood.Random2() / 32.; + mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0.), ALLOW_REPLACE); + mo->Vel.X = pr_dripblood.Random2 () / 64.; + mo->Vel.Y = pr_dripblood.Random2() / 64.; + mo->Gravity = 1./8; return 0; } @@ -60,11 +60,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_KnightAttack) S_Sound (self, CHAN_BODY, self->AttackSound, 1, ATTN_NORM); if (self->flags & MF_SHADOW || pr_knightatk () < 40) { // Red axe - P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("RedAxe")); + P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("RedAxe")); return 0; } // Green axe - P_SpawnMissileZ (self, self->Z() + 36*FRACUNIT, self->target, PClass::FindActor("KnightAxe")); + P_SpawnMissileZ (self, self->Z() + 36, self->target, PClass::FindActor("KnightAxe")); return 0; } diff --git a/src/g_heretic/a_wizard.cpp b/src/g_heretic/a_wizard.cpp index 7a92a1155..51a01efc5 100644 --- a/src/g_heretic/a_wizard.cpp +++ b/src/g_heretic/a_wizard.cpp @@ -88,8 +88,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_WizAtk3) mo = P_SpawnMissile (self, self->target, fx); if (mo != NULL) { - P_SpawnMissileAngle(self, fx, mo->angle-(ANG45/8), mo->vel.z); - P_SpawnMissileAngle(self, fx, mo->angle+(ANG45/8), mo->vel.z); + P_SpawnMissileAngle(self, fx, mo->Angles.Yaw - 45. / 8, mo->Vel.Z); + P_SpawnMissileAngle(self, fx, mo->Angles.Yaw + 45. / 8, mo->Vel.Z); } return 0; } diff --git a/src/g_hexen/a_bats.cpp b/src/g_hexen/a_bats.cpp index 2bde56340..507af8011 100644 --- a/src/g_hexen/a_bats.cpp +++ b/src/g_hexen/a_bats.cpp @@ -47,7 +47,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatSpawn) delta = self->args[1]; if (delta==0) delta=1; - angle = self->angle + (((pr_batspawn()%delta)-(delta>>1))<<24); + angle = self->_f_angle() + (((pr_batspawn()%delta)-(delta>>1))<<24); mo = P_SpawnMissileAngle (self, PClass::FindActor("Bat"), angle, 0); if (mo) { @@ -64,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) { PARAM_ACTION_PROLOGUE; - angle_t newangle; + DAngle newangle; if (self->special2 < 0) { @@ -74,17 +74,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) if (pr_batmove()<128) { - newangle = self->angle + ANGLE_1*self->args[4]; + newangle = self->Angles.Yaw + self->args[4]; } else { - newangle = self->angle - ANGLE_1*self->args[4]; + newangle = self->Angles.Yaw - self->args[4]; } // Adjust velocity vector to new direction - newangle >>= ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[newangle]); - self->vel.y = FixedMul (self->Speed, finesine[newangle]); + self->VelFromAngle(newangle, self->Speed); if (pr_batmove()<15) { @@ -92,7 +90,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BatMove) } // Handle Z movement - self->SetZ(self->target->Z() + 16*finesine[self->args[0] << BOBTOFINESHIFT]); + self->SetZ(self->target->Z() + 16 * g_sin(BOBTORAD(self->args[0]))); self->args[0] = (self->args[0]+3)&63; return 0; } diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp index 649e5b273..319c2b53d 100644 --- a/src/g_hexen/a_bishop.cpp +++ b/src/g_hexen/a_bishop.cpp @@ -118,15 +118,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopDoBlur) self->special1 = (pr_doblur() & 3) + 3; // Random number of blurs if (pr_doblur() < 120) { - P_ThrustMobj (self, self->angle + ANG90, 11*FRACUNIT); + self->Thrust(self->Angles.Yaw + 90, 11); } else if (pr_doblur() > 125) { - P_ThrustMobj (self, self->angle - ANG90, 11*FRACUNIT); + self->Thrust(self->Angles.Yaw - 90, 11); } else { // Thrust forward - P_ThrustMobj (self, self->angle, 11*FRACUNIT); + self->Thrust(11); } S_Sound (self, CHAN_BODY, "BishopBlur", 1, ATTN_NORM); return 0; @@ -146,8 +146,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur) if (!--self->special1) { - self->vel.x = 0; - self->vel.y = 0; + self->Vel.X = self->Vel.Y = 0; if (pr_sblur() > 96) { self->SetState (self->SeeState); @@ -160,7 +159,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopSpawnBlur) mo = Spawn ("BishopBlur", self->Pos(), ALLOW_REPLACE); if (mo) { - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; } return 0; } @@ -175,10 +174,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopChase) { PARAM_ACTION_PROLOGUE; - fixed_t newz = self->Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4; + fixed_t newz = self->_f_Z() - finesine[self->special2 << BOBTOFINESHIFT] * 4; self->special2 = (self->special2 + 4) & 63; newz += finesine[self->special2 << BOBTOFINESHIFT] * 4; - self->SetZ(newz); + self->_f_SetZ(newz); return 0; } @@ -197,7 +196,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPuff) mo = Spawn ("BishopPuff", self->PosPlusZ(40*FRACUNIT), ALLOW_REPLACE); if (mo) { - mo->vel.z = FRACUNIT/2; + mo->Vel.Z = -.5; } return 0; } @@ -225,7 +224,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur) mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; } return 0; } diff --git a/src/g_hexen/a_blastradius.cpp b/src/g_hexen/a_blastradius.cpp index 541b6bfac..2e9f358f1 100644 --- a/src/g_hexen/a_blastradius.cpp +++ b/src/g_hexen/a_blastradius.cpp @@ -22,11 +22,11 @@ // //========================================================================== -void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage) +void BlastActor (AActor *victim, fixed_t strength, double speed, AActor *Owner, PClassActor *blasteffect, bool dontdamage) { - angle_t angle,ang; + DAngle angle; AActor *mo; - fixedvec3 pos; + DVector3 pos; if (!victim->SpecialBlastHandling (Owner, strength)) { @@ -34,35 +34,33 @@ void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor *Owner, } angle = Owner->AngleTo(victim); - angle >>= ANGLETOFINESHIFT; - victim->vel.x = FixedMul (speed, finecosine[angle]); - victim->vel.y = FixedMul (speed, finesine[angle]); + DVector2 move = angle.ToVector(speed); + victim->Vel.X = move.X; + victim->Vel.Y = move.Y; // Spawn blast puff - ang = victim->AngleTo(Owner); - ang >>= ANGLETOFINESHIFT; + angle -= 180.; pos = victim->Vec3Offset( - FixedMul (victim->radius+FRACUNIT, finecosine[ang]), - FixedMul (victim->radius+FRACUNIT, finesine[ang]), - -victim->floorclip + (victim->height>>1)); + (victim->radius + 1) * angle.Cos(), + (victim->radius + 1) * angle.Sin(), + (victim->Height / 2) - victim->Floorclip); mo = Spawn (blasteffect, pos, ALLOW_REPLACE); if (mo) { - mo->vel.x = victim->vel.x; - mo->vel.y = victim->vel.y; + mo->Vel.X = victim->Vel.X; + mo->Vel.Y = victim->Vel.Y; } if (victim->flags & MF_MISSILE) { // [RH] Floor and ceiling huggers should not be blasted vertically. if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { - victim->vel.z = 8*FRACUNIT; - mo->vel.z = victim->vel.z; + mo->Vel.Z = victim->Vel.Z = 8; } } else { - victim->vel.z = (1000 / victim->Mass) << FRACBITS; + victim->Vel.Z = 1000. / victim->Mass; } if (victim->player) { @@ -100,14 +98,13 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast) PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (blastflags) { blastflags = 0; } PARAM_FIXED_OPT (strength) { strength = 255*FRACUNIT; } - PARAM_FIXED_OPT (radius) { radius = 255*FRACUNIT; } - PARAM_FIXED_OPT (speed) { speed = 20*FRACUNIT; } + PARAM_FLOAT_OPT (radius) { radius = 255; } + PARAM_FLOAT_OPT (speed) { speed = 20; } PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); } PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; } AActor *mo; TThinkerIterator iterator; - fixed_t dist; if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_WEAPON()) { @@ -146,8 +143,7 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast) { // Must be monster, player, missile, touchy or vulnerable continue; } - dist = self->AproxDistance (mo); - if (dist > radius) + if (self->Distance2D(mo) > radius) { // Out of range continue; } diff --git a/src/g_hexen/a_clericflame.cpp b/src/g_hexen/a_clericflame.cpp index 62395d321..10aff1ca0 100644 --- a/src/g_hexen/a_clericflame.cpp +++ b/src/g_hexen/a_clericflame.cpp @@ -13,9 +13,9 @@ #include "thingdef/thingdef.h" */ -const fixed_t FLAMESPEED = fixed_t(0.45*FRACUNIT); +const double FLAMESPEED = 0.45; const fixed_t CFLAMERANGE = 12*64*FRACUNIT; -const fixed_t FLAMEROTSPEED = 2*FRACUNIT; +const double FLAMEROTSPEED = 2.; static FRandom pr_missile ("CFlameMissile"); @@ -43,20 +43,18 @@ void ACFlameMissile::BeginPlay () void ACFlameMissile::Effect () { - fixed_t newz; - if (!--special1) { special1 = 4; - newz = Z()-12*FRACUNIT; + double newz = Z()-12; if (newz < floorz) { newz = floorz; } - AActor *mo = Spawn ("CFlameFloor", X(), Y(), newz, ALLOW_REPLACE); + AActor *mo = Spawn ("CFlameFloor", PosAtZ(newz), ALLOW_REPLACE); if (mo) { - mo->angle = angle; + mo->Angles.Yaw = Angles.Yaw; } } } @@ -99,9 +97,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlamePuff) PARAM_ACTION_PROLOGUE; self->renderflags &= ~RF_INVISIBLE; - self->vel.x = 0; - self->vel.y = 0; - self->vel.z = 0; + self->Vel.Zero(); S_Sound (self, CHAN_BODY, "ClericFlameExplode", 1, ATTN_NORM); return 0; } @@ -117,7 +113,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile) PARAM_ACTION_PROLOGUE; int i; - int an, an90; + DAngle an; fixed_t dist; AActor *mo; @@ -126,33 +122,32 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameMissile) AActor *BlockingMobj = self->BlockingMobj; if (BlockingMobj && BlockingMobj->flags&MF_SHOOTABLE) { // Hit something, so spawn the flame circle around the thing - dist = BlockingMobj->radius+18*FRACUNIT; + dist = BlockingMobj->_f_radius()+18*FRACUNIT; for (i = 0; i < 4; i++) { - an = (i*ANG45)>>ANGLETOFINESHIFT; - an90 = (i*ANG45+ANG90)>>ANGLETOFINESHIFT; + an = i*45.; mo = Spawn ("CircleFlame", BlockingMobj->Vec3Offset( - FixedMul(dist, finecosine[an]), - FixedMul(dist, finesine[an]), + xs_CRoundToInt(an.Cos()*dist), xs_CRoundToInt(an.Sin()*dist), 5*FRACUNIT), ALLOW_REPLACE); if (mo) { - mo->angle = an<Angles.Yaw = an; mo->target = self->target; - mo->vel.x = mo->special1 = FixedMul(FLAMESPEED, finecosine[an]); - mo->vel.y = mo->special2 = FixedMul(FLAMESPEED, finesine[an]); + mo->VelFromAngle(FLAMESPEED); + mo->specialf1 = mo->Vel.X; + mo->specialf2 = mo->Vel.Y; mo->tics -= pr_missile()&3; } mo = Spawn ("CircleFlame", BlockingMobj->Vec3Offset( - -FixedMul(dist, finecosine[an]), - -FixedMul(dist, finesine[an]), + -xs_CRoundToInt(an.Cos()*dist), -xs_CRoundToInt(an.Sin()*dist), 5*FRACUNIT), ALLOW_REPLACE); if(mo) { - mo->angle = ANG180+(an<Angles.Yaw = an + 180.; mo->target = self->target; - mo->vel.x = mo->special1 = FixedMul(-FLAMESPEED, finecosine[an]); - mo->vel.y = mo->special2 = FixedMul(-FLAMESPEED, finesine[an]); + mo->VelFromAngle(-FLAMESPEED); + mo->specialf1 = mo->Vel.X; + mo->specialf2 = mo->Vel.Y; mo->tics -= pr_missile()&3; } } @@ -171,11 +166,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CFlameRotate) { PARAM_ACTION_PROLOGUE; - int an; + DAngle an = self->Angles.Yaw + 90.; + self->VelFromAngle(an, FLAMEROTSPEED); + self->Vel += DVector2(self->specialf1, self->specialf2); - an = (self->angle+ANG90)>>ANGLETOFINESHIFT; - self->vel.x = self->special1+FixedMul(FLAMEROTSPEED, finecosine[an]); - self->vel.y = self->special2+FixedMul(FLAMEROTSPEED, finesine[an]); - self->angle += ANG90/15; + self->Angles.Yaw += 6.; return 0; } diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index fe71289ac..7e61721cd 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -159,9 +159,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack2) mo->special2 = ((FINEANGLES/2 + i) << 16) + FINEANGLES/2 + pr_holyatk2(8 << BOBTOFINESHIFT); break; } - mo->SetZ(self->Z()); - mo->angle = self->angle+(ANGLE_45+ANGLE_45/2)-ANGLE_45*j; - P_ThrustMobj(mo, mo->angle, mo->Speed); + mo->_f_SetZ(self->_f_Z()); + mo->Angles.Yaw = self->Angles.Yaw + 67.5 - 45.*j; + mo->Thrust(); mo->target = self->target; mo->args[0] = 10; // initial turn value mo->args[1] = 0; // initial look angle @@ -225,7 +225,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->angle, &t); + AActor *missile = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("HolyMissile"), self->Angles.Yaw, &t); if (missile != NULL && !t.unlinked) { missile->tracer = t.linetarget; @@ -274,26 +274,26 @@ static void CHolyTailFollow (AActor *actor, fixed_t dist) child = actor->tracer; if (child) { - an = actor->AngleTo(child) >> ANGLETOFINESHIFT; + an = actor->__f_AngleTo(child) >> ANGLETOFINESHIFT; oldDistance = child->AproxDistance (actor); - if (P_TryMove (child, actor->X()+FixedMul(dist, finecosine[an]), - actor->Y()+FixedMul(dist, finesine[an]), true)) + if (P_TryMove (child, actor->_f_X()+FixedMul(dist, finecosine[an]), + actor->_f_Y()+FixedMul(dist, finesine[an]), true)) { newDistance = child->AproxDistance (actor)-FRACUNIT; if (oldDistance < FRACUNIT) { if (child->Z() < actor->Z()) { - child->SetZ(actor->Z()-dist); + child->_f_SetZ(actor->_f_Z()-dist); } else { - child->SetZ(actor->Z()+dist); + child->_f_SetZ(actor->_f_Z()+dist); } } else { - child->SetZ(actor->Z() + Scale (newDistance, child->Z()-actor->Z(), oldDistance)); + child->_f_SetZ(actor->_f_Z() + Scale (newDistance, child->_f_Z()-actor->_f_Z(), oldDistance)); } } } @@ -342,10 +342,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolyTail) else { if (P_TryMove (self, - parent->X() - 14*finecosine[parent->angle>>ANGLETOFINESHIFT], - parent->Y() - 14*finesine[parent->angle>>ANGLETOFINESHIFT], true)) + parent->_f_X() - 14*finecosine[parent->_f_angle()>>ANGLETOFINESHIFT], + parent->_f_Y() - 14*finesine[parent->_f_angle()>>ANGLETOFINESHIFT], true)) { - self->SetZ(parent->Z()-5*FRACUNIT); + self->_f_SetZ(parent->_f_Z()-5*FRACUNIT); } CHolyTailFollow (self, 10*FRACUNIT); } @@ -377,12 +377,11 @@ static void CHolyFindTarget (AActor *actor) // Similar to P_SeekerMissile, but seeks to a random Z on the target //============================================================================ -static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) +static void CHolySeekerMissile (AActor *actor, DAngle thresh, DAngle turnMax) { int dir; int dist; - angle_t delta; - angle_t angle; + DAngle delta; AActor *target; fixed_t newZ; fixed_t deltaZ; @@ -404,7 +403,7 @@ static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if (delta > turnMax) { delta = turnMax; @@ -412,21 +411,20 @@ static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) } if (dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->vel.x = FixedMul (actor->Speed, finecosine[angle]); - actor->vel.y = FixedMul (actor->Speed, finesine[angle]); + actor->VelFromAngle(); + if (!(level.time&15) || actor->Z() > target->Top() || actor->Top() < target->Z()) { - newZ = target->Z()+((pr_holyseeker()*target->height)>>8); - deltaZ = newZ - actor->Z(); + newZ = target->_f_Z()+((pr_holyseeker()*target->_f_height())>>8); + deltaZ = newZ - actor->_f_Z(); if (abs(deltaZ) > 15*FRACUNIT) { if (deltaZ > 0) @@ -439,12 +437,12 @@ static void CHolySeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax) } } dist = actor->AproxDistance (target); - dist = dist / actor->Speed; + dist = dist / actor->_f_speed(); if (dist < 1) { dist = 1; } - actor->vel.z = deltaZ / dist; + actor->Vel.Z = FIXED2DBL(deltaZ / dist); } return; } @@ -463,18 +461,18 @@ void CHolyWeave (AActor *actor, FRandom &pr_random) weaveXY = actor->special2 >> 16; weaveZ = actor->special2 & FINEMASK; - angle = (actor->angle + ANG90) >> ANGLETOFINESHIFT; - newX = actor->X() - FixedMul(finecosine[angle], finesine[weaveXY] * 32); - newY = actor->Y() - FixedMul(finesine[angle], finesine[weaveXY] * 32); + angle = (actor->_f_angle() + ANG90) >> ANGLETOFINESHIFT; + newX = actor->_f_X() - FixedMul(finecosine[angle], finesine[weaveXY] * 32); + newY = actor->_f_Y() - FixedMul(finesine[angle], finesine[weaveXY] * 32); weaveXY = (weaveXY + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK; newX += FixedMul(finecosine[angle], finesine[weaveXY] * 32); newY += FixedMul(finesine[angle], finesine[weaveXY] * 32); P_TryMove(actor, newX, newY, true); - newZ = actor->Z(); + newZ = actor->_f_Z(); newZ -= finesine[weaveZ] * 16; weaveZ = (weaveZ + pr_random(5 << BOBTOFINESHIFT)) & FINEMASK; newZ += finesine[weaveZ] * 16; - actor->SetZ(newZ); + actor->_f_SetZ(newZ); actor->special2 = weaveZ + (weaveXY << 16); } @@ -491,17 +489,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_CHolySeek) self->health--; if (self->health <= 0) { - self->vel.x >>= 2; - self->vel.y >>= 2; - self->vel.z = 0; + self->Vel.X /= 4; + self->Vel.Y /= 4; + self->Vel.Z = 0; self->SetState (self->FindState(NAME_Death)); self->tics -= pr_holyseek()&3; return 0; } if (self->tracer) { - CHolySeekerMissile (self, self->args[0]*ANGLE_1, - self->args[0]*ANGLE_1*2); + CHolySeekerMissile (self, (double)self->args[0], self->args[0]*2.); if (!((level.time+7)&15)) { self->args[0] = 5+(pr_holyseek()/20); @@ -546,7 +543,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClericAttack) if (!self->target) return 0; - AActor * missile = P_SpawnMissileZ (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor ("HolyMissile")); + AActor * missile = P_SpawnMissileZ (self, self->_f_Z() + 40*FRACUNIT, self->target, PClass::FindActor ("HolyMissile")); if (missile != NULL) missile->tracer = NULL; // No initial target S_Sound (self, CHAN_WEAPON, "HolySymbolFire", 1, ATTN_NORM); return 0; diff --git a/src/g_hexen/a_clericmace.cpp b/src/g_hexen/a_clericmace.cpp index 6b7fe06ae..8715316f1 100644 --- a/src/g_hexen/a_clericmace.cpp +++ b/src/g_hexen/a_clericmace.cpp @@ -17,9 +17,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; int i; player_t *player; FTranslatedLineTarget t; @@ -36,7 +36,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) { for (int j = 1; j >= -1; j -= 2) { - angle = player->mo->angle + j*i*(ANG45 / 16); + angle = player->mo->Angles.Yaw + j*i*(45. / 16); slope = P_AimLineAttack(player->mo, angle, 2 * MELEERANGE, &t); if (t.linetarget) { @@ -52,7 +52,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) // didn't find any creatures, so try to strike any walls player->mo->weaponspecial = 0; - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack (player->mo, angle, MELEERANGE); P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime); macedone: diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index fcad8f20c..2b6c88d6f 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -51,8 +51,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) APlayerPawn *pmo; int damage; int newLife, max; - angle_t angle; - int slope; + DAngle angle; + DAngle slope; int i; player_t *player; FTranslatedLineTarget t; @@ -72,14 +72,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) { for (int j = 1; j >= -1; j -= 2) { - angle = pmo->angle + j*i*(ANG45 / 16); - slope = P_AimLineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), &t, 0, ALF_CHECK3D); + angle = pmo->Angles.Yaw + j*i*(45. / 16); + slope = P_AimLineAttack(pmo, angle, 1.5 * MELEERANGE, &t, 0., ALF_CHECK3D); if (t.linetarget) { - P_LineAttack(pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, puff, false, &t); + P_LineAttack(pmo, angle, 1.5 * MELEERANGE, slope, damage, NAME_Melee, puff, false, &t); if (t.linetarget != NULL) { - pmo->angle = t.angleFromSource; + pmo->Angles.Yaw = t.angleFromSource; if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER) && (!(t.linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE)))) { @@ -131,12 +131,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle-(ANG45/15)); + mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw - 3.0); if (mo) { mo->WeaveIndexXY = 32; } - mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->angle+(ANG45/15)); + mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw + 3.0); if (mo) { mo->WeaveIndexXY = 0; diff --git a/src/g_hexen/a_dragon.cpp b/src/g_hexen/a_dragon.cpp index f9b38268b..088d2de13 100644 --- a/src/g_hexen/a_dragon.cpp +++ b/src/g_hexen/a_dragon.cpp @@ -22,12 +22,11 @@ DECLARE_ACTION(A_DragonFlight) // //============================================================================ -static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) +static void DragonSeek (AActor *actor, DAngle thresh, DAngle turnMax) { int dir; - int dist; - angle_t delta; - angle_t angle; + double dist; + DAngle delta; AActor *target; int i; angle_t bestAngle; @@ -42,7 +41,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if (delta > turnMax) { delta = turnMax; @@ -50,30 +49,25 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) } if (dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->vel.x = FixedMul (actor->Speed, finecosine[angle]); - actor->vel.y = FixedMul (actor->Speed, finesine[angle]); - dist = actor->AproxDistance (target) / actor->Speed; + actor->VelFromAngle(); + + dist = actor->DistanceBySpeed(target, actor->Speed); if (actor->Top() < target->Z() || target->Top() < actor->Z()) { - if (dist < 1) - { - dist = 1; - } - actor->vel.z = (target->Z() - actor->Z())/dist; + actor->Vel.Z = (target->Z() - actor->Z()) / dist; } if (target->flags&MF_SHOOTABLE && pr_dragonseek() < 64) { // attack the destination mobj if it's attackable AActor *oldTarget; - if (absangle(actor->angle - actor->AngleTo(target)) < ANGLE_45/2) + if (absangle(actor->_f_angle() - actor->__f_AngleTo(target)) < ANGLE_45/2) { oldTarget = actor->target; actor->target = target; @@ -98,7 +92,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) { AActor *bestActor = NULL; bestAngle = ANGLE_MAX; - angleToTarget = actor->AngleTo(actor->target); + angleToTarget = actor->__f_AngleTo(actor->target); for (i = 0; i < 5; i++) { if (!target->args[i]) @@ -111,7 +105,7 @@ static void DragonSeek (AActor *actor, angle_t thresh, angle_t turnMax) { continue; } - angleToSpot = actor->AngleTo(mo); + angleToSpot = actor->__f_AngleTo(mo); if (absangle(angleToSpot-angleToTarget) < bestAngle) { bestAngle = absangle(angleToSpot-angleToTarget); @@ -184,7 +178,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) angle_t angle; - DragonSeek (self, 4*ANGLE_1, 8*ANGLE_1); + DragonSeek (self, 4., 8.); if (self->target) { if(!(self->target->flags&MF_SHOOTABLE)) @@ -192,15 +186,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFlight) self->target = NULL; return 0; } - angle = self->AngleTo(self->target); - if (absangle(self->angle-angle) < ANGLE_45/2 && self->CheckMeleeRange()) + angle = self->__f_AngleTo(self->target); + if (absangle(self->_f_angle()-angle) < ANGLE_45/2 && self->CheckMeleeRange()) { int damage = pr_dragonflight.HitDice (8); int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee); P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); } - else if (absangle(self->angle-angle) <= ANGLE_1*20) + else if (absangle(self->_f_angle()-angle) <= ANGLE_1*20) { self->SetState (self->MissileState); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); diff --git a/src/g_hexen/a_fighteraxe.cpp b/src/g_hexen/a_fighteraxe.cpp index aa6a6ec5c..c83726b44 100644 --- a/src/g_hexen/a_fighteraxe.cpp +++ b/src/g_hexen/a_fighteraxe.cpp @@ -13,7 +13,7 @@ #include "thingdef/thingdef.h" */ -#define AXERANGE ((fixed_t)(2.25*MELEERANGE)) +#define AXERANGE (2.25 * MELEERANGE) static FRandom pr_axeatk ("FAxeAtk"); @@ -199,10 +199,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; - fixed_t power; + DAngle angle; + int power; int damage; - int slope; + DAngle slope; int i; int useMana; player_t *player; @@ -223,7 +223,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) if (player->ReadyWeapon->Ammo1->Amount > 0) { damage <<= 1; - power = 6*FRACUNIT; + power = 6; pufftype = PClass::FindActor ("AxePuffGlow"); useMana = 1; } @@ -236,7 +236,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) { for (int j = 1; j >= -1; j -= 2) { - angle = pmo->angle + j*i*(ANG45 / 16); + angle = pmo->Angles.Yaw + j*i*(45. / 16); slope = P_AimLineAttack(pmo, angle, AXERANGE, &t); if (t.linetarget) { @@ -245,7 +245,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) { if (t.linetarget->flags3&MF3_ISMONSTER || t.linetarget->player) { - P_ThrustMobj(t.linetarget, t.angleFromSource, power); + t.linetarget->Thrust(t.angleFromSource, power); } AdjustPlayerAngle(pmo, &t); useMana++; @@ -257,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack) // didn't find any creatures, so try to strike any walls pmo->weaponspecial = 0; - angle = pmo->angle; + angle = pmo->Angles.Yaw; slope = P_AimLineAttack (pmo, angle, MELEERANGE); P_LineAttack (pmo, angle, MELEERANGE, slope, damage, NAME_Melee, pufftype, true); diff --git a/src/g_hexen/a_fighterhammer.cpp b/src/g_hexen/a_fighterhammer.cpp index eadf7a05c..c33737bfd 100644 --- a/src/g_hexen/a_fighterhammer.cpp +++ b/src/g_hexen/a_fighterhammer.cpp @@ -13,7 +13,7 @@ #include "thingdef/thingdef.h" */ -const fixed_t HAMMER_RANGE = MELEERANGE+MELEERANGE/2; +const double HAMMER_RANGE = 1.5 * MELEERANGE; static FRandom pr_hammeratk ("FHammerAtk"); @@ -27,10 +27,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - fixed_t power; - int slope; + DAngle slope; int i; player_t *player; FTranslatedLineTarget t; @@ -43,46 +42,32 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) AActor *pmo=player->mo; damage = 60+(pr_hammeratk()&63); - power = 10*FRACUNIT; hammertime = PClass::FindActor("HammerPuff"); for (i = 0; i < 16; i++) { - angle = pmo->angle + i*(ANG45/32); - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D); - if (t.linetarget != NULL) + for (int j = 1; j >= -1; j -= 2) { - P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); + angle = pmo->Angles.Yaw + j*i*(45. / 32); + slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0., ALF_CHECK3D); if (t.linetarget != NULL) { - AdjustPlayerAngle(pmo, &t); - if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) + P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); + if (t.linetarget != NULL) { - P_ThrustMobj(t.linetarget, t.angleFromSource, power); + AdjustPlayerAngle(pmo, &t); + if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) + { + t.linetarget->Thrust(t.angleFromSource, 10); + } + pmo->weaponspecial = false; // Don't throw a hammer + goto hammerdone; } - pmo->weaponspecial = false; // Don't throw a hammer - goto hammerdone; - } - } - angle = pmo->angle-i*(ANG45/32); - slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &t, 0, ALF_CHECK3D); - if (t.linetarget != NULL) - { - P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true, &t); - if (t.linetarget != NULL) - { - AdjustPlayerAngle(pmo, &t); - if (t.linetarget->flags3 & MF3_ISMONSTER || t.linetarget->player) - { - P_ThrustMobj(t.linetarget, t.angleFromSource, power); - } - pmo->weaponspecial = false; // Don't throw a hammer - goto hammerdone; } } } // didn't find any targets in meleerange, so set to throw out a hammer - angle = pmo->angle; - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0, ALF_CHECK3D); + angle = pmo->Angles.Yaw; + slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, NULL, 0., ALF_CHECK3D); if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, hammertime, true) != NULL) { pmo->weaponspecial = false; diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 8abf3fa18..607a9a88a 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -23,29 +23,25 @@ static FRandom pr_fpatk ("FPunchAttack"); // //============================================================================ -#define MAX_ANGLE_ADJUST (5*ANGLE_1) +#define MAX_ANGLE_ADJUST (5.) void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t) { - angle_t angle; - int difference; - - angle = pmo->AngleTo(t->linetarget); - difference = (int)angle - (int)pmo->angle; - if (abs(difference) > MAX_ANGLE_ADJUST) + DAngle difference = deltaangle(pmo->Angles.Yaw, pmo->AngleTo(t->linetarget)); + if (fabs(difference) > MAX_ANGLE_ADJUST) { if (difference > 0) { - pmo->angle += MAX_ANGLE_ADJUST; + pmo->Angles.Yaw += MAX_ANGLE_ADJUST; } else { - pmo->angle -= MAX_ANGLE_ADJUST; + pmo->Angles.Yaw -= MAX_ANGLE_ADJUST; } } else { - pmo->angle = angle; + pmo->Angles.Yaw = t->angleFromSource; } } @@ -57,11 +53,11 @@ void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t) // //============================================================================ -static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power) +static bool TryPunch(APlayerPawn *pmo, DAngle angle, int damage, int power) { PClassActor *pufftype; FTranslatedLineTarget t; - int slope; + DAngle slope; slope = P_AimLineAttack (pmo, angle, 2*MELEERANGE, &t); if (t.linetarget != NULL) @@ -82,7 +78,7 @@ static bool TryPunch(APlayerPawn *pmo, angle_t angle, int damage, fixed_t power) if (t.linetarget->player != NULL || (t.linetarget->Mass != INT_MAX && (t.linetarget->flags3 & MF3_ISMONSTER))) { - P_ThrustMobj (t.linetarget, t.angleFromSource, power); + t.linetarget->Thrust(t.angleFromSource, power); } AdjustPlayerAngle (pmo, &t); return true; @@ -102,7 +98,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) PARAM_ACTION_PROLOGUE; int damage; - fixed_t power; int i; player_t *player; @@ -113,11 +108,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) APlayerPawn *pmo = player->mo; damage = 40+(pr_fpatk()&15); - power = 2*FRACUNIT; for (i = 0; i < 16; i++) { - if (TryPunch(pmo, pmo->angle + i*(ANG45/16), damage, power) || - TryPunch(pmo, pmo->angle - i*(ANG45/16), damage, power)) + if (TryPunch(pmo, pmo->Angles.Yaw + i*(45./16), damage, 2) || + TryPunch(pmo, pmo->Angles.Yaw - i*(45./16), damage, 2)) { // hit something if (pmo->weaponspecial >= 3) { @@ -131,7 +125,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack) // didn't find any creatures, so try to strike any walls pmo->weaponspecial = 0; - int slope = P_AimLineAttack (pmo, pmo->angle, MELEERANGE); - P_LineAttack (pmo, pmo->angle, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true); + DAngle slope = P_AimLineAttack (pmo, pmo->Angles.Yaw, MELEERANGE); + P_LineAttack (pmo, pmo->Angles.Yaw, MELEERANGE, slope, damage, NAME_Melee, PClass::FindActor("PunchPuff"), true); return 0; } diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index cb797f661..abc8cf0c9 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -31,19 +31,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces) PARAM_CLASS(p2, AActor); PARAM_CLASS(p3, AActor); - for (int i = 0, j = 0, fineang = 0; i < 3; ++i) + for (int i = 0, j = 0; i < 3; ++i) { PClassActor *cls = j == 0 ? p1 : j == 1 ? p2 : p3; if (cls) { - AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE); + AActor *piece = Spawn (cls, self->_f_Pos(), ALLOW_REPLACE); if (piece != NULL) { - piece->vel.x = self->vel.x + finecosine[fineang]; - piece->vel.y = self->vel.y + finesine[fineang]; - piece->vel.z = self->vel.z; + piece->Vel = self->Vel + DAngle(i*120.).ToVector(1); piece->flags |= MF_DROPPED; - fineang += FINEANGLES/3; j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j; } } @@ -95,11 +92,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/4); - P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle+ANGLE_45/8); - P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->angle); - P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/8); - P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->angle-ANGLE_45/4); + P_SpawnPlayerMissile (self, 0, 0, -10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./4)); + P_SpawnPlayerMissile (self, 0, 0, -5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw + (45./8)); + P_SpawnPlayerMissile (self, 0, 0, 0, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw); + P_SpawnPlayerMissile (self, 0, 0, 5*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./8)); + P_SpawnPlayerMissile (self, 0, 0, 10*FRACUNIT, RUNTIME_CLASS(AFSwordMissile), self->Angles.Yaw - (45./4)); S_Sound (self, CHAN_WEAPON, "FighterSwordFire", 1, ATTN_NORM); return 0; } @@ -138,7 +135,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FighterAttack) if (!self->target) return 0; - angle_t angle = self->angle; + angle_t angle = self->_f_angle(); P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/4, 0); P_SpawnMissileAngle (self, RUNTIME_CLASS(AFSwordMissile), angle+ANG45/8, 0); diff --git a/src/g_hexen/a_firedemon.cpp b/src/g_hexen/a_firedemon.cpp index cbfffdd1d..b35521200 100644 --- a/src/g_hexen/a_firedemon.cpp +++ b/src/g_hexen/a_firedemon.cpp @@ -61,9 +61,9 @@ void A_FiredSpawnRock (AActor *actor) if (mo) { mo->target = actor; - mo->vel.x = (pr_firedemonrock() - 128) <<10; - mo->vel.y = (pr_firedemonrock() - 128) <<10; - mo->vel.z = (pr_firedemonrock() << 10); + mo->Vel.X = (pr_firedemonrock() - 128) / 64.; + mo->Vel.Y = (pr_firedemonrock() - 128) / 64.; + mo->Vel.Z = (pr_firedemonrock() / 64.); mo->special1 = 2; // Number bounces } @@ -101,10 +101,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SmBounce) PARAM_ACTION_PROLOGUE; // give some more velocity (x,y,&z) - self->SetZ(self->floorz + FRACUNIT); - self->vel.z = (2*FRACUNIT) + (pr_smbounce() << 10); - self->vel.x = pr_smbounce()%3<vel.y = pr_smbounce()%3<SetZ(self->floorz + 1); + self->Vel.Z = 2. + pr_smbounce() / 64.; + self->Vel.X = pr_smbounce() % 3; + self->Vel.Y = pr_smbounce() % 3; return 0; } @@ -137,20 +137,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) int weaveindex = self->special1; AActor *target = self->target; - angle_t ang; + DAngle ang; fixed_t dist; if (self->reactiontime) self->reactiontime--; if (self->threshold) self->threshold--; // Float up and down - self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); + self->_f_AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); self->special1 = (weaveindex + 2) & 63; // Ensure it stays above certain height - if (self->Z() < self->floorz + (64*FRACUNIT)) + if (self->Z() < self->floorz + 64) { - self->AddZ(2*FRACUNIT); + self->AddZ(2); } if(!self->target || !(self->target->flags&MF_SHOOTABLE)) @@ -167,7 +167,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) else { self->special2 = 0; - self->vel.x = self->vel.y = 0; + self->Vel.X = self->Vel.Y = 0; dist = self->AproxDistance (target); if (dist < FIREDEMON_ATTACK_RANGE) { @@ -175,12 +175,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredChase) { ang = self->AngleTo(target); if (pr_firedemonchase() < 128) - ang += ANGLE_90; + ang += 90; else - ang -= ANGLE_90; - ang >>= ANGLETOFINESHIFT; - self->vel.x = finecosine[ang] << 3; //FixedMul (8*FRACUNIT, finecosine[ang]); - self->vel.y = finesine[ang] << 3; //FixedMul (8*FRACUNIT, finesine[ang]); + ang -= 90; + self->Thrust(ang, 8); self->special2 = 3; // strafe time } } @@ -235,16 +233,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_FiredSplotch) mo = Spawn ("FireDemonSplotch1", self->Pos(), ALLOW_REPLACE); if (mo) { - mo->vel.x = (pr_firedemonsplotch() - 128) << 11; - mo->vel.y = (pr_firedemonsplotch() - 128) << 11; - mo->vel.z = (pr_firedemonsplotch() << 10) + FRACUNIT*3; + mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3; } mo = Spawn ("FireDemonSplotch2", self->Pos(), ALLOW_REPLACE); if (mo) { - mo->vel.x = (pr_firedemonsplotch() - 128) << 11; - mo->vel.y = (pr_firedemonsplotch() - 128) << 11; - mo->vel.z = (pr_firedemonsplotch() << 10) + FRACUNIT*3; + mo->Vel.X = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Y = (pr_firedemonsplotch() - 128) / 32.; + mo->Vel.Z = (pr_firedemonsplotch() / 64.) + 3; } return 0; } diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 09fb735e9..19cb3132c 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -39,13 +39,13 @@ IMPLEMENT_CLASS (AArtiPoisonBag1) bool AArtiPoisonBag1::Use (bool pickup) { - angle_t angle = Owner->angle >> ANGLETOFINESHIFT; + angle_t angle = Owner->_f_angle() >> ANGLETOFINESHIFT; AActor *mo; - mo = Spawn ("PoisonBag", Owner->Vec3Offset( - 16*finecosine[angle], - 24*finesine[angle], - -Owner->floorclip+8*FRACUNIT), ALLOW_REPLACE); + mo = Spawn("PoisonBag", Owner->Vec3Offset( + 16 * Owner->Angles.Yaw.Cos(), + 24 * Owner->Angles.Yaw.Sin(), + -Owner->Floorclip + 8), ALLOW_REPLACE); if (mo) { mo->target = Owner; @@ -67,13 +67,13 @@ IMPLEMENT_CLASS (AArtiPoisonBag2) bool AArtiPoisonBag2::Use (bool pickup) { - angle_t angle = Owner->angle >> ANGLETOFINESHIFT; + angle_t angle = Owner->_f_angle() >> ANGLETOFINESHIFT; AActor *mo; - mo = Spawn ("FireBomb", Owner->Vec3Offset( - 16*finecosine[angle], - 24*finesine[angle], - -Owner->floorclip+8*FRACUNIT), ALLOW_REPLACE); + mo = Spawn("FireBomb", Owner->Vec3Offset( + 16 * Owner->Angles.Yaw.Cos(), + 24 * Owner->Angles.Yaw.Sin(), + -Owner->Floorclip + 8), ALLOW_REPLACE); if (mo) { mo->target = Owner; @@ -97,15 +97,15 @@ bool AArtiPoisonBag3::Use (bool pickup) { AActor *mo; - mo = Spawn("ThrowingBomb", Owner->PosPlusZ(-Owner->floorclip+35*FRACUNIT + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE); + mo = Spawn("ThrowingBomb", Owner->PosPlusZ(-Owner->_f_floorclip()+35*FRACUNIT + (Owner->player? Owner->player->crouchoffset : 0)), ALLOW_REPLACE); if (mo) { - mo->angle = Owner->angle + (((pr_poisonbag()&7) - 4) << 24); + mo->Angles.Yaw = Owner->Angles.Yaw + (((pr_poisonbag() & 7) - 4) * (360./256.)); /* Original flight code from Hexen * mo->momz = 4*FRACUNIT+((player->lookdir)<<(FRACBITS-4)); * mo->z += player->lookdir<<(FRACBITS-4); - * P_ThrustMobj(mo, mo->angle, mo->info->speed); + * P_ThrustMobj(mo, mo->_f_angle(), mo->info->speed); * mo->momx += player->mo->momx>>1; * mo->momy += player->mo->momy>>1; */ @@ -114,16 +114,16 @@ bool AArtiPoisonBag3::Use (bool pickup) // is as set by the projectile. To accommodate this with a proper trajectory, we // aim the projectile ~20 degrees higher than we're looking at and increase the // speed we fire at accordingly. - angle_t orgpitch = angle_t(-Owner->pitch) >> ANGLETOFINESHIFT; - angle_t modpitch = angle_t(0xDC00000 - Owner->pitch) >> ANGLETOFINESHIFT; - angle_t angle = mo->angle >> ANGLETOFINESHIFT; - fixed_t speed = fixed_t(sqrt((double)mo->Speed*mo->Speed + (4.0*65536*4*65536))); - fixed_t xyscale = FixedMul(speed, finecosine[modpitch]); + DAngle orgpitch = -Owner->Angles.Pitch; + DAngle modpitch = clamp(-Owner->Angles.Pitch + 20, -89., 89.); + DAngle angle = mo->Angles.Yaw; + double speed = DVector2(mo->Speed, 4.).Length(); + double xyscale = speed * modpitch.Cos(); - mo->vel.z = FixedMul(speed, finesine[modpitch]); - mo->vel.x = FixedMul(xyscale, finecosine[angle]) + (Owner->vel.x >> 1); - mo->vel.y = FixedMul(xyscale, finesine[angle]) + (Owner->vel.y >> 1); - mo->AddZ(FixedMul(mo->Speed, finesine[orgpitch])); + mo->Vel.Z = speed * modpitch.Sin(); + mo->Vel.X = xyscale * angle.Cos() + Owner->Vel.X / 2; + mo->Vel.Y = xyscale * angle.Sin() + Owner->Vel.Y / 2; + mo->AddZ(mo->Speed * orgpitch.Sin()); mo->target = Owner; mo->tics -= pr_poisonbag()&3; @@ -306,7 +306,7 @@ IMPLEMENT_CLASS (APoisonCloud) void APoisonCloud::BeginPlay () { - vel.x = 1; // missile objects must move to impact other objects + Vel.X = MinVel; // missile objects must move to impact other objects special1 = 24+(pr_poisoncloud()&7); special2 = 0; } @@ -419,7 +419,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage) P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE); bobIndex = self->special2; - self->AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1); + self->_f_AddZ(finesine[bobIndex << BOBTOFINESHIFT] >> 1); self->special2 = (bobIndex + 1) & 63; return 0; } @@ -454,13 +454,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2) // [RH] Check using actual velocity, although the vel.z < 2 check still stands //if (abs(self->vel.x) < FRACUNIT*3/2 && abs(self->vel.y) < FRACUNIT*3/2 // && self->vel.z < 2*FRACUNIT) - if (self->vel.z < 2*FRACUNIT && - TMulScale32 (self->vel.x, self->vel.x, self->vel.y, self->vel.y, self->vel.z, self->vel.z) - < (3*3)/(2*2)) + if (self->Vel.Z < 2 && self->Vel.LengthSquared() < (9./4.)) { self->SetState (self->SpawnState + 6); self->SetZ(self->floorz); - self->vel.z = 0; + self->Vel.Z = 0; self->BounceFlags = BOUNCE_None; self->flags &= ~MF_MISSILE; } diff --git a/src/g_hexen/a_flies.cpp b/src/g_hexen/a_flies.cpp index 16fefef73..9714f6a72 100644 --- a/src/g_hexen/a_flies.cpp +++ b/src/g_hexen/a_flies.cpp @@ -84,26 +84,26 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlyBuzz) return 0; } - angle_t ang = self->AngleTo(targ); - self->angle = ang; + self->Angles.Yaw = self->AngleTo(targ); self->args[0]++; + angle_t ang = self->__f_AngleTo(targ); ang >>= ANGLETOFINESHIFT; - if (!P_TryMove(self, self->X() + 6 * finecosine[ang], self->Y() + 6 * finesine[ang], true)) + if (!P_TryMove(self, self->_f_X() + 6 * finecosine[ang], self->_f_Y() + 6 * finesine[ang], true)) { self->SetIdle(true); return 0; } if (self->args[0] & 2) { - self->vel.x += (pr_fly() - 128) << BOBTOFINESHIFT; - self->vel.y += (pr_fly() - 128) << BOBTOFINESHIFT; + self->Vel.X += (pr_fly() - 128) / 512.; + self->Vel.Y += (pr_fly() - 128) / 512.; } int zrand = pr_fly(); - if (targ->Z() + 5*FRACUNIT < self->Z() && zrand > 150) + if (targ->Z() + 5. < self->Z() && zrand > 150) { zrand = -zrand; } - self->vel.z = zrand << BOBTOFINESHIFT; + self->Vel.Z = zrand / 512.; if (pr_fly() < 40) { S_Sound(self, CHAN_VOICE, self->ActiveSound, 0.5f, ATTN_STATIC); diff --git a/src/g_hexen/a_fog.cpp b/src/g_hexen/a_fog.cpp index d974910cc..90c069223 100644 --- a/src/g_hexen/a_fog.cpp +++ b/src/g_hexen/a_fog.cpp @@ -51,7 +51,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogSpawn) { delta = self->args[1]; if (delta==0) delta=1; - mo->angle = self->angle + (((pr_fogspawn()%delta)-(delta>>1))<<24); + mo->Angles.Yaw = self->Angles.Yaw + (((pr_fogspawn() % delta) - (delta >> 1)) * (360 / 256.)); mo->target = self; if (self->args[0] < 1) self->args[0] = 1; mo->args[0] = (pr_fogspawn() % (self->args[0]))+1; // Random speed @@ -73,7 +73,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove) PARAM_ACTION_PROLOGUE; int speed = self->args[0]<args[4]) @@ -90,13 +89,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FogMove) if ((self->args[3] % 4) == 0) { weaveindex = self->special2; - self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 4); + self->_f_AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 4); self->special2 = (weaveindex + 1) & 63; } - angle = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul(speed, finecosine[angle]); - self->vel.y = FixedMul(speed, finesine[angle]); + self->VelFromAngle(speed); return 0; } diff --git a/src/g_hexen/a_heresiarch.cpp b/src/g_hexen/a_heresiarch.cpp index 6aee19a71..87a3d17ae 100644 --- a/src/g_hexen/a_heresiarch.cpp +++ b/src/g_hexen/a_heresiarch.cpp @@ -242,7 +242,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcSpinBalls) self->args[4] = SORCBALL_INITIAL_SPEED; // Initial orbit speed self->special1 = ANGLE_1; - fixedvec3 pos = self->PosPlusZ(-self->floorclip + self->height); + DVector3 pos = self->PosPlusZ(-self->Floorclip + self->Height); mo = Spawn("SorcBall1", pos, NO_REPLACE); if (mo) @@ -279,7 +279,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) angle_t angle, baseangle; int mode = self->target->args[3]; AHeresiarch *parent = barrier_cast(self->target); - int dist = parent->radius - (self->radius<<1); + int dist = parent->_f_radius() - (self->_f_radius()<<1); angle_t prevangle = self->special1; if (!self->IsKindOf (RUNTIME_CLASS(ASorcBall))) @@ -296,7 +296,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) baseangle = (angle_t)parent->special1; angle = baseangle + actor->AngleOffset; - actor->angle = angle; + actor->Angles.Yaw = ANGLE2FLOAT(angle); angle >>= ANGLETOFINESHIFT; switch (mode) @@ -318,13 +318,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) case SORC_STOPPING: // Balls stopping if ((parent->StopBall == actor->GetClass()) && (parent->args[1] > SORCBALL_SPEED_ROTATIONS) && - (absangle(angle - (parent->angle>>ANGLETOFINESHIFT)) < (30<<5))) + (absangle(angle - (parent->_f_angle()>>ANGLETOFINESHIFT)) < (30<<5))) { // Can stop now actor->target->args[3] = SORC_FIRESPELL; actor->target->args[4] = 0; // Set angle so self angle == sorcerer angle - parent->special1 = (int)(parent->angle - actor->AngleOffset); + parent->special1 = (int)(parent->_f_angle() - actor->AngleOffset); } else { @@ -378,7 +378,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallOrbit) fixedvec3 pos = parent->Vec3Offset( FixedMul(dist, finecosine[angle]), FixedMul(dist, finesine[angle]), - -parent->floorclip + parent->height); + -parent->_f_floorclip() + parent->_f_height()); actor->SetOrigin (pos, true); actor->floorz = parent->floorz; actor->ceilingz = parent->ceilingz; @@ -551,7 +551,7 @@ void ASorcBall2::CastSorcererSpell () AActor *parent = target; AActor *mo; - mo = Spawn("SorcFX2", PosPlusZ(-parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT), ALLOW_REPLACE); + mo = Spawn("SorcFX2", PosPlusZ(-parent->_f_floorclip() + SORC_DEFENSE_HEIGHT*FRACUNIT), ALLOW_REPLACE); parent->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE; parent->args[0] = SORC_DEFENSE_TIME; if (mo) mo->target = parent; @@ -573,8 +573,8 @@ void ASorcBall3::CastSorcererSpell () angle_t ang1, ang2; AActor *parent = target; - ang1 = angle - ANGLE_45; - ang2 = angle + ANGLE_45; + ang1 = FLOAT2ANGLE(Angles.Yaw.Degrees) - ANGLE_45; + ang2 = FLOAT2ANGLE(Angles.Yaw.Degrees) + ANGLE_45; PClassActor *cls = PClass::FindActor("SorcFX3"); if (health < (SpawnHealth()/3)) { // Spawn 2 at a time @@ -622,8 +622,8 @@ void ASorcBall1::CastSorcererSpell () angle_t ang1, ang2; AActor *parent = target; - ang1 = angle + ANGLE_1*70; - ang2 = angle - ANGLE_1*70; + ang1 = FLOAT2ANGLE(Angles.Yaw.Degrees) + ANGLE_1*70; + ang2 = FLOAT2ANGLE(Angles.Yaw.Degrees) - ANGLE_1*70; PClassActor *cls = PClass::FindActor("SorcFX1"); mo = P_SpawnMissileAngle (parent, cls, ang1, 0); if (mo) @@ -658,7 +658,7 @@ void A_SorcOffense2(AActor *actor) int delta, index; AActor *parent = actor->target; AActor *dest = parent->target; - int dist; + double dist; // [RH] If no enemy, then don't try to shoot. if (dest == NULL) @@ -670,14 +670,13 @@ void A_SorcOffense2(AActor *actor) actor->args[4] = (actor->args[4] + 15) & 255; delta = (finesine[index])*SORCFX4_SPREAD_ANGLE; delta = (delta>>FRACBITS)*ANGLE_1; - ang1 = actor->angle + delta; + ang1 = actor->_f_angle() + delta; mo = P_SpawnMissileAngle(parent, PClass::FindActor("SorcFX4"), ang1, 0); if (mo) { mo->special2 = 35*5/2; // 5 seconds - dist = mo->AproxDistance(dest) / mo->Speed; - if(dist < 1) dist = 1; - mo->vel.z = (dest->Z() - mo->Z()) / dist; + dist = mo->DistanceBySpeed(dest, mo->Speed); + mo->Vel.Z = (dest->Z() - mo->Z()) / dist; } } @@ -710,21 +709,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnFizzle) { PARAM_ACTION_PROLOGUE; fixed_t dist = 5*FRACUNIT; - fixed_t speed = self->Speed >> FRACBITS; - angle_t rangle; + int speed = (int)self->Speed; + DAngle rangle; AActor *mo; int ix; - fixedvec3 pos = self->Vec3Angle(dist, self->angle, -self->floorclip + (self->height >> 1)); + fixedvec3 pos = self->_f_Vec3Angle(dist, self->_f_angle(), -self->_f_floorclip() + (self->_f_height() >> 1)); for (ix=0; ix<5; ix++) { mo = Spawn("SorcSpark1", pos, ALLOW_REPLACE); if (mo) { - rangle = (self->angle >> ANGLETOFINESHIFT) + ((pr_heresiarch()%5) << 1); - mo->vel.x = FixedMul(pr_heresiarch()%speed, finecosine[rangle]); - mo->vel.y = FixedMul(pr_heresiarch()%speed, finesine[rangle]); - mo->vel.z = FRACUNIT*2; + rangle = self->Angles.Yaw + (pr_heresiarch() % 5) * (4096 / 360.); + mo->Vel.X = (pr_heresiarch() % speed) * rangle.Cos(); + mo->Vel.Y = (pr_heresiarch() % speed) * rangle.Sin(); + mo->Vel.Z = 2; } } return 0; @@ -776,7 +775,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split) { mo->target = self->target; mo->args[0] = 0; // CW - mo->special1 = self->angle; // Set angle + mo->special1 = self->_f_angle(); // Set angle mo->SetState (mo->FindState("Orbit")); } mo = Spawn(self->GetClass(), self->Pos(), NO_REPLACE); @@ -784,7 +783,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Split) { mo->target = self->target; mo->args[0] = 1; // CCW - mo->special1 = self->angle; // Set angle + mo->special1 = self->_f_angle(); // Set angle mo->SetState (mo->FindState("Orbit")); } self->Destroy (); @@ -814,7 +813,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) return 0; } - fixed_t dist = parent->radius; + fixed_t dist = parent->_f_radius(); if ((parent->health <= 0) || // Sorcerer is dead (!parent->args[0])) // Time expired @@ -840,7 +839,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) pos = parent->Vec3Offset( FixedMul(dist, finecosine[angle]), FixedMul(dist, finesine[angle]), - parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT); + parent->_f_floorclip() + SORC_DEFENSE_HEIGHT*FRACUNIT); pos.z += FixedMul(15*FRACUNIT,finecosine[angle]); // Spawn trailer Spawn("SorcFX2T1", pos, ALLOW_REPLACE); @@ -852,7 +851,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcFX2Orbit) pos = parent->Vec3Offset( FixedMul(dist, finecosine[angle]), FixedMul(dist, finesine[angle]), - parent->floorclip + SORC_DEFENSE_HEIGHT*FRACUNIT); + parent->_f_floorclip() + SORC_DEFENSE_HEIGHT*FRACUNIT); pos.z += FixedMul(20*FRACUNIT,finesine[angle]); // Spawn trailer Spawn("SorcFX2T1", pos, ALLOW_REPLACE); @@ -943,10 +942,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SorcBallPop) S_Sound (self, CHAN_BODY, "SorcererBallPop", 1, ATTN_NONE); self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT/8; - self->vel.x = ((pr_heresiarch()%10)-5) << FRACBITS; - self->vel.y = ((pr_heresiarch()%10)-5) << FRACBITS; - self->vel.z = (2+(pr_heresiarch()%3)) << FRACBITS; + self->Gravity = 1. / 8;; + + self->Vel.X = ((pr_heresiarch()%10)-5); + self->Vel.Y = ((pr_heresiarch()%10)-5); + self->Vel.Z = (2+(pr_heresiarch()%3)); self->special2 = 4*FRACUNIT; // Initial bounce factor self->args[4] = BOUNCE_TIME_UNIT; // Bounce time unit self->args[3] = 5; // Bounce time in seconds diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp index 2e9304cdc..b3d1348ed 100644 --- a/src/g_hexen/a_hexenspecialdecs.cpp +++ b/src/g_hexen/a_hexenspecialdecs.cpp @@ -66,9 +66,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode) if (mo) { mo->SetState (mo->SpawnState + (pr_pottery()%5)); - mo->vel.z = ((pr_pottery()&7)+5)*(3*FRACUNIT/4); - mo->vel.x = (pr_pottery.Random2())<<(FRACBITS-6); - mo->vel.y = (pr_pottery.Random2())<<(FRACBITS-6); + mo->Vel.X = pr_pottery.Random2() / 64.; + mo->Vel.Y = pr_pottery.Random2() / 64.; + mo->Vel.Z = ((pr_pottery() & 7) + 5) * 0.75; } } S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM); @@ -117,7 +117,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryCheck) if (playeringame[i]) { AActor *pmo = players[i].mo; - if (P_CheckSight (self, pmo) && (absangle(pmo->AngleTo(self) - pmo->angle) <= ANGLE_45)) + if (P_CheckSight (self, pmo) && (absangle(pmo->__f_AngleTo(self) - pmo->_f_angle()) <= ANGLE_45)) { // Previous state (pottery bit waiting state) self->SetState (self->state - 1); return 0; @@ -141,7 +141,7 @@ IMPLEMENT_CLASS (AZCorpseLynchedNoHeart) void AZCorpseLynchedNoHeart::PostBeginPlay () { Super::PostBeginPlay (); - Spawn ("BloodPool", X(), Y(), floorz, ALLOW_REPLACE); + Spawn ("BloodPool", PosAtZ(floorz), ALLOW_REPLACE); } //============================================================================ @@ -156,7 +156,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseBloodDrip) if (pr_drip() <= 128) { - Spawn ("CorpseBloodDrip", self->PosPlusZ(self->height/2), ALLOW_REPLACE); + Spawn ("CorpseBloodDrip", self->PosPlusZ(self->_f_height()/2), ALLOW_REPLACE); } return 0; } @@ -180,19 +180,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_CorpseExplode) if (mo) { mo->SetState (mo->SpawnState + (pr_foo()%3)); - mo->vel.z = ((pr_foo()&7)+5)*(3*FRACUNIT/4); - mo->vel.x = pr_foo.Random2()<<(FRACBITS-6); - mo->vel.y = pr_foo.Random2()<<(FRACBITS-6); + mo->Vel.X = pr_foo.Random2() / 64.; + mo->Vel.Y = pr_foo.Random2() / 64.; + mo->Vel.Z = ((pr_foo() & 7) + 5) * 0.75; } } // Spawn a skull - mo = Spawn ("CorpseBit", self->Pos(), ALLOW_REPLACE); + mo = Spawn ("CorpseBit", self->_f_Pos(), ALLOW_REPLACE); if (mo) { mo->SetState (mo->SpawnState + 3); - mo->vel.z = ((pr_foo()&7)+5)*(3*FRACUNIT/4); - mo->vel.x = pr_foo.Random2()<<(FRACBITS-6); - mo->vel.y = pr_foo.Random2()<<(FRACBITS-6); + mo->Vel.X = pr_foo.Random2() / 64.; + mo->Vel.Y = pr_foo.Random2() / 64.; + mo->Vel.Z = ((pr_foo() & 7) + 5) * 0.75; } S_Sound (self, CHAN_BODY, self->DeathSound, 1, ATTN_IDLE); self->Destroy (); @@ -222,7 +222,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn) if (mo) { - P_ThrustMobj (mo, self->angle, (pr_leaf()<<9)+3*FRACUNIT); + mo->Thrust(pr_leaf() / 128. + 3); mo->target = self; mo->special1 = 0; } @@ -242,7 +242,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafThrust) if (pr_leafthrust() <= 96) { - self->vel.z += (pr_leafthrust()<<9)+FRACUNIT; + self->Vel.Z += pr_leafthrust() / 128. + 1; } return 0; } @@ -263,18 +263,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafCheck) self->SetState (NULL); return 0; } - angle_t ang = self->target ? self->target->angle : self->angle; + DAngle ang = self->target ? self->target->Angles.Yaw : self->Angles.Yaw; if (pr_leafcheck() > 64) { - if (!self->vel.x && !self->vel.y) + if (self->Vel.X == 0 && self->Vel.Y == 0) { - P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+FRACUNIT); + self->Thrust(ang, pr_leafcheck() / 128. + 1); } return 0; } self->SetState (self->SpawnState + 7); - self->vel.z = (pr_leafcheck()<<9)+FRACUNIT; - P_ThrustMobj (self, ang, (pr_leafcheck()<<9)+2*FRACUNIT); + self->Vel.Z = pr_leafcheck() / 128. + 1; + self->Thrust(ang, pr_leafcheck() / 128. + 2); self->flags |= MF_MISSILE; return 0; } @@ -310,14 +310,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode) { fixed_t xo = ((pr_soaexplode() - 128) << 12); fixed_t yo = ((pr_soaexplode() - 128) << 12); - fixed_t zo = (pr_soaexplode()*self->height / 256); + fixed_t zo = (pr_soaexplode()*self->_f_height() / 256); mo = Spawn ("ZArmorChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { mo->SetState (mo->SpawnState + i); - mo->vel.z = ((pr_soaexplode()&7)+5)*FRACUNIT; - mo->vel.x = pr_soaexplode.Random2()<<(FRACBITS-6); - mo->vel.y = pr_soaexplode.Random2()<<(FRACBITS-6); + mo->Vel.X = pr_soaexplode.Random2() / 64.; + mo->Vel.Y = pr_soaexplode.Random2() / 64.; + mo->Vel.Z = (pr_soaexplode() & 7) + 5; } } // Spawn an item? @@ -365,7 +365,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BellReset1) PARAM_ACTION_PROLOGUE; self->flags |= MF_NOGRAVITY; - self->height <<= 2; + self->Height *= 4; if (self->special) { // Initiate death action P_ExecuteSpecial(self->special, NULL, NULL, false, self->args[0], diff --git a/src/g_hexen/a_iceguy.cpp b/src/g_hexen/a_iceguy.cpp index babc14f8f..fd7efe426 100644 --- a/src/g_hexen/a_iceguy.cpp +++ b/src/g_hexen/a_iceguy.cpp @@ -34,8 +34,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyLook) CALL_ACTION(A_Look, self); if (pr_iceguylook() < 64) { - dist = ((pr_iceguylook()-128)*self->radius)>>7; - an = (self->angle+ANG90)>>ANGLETOFINESHIFT; + dist = ((pr_iceguylook()-128)*self->_f_radius())>>7; + an = (self->_f_angle()+ANG90)>>ANGLETOFINESHIFT; Spawn(WispTypes[pr_iceguylook() & 1], self->Vec3Offset( FixedMul(dist, finecosine[an]), @@ -62,8 +62,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase) A_Chase (stack, self); if (pr_iceguychase() < 128) { - dist = ((pr_iceguychase()-128)*self->radius)>>7; - an = (self->angle+ANG90)>>ANGLETOFINESHIFT; + dist = ((pr_iceguychase()-128)*self->_f_radius())>>7; + an = (self->_f_angle()+ANG90)>>ANGLETOFINESHIFT; mo = Spawn(WispTypes[pr_iceguychase() & 1], self->Vec3Offset( FixedMul(dist, finecosine[an]), @@ -71,9 +71,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyChase) 60 * FRACUNIT), ALLOW_REPLACE); if (mo) { - mo->vel.x = self->vel.x; - mo->vel.y = self->vel.y; - mo->vel.z = self->vel.z; + mo->Vel = self->Vel; mo->target = self; } } @@ -94,8 +92,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyAttack) { return 0; } - P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle+ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); - P_SpawnMissileXYZ(self->Vec3Angle(self->radius>>1, self->angle-ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); + P_SpawnMissileXYZ(self->_f_Vec3Angle(self->_f_radius()>>1, self->_f_angle()+ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); + P_SpawnMissileXYZ(self->_f_Vec3Angle(self->_f_radius()>>1, self->_f_angle()-ANG90, 40*FRACUNIT), self, self->target, PClass::FindActor ("IceGuyFX")); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); return 0; } @@ -110,10 +108,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyDie) { PARAM_ACTION_PROLOGUE; - self->vel.x = 0; - self->vel.y = 0; - self->vel.z = 0; - self->height = self->GetDefault()->height; + self->Vel.Zero(); + self->Height = self->GetDefault()->Height; CALL_ACTION(A_FreezeDeathChunks, self); return 0; } @@ -133,7 +129,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_IceGuyMissileExplode) for (i = 0; i < 8; i++) { - mo = P_SpawnMissileAngleZ (self, self->Z()+3*FRACUNIT, + mo = P_SpawnMissileAngleZ (self, self->_f_Z()+3*FRACUNIT, PClass::FindActor("IceGuyFX2"), i*ANG45, (fixed_t)(-0.3*FRACUNIT)); if (mo) { diff --git a/src/g_hexen/a_korax.cpp b/src/g_hexen/a_korax.cpp index fdcf95365..0cb8f1149 100644 --- a/src/g_hexen/a_korax.cpp +++ b/src/g_hexen/a_korax.cpp @@ -48,7 +48,7 @@ const int KORAX_ARM4_HEIGHT = 104*FRACUNIT; const int KORAX_ARM5_HEIGHT = 86*FRACUNIT; const int KORAX_ARM6_HEIGHT = 53*FRACUNIT; -const int KORAX_BOLT_HEIGHT = 48*FRACUNIT; +const double KORAX_BOLT_HEIGHT = 48.; const int KORAX_BOLT_LIFETIME = 3; @@ -99,7 +99,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase) spot = iterator.Next (); if (spot != NULL) { - P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (self, spot->_f_X(), spot->_f_Y(), ONFLOORZ, spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG); } P_StartScript (self, NULL, 249, NULL, NULL, 0, 0); @@ -141,7 +141,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxChase) self->tracer = spot; if (spot) { - P_Teleport (self, spot->X(), spot->Y(), ONFLOORZ, spot->angle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (self, spot->_f_X(), spot->_f_Y(), ONFLOORZ, spot->Angles.Yaw, TELF_SOURCEFOG | TELF_DESTFOG); } } } @@ -273,7 +273,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KoraxCommand) S_Sound (self, CHAN_VOICE, "KoraxCommand", 1, ATTN_NORM); // Shoot stream of lightning to ceiling - ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; + ang = (self->_f_angle() - ANGLE_90) >> ANGLETOFINESHIFT; fixedvec3 pos = self->Vec3Offset( KORAX_COMMAND_OFFSET * finecosine[ang], KORAX_COMMAND_OFFSET * finesine[ang], @@ -331,11 +331,11 @@ void KoraxFire (AActor *actor, PClassActor *type, int arm) angle_t ang; - ang = (actor->angle + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE)) >> ANGLETOFINESHIFT; + ang = (actor->_f_angle() + (arm < 3 ? -KORAX_DELTAANGLE : KORAX_DELTAANGLE)) >> ANGLETOFINESHIFT; fixedvec3 pos = actor->Vec3Offset( extension[arm] * finecosine[ang], extension[arm] * finesine[ang], - -actor->floorclip + armheight[arm]); + -actor->_f_floorclip() + armheight[arm]); P_SpawnKoraxMissile (pos.x, pos.y, pos.z, actor, actor->target, type); } @@ -354,12 +354,11 @@ void CHolyWeave (AActor *actor, FRandom &pr_random); // //============================================================================ -void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) +static void A_KSpiritSeeker (AActor *actor, DAngle thresh, DAngle turnMax) { int dir; int dist; - angle_t delta; - angle_t angle; + DAngle delta; AActor *target; fixed_t newZ; fixed_t deltaZ; @@ -372,7 +371,7 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if(delta > turnMax) { delta = turnMax; @@ -380,22 +379,20 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) } if(dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; - actor->vel.x = FixedMul (actor->Speed, finecosine[angle]); - actor->vel.y = FixedMul (actor->Speed, finesine[angle]); + actor->VelFromAngle(); if (!(level.time&15) - || actor->Z() > target->Z()+(target->GetDefault()->height) - || actor->Top() < target->Z()) + || actor->_f_Z() > target->_f_Z()+(target->GetDefault()->_f_height()) + || actor->_f_Top() < target->_f_Z()) { - newZ = target->Z()+((pr_kspiritseek()*target->GetDefault()->height)>>8); - deltaZ = newZ-actor->Z(); + newZ = target->_f_Z()+((pr_kspiritseek()*target->GetDefault()->_f_height())>>8); + deltaZ = newZ-actor->_f_Z(); if (abs(deltaZ) > 15*FRACUNIT) { if(deltaZ > 0) @@ -407,12 +404,12 @@ void A_KSpiritSeeker (AActor *actor, angle_t thresh, angle_t turnMax) deltaZ = -15*FRACUNIT; } } - dist = actor->AproxDistance (target) / actor->Speed; + dist = actor->AproxDistance (target) / actor->_f_speed(); if (dist < 1) { dist = 1; } - actor->vel.z = deltaZ/dist; + actor->Vel.Z = FIXED2DBL(deltaZ/dist); } return; } @@ -436,8 +433,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_KSpiritRoam) { if (self->tracer) { - A_KSpiritSeeker (self, self->args[0]*ANGLE_1, - self->args[0]*ANGLE_1*2); + A_KSpiritSeeker(self, (double)self->args[0], self->args[0] * 2.); } CHolyWeave(self, pr_kspiritweave); if (pr_kspiritroam()<50) @@ -477,14 +473,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_KBoltRaise) PARAM_ACTION_PROLOGUE; AActor *mo; - fixed_t z; // Spawn a child upward - z = self->Z() + KORAX_BOLT_HEIGHT; + double z = self->Z() + KORAX_BOLT_HEIGHT; if ((z + KORAX_BOLT_HEIGHT) < self->ceilingz) { - mo = Spawn("KoraxBolt", self->X(), self->Y(), z, ALLOW_REPLACE); + mo = Spawn("KoraxBolt", self->PosAtZ(z), ALLOW_REPLACE); if (mo) { mo->special1 = KORAX_BOLT_LIFETIME; @@ -507,26 +502,24 @@ AActor *P_SpawnKoraxMissile (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, PClassActor *type) { AActor *th; - angle_t an; + DAngle an; int dist; - z -= source->floorclip; + z -= source->_f_floorclip(); th = Spawn (type, x, y, z, ALLOW_REPLACE); th->target = source; // Originator an = th->AngleTo(dest); if (dest->flags & MF_SHADOW) { // Invisible target - an += pr_kmissile.Random2()<<21; + an += pr_kmissile.Random2() * (45/256.); } - th->angle = an; - an >>= ANGLETOFINESHIFT; - th->vel.x = FixedMul (th->Speed, finecosine[an]); - th->vel.y = FixedMul (th->Speed, finesine[an]); - dist = dest->AproxDistance (th) / th->Speed; + th->Angles.Yaw = an; + th->VelFromAngle(); + dist = dest->AproxDistance (th) / th->_f_speed(); if (dist < 1) { dist = 1; } - th->vel.z = (dest->Z()-z+(30*FRACUNIT))/dist; + th->Vel.Z = FIXED2DBL((dest->_f_Z()-z+(30*FRACUNIT))/dist); return (P_CheckMissileSpawn(th, source->radius) ? th : NULL); } diff --git a/src/g_hexen/a_magecone.cpp b/src/g_hexen/a_magecone.cpp index 69cc31f4f..2346cb26a 100644 --- a/src/g_hexen/a_magecone.cpp +++ b/src/g_hexen/a_magecone.cpp @@ -53,9 +53,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; int i; AActor *mo; bool conedone=false; @@ -78,11 +78,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) damage = 90+(pr_cone()&15); for (i = 0; i < 16; i++) { - angle = self->angle+i*(ANG45/16); - slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0, ALF_CHECK3D); + angle = self->Angles.Yaw + i*(45./16); + slope = P_AimLineAttack (self, angle, MELEERANGE, &t, 0., ALF_CHECK3D); if (t.linetarget) { - P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.angleFromSource); + P_DamageMobj (t.linetarget, self, self, damage, NAME_Ice, DMG_USEANGLE, t.angleFromSource.Degrees); conedone = true; break; } @@ -128,35 +128,35 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard) // every so many calls, spawn a new missile in its set directions if (spawndir & SHARDSPAWN_LEFT) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle+(ANG45/9), + mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z(), RUNTIME_CLASS(AFrostMissile), self->_f_angle()+(ANG45/9), 0, (20+2*spermcount)<target); if (mo) { mo->special1 = SHARDSPAWN_LEFT; mo->special2 = spermcount; - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; mo->args[0] = (spermcount==3)?2:0; } } if (spawndir & SHARDSPAWN_RIGHT) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z(), RUNTIME_CLASS(AFrostMissile), self->angle-(ANG45/9), + mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z(), RUNTIME_CLASS(AFrostMissile), self->_f_angle()-(ANG45/9), 0, (20+2*spermcount)<target); if (mo) { mo->special1 = SHARDSPAWN_RIGHT; mo->special2 = spermcount; - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; mo->args[0] = (spermcount==3)?2:0; } } if (spawndir & SHARDSPAWN_UP) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z()+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle, + mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z()+8*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->_f_angle(), 0, (15+2*spermcount)<target); if (mo) { - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; if (spermcount & 1) // Every other reproduction mo->special1 = SHARDSPAWN_UP | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT; else @@ -167,11 +167,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShedShard) } if (spawndir & SHARDSPAWN_DOWN) { - mo = P_SpawnMissileAngleZSpeed (self, self->Z()-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->angle, + mo = P_SpawnMissileAngleZSpeed (self, self->_f_Z()-4*FRACUNIT, RUNTIME_CLASS(AFrostMissile), self->_f_angle(), 0, (15+2*spermcount)<target); if (mo) { - mo->vel.z = self->vel.z; + mo->Vel.Z = self->Vel.Z; if (spermcount & 1) // Every other reproduction mo->special1 = SHARDSPAWN_DOWN | SHARDSPAWN_LEFT | SHARDSPAWN_RIGHT; else diff --git a/src/g_hexen/a_magelightning.cpp b/src/g_hexen/a_magelightning.cpp index 2c9b0d8c1..f3f2e439d 100644 --- a/src/g_hexen/a_magelightning.cpp +++ b/src/g_hexen/a_magelightning.cpp @@ -14,7 +14,7 @@ #include "g_level.h" */ -#define ZAGSPEED FRACUNIT +#define ZAGSPEED 1. static FRandom pr_lightningready ("LightningReady"); static FRandom pr_lightningclip ("LightningClip"); @@ -42,8 +42,8 @@ int ALightning::SpecialMissileHit (AActor *thing) { if (thing->Mass != INT_MAX) { - thing->vel.x += vel.x>>4; - thing->vel.y += vel.y>>4; + thing->Vel.X += Vel.X / 16; + thing->Vel.Y += Vel.Y / 16; } if ((!thing->player && !(thing->flags2&MF2_BOSS)) || !(level.time&1)) @@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip) } else if (self->flags3 & MF3_CEILINGHUGGER) { - self->SetZ(self->ceilingz-self->height); + self->SetZ(self->ceilingz - self->Height); target = self->tracer; } if (self->flags3 & MF3_FLOORHUGGER) @@ -170,19 +170,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip) zigZag = pr_lightningclip(); if((zigZag > 128 && self->special1 < 2) || self->special1 < -2) { - P_ThrustMobj(self, self->angle+ANG90, ZAGSPEED); + self->Thrust(self->Angles.Yaw + 90, ZAGSPEED); if(cMo) { - P_ThrustMobj(cMo, self->angle+ANG90, ZAGSPEED); + cMo->Thrust(self->Angles.Yaw + 90, ZAGSPEED); } self->special1++; } else { - P_ThrustMobj(self, self->angle-ANG90, ZAGSPEED); + self->Thrust(self->Angles.Yaw - 90, ZAGSPEED); if(cMo) { - P_ThrustMobj(cMo, cMo->angle-ANG90, ZAGSPEED); + cMo->Thrust(self->Angles.Yaw - 90, ZAGSPEED); } self->special1--; } @@ -195,10 +195,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningClip) } else { - self->angle = self->AngleTo(target); - self->vel.x = 0; - self->vel.y = 0; - P_ThrustMobj (self, self->angle, self->Speed>>1); + self->Angles.Yaw = self->AngleTo(target); + self->VelFromAngle(self->Speed / 2); } } return 0; @@ -240,23 +238,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap) { deltaZ = -10*FRACUNIT; } - fixed_t xo = ((pr_zap() - 128)*self->radius / 256); - fixed_t yo = ((pr_zap() - 128)*self->radius / 256); + fixed_t xo = ((pr_zap() - 128)*self->_f_radius() / 256); + fixed_t yo = ((pr_zap() - 128)*self->_f_radius() / 256); mo = Spawn(lightning, self->Vec3Offset(xo, yo, deltaZ), ALLOW_REPLACE); if (mo) { mo->lastenemy = self; - mo->vel.x = self->vel.x; - mo->vel.y = self->vel.y; + mo->Vel.X = self->Vel.X; + mo->Vel.Y = self->Vel.Y; mo->target = self->target; if (self->flags3 & MF3_FLOORHUGGER) { - mo->vel.z = 20*FRACUNIT; + mo->Vel.Z = 20; } else { - mo->vel.z = -20*FRACUNIT; + mo->Vel.Z = -20; } } if ((self->flags3 & MF3_FLOORHUGGER) && pr_zapf() < 160) @@ -328,8 +326,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ZapMimic) } else { - self->vel.x = mo->vel.x; - self->vel.y = mo->vel.y; + self->Vel.X = mo->Vel.X; + self->Vel.Y = mo->Vel.Y; } } return 0; @@ -356,7 +354,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LastZap) if (mo) { mo->SetState (mo->FindState (NAME_Death)); - mo->vel.z = 40*FRACUNIT; + mo->Vel.Z = 40; mo->Damage = NULL; } return 0; diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index ee31257d6..dff795dcd 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -97,13 +97,12 @@ bool AMageStaffFX2::SpecialBlastHandling (AActor *source, fixed_t strength) // //============================================================================ -void MStaffSpawn (AActor *pmo, angle_t angle, AActor *alttarget) +void MStaffSpawn (AActor *pmo, DAngle angle, AActor *alttarget) { AActor *mo; FTranslatedLineTarget t; - mo = P_SpawnPlayerMissile (pmo, 0, 0, 8*FRACUNIT, - RUNTIME_CLASS(AMageStaffFX2), angle, &t); + mo = P_SpawnPlayerMissile (pmo, 0, 0, 8*FRACUNIT, RUNTIME_CLASS(AMageStaffFX2), angle, &t); if (mo) { mo->target = pmo; @@ -124,7 +123,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; player_t *player; FTranslatedLineTarget t; @@ -139,21 +138,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_MStaffAttack) if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } - angle = self->angle; + angle = self->Angles.Yaw; // [RH] Let's try and actually track what the player aimed at - P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, ANGLE_1*32); + P_AimLineAttack (self, angle, PLAYERMISSILERANGE, &t, 32.); if (t.linetarget == NULL) { - BlockCheckLine.x = self->X(); - BlockCheckLine.y = self->Y(); - BlockCheckLine.dx = -finesine[angle >> ANGLETOFINESHIFT]; - BlockCheckLine.dy = -finecosine[angle >> ANGLETOFINESHIFT]; + BlockCheckLine.x = self->_f_X(); + BlockCheckLine.y = self->_f_Y(); + BlockCheckLine.dx = FLOAT2FIXED(-angle.Sin()); + BlockCheckLine.dy = FLOAT2FIXED(-angle.Cos()); t.linetarget = P_BlockmapSearch (self, 10, FrontBlockCheck); } MStaffSpawn (self, angle, t.linetarget); - MStaffSpawn (self, angle-ANGLE_1*5, t.linetarget); - MStaffSpawn (self, angle+ANGLE_1*5, t.linetarget); + MStaffSpawn (self, angle-5, t.linetarget); + MStaffSpawn (self, angle+5, t.linetarget); S_Sound (self, CHAN_WEAPON, "MageStaffFire", 1, ATTN_NORM); weapon->MStaffCount = 3; return 0; @@ -214,7 +213,7 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *) { if (link->Me != mo) { - if (P_PointOnDivlineSide (link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 && + if (P_PointOnDivlineSide (link->Me->_f_X(), link->Me->_f_Y(), &BlockCheckLine) == 0 && mo->IsOkayToAttack (link->Me)) { return link->Me; @@ -234,7 +233,7 @@ void MStaffSpawn2 (AActor *actor, angle_t angle) { AActor *mo; - mo = P_SpawnMissileAngleZ (actor, actor->Z()+40*FRACUNIT, + mo = P_SpawnMissileAngleZ (actor, actor->_f_Z()+40*FRACUNIT, RUNTIME_CLASS(AMageStaffFX2), angle, 0); if (mo) { @@ -258,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MageAttack) return 0; } angle_t angle; - angle = self->angle; + angle = self->_f_angle(); MStaffSpawn2 (self, angle); MStaffSpawn2 (self, angle-ANGLE_1*5); MStaffSpawn2 (self, angle+ANGLE_1*5); diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 4d3201ac4..b53442c14 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -35,7 +35,7 @@ void APigPlayer::MorphPlayerThink () { return; } - if(!(vel.x | vel.y) && pr_pigplayerthink() < 64) + if(Vel.X == 0 && Vel.Y == 0 && pr_pigplayerthink() < 64) { // Snout sniff if (player->ReadyWeapon != NULL) { @@ -60,9 +60,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int slope; + DAngle slope; player_t *player; AActor *puff; FTranslatedLineTarget t; @@ -73,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack) } damage = 3+(pr_snoutattack()&3); - angle = player->mo->angle; + angle = player->mo->Angles.Yaw; slope = P_AimLineAttack(player->mo, angle, MELEERANGE); puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &t); S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM); @@ -101,7 +101,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PigPain) CALL_ACTION(A_Pain, self); if (self->Z() <= self->floorz) { - self->vel.z = FRACUNIT*7/2; + self->Vel.Z = 3.5; } return 0; } diff --git a/src/g_hexen/a_serpent.cpp b/src/g_hexen/a_serpent.cpp index 07863edd7..998466053 100644 --- a/src/g_hexen/a_serpent.cpp +++ b/src/g_hexen/a_serpent.cpp @@ -28,7 +28,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentUnHide) PARAM_ACTION_PROLOGUE; self->renderflags &= ~RF_INVISIBLE; - self->floorclip = 24*FRACUNIT; + self->Floorclip = 24; return 0; } @@ -43,7 +43,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentHide) PARAM_ACTION_PROLOGUE; self->renderflags |= RF_INVISIBLE; - self->floorclip = 0; + self->Floorclip = 0; return 0; } @@ -58,7 +58,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentRaiseHump) { PARAM_ACTION_PROLOGUE; - self->floorclip -= 4*FRACUNIT; + self->Floorclip -= 4; return 0; } @@ -72,7 +72,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentLowerHump) { PARAM_ACTION_PROLOGUE; - self->floorclip += 4*FRACUNIT; + self->Floorclip += 4; return 0; } @@ -228,17 +228,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_SerpentSpawnGibs) for (int i = countof(GibTypes)-1; i >= 0; --i) { - fixedvec2 pos = self->Vec2Offset( - ((pr_serpentgibs() - 128) << 12), - ((pr_serpentgibs() - 128) << 12)); + double x = (pr_serpentgibs() - 128) / 16.; + double y = (pr_serpentgibs() - 128) / 16.; - mo = Spawn (GibTypes[i], pos.x, pos.y, - self->floorz+FRACUNIT, ALLOW_REPLACE); + mo = Spawn (GibTypes[i], self->Vec2OffsetZ(x, y, self->floorz + 1), ALLOW_REPLACE); if (mo) { - mo->vel.x = (pr_serpentgibs()-128)<<6; - mo->vel.y = (pr_serpentgibs()-128)<<6; - mo->floorclip = 6*FRACUNIT; + mo->Vel.X = (pr_serpentgibs() - 128) / 1024.f; + mo->Vel.Y = (pr_serpentgibs() - 128) / 1024.f; + mo->Floorclip = 6; } } return 0; @@ -254,7 +252,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FloatGib) { PARAM_ACTION_PROLOGUE; - self->floorclip -= FRACUNIT; + self->Floorclip -= 1; return 0; } @@ -268,7 +266,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SinkGib) { PARAM_ACTION_PROLOGUE; - self->floorclip += FRACUNIT; + self->Floorclip += 1;; return 0; } diff --git a/src/g_hexen/a_spike.cpp b/src/g_hexen/a_spike.cpp index 3943bee30..dd1978583 100644 --- a/src/g_hexen/a_spike.cpp +++ b/src/g_hexen/a_spike.cpp @@ -82,7 +82,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitUp) self->special2 = 5; // Raise speed self->args[0] = 1; // Mark as up - self->floorclip = 0; + self->Floorclip = 0; self->flags = MF_SOLID; self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP; self->special1 = 0L; @@ -95,7 +95,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustInitDn) self->special2 = 5; // Raise speed self->args[0] = 0; // Mark as down - self->floorclip = self->GetDefault()->height; + self->Floorclip = self->GetDefault()->Height; self->flags = 0; self->flags2 = MF2_NOTELEPORT|MF2_FLOORCLIP; self->renderflags = RF_INVISIBLE; @@ -111,7 +111,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise) AThrustFloor *actor = static_cast(self); - if (A_RaiseMobj (actor, self->special2*FRACUNIT)) + if (A_RaiseMobj (actor, self->special2)) { // Reached it's target height actor->args[0] = 1; if (actor->args[1]) @@ -121,7 +121,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustRaise) } // Lose the dirt clump - if ((actor->floorclip < actor->height) && actor->DirtClump) + if ((actor->Floorclip < actor->Height) && actor->DirtClump) { actor->DirtClump->Destroy (); actor->DirtClump = NULL; @@ -138,7 +138,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustLower) { PARAM_ACTION_PROLOGUE; - if (A_SinkMobj (self, 6*FRACUNIT)) + if (A_SinkMobj (self, 6)) { self->args[0] = 0; if (self->args[1]) @@ -160,8 +160,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrustImpale) FMultiBlockThingsIterator::CheckResult cres; while (it.Next(&cres)) { - fixed_t blockdist = self->radius + cres.thing->radius; - if (abs(cres.thing->X() - cres.position.x) >= blockdist || abs(cres.thing->Y() - cres.position.y) >= blockdist) + fixed_t blockdist = self->_f_radius() + cres.thing->_f_radius(); + if (abs(cres.thing->_f_X() - cres.position.x) >= blockdist || abs(cres.thing->_f_Y() - cres.position.y) >= blockdist) continue; // Q: Make this z-aware for everything? It never was before. diff --git a/src/g_hexen/a_summon.cpp b/src/g_hexen/a_summon.cpp index d50682dc9..61df3fb2d 100644 --- a/src/g_hexen/a_summon.cpp +++ b/src/g_hexen/a_summon.cpp @@ -36,7 +36,7 @@ bool AArtiDarkServant::Use (bool pickup) { mo->target = Owner; mo->tracer = Owner; - mo->vel.z = 5*FRACUNIT; + mo->Vel.Z = 5; } return true; } @@ -59,7 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Summon) if (P_TestMobjLocation(mo) == false || !self->tracer) { // Didn't fit - change back to artifact mo->Destroy (); - AActor *arti = Spawn (self->Pos(), ALLOW_REPLACE); + AActor *arti = Spawn (self->_f_Pos(), ALLOW_REPLACE); if (arti) arti->flags |= MF_DROPPED; return 0; } diff --git a/src/g_hexen/a_teleportother.cpp b/src/g_hexen/a_teleportother.cpp index 3daca2103..8903d47e0 100644 --- a/src/g_hexen/a_teleportother.cpp +++ b/src/g_hexen/a_teleportother.cpp @@ -55,11 +55,9 @@ static void TeloSpawn (AActor *source, const char *type) if (fx) { fx->special1 = TELEPORT_LIFE; // Lifetime countdown - fx->angle = source->angle; + fx->Angles.Yaw = source->Angles.Yaw; fx->target = source->target; - fx->vel.x = source->vel.x >> 1; - fx->vel.y = source->vel.y >> 1; - fx->vel.z = source->vel.z >> 1; + fx->Vel = source->Vel / 2; } } @@ -167,13 +165,11 @@ int ATelOtherFX1::DoSpecialDamage (AActor *target, int damage, FName damagetype) void P_TeleportToPlayerStarts (AActor *victim) { fixed_t destX,destY; - angle_t destAngle; FPlayerStart *start = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK); destX = start->x; destY = start->y; - destAngle = ANG45 * (start->angle/45); - P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (victim, destX, destY, ONFLOORZ, (double)start->angle, TELF_SOURCEFOG | TELF_DESTFOG); } //=========================================================================== @@ -186,7 +182,6 @@ void P_TeleportToDeathmatchStarts (AActor *victim) { unsigned int i, selections; fixed_t destX,destY; - angle_t destAngle; selections = deathmatchstarts.Size (); if (selections > 0) @@ -194,8 +189,7 @@ void P_TeleportToDeathmatchStarts (AActor *victim) i = pr_teledm() % selections; destX = deathmatchstarts[i].x; destY = deathmatchstarts[i].y; - destAngle = ANG45 * (deathmatchstarts[i].angle/45); - P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (victim, destX, destY, ONFLOORZ, (double)deathmatchstarts[i].angle, TELF_SOURCEFOG | TELF_DESTFOG); } else { diff --git a/src/g_hexen/a_wraith.cpp b/src/g_hexen/a_wraith.cpp index 44aa2c308..de5f4bb72 100644 --- a/src/g_hexen/a_wraith.cpp +++ b/src/g_hexen/a_wraith.cpp @@ -31,12 +31,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithInit) { PARAM_ACTION_PROLOGUE; - self->AddZ(48<AddZ(48); // [RH] Make sure the wraith didn't go into the ceiling if (self->Top() > self->ceilingz) { - self->SetZ(self->ceilingz - self->height); + self->SetZ(self->ceilingz - self->Height); } self->special1 = 0; // index into floatbob @@ -57,7 +57,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithRaiseInit) self->flags2 &= ~MF2_NONSHOOTABLE; self->flags3 &= ~MF3_DONTBLAST; self->flags |= MF_SHOOTABLE|MF_SOLID; - self->floorclip = self->height; + self->Floorclip = self->Height; return 0; } @@ -119,7 +119,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2) PARAM_ACTION_PROLOGUE; AActor *mo; - angle_t angle; + DAngle angle; int i; for (i = 2; i; --i) @@ -127,21 +127,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX2) mo = Spawn ("WraithFX2", self->Pos(), ALLOW_REPLACE); if(mo) { - if (pr_wraithfx2 ()<128) + angle = pr_wraithfx2() * (360 / 1024.f); + if (pr_wraithfx2() >= 128) { - angle = self->angle+(pr_wraithfx2()<<22); + angle = -angle; } - else - { - angle = self->angle-(pr_wraithfx2()<<22); - } - mo->vel.z = 0; - mo->vel.x = FixedMul((pr_wraithfx2()<<7)+FRACUNIT, - finecosine[angle>>ANGLETOFINESHIFT]); - mo->vel.y = FixedMul((pr_wraithfx2()<<7)+FRACUNIT, - finesine[angle>>ANGLETOFINESHIFT]); + angle += self->Angles.Yaw; + mo->Vel.X = ((pr_wraithfx2() << 7) + 1) * angle.Cos(); + mo->Vel.Y = ((pr_wraithfx2() << 7) + 1) * angle.Sin(); + mo->Vel.Z = 0; mo->target = self; - mo->floorclip = 10*FRACUNIT; + mo->Floorclip = 10; } } return 0; @@ -255,9 +251,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithChase) PARAM_ACTION_PROLOGUE; int weaveindex = self->special1; - self->AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); + self->_f_AddZ(finesine[weaveindex << BOBTOFINESHIFT] * 8); self->special1 = (weaveindex + 2) & 63; -// if (self->floorclip > 0) +// if (self->Floorclip > 0) // { // P_SetMobjState(self, S_WRAITH_RAISE2); // return; diff --git a/src/g_level.cpp b/src/g_level.cpp index 74e576056..f2d179e4a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1228,7 +1228,7 @@ void G_FinishTravel () { Printf(TEXTCOLOR_RED "No player %d start to travel to!\n", pnum + 1); // Move to the coordinates this player had when they left the level. - pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z()); + pawn->SetXYZ(pawndup->_f_X(), pawndup->_f_Y(), pawndup->_f_Z()); } } oldpawn = pawndup; @@ -1240,13 +1240,10 @@ void G_FinishTravel () { if (!(changeflags & CHANGELEVEL_KEEPFACING)) { - pawn->angle = pawndup->angle; - pawn->pitch = pawndup->pitch; + pawn->Angles = pawndup->Angles; } - pawn->SetXYZ(pawndup->X(), pawndup->Y(), pawndup->Z()); - pawn->vel.x = pawndup->vel.x; - pawn->vel.y = pawndup->vel.y; - pawn->vel.z = pawndup->vel.z; + pawn->SetXYZ(pawndup->Pos()); + pawn->Vel = pawndup->Vel; pawn->Sector = pawndup->Sector; pawn->floorz = pawndup->floorz; pawn->ceilingz = pawndup->ceilingz; @@ -1256,7 +1253,7 @@ void G_FinishTravel () pawn->floorterrain = pawndup->floorterrain; pawn->ceilingsector = pawndup->ceilingsector; pawn->ceilingpic = pawndup->ceilingpic; - pawn->floorclip = pawndup->floorclip; + pawn->Floorclip = pawndup->Floorclip; pawn->waterlevel = pawndup->waterlevel; } else @@ -1316,7 +1313,7 @@ void G_InitLevelLocals () NormalLight.ChangeColor (PalEntry (255, 255, 255), 0); level.gravity = sv_gravity * 35/TICRATE; - level.aircontrol = (fixed_t)(sv_aircontrol * 65536.f); + level.aircontrol = sv_aircontrol; level.teamdamage = teamdamage; level.flags = 0; level.flags2 = 0; @@ -1357,7 +1354,7 @@ void G_InitLevelLocals () } if (info->aircontrol != 0.f) { - level.aircontrol = (fixed_t)(info->aircontrol * 65536.f); + level.aircontrol = info->aircontrol; } if (info->teamdamage != 0.f) { @@ -1462,15 +1459,14 @@ FString CalcMapName (int episode, int level) void G_AirControlChanged () { - if (level.aircontrol <= 256) + if (level.aircontrol <= 1/256.) { - level.airfriction = FRACUNIT; + level.airfriction = 1.; } else { // Friction is inversely proportional to the amount of control - float fric = ((float)level.aircontrol/65536.f) * -0.0941f + 1.0004f; - level.airfriction = (fixed_t)(fric * 65536.f); + level.airfriction = level.aircontrol * -0.0941 + 1.0004; } } diff --git a/src/g_level.h b/src/g_level.h index ca70b654b..8de66974c 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -304,8 +304,8 @@ struct level_info_t DWORD outsidefog; int cdtrack; unsigned int cdid; - float gravity; - float aircontrol; + double gravity; + double aircontrol; int WarpTrans; int airsupply; DWORD compatflags, compatflags2; @@ -429,9 +429,9 @@ struct FLevelLocals int total_monsters; int killed_monsters; - float gravity; - fixed_t aircontrol; - fixed_t airfriction; + double gravity; + double aircontrol; + double airfriction; int airsupply; int DefaultEnvironment; // Default sound environment. diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index fb1ae933f..4d5bfeb99 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -989,14 +989,14 @@ DEFINE_MAP_OPTION(gravity, true) { parse.ParseAssign(); parse.sc.MustGetFloat(); - info->gravity = float(parse.sc.Float); + info->gravity = parse.sc.Float; } DEFINE_MAP_OPTION(aircontrol, true) { parse.ParseAssign(); parse.sc.MustGetFloat(); - info->aircontrol = float(parse.sc.Float); + info->aircontrol = parse.sc.Float; } DEFINE_MAP_OPTION(airsupply, true) diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp index 88739492d..8463609be 100644 --- a/src/g_raven/a_artitele.cpp +++ b/src/g_raven/a_artitele.cpp @@ -29,7 +29,7 @@ bool AArtiTeleport::Use (bool pickup) { fixed_t destX; fixed_t destY; - angle_t destAngle; + int destAngle; if (deathmatch) { @@ -37,16 +37,16 @@ bool AArtiTeleport::Use (bool pickup) unsigned int i = pr_tele() % selections; destX = deathmatchstarts[i].x; destY = deathmatchstarts[i].y; - destAngle = ANG45 * (deathmatchstarts[i].angle/45); + destAngle = deathmatchstarts[i].angle; } else { FPlayerStart *start = G_PickPlayerStart(int(Owner->player - players)); destX = start->x; destY = start->y; - destAngle = ANG45 * (start->angle/45); + destAngle = start->angle; } - P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + P_Teleport (Owner, destX, destY, ONFLOORZ, (double)destAngle, TELF_SOURCEFOG | TELF_DESTFOG); bool canlaugh = true; if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) { // Teleporting away will undo any morph effects (pig) diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 8bd648f66..c6c4e233f 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -175,14 +175,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk1) // //---------------------------------------------------------------------------- -#define MNTR_CHARGE_SPEED (13*FRACUNIT) +#define MNTR_CHARGE_SPEED (13.) DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) { PARAM_ACTION_PROLOGUE; bool friendly = !!(self->flags5 & MF5_SUMMONEDMONSTER); - angle_t angle; AActor *target; int dist; @@ -210,9 +209,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurDecide) self->flags2 |= MF2_INVULNERABLE; } A_FaceTarget (self); - angle = self->angle>>ANGLETOFINESHIFT; - self->vel.x = FixedMul (MNTR_CHARGE_SPEED, finecosine[angle]); - self->vel.y = FixedMul (MNTR_CHARGE_SPEED, finesine[angle]); + self->VelFromAngle(MNTR_CHARGE_SPEED); self->special1 = TICRATE/2; // Charge duration } else if (target->Z() == target->floorz @@ -260,7 +257,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurCharge) type = PClass::FindActor("PunchPuff"); } puff = Spawn (type, self->Pos(), ALLOW_REPLACE); - puff->vel.z = 2*FRACUNIT; + puff->Vel.Z = 2; self->special1--; } else @@ -303,7 +300,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self); return 0; } - z = self->Z() + 40*FRACUNIT; + z = self->_f_Z() + 40*FRACUNIT; PClassActor *fx = PClass::FindActor("MinotaurFX1"); if (fx) { @@ -311,8 +308,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk2) if (mo != NULL) { // S_Sound (mo, CHAN_WEAPON, "minotaur/attack2", 1, ATTN_NORM); - vz = mo->vel.z; - angle = mo->angle; + vz = mo->_f_velz(); + angle = mo->_f_angle(); P_SpawnMissileAngleZ (self, z, fx, angle-(ANG45/8), vz); P_SpawnMissileAngleZ (self, z, fx, angle+(ANG45/8), vz); P_SpawnMissileAngleZ (self, z, fx, angle-(ANG45/16), vz); @@ -358,7 +355,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3) } else { - if (self->floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR)) + if (self->Floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR)) { // only play the sound. S_Sound (self, CHAN_WEAPON, "minotaur/fx2hit", 1, ATTN_NORM); @@ -393,12 +390,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire) AActor *mo; self->SetZ(self->floorz); - fixedvec2 pos = self->Vec2Offset( - (pr_fire.Random2 () << 10), - (pr_fire.Random2 () << 10)); - mo = Spawn("MinotaurFX3", pos.x, pos.y, self->floorz, ALLOW_REPLACE); + double x = pr_fire.Random2() / 64.; + double y = pr_fire.Random2() / 64.; + + mo = Spawn("MinotaurFX3", self->Vec2OffsetZ(x, y, self->floorz), ALLOW_REPLACE); mo->target = self->target; - mo->vel.x = 1; // Force block checking + mo->Vel.X = MinVel; // Force block checking P_CheckMissileSpawn (mo, self->radius); return 0; } @@ -411,18 +408,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire) void P_MinotaurSlam (AActor *source, AActor *target) { - angle_t angle; - fixed_t thrust; + DAngle angle; + double thrust; int damage; angle = source->AngleTo(target); - angle >>= ANGLETOFINESHIFT; - thrust = 16*FRACUNIT+(pr_minotaurslam()<<10); - target->vel.x += FixedMul (thrust, finecosine[angle]); - target->vel.y += FixedMul (thrust, finesine[angle]); + thrust = 16 + pr_minotaurslam() / 64.; + target->VelFromAngle(angle, thrust); damage = pr_minotaurslam.HitDice (static_cast(source) ? 4 : 6); int newdam = P_DamageMobj (target, NULL, NULL, damage, NAME_Melee); - P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0); + P_TraceBleed (newdam > 0 ? newdam : damage, target, angle, 0.); if (target->player) { target->reactiontime = 14+(pr_minotaurslam()&7); diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 29335e618..dbb50445f 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -142,7 +142,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip) PARAM_ACTION_PROLOGUE; self->flags2 &= ~MF2_FLOORCLIP; - self->floorclip = 0; + self->Floorclip = 0; return 0; } @@ -189,7 +189,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeath) self->flags |= MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD|MF_ICECORPSE; self->flags2 |= MF2_PUSHABLE|MF2_TELESTOMP|MF2_PASSMOBJ|MF2_SLIDE; self->flags3 |= MF3_CRASHED; - self->height = self->GetDefault()->height; + self->Height = self->GetDefault()->Height; // Remove fuzz effects from frozen actors. if (self->RenderStyle.BlendOp >= STYLEOP_Fuzz && self->RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) { @@ -274,33 +274,33 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) int numChunks; AActor *mo; - if ((self->vel.x || self->vel.y || self->vel.z) && !(self->flags6 & MF6_SHATTERING)) + if (!self->Vel.isZero() && !(self->flags6 & MF6_SHATTERING)) { self->tics = 3*TICRATE; return 0; } - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); S_Sound (self, CHAN_BODY, "misc/icebreak", 1, ATTN_NORM); // [RH] In Hexen, this creates a random number of shards (range [24,56]) // with no relation to the size of the self shattering. I think it should // base the number of shards on the size of the dead thing, so bigger // things break up into more shards than smaller things. - // An actor with radius 20 and height 64 creates ~40 chunks. - numChunks = MAX (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32); + // An actor with _f_radius() 20 and height 64 creates ~40 chunks. + numChunks = MAX (4, (self->_f_radius()>>FRACBITS)*(self->_f_height()>>FRACBITS)/32); i = (pr_freeze.Random2()) % (numChunks/4); for (i = MAX (24, numChunks + i); i >= 0; i--) { - fixed_t xo = (((pr_freeze() - 128)*self->radius) >> 7); - fixed_t yo = (((pr_freeze() - 128)*self->radius) >> 7); - fixed_t zo = (pr_freeze()*self->height / 255); + fixed_t xo = (((pr_freeze() - 128)*self->_f_radius()) >> 7); + fixed_t yo = (((pr_freeze() - 128)*self->_f_radius()) >> 7); + fixed_t zo = (pr_freeze()*self->_f_height() / 255); mo = Spawn("IceChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - mo->SetState (mo->SpawnState + (pr_freeze()%3)); - mo->vel.z = FixedDiv(mo->Z() - self->Z(), self->height)<<2; - mo->vel.x = pr_freeze.Random2 () << (FRACBITS-7); - mo->vel.y = pr_freeze.Random2 () << (FRACBITS-7); + mo->SetState (mo->SpawnState + (pr_freeze()%3)); + mo->Vel.X = pr_freeze.Random2() / 128.; + mo->Vel.Y = pr_freeze.Random2() / 128.; + mo->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4; CALL_ACTION(A_IceSetTics, mo); // set a random tic wait mo->RenderStyle = self->RenderStyle; mo->alpha = self->alpha; @@ -311,11 +311,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) AActor *head = Spawn("IceChunkHead", self->PosPlusZ(self->player->mo->ViewHeight), ALLOW_REPLACE); if (head != NULL) { - head->vel.z = FixedDiv(head->Z() - self->Z(), self->height)<<2; - head->vel.x = pr_freeze.Random2 () << (FRACBITS-7); - head->vel.y = pr_freeze.Random2 () << (FRACBITS-7); + head->Vel.X = pr_freeze.Random2() / 128.; + head->Vel.Y = pr_freeze.Random2() / 128.; + head->Vel.Z = (mo->Z() - self->Z()) / self->Height * 4; + head->health = self->health; - head->angle = self->angle; + head->Angles.Yaw = self->Angles.Yaw; if (head->IsKindOf(RUNTIME_CLASS(APlayerPawn))) { head->player = self->player; @@ -323,7 +324,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) self->player = NULL; head->ObtainInventory (self); } - head->pitch = 0; + head->Angles.Pitch = 0.; head->RenderStyle = self->RenderStyle; head->alpha = self->alpha; if (head->player->camera == self) @@ -611,7 +612,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Gravity) PARAM_ACTION_PROLOGUE; self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT; + self->Gravity = 1; return 0; } @@ -626,7 +627,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LowGravity) PARAM_ACTION_PROLOGUE; self->flags &= ~MF_NOGRAVITY; - self->gravity = FRACUNIT/8; + self->Gravity = 1. / 8;; return 0; } @@ -636,34 +637,33 @@ DEFINE_ACTION_FUNCTION(AActor, A_LowGravity) // //=========================================================================== -void FaceMovementDirection (AActor *actor) +void FaceMovementDirection(AActor *actor) { switch (actor->movedir) { case DI_EAST: - actor->angle = 0<<24; + actor->Angles.Yaw = 0.; break; case DI_NORTHEAST: - actor->angle = 32<<24; + actor->Angles.Yaw = 45.; break; case DI_NORTH: - actor->angle = 64<<24; + actor->Angles.Yaw = 90.; break; case DI_NORTHWEST: - actor->angle = 96<<24; + actor->Angles.Yaw = 135.; break; case DI_WEST: - actor->angle = 128<<24; + actor->Angles.Yaw = 180.; break; case DI_SOUTHWEST: - actor->angle = 160<<24; + actor->Angles.Yaw = 225.; break; case DI_SOUTH: - actor->angle = 192<<24; + actor->Angles.Yaw = 270.; break; case DI_SOUTHEAST: - actor->angle = 224<<24; + actor->Angles.Yaw = 315.; break; } } - diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index 30ada14cc..12e841d7e 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -520,9 +520,9 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) // -O1 optimizer bug work around. Only needed for // GCC 4.2.1 on OS X for 10.4/10.5 tools compatibility. volatile fixed_t tmp = 300; - Slots[i] -= Scale (damage, SlotsIncrement[i], tmp); + Slots[i] -= ::Scale (damage, SlotsIncrement[i], tmp); #else - Slots[i] -= Scale (damage, SlotsIncrement[i], 300); + Slots[i] -= ::Scale (damage, SlotsIncrement[i], 300); #endif if (Slots[i] < 2*FRACUNIT) { @@ -535,7 +535,7 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage) } } } - int saved = Scale (damage, savedPercent, 100*FRACUNIT); + int saved = ::Scale (damage, savedPercent, 100*FRACUNIT); if (saved > savedPercent >> (FRACBITS-1)) { saved = savedPercent >> (FRACBITS-1); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 25646ba35..83ce03099 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -981,9 +981,9 @@ void APowerFlight::InitEffect () Owner->flags |= MF_NOGRAVITY; if (Owner->Z() <= Owner->floorz) { - Owner->vel.z = 4*FRACUNIT; // thrust the player in the air a bit + Owner->Vel.Z = 4;; // thrust the player in the air a bit } - if (Owner->vel.z <= -35*FRACUNIT) + if (Owner->Vel.Z <= -35) { // stop falling scream S_StopSound (Owner, CHAN_VOICE); } @@ -1220,10 +1220,10 @@ void APowerSpeed::Serialize(FArchive &arc) // //=========================================================================== -fixed_t APowerSpeed ::GetSpeedFactor () +double APowerSpeed ::GetSpeedFactor () { if (Inventory != NULL) - return FixedMul(Speed, Inventory->GetSpeedFactor()); + return Speed * Inventory->GetSpeedFactor(); else return Speed; } @@ -1261,22 +1261,21 @@ void APowerSpeed::DoEffect () } } - if (P_AproxDistance (Owner->vel.x, Owner->vel.y) <= 12*FRACUNIT) + if (Owner->Vel.LengthSquared() <= 12*12) return; AActor *speedMo = Spawn (Owner->Pos(), NO_REPLACE); if (speedMo) { - speedMo->angle = Owner->angle; + speedMo->Angles.Yaw = Owner->Angles.Yaw; speedMo->Translation = Owner->Translation; speedMo->target = Owner; speedMo->sprite = Owner->sprite; speedMo->frame = Owner->frame; - speedMo->floorclip = Owner->floorclip; + speedMo->Floorclip = Owner->Floorclip; // [BC] Also get the scale from the owner. - speedMo->scaleX = Owner->scaleX; - speedMo->scaleY = Owner->scaleY; + speedMo->Scale = Owner->Scale; if (Owner == players[consoleplayer].camera && !(Owner->player->cheats & CF_CHASECAM)) @@ -1317,10 +1316,10 @@ void APowerTargeter::InitEffect () P_SetPsprite (player, ps_targetright, state + 2); } - player->psprites[ps_targetcenter].sx = (160-3)*FRACUNIT; + player->psprites[ps_targetcenter].sx = (160-3); player->psprites[ps_targetcenter].sy = player->psprites[ps_targetleft].sy = - player->psprites[ps_targetright].sy = (100-3)*FRACUNIT; + player->psprites[ps_targetright].sy = (100-3); PositionAccuracy (); } @@ -1383,8 +1382,8 @@ void APowerTargeter::PositionAccuracy () if (player != NULL) { - player->psprites[ps_targetleft].sx = (160-3)*FRACUNIT - ((100 - player->mo->accuracy) << FRACBITS); - player->psprites[ps_targetright].sx = (160-3)*FRACUNIT + ((100 - player->mo->accuracy) << FRACBITS); + player->psprites[ps_targetleft].sx = (160-3) - ((100 - player->mo->accuracy)); + player->psprites[ps_targetright].sx = (160-3)+ ((100 - player->mo->accuracy)); } } diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index a355cb924..23ff347d3 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -158,7 +158,7 @@ class APowerSpeed : public APowerup protected: void DoEffect (); void Serialize(FArchive &arc); - fixed_t GetSpeedFactor(); + double GetSpeedFactor(); public: int SpeedFlags; }; diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp index 3b1b34d71..e874bc58e 100644 --- a/src/g_shared/a_bridge.cpp +++ b/src/g_shared/a_bridge.cpp @@ -9,7 +9,7 @@ static FRandom pr_orbit ("Orbit"); // Custom bridge -------------------------------------------------------- /* - args[0]: Bridge radius, in mapunits + args[0]: Bridge _f_radius(), in mapunits args[1]: Bridge height, in mapunits args[2]: Amount of bridge balls (if 0: Doom bridge) args[3]: Rotation speed of bridge balls, in byte angle per seconds, sorta: @@ -28,8 +28,8 @@ static FRandom pr_orbit ("Orbit"); 233: -30° / seconds 244: -15° / seconds This value only matters if args[2] is not zero. - args[4]: Rotation radius of bridge balls, in bridge radius %. - If 0, use Hexen default: ORBIT_RADIUS, regardless of bridge radius. + args[4]: Rotation _f_radius() of bridge balls, in bridge _f_radius() %. + If 0, use Hexen default: ORBIT_RADIUS, regardless of bridge _f_radius(). This value only matters if args[2] is not zero. */ @@ -48,13 +48,13 @@ void ACustomBridge::BeginPlay () if (args[2]) // Hexen bridge if there are balls { SetState(SeeState); - radius = args[0] ? args[0] << FRACBITS : 32 * FRACUNIT; - height = args[1] ? args[1] << FRACBITS : 2 * FRACUNIT; + radius = args[0] ? args[0] : 32; + Height = args[1] ? args[1] : 2; } else // No balls? Then a Doom bridge. { - radius = args[0] ? args[0] << FRACBITS : 36 * FRACUNIT; - height = args[1] ? args[1] << FRACBITS : 4 * FRACUNIT; + radius = args[0] ? args[0] : 36; + Height = args[1] ? args[1] : 4; RenderStyle = STYLE_Normal; } } @@ -101,18 +101,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit) } // Set default values // Every five tics, Hexen moved the ball 3/256th of a revolution. - int rotationspeed = ANGLE_45/32*3/5; - int rotationradius = ORBIT_RADIUS * FRACUNIT; + DAngle rotationspeed = 45./32*3/5; + int rotationradius = ORBIT_RADIUS; // If the bridge is custom, set non-default values if any. // Set angular speed; 1--128: counterclockwise rotation ~=1--180°; 129--255: clockwise rotation ~= 180--1° - if (self->target->args[3] > 128) rotationspeed = ANGLE_45/32 * (self->target->args[3]-256) / TICRATE; - else if (self->target->args[3] > 0) rotationspeed = ANGLE_45/32 * (self->target->args[3]) / TICRATE; - // Set rotation radius - if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / 100); + if (self->target->args[3] > 128) rotationspeed = 45./32 * (self->target->args[3]-256) / TICRATE; + else if (self->target->args[3] > 0) rotationspeed = 45./32 * (self->target->args[3]) / TICRATE; + // Set rotation _f_radius() + if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->_f_radius()) / 100); - self->angle += rotationspeed; - self->SetOrigin(self->target->Vec3Angle(rotationradius, self->angle, 0), true); + self->Angles.Yaw += rotationspeed; + self->SetOrigin(self->target->Vec3Angle(rotationradius*FRACUNIT, self->Angles.Yaw, 0), true); self->floorz = self->target->floorz; self->ceilingz = self->target->ceilingz; return 0; @@ -124,7 +124,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) PARAM_ACTION_PROLOGUE; PARAM_CLASS_OPT(balltype, AActor) { balltype = NULL; } - angle_t startangle; AActor *ball; if (balltype == NULL) @@ -132,7 +131,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) balltype = PClass::FindActor("BridgeBall"); } - startangle = pr_orbit() << 24; + DAngle startangle = pr_orbit() * (360./256.); // Spawn triad into world -- may be more than a triad now. int ballcount = self->args[2]==0 ? 3 : self->args[2]; @@ -140,7 +139,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) for (int i = 0; i < ballcount; i++) { ball = Spawn(balltype, self->Pos(), ALLOW_REPLACE); - ball->angle = startangle + (ANGLE_45/32) * (256/ballcount) * i; + ball->Angles.Yaw = startangle + (45./32) * (256/ballcount) * i; ball->target = self; CALL_ACTION(A_BridgeOrbit, ball); } @@ -163,8 +162,8 @@ void AInvisibleBridge::BeginPlay () { Super::BeginPlay (); if (args[0]) - radius = args[0] << FRACBITS; + radius = args[0]; if (args[1]) - height = args[1] << FRACBITS; + Height = args[1]; } diff --git a/src/g_shared/a_camera.cpp b/src/g_shared/a_camera.cpp index 7febf80d1..5c2e24444 100644 --- a/src/g_shared/a_camera.cpp +++ b/src/g_shared/a_camera.cpp @@ -37,6 +37,7 @@ #include "a_sharedglobal.h" #include "p_local.h" #include "farchive.h" +#include "math/cmath.h" /* == SecurityCamera @@ -56,10 +57,10 @@ public: void Serialize (FArchive &arc); protected: - angle_t Center; - angle_t Acc; - angle_t Delta; - angle_t Range; + DAngle Center; + DAngle Acc; + DAngle Delta; + DAngle Range; }; IMPLEMENT_CLASS (ASecurityCamera) @@ -73,29 +74,25 @@ void ASecurityCamera::Serialize (FArchive &arc) void ASecurityCamera::PostBeginPlay () { Super::PostBeginPlay (); - Center = angle; + Center = Angles.Yaw; if (args[2]) - Delta = ANGLE_MAX / (args[2] * TICRATE / 8); + Delta = 360. / (args[2] * TICRATE / 8); else - Delta = 0; + Delta = 0.; if (args[1]) Delta /= 2; - Acc = 0; - pitch = (signed int)((char)args[0]) * ANGLE_1; - if (pitch <= -ANGLE_90) - pitch = -ANGLE_90 + ANGLE_1; - else if (pitch >= ANGLE_90) - pitch = ANGLE_90 - ANGLE_1; - Range = FLOAT2ANGLE(args[1]); + Acc = 0.; + Angles.Pitch = (double)clamp((signed char)args[0], -89, 89); + Range = (double)args[1]; } void ASecurityCamera::Tick () { Acc += Delta; - if (Range) - angle = Center + FixedMul (Range, finesine[Acc >> ANGLETOFINESHIFT]); - else if (Delta) - angle = Acc; + if (Range != 0) + Angles.Yaw = Center + Range * Acc.Sin(); + else if (Delta != 0) + Angles.Yaw = Acc; } /* @@ -119,7 +116,7 @@ public: void Serialize (FArchive &arc); protected: - int MaxPitchChange; + DAngle MaxPitchChange; }; IMPLEMENT_CLASS (AAimingCamera) @@ -136,7 +133,7 @@ void AAimingCamera::PostBeginPlay () args[2] = 0; Super::PostBeginPlay (); - MaxPitchChange = FLOAT2ANGLE(changepitch * TICRATE); + MaxPitchChange = double(changepitch / TICRATE); Range /= TICRATE; TActorIterator iterator (args[3]); @@ -160,7 +157,7 @@ void AAimingCamera::Tick () } if (tracer != NULL) { - angle_t delta; + DAngle delta; int dir = P_FaceMobj (this, tracer, &delta); if (delta > Range) { @@ -168,31 +165,31 @@ void AAimingCamera::Tick () } if (dir) { - angle += delta; + Angles.Yaw += delta; } else { - angle -= delta; + Angles.Yaw -= delta; } - if (MaxPitchChange) + if (MaxPitchChange != 0) { // Aim camera's pitch; use floats for precision - fixedvec2 fv3 = tracer->Vec2To(this); + fixedvec2 fv3 = tracer->_f_Vec2To(this); DVector2 vect(fv3.x, fv3.y); - double dz = Z() - tracer->Z() - tracer->height/2; + double dz = _f_Z() - tracer->_f_Z() - tracer->_f_height()/2; double dist = vect.Length(); - double ang = dist != 0.f ? atan2 (dz, dist) : 0; - int desiredpitch = (int)RAD2ANGLE(ang); - if (abs (desiredpitch - pitch) < MaxPitchChange) + DAngle desiredPitch = dist != 0.f ? VecToAngle(dist, dz) : 0.; + DAngle diff = deltaangle(Angles.Pitch, desiredPitch); + if (fabs (diff) < MaxPitchChange) { - pitch = desiredpitch; + Angles.Pitch = desiredPitch; } - else if (desiredpitch < pitch) + else if (diff < 0) { - pitch -= MaxPitchChange; + Angles.Pitch -= MaxPitchChange; } else { - pitch += MaxPitchChange; + Angles.Pitch += MaxPitchChange; } } } diff --git a/src/g_shared/a_debris.cpp b/src/g_shared/a_debris.cpp index b5785eb9e..895c3b170 100644 --- a/src/g_shared/a_debris.cpp +++ b/src/g_shared/a_debris.cpp @@ -15,7 +15,7 @@ public: { if (!Super::FloorBounceMissile (plane)) { - if (abs (vel.z) < (FRACUNIT/2)) + if (fabs (Vel.Z) < 0.5) { Destroy (); } @@ -29,13 +29,13 @@ IMPLEMENT_CLASS(AGlassShard) // Dirt stuff -void P_SpawnDirt (AActor *actor, fixed_t radius) +void P_SpawnDirt (AActor *actor, double radius) { PClassActor *dtype = NULL; AActor *mo; - fixed_t zo = (pr_dirt() << 9) + FRACUNIT; - fixedvec3 pos = actor->Vec3Angle(radius, pr_dirt() << 24, zo); + double zo = pr_dirt() / 128. + 1; + DVector3 pos = actor->Vec3Angle(radius, pr_dirt() * (360./256), zo); char fmt[8]; mysnprintf(fmt, countof(fmt), "Dirt%d", 1 + pr_dirt()%6); @@ -45,7 +45,7 @@ void P_SpawnDirt (AActor *actor, fixed_t radius) mo = Spawn (dtype, pos, ALLOW_REPLACE); if (mo) { - mo->vel.z = pr_dirt()<<10; + mo->Vel.Z = pr_dirt() / 64.; } } } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index d37250887..bcab12b4a 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -92,7 +92,7 @@ DBaseDecal::DBaseDecal (int statnum, fixed_t z) DBaseDecal::DBaseDecal (const AActor *basis) : DThinker(STAT_DECAL), - WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->Z()), ScaleX(basis->scaleX), ScaleY(basis->scaleY), + WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->_f_Z()), ScaleX(FLOAT2FIXED(basis->Scale.X)), ScaleY(FLOAT2FIXED(basis->Scale.Y)), Alpha(basis->alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum), RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle) { @@ -414,7 +414,7 @@ static void GetWallStuff (side_t *wall, vertex_t *&v1, fixed_t &ldx, fixed_t &ld static fixed_t Length (fixed_t dx, fixed_t dy) { - return (fixed_t)sqrt ((double)dx*(double)dx+(double)dy*(double)dy); + return (fixed_t)g_sqrt ((double)dx*(double)dx+(double)dy*(double)dy); } static side_t *NextWall (const side_t *wall) @@ -820,22 +820,22 @@ void ADecal::BeginPlay () { if (!tpl->PicNum.Exists()) { - Printf("Decal actor at (%d,%d) does not have a valid texture\n", X()>>FRACBITS, Y()>>FRACBITS); + Printf("Decal actor at (%f,%f) does not have a valid texture\n", X(), Y()); } else { // Look for a wall within 64 units behind the actor. If none can be // found, then no decal is created, and this actor is destroyed // without effectively doing anything. - if (NULL == ShootDecal(tpl, this, Sector, X(), Y(), Z(), angle + ANGLE_180, 64*FRACUNIT, true)) + if (NULL == ShootDecal(tpl, this, Sector, _f_X(), _f_Y(), _f_Z(), FLOAT2ANGLE(Angles.Yaw.Degrees) + ANGLE_180, 64*FRACUNIT, true)) { - DPrintf ("Could not find a wall to stick decal to at (%d,%d)\n", X()>>FRACBITS, Y()>>FRACBITS); + DPrintf ("Could not find a wall to stick decal to at (%f,%f)\n", X(), Y()); } } } else { - DPrintf ("Decal actor at (%d,%d) does not have a good template\n", X()>>FRACBITS, Y()>>FRACBITS); + DPrintf ("Decal actor at (%f,%f) does not have a good template\n", X(), Y()); } // This actor doesn't need to stick around anymore. Destroy(); diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index bf35157b3..e71f809aa 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -28,7 +28,7 @@ void AFastProjectile::Tick () int changexy; ClearInterpolation(); - fixed_t oldz = Z(); + fixed_t oldz = _f_Z(); if (!(flags5 & MF5_NOTIMEFREEZE)) { @@ -45,9 +45,9 @@ void AFastProjectile::Tick () int shift = 3; int count = 8; - if (radius > 0) + if (_f_radius() > 0) { - while ( ((abs(vel.x) >> shift) > radius) || ((abs(vel.y) >> shift) > radius)) + while ( ((abs(_f_velx()) >> shift) > _f_radius()) || ((abs(_f_vely()) >> shift) > _f_radius())) { // we need to take smaller steps. shift++; @@ -56,11 +56,11 @@ void AFastProjectile::Tick () } // Handle movement - if (vel.x || vel.y || (Z() != floorz) || vel.z) + if (!Vel.isZero() || (Z() != floorz)) { - xfrac = vel.x >> shift; - yfrac = vel.y >> shift; - zfrac = vel.z >> shift; + xfrac = _f_velx() >> shift; + yfrac = _f_vely() >> shift; + zfrac = _f_velz() >> shift; changexy = xfrac || yfrac; int ripcount = count >> 3; for (i = 0; i < count; i++) @@ -72,14 +72,14 @@ void AFastProjectile::Tick () tm.LastRipped.Clear(); // [RH] Do rip damage each step, like Hexen } - if (!P_TryMove (this, X() + xfrac,Y() + yfrac, true, NULL, tm)) + if (!P_TryMove (this, _f_X() + xfrac,_f_Y() + yfrac, true, NULL, tm)) { // Blocked move if (!(flags3 & MF3_SKYEXPLODE)) { if (tm.ceilingline && tm.ceilingline->backsector && tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum && - Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(PosRelative(tm.ceilingline))) + _f_Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(PosRelative(tm.ceilingline))) { // Hack to prevent missiles exploding against the sky. // Does not handle sky floors. @@ -98,9 +98,9 @@ void AFastProjectile::Tick () return; } } - AddZ(zfrac); + _f_AddZ(zfrac); UpdateWaterLevel (oldz); - oldz = Z(); + oldz = _f_Z(); if (Z() <= floorz) { // Hit the floor @@ -126,7 +126,7 @@ void AFastProjectile::Tick () return; } - SetZ(ceilingz - height); + SetZ(ceilingz - Height); P_ExplodeMissile (this, NULL, NULL); return; } @@ -156,28 +156,25 @@ void AFastProjectile::Tick () void AFastProjectile::Effect() { - //if (pr_smoke() < 128) // [RH] I think it looks better if it's consistent + FName name = GetClass()->MissileName; + if (name != NAME_None) { - FName name = GetClass()->MissileName; - if (name != NAME_None) - { - fixed_t hitz = Z()-8*FRACUNIT; + double hitz = Z()-8; - if (hitz < floorz) - { - hitz = floorz; - } - // Do not clip this offset to the floor. - hitz += GetClass()->MissileHeight; + if (hitz < floorz) + { + hitz = floorz; + } + // Do not clip this offset to the floor. + hitz += GetClass()->MissileHeight; - PClassActor *trail = PClass::FindActor(name); - if (trail != NULL) + PClassActor *trail = PClass::FindActor(name); + if (trail != NULL) + { + AActor *act = Spawn (trail, PosAtZ(hitz), ALLOW_REPLACE); + if (act != NULL) { - AActor *act = Spawn (trail, X(), Y(), hitz, ALLOW_REPLACE); - if (act != NULL) - { - act->angle = this->angle; - } + act->Angles.Yaw = Angles.Yaw; } } } diff --git a/src/g_shared/a_hatetarget.cpp b/src/g_shared/a_hatetarget.cpp index 53cec29f9..4d0d9a8e7 100644 --- a/src/g_shared/a_hatetarget.cpp +++ b/src/g_shared/a_hatetarget.cpp @@ -40,22 +40,20 @@ class AHateTarget : public AActor { - DECLARE_CLASS (AHateTarget, AActor) + DECLARE_CLASS(AHateTarget, AActor) public: - void BeginPlay (); - int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype); + void BeginPlay(); + int TakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype); }; -IMPLEMENT_CLASS (AHateTarget) +IMPLEMENT_CLASS(AHateTarget) -void AHateTarget::BeginPlay () +void AHateTarget::BeginPlay() { - Super::BeginPlay (); - if (angle != 0) + Super::BeginPlay(); + if (SpawnAngle != 0) { // Each degree translates into 10 units of health - health = Scale (angle >> 1, 1800, 0x40000000); - // Round to the nearest 10 because of inaccuracy above - health = (health + 5) / 10 * 10; + health = SpawnAngle * 10; } else { @@ -64,7 +62,7 @@ void AHateTarget::BeginPlay () } } -int AHateTarget::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype) +int AHateTarget::TakeSpecialDamage(AActor *inflictor, AActor *source, int damage, FName damagetype) { if (special2 != 0) { diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index acd5f6f5c..33d25e638 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -88,7 +88,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp actor->RemoveFromHash (); actor->tid = 0; } - morphed->angle = actor->angle; + morphed->Angles.Yaw = actor->Angles.Yaw; morphed->target = actor->target; morphed->tracer = actor; morphed->Score = actor->Score; @@ -120,7 +120,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassPlayerPawn *spawntyp p->MorphExitFlash = (exit_flash) ? exit_flash : RUNTIME_CLASS(ATeleportFog); p->health = morphed->health; p->mo = morphed; - p->vel.x = p->vel.y = 0; + p->Vel.X = p->Vel.Y = 0; morphed->ObtainInventory (actor); // Remove all armor for (item = morphed->Inventory; item != NULL; ) @@ -223,15 +223,13 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, mo->tid = pmo->tid; mo->AddToHash (); } - mo->angle = pmo->angle; + mo->Angles.Yaw = pmo->Angles.Yaw; mo->player = player; mo->reactiontime = 18; mo->flags = ActorFlags::FromInt (pmo->special2) & ~MF_JUSTHIT; - mo->vel.x = 0; - mo->vel.y = 0; - player->vel.x = 0; - player->vel.y = 0; - mo->vel.z = pmo->vel.z; + mo->Vel.X = mo->Vel.Y = 0; + player->Vel.Zero(); + mo->Vel.Z = pmo->Vel.Z; if (!(pmo->special2 & MF_JUSTHIT)) { mo->renderflags &= ~RF_INVISIBLE; @@ -307,7 +305,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, } } - angle = mo->angle >> ANGLETOFINESHIFT; + angle = mo->_f_angle() >> ANGLETOFINESHIFT; AActor *eflash = NULL; if (exit_flash != NULL) { @@ -385,7 +383,7 @@ bool P_MorphMonster (AActor *actor, PClassActor *spawntype, int duration, int st morphed = static_cast(Spawn (spawntype, actor->Pos(), NO_REPLACE)); DObject::StaticPointerSubstitution (actor, morphed); morphed->tid = actor->tid; - morphed->angle = actor->angle; + morphed->Angles.Yaw = actor->Angles.Yaw; morphed->UnmorphedMe = actor; morphed->alpha = actor->alpha; morphed->RenderStyle = actor->RenderStyle; @@ -450,7 +448,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force) beast->UnmorphTime = level.time + 5*TICRATE; // Next try in 5 seconds return false; } - actor->angle = beast->angle; + actor->Angles.Yaw = beast->Angles.Yaw; actor->target = beast->target; actor->FriendPlayer = beast->FriendPlayer; actor->flags = beast->FlagsSave & ~MF_JUSTHIT; @@ -461,9 +459,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force) if (!(beast->FlagsSave & MF_JUSTHIT)) actor->renderflags &= ~RF_INVISIBLE; actor->health = actor->SpawnHealth(); - actor->vel.x = beast->vel.x; - actor->vel.y = beast->vel.y; - actor->vel.z = beast->vel.z; + actor->Vel = beast->Vel; actor->tid = beast->tid; actor->special = beast->special; actor->Score = beast->Score; diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index b67e7f8e3..73c49167a 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -102,11 +102,7 @@ void AInterpolationPoint::FormChain () if (Next == NULL && (args[3] | args[4])) Printf ("Can't find target for camera node %d\n", tid); - pitch = (signed int)((char)args[0]) * ANGLE_1; - if (pitch <= -ANGLE_90) - pitch = -ANGLE_90 + ANGLE_1; - else if (pitch >= ANGLE_90) - pitch = ANGLE_90 - ANGLE_1; + Angles.Pitch = (double)clamp((signed char)args[0], -89, 89); if (Next != NULL) Next->FormChain (); @@ -302,7 +298,7 @@ void APathFollower::Tick () if (CurrNode->args[2]) { HoldTime = level.time + CurrNode->args[2] * TICRATE / 8; - SetXYZ(CurrNode->X(), CurrNode->Y(), CurrNode->Z()); + SetXYZ(CurrNode->_f_X(), CurrNode->_f_Y(), CurrNode->_f_Z()); } } @@ -360,9 +356,9 @@ bool APathFollower::Interpolate () if ((args[2] & 8) && Time > 0.f) { - dx = X(); - dy = Y(); - dz = Z(); + dx = _f_X(); + dy = _f_Y(); + dz = _f_Z(); } if (CurrNode->Next==NULL) return false; @@ -371,20 +367,20 @@ bool APathFollower::Interpolate () fixed_t x, y, z; if (args[2] & 1) { // linear - x = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->X()), FIXED2DBL(CurrNode->Next->X()))); - y = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->Y()), FIXED2DBL(CurrNode->Next->Y()))); - z = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->Z()), FIXED2DBL(CurrNode->Next->Z()))); + x = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->_f_X()), FIXED2DBL(CurrNode->Next->_f_X()))); + y = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->_f_Y()), FIXED2DBL(CurrNode->Next->_f_Y()))); + z = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->_f_Z()), FIXED2DBL(CurrNode->Next->_f_Z()))); } else { // spline if (CurrNode->Next->Next==NULL) return false; - x = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->X()), FIXED2DBL(CurrNode->X()), - FIXED2DBL(CurrNode->Next->X()), FIXED2DBL(CurrNode->Next->Next->X()))); - y = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->Y()), FIXED2DBL(CurrNode->Y()), - FIXED2DBL(CurrNode->Next->Y()), FIXED2DBL(CurrNode->Next->Next->Y()))); - z = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->Z()), FIXED2DBL(CurrNode->Z()), - FIXED2DBL(CurrNode->Next->Z()), FIXED2DBL(CurrNode->Next->Next->Z()))); + x = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->_f_X()), FIXED2DBL(CurrNode->_f_X()), + FIXED2DBL(CurrNode->Next->_f_X()), FIXED2DBL(CurrNode->Next->Next->_f_X()))); + y = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->_f_Y()), FIXED2DBL(CurrNode->_f_Y()), + FIXED2DBL(CurrNode->Next->_f_Y()), FIXED2DBL(CurrNode->Next->Next->_f_Y()))); + z = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->_f_Z()), FIXED2DBL(CurrNode->_f_Z()), + FIXED2DBL(CurrNode->Next->_f_Z()), FIXED2DBL(CurrNode->Next->Next->_f_Z()))); } SetXYZ(x, y, z); LinkToWorld (); @@ -395,9 +391,9 @@ bool APathFollower::Interpolate () { if (args[2] & 1) { // linear - dx = CurrNode->Next->X() - CurrNode->X(); - dy = CurrNode->Next->Y() - CurrNode->Y(); - dz = CurrNode->Next->Z() - CurrNode->Z(); + dx = CurrNode->Next->_f_X() - CurrNode->_f_X(); + dy = CurrNode->Next->_f_Y() - CurrNode->_f_Y(); + dz = CurrNode->Next->_f_Z() - CurrNode->_f_Z(); } else if (Time > 0.f) { // spline @@ -426,66 +422,38 @@ bool APathFollower::Interpolate () } if (args[2] & 2) { // adjust yaw - angle = R_PointToAngle2 (0, 0, dx, dy); + Angles.Yaw = VecToAngle(dx, dy); } if (args[2] & 4) { // adjust pitch; use floats for precision double fdx = FIXED2DBL(dx); double fdy = FIXED2DBL(dy); double fdz = FIXED2DBL(-dz); - double dist = sqrt (fdx*fdx + fdy*fdy); - double ang = dist != 0.f ? atan2 (fdz, dist) : 0; - pitch = (fixed_t)RAD2ANGLE(ang); + double dist = g_sqrt (fdx*fdx + fdy*fdy); + Angles.Pitch = dist != 0.f ? VecToAngle(dist, fdz) : 0.; } } else { if (args[2] & 2) { // interpolate angle - double angle1 = (double)CurrNode->angle; - double angle2 = (double)CurrNode->Next->angle; - if (angle2 - angle1 <= -2147483648.f) - { - double lerped = Lerp (angle1, angle2 + 4294967296.f); - if (lerped >= 4294967296.f) - { - angle = xs_CRoundToUInt(lerped - 4294967296.f); - } - else - { - angle = xs_CRoundToUInt(lerped); - } - } - else if (angle2 - angle1 >= 2147483648.f) - { - double lerped = Lerp (angle1, angle2 - 4294967296.f); - if (lerped < 0.f) - { - angle = xs_CRoundToUInt(lerped + 4294967296.f); - } - else - { - angle = xs_CRoundToUInt(lerped); - } - } - else - { - angle = xs_CRoundToUInt(Lerp (angle1, angle2)); - } + DAngle angle1 = CurrNode->Angles.Yaw.Normalized180(); + DAngle angle2 = angle1 + deltaangle(angle1, CurrNode->Next->Angles.Yaw); + Angles.Yaw = Lerp(angle1.Degrees, angle2.Degrees); } if (args[2] & 1) { // linear if (args[2] & 4) { // interpolate pitch - pitch = FLOAT2FIXED(Lerp (FIXED2DBL(CurrNode->pitch), FIXED2DBL(CurrNode->Next->pitch))); + Angles.Pitch = Lerp(CurrNode->Angles.Pitch.Degrees, CurrNode->Next->Angles.Pitch.Degrees); } } else { // spline if (args[2] & 4) { // interpolate pitch - pitch = FLOAT2FIXED(Splerp (FIXED2DBL(PrevNode->pitch), FIXED2DBL(CurrNode->pitch), - FIXED2DBL(CurrNode->Next->pitch), FIXED2DBL(CurrNode->Next->Next->pitch))); + Angles.Pitch = Splerp(PrevNode->Angles.Pitch.Degrees, CurrNode->Angles.Pitch.Degrees, + CurrNode->Next->Angles.Pitch.Degrees, CurrNode->Next->Next->Angles.Pitch.Degrees); } } } @@ -549,18 +517,18 @@ bool AActorMover::Interpolate () if (Super::Interpolate ()) { - fixed_t savedz = tracer->Z(); - tracer->SetZ(Z()); - if (!P_TryMove (tracer, X(), Y(), true)) + fixed_t savedz = tracer->_f_Z(); + tracer->_f_SetZ(_f_Z()); + if (!P_TryMove (tracer, _f_X(), _f_Y(), true)) { - tracer->SetZ(savedz); + tracer->_f_SetZ(savedz); return false; } if (args[2] & 2) - tracer->angle = angle; + tracer->Angles.Yaw = Angles.Yaw; if (args[2] & 4) - tracer->pitch = pitch; + tracer->Angles.Pitch = Angles.Pitch; return true; } @@ -665,16 +633,15 @@ bool AMovingCamera::Interpolate () if (Super::Interpolate ()) { - angle = AngleTo(tracer, true); + Angles.Yaw = AngleTo(tracer, true); if (args[2] & 4) { // Also aim camera's pitch; use floats for precision - double dx = FIXED2DBL(X() - tracer->X()); - double dy = FIXED2DBL(Y() - tracer->Y()); - double dz = FIXED2DBL(Z() - tracer->Z() - tracer->height/2); - double dist = sqrt (dx*dx + dy*dy); - double ang = dist != 0.f ? atan2 (dz, dist) : 0; - pitch = RAD2ANGLE(ang); + double dx = FIXED2DBL(_f_X() - tracer->_f_X()); + double dy = FIXED2DBL(_f_Y() - tracer->_f_Y()); + double dz = FIXED2DBL(_f_Z() - tracer->_f_Z() - tracer->_f_height()/2); + double dist = g_sqrt (dx*dx + dy*dy); + Angles.Pitch = dist != 0.f ? VecToAngle(dist, dz) : 0.; } return true; diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index b2a80cbc2..2aea9fa14 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -421,20 +421,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) self->UnlinkFromWorld(); self->SetXY(_x, _y); self->LinkToWorld(true); - self->SetZ(self->Sector->floorplane.ZatPoint(_x, _y)); + self->_f_SetZ(self->Sector->floorplane.ZatPoint(_x, _y)); P_FindFloorCeiling(self, FFCF_ONLYSPAWNPOS | FFCF_NOPORTALS); // no portal checks here so that things get spawned in this sector. if (self->flags & MF_SPAWNCEILING) { - self->SetZ(self->ceilingz - self->height - self->SpawnPoint[2]); + self->_f_SetZ(self->_f_ceilingz() - self->_f_height() - self->SpawnPoint[2]); } else if (self->flags2 & MF2_SPAWNFLOAT) { - fixed_t space = self->ceilingz - self->height - self->floorz; - if (space > 48*FRACUNIT) + double space = self->ceilingz - self->Height - self->floorz; + if (space > 48) { - space -= 40*FRACUNIT; - self->SetZ(((space * pr_restore())>>8) + self->floorz + 40*FRACUNIT); + space -= 40; + self->SetZ((space * pr_restore()) / 256. + self->floorz + 40); } else { @@ -443,7 +443,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) } else { - self->SetZ(self->SpawnPoint[2] + self->floorz); + self->_f_SetZ(self->SpawnPoint[2] + self->_f_floorz()); } // Redo floor/ceiling check, in case of 3D floors and portals P_FindFloorCeiling(self, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); @@ -454,7 +454,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition) } if ((self->flags & MF_SOLID) && (self->Top() > self->ceilingz)) { // Do the same for the ceiling. - self->SetZ(self->ceilingz - self->height); + self->SetZ(self->ceilingz - self->Height); } // Do not interpolate from the position the actor was at when it was // picked up, in case that is different from where it is now. @@ -790,7 +790,7 @@ AInventory *AInventory::CreateTossable () flags &= ~(MF_SPECIAL|MF_SOLID); return this; } - copy = static_cast(Spawn (GetClass(), Owner->Pos(), NO_REPLACE)); + copy = static_cast(Spawn (GetClass(), Owner->_f_Pos(), NO_REPLACE)); if (copy != NULL) { copy->MaxAmount = MaxAmount; @@ -902,7 +902,7 @@ void AInventory::ModifyDamage (int damage, FName damageType, int &newdamage, boo // //=========================================================================== -fixed_t AInventory::GetSpeedFactor () +double AInventory::GetSpeedFactor () { if (Inventory != NULL) { @@ -910,7 +910,7 @@ fixed_t AInventory::GetSpeedFactor () } else { - return FRACUNIT; + return 1.; } } @@ -1354,7 +1354,7 @@ bool AInventory::DoRespawn () if (spot != NULL) { SetOrigin (spot->Pos(), false); - SetZ(floorz); + _f_SetZ(_f_floorz()); } } return true; diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 933b235dd..67ec3d8c9 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -207,7 +207,7 @@ public: virtual void AbsorbDamage (int damage, FName damageType, int &newdamage); virtual void ModifyDamage (int damage, FName damageType, int &newdamage, bool passive); - virtual fixed_t GetSpeedFactor(); + virtual double GetSpeedFactor(); virtual bool GetNoTeleportFreeze(); virtual int AlterWeaponSprite (visstyle_t *vis); diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 2e1c5fa16..62c477595 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -132,7 +132,7 @@ void DEarthquake::Tick () fixed_t dist; dist = m_Spot->AproxDistance (victim, true); - // Check if in damage radius + // Check if in damage _f_radius() if (dist < m_DamageRadius && victim->Z() <= victim->floorz) { if (pr_quake() < 50) @@ -140,19 +140,9 @@ void DEarthquake::Tick () P_DamageMobj (victim, NULL, NULL, pr_quake.HitDice (1), NAME_None); } // Thrust player around - angle_t an = victim->angle + ANGLE_1*pr_quake(); - if (m_IntensityX == m_IntensityY) - { // Thrust in a circle - P_ThrustMobj (victim, an, m_IntensityX/2); - } - else - { // Thrust in an ellipse - an >>= ANGLETOFINESHIFT; - // So this is actually completely wrong, but it ought to be good - // enough. Otherwise, I'd have to use tangents and square roots. - victim->vel.x += FixedMul(m_IntensityX/2, finecosine[an]); - victim->vel.y += FixedMul(m_IntensityY/2, finesine[an]); - } + DAngle an = victim->Angles.Yaw + pr_quake(); + victim->Vel.X += FIXED2DBL(m_IntensityX) * an.Cos() * 0.5; + victim->Vel.Y += FIXED2DBL(m_IntensityY) * an.Sin() * 0.5; } } } @@ -175,7 +165,7 @@ fixed_t DEarthquake::GetModWave(double waveMultiplier) const //Named waveMultiplier because that's as the name implies: adds more waves per second. double time = m_Countdown - FIXED2DBL(r_TicFrac); - return FLOAT2FIXED(sin(waveMultiplier * time * (M_PI * 2 / TICRATE))); + return FLOAT2FIXED(g_sin(waveMultiplier * time * (M_PI * 2 / TICRATE))); } //========================================================================== diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp index 5784197a2..241cb1b14 100644 --- a/src/g_shared/a_randomspawner.cpp +++ b/src/g_shared/a_randomspawner.cpp @@ -114,7 +114,7 @@ class ARandomSpawner : public AActor { Species = cls->TypeName; AActor *defmobj = GetDefaultByType(cls); - this->Speed = defmobj->Speed; + this->Speed = defmobj->Speed; this->flags |= (defmobj->flags & MF_MISSILE); this->flags2 |= (defmobj->flags2 & MF2_SEEKERMISSILE); this->flags4 |= (defmobj->flags4 & MF4_SPECTRAL); @@ -151,7 +151,7 @@ class ARandomSpawner : public AActor { tracer = target->target; } - newmobj = P_SpawnMissileXYZ(Pos(), target, target->target, cls, false); + newmobj = P_SpawnMissileXYZ(_f_Pos(), target, target->target, cls, false); } else { @@ -160,7 +160,8 @@ class ARandomSpawner : public AActor if (newmobj != NULL) { // copy everything relevant - newmobj->SpawnAngle = newmobj->angle = angle; + newmobj->SpawnAngle = SpawnAngle; + newmobj->Angles = Angles; newmobj->SpawnPoint[2] = SpawnPoint[2]; newmobj->special = special; newmobj->args[0] = args[0]; @@ -175,9 +176,7 @@ class ARandomSpawner : public AActor newmobj->SpawnFlags = SpawnFlags; newmobj->tid = tid; newmobj->AddToHash(); - newmobj->vel.x = vel.x; - newmobj->vel.y = vel.y; - newmobj->vel.z = vel.z; + newmobj->Vel = Vel; newmobj->master = master; // For things such as DamageMaster/DamageChildren, transfer mastery. newmobj->target = target; newmobj->tracer = tracer; @@ -189,17 +188,17 @@ class ARandomSpawner : public AActor // Handle special altitude flags if (newmobj->flags & MF_SPAWNCEILING) { - newmobj->SetZ(newmobj->ceilingz - newmobj->height - SpawnPoint[2]); + newmobj->_f_SetZ(newmobj->_f_ceilingz() - newmobj->_f_height() - SpawnPoint[2]); } else if (newmobj->flags2 & MF2_SPAWNFLOAT) { - fixed_t space = newmobj->ceilingz - newmobj->height - newmobj->floorz; - if (space > 48*FRACUNIT) + double space = newmobj->ceilingz - newmobj->Height - newmobj->floorz; + if (space > 48) { - space -= 40*FRACUNIT; - newmobj->SetZ(MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT); + space -= 40; + newmobj->SetZ((space * pr_randomspawn()) / 256. + newmobj->floorz + 40); } - newmobj->AddZ(SpawnPoint[2]); + newmobj->_f_AddZ(SpawnPoint[2]); } if (newmobj->flags & MF_MISSILE) P_CheckMissileSpawn(newmobj, 0); diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 1e59bf740..ff08a04d9 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -9,7 +9,7 @@ struct vertex_t; struct side_t; struct F3DFloor; -void P_SpawnDirt (AActor *actor, fixed_t radius); +void P_SpawnDirt (AActor *actor, double radius); class DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *sec, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t tracedist, bool permanent); class DBaseDecal : public DThinker diff --git a/src/g_shared/a_spark.cpp b/src/g_shared/a_spark.cpp index 7e7aa1f8e..557abe5a2 100644 --- a/src/g_shared/a_spark.cpp +++ b/src/g_shared/a_spark.cpp @@ -50,6 +50,6 @@ IMPLEMENT_CLASS (ASpark) void ASpark::Activate (AActor *activator) { Super::Activate (activator); - P_DrawSplash (args[0] ? args[0] : 32, X(), Y(), Z(), angle, 1); + P_DrawSplash (args[0] ? args[0] : 32, _f_X(), _f_Y(), _f_Z(), FLOAT2ANGLE(Angles.Yaw.Degrees), 1); S_Sound (this, CHAN_AUTO, "world/spark", 1, ATTN_STATIC); } diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index 8dfefb311..a0469fb40 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -149,17 +149,17 @@ struct FSpotList // //---------------------------------------------------------------------------- - ASpecialSpot *GetSpotWithMinMaxDistance(fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist) + ASpecialSpot *GetSpotWithMinMaxDistance(double x, double y, double mindist, double maxdist) { if (Spots.Size() == 0) return NULL; int i = pr_spot() % Spots.Size(); int initial = i; - fixed_t distance; + double distance; while (true) { - distance = Spots[i]->AproxDistance(x, y); + distance = Spots[i]->Distance2D(x, y); if ((distance >= mindist) && ((maxdist == 0) || (distance <= maxdist))) break; @@ -337,7 +337,7 @@ ASpecialSpot *DSpotState::GetNextInList(const PClass *type, int skipcounter) // //---------------------------------------------------------------------------- -ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist) +ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, double x, double y, double mindist, double maxdist) { FSpotList *list = FindSpotList(type); if (list != NULL) return list->GetSpotWithMinMaxDistance(x, y, mindist, maxdist); diff --git a/src/g_shared/a_specialspot.h b/src/g_shared/a_specialspot.h index 937814280..db148b19d 100644 --- a/src/g_shared/a_specialspot.h +++ b/src/g_shared/a_specialspot.h @@ -36,7 +36,7 @@ public: bool RemoveSpot(ASpecialSpot *spot); void Serialize(FArchive &arc); ASpecialSpot *GetNextInList(const PClass *type, int skipcounter); - ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, fixed_t x, fixed_t y, fixed_t mindist, fixed_t maxdist); + ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, double x, double y, double mindist, double maxdist); ASpecialSpot *GetRandomSpot(const PClass *type, bool onlyonce = false); }; diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index 2eaabc7f7..b26541c99 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -338,9 +338,6 @@ bool FMugShot::SetState(const char *state_name, bool wait_till_done, bool reset) CVAR(Bool,st_oldouch,false,CVAR_ARCHIVE) int FMugShot::UpdateState(player_t *player, StateFlags stateflags) { - int i; - angle_t badguyangle; - angle_t diffang; FString full_state_name; if (player->health > 0) @@ -366,25 +363,14 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) if (player->mo != NULL) { // The next 12 lines are from the Doom statusbar code. - badguyangle = player->mo->AngleTo(player->attacker); - if (badguyangle > player->mo->angle) - { - // whether right or left - diffang = badguyangle - player->mo->angle; - i = diffang > ANG180; - } - else - { - // whether left or right - diffang = player->mo->angle - badguyangle; - i = diffang <= ANG180; - } // confusing, aint it? - if (i && diffang >= ANG45) - { + DAngle badguyangle = player->mo->AngleTo(player->attacker); + DAngle diffang = deltaangle(player->mo->Angles.Yaw, badguyangle); + if (diffang > 45.) + { // turn face right damage_angle = 0; } - else if (!i && diffang >= ANG45) - { + else if (diffang < -45.) + { // turn face left damage_angle = 2; } } diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index e08fb1a20..78b7bc859 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -310,8 +310,8 @@ class CommandDrawImage : public SBarInfoCommandFlowControl if (applyscale) { - spawnScaleX = FIXED2DBL(item->scaleX); - spawnScaleY = FIXED2DBL(item->scaleY); + spawnScaleX = item->Scale.X; + spawnScaleY = item->Scale.Y; } texture = TexMan[icon]; diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 821008456..e6f3420b0 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -828,9 +828,9 @@ static void DrawCoordinates(player_t * CPlayer) if (!map_point_coordinates || !automapactive) { - x=CPlayer->mo->X(); - y=CPlayer->mo->Y(); - z=CPlayer->mo->Z(); + x=CPlayer->mo->_f_X(); + y=CPlayer->mo->_f_Y(); + z=CPlayer->mo->_f_Z(); } else { diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index d0153a98f..781ca915e 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1286,7 +1286,7 @@ void DBaseStatusBar::Draw (EHudState state) y -= height * 2; } - fixedvec3 pos = CPlayer->mo->Pos(); + fixedvec3 pos = CPlayer->mo->_f_Pos(); for (i = 2, value = &pos.z; i >= 0; y -= height, --value, --i) { mysnprintf (line, countof(line), "%c: %d", labels[i], *value >> FRACBITS); diff --git a/src/g_strife/a_alienspectres.cpp b/src/g_strife/a_alienspectres.cpp index 53ab1b42a..de95de431 100644 --- a/src/g_strife/a_alienspectres.cpp +++ b/src/g_strife/a_alienspectres.cpp @@ -29,12 +29,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkSmall) int t; t = pr_spectrechunk() & 15; - foo->vel.x = (t - (pr_spectrechunk() & 7)) << FRACBITS; + foo->Vel.X = (t - (pr_spectrechunk() & 7)); t = pr_spectrechunk() & 15; - foo->vel.y = (t - (pr_spectrechunk() & 7)) << FRACBITS; + foo->Vel.Y = (t - (pr_spectrechunk() & 7)); - foo->vel.z = (pr_spectrechunk() & 15) << FRACBITS; + foo->Vel.Z = (pr_spectrechunk() & 15); } return 0; } @@ -50,12 +50,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkLarge) int t; t = pr_spectrechunk() & 7; - foo->vel.x = (t - (pr_spectrechunk() & 15)) << FRACBITS; + foo->Vel.X = (t - (pr_spectrechunk() & 15)); t = pr_spectrechunk() & 7; - foo->vel.y = (t - (pr_spectrechunk() & 15)) << FRACBITS; + foo->Vel.Y = (t - (pr_spectrechunk() & 15)); - foo->vel.z = (pr_spectrechunk() & 7) << FRACBITS; + foo->Vel.Z = (pr_spectrechunk() & 7); } return 0; } @@ -69,18 +69,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_Spectre3Attack) AActor *foo = Spawn("SpectralLightningV2", self->PosPlusZ(32*FRACUNIT), ALLOW_REPLACE); - foo->vel.z = -12*FRACUNIT; + foo->Vel.Z = -12; foo->target = self; foo->FriendPlayer = 0; foo->tracer = self->target; - self->angle -= ANGLE_180 / 20 * 10; + self->Angles.Yaw -= 90.; for (int i = 0; i < 20; ++i) { - self->angle += ANGLE_180 / 20; + self->Angles.Yaw += 9.; P_SpawnSubMissile (self, PClass::FindActor("SpectralLightningBall2"), self); } - self->angle -= ANGLE_180 / 20 * 10; + self->Angles.Yaw -= 90.; return 0; } diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp index a7b2ac23c..9fef47f09 100644 --- a/src/g_strife/a_crusader.cpp +++ b/src/g_strife/a_crusader.cpp @@ -28,20 +28,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose) if (CrusaderCheckRange (self)) { A_FaceTarget (self); - self->angle -= ANGLE_180/16; - P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); + self->Angles.Yaw -= 180./16; + P_SpawnMissileZAimed (self, self->_f_Z() + 40*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); } else { if (P_CheckMissileRange (self)) { A_FaceTarget (self); - P_SpawnMissileZAimed (self, self->Z() + 56*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); - self->angle -= ANGLE_45/32; - P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); - self->angle += ANGLE_45/16; - P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); - self->angle -= ANGLE_45/16; + P_SpawnMissileZAimed (self, self->_f_Z() + 56*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); + self->Angles.Yaw -= 45./32; + P_SpawnMissileZAimed (self, self->_f_Z() + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); + self->Angles.Yaw += 45./16; + P_SpawnMissileZAimed (self, self->_f_Z() + 40*FRACUNIT, self->target, PClass::FindActor("CrusaderMissile")); + self->Angles.Yaw -= 45./16; self->reactiontime += 15; } self->SetState (self->SeeState); @@ -53,11 +53,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepLeft) { PARAM_ACTION_PROLOGUE; - self->angle += ANGLE_90/16; - AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); + self->Angles.Yaw += 90./16; + AActor *misl = P_SpawnMissileZAimed (self, self->_f_Z() + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); if (misl != NULL) { - misl->vel.z += FRACUNIT; + misl->Vel.Z += 1; } return 0; } @@ -66,11 +66,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepRight) { PARAM_ACTION_PROLOGUE; - self->angle -= ANGLE_90/16; - AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); + self->Angles.Yaw -= 90./16; + AActor *misl = P_SpawnMissileZAimed (self, self->_f_Z() + 48*FRACUNIT, self->target, PClass::FindActor("FastFlameMissile")); if (misl != NULL) { - misl->vel.z += FRACUNIT; + misl->Vel.Z += 1; } return 0; } diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp index 3195d3813..2913a7f8a 100644 --- a/src/g_strife/a_entityboss.cpp +++ b/src/g_strife/a_entityboss.cpp @@ -81,9 +81,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnEntity) AActor *entity = Spawn("EntityBoss", self->PosPlusZ(70*FRACUNIT), ALLOW_REPLACE); if (entity != NULL) { - entity->angle = self->angle; + entity->Angles.Yaw = self->Angles.Yaw; entity->CopyFriendliness(self, true); - entity->vel.z = 5*FRACUNIT; + entity->Vel.Z = 5; entity->tracer = self; } return 0; @@ -94,39 +94,23 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath) PARAM_ACTION_PROLOGUE; AActor *second; - fixed_t secondRadius = GetDefaultByName("EntitySecond")->radius * 2; - angle_t an; + double secondRadius = FIXED2DBL(GetDefaultByName("EntitySecond")->_f_radius() * 2); + + static const double turns[3] = { 0, 90, -90 }; + const double velmul[3] = { 4.8828125f, secondRadius*4, secondRadius*4 }; AActor *spot = self->tracer; if (spot == NULL) spot = self; - fixedvec3 pos = spot->Vec3Angle(secondRadius, self->angle, self->tracer? 70*FRACUNIT : 0); - - an = self->angle >> ANGLETOFINESHIFT; - second = Spawn("EntitySecond", pos, ALLOW_REPLACE); - second->CopyFriendliness(self, true); - //second->target = self->target; - A_FaceTarget (second); - an = second->angle >> ANGLETOFINESHIFT; - second->vel.x += FixedMul (finecosine[an], 320000); - second->vel.y += FixedMul (finesine[an], 320000); + for (int i = 0; i < 3; i++) + { + DAngle an = self->Angles.Yaw + turns[i]; + DVector3 pos = spot->Vec3Angle(secondRadius, an, self->tracer ? 70. : 0.); - pos = spot->Vec3Angle(secondRadius, self->angle + ANGLE_90, self->tracer? 70*FRACUNIT : 0); - an = (self->angle + ANGLE_90) >> ANGLETOFINESHIFT; - second = Spawn("EntitySecond", pos, ALLOW_REPLACE); - second->CopyFriendliness(self, true); - //second->target = self->target; - second->vel.x = FixedMul (secondRadius, finecosine[an]) << 2; - second->vel.y = FixedMul (secondRadius, finesine[an]) << 2; - A_FaceTarget (second); - - pos = spot->Vec3Angle(secondRadius, self->angle - ANGLE_90, self->tracer? 70*FRACUNIT : 0); - an = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; - second = Spawn("EntitySecond", pos, ALLOW_REPLACE); - second->CopyFriendliness(self, true); - //second->target = self->target; - second->vel.x = FixedMul (secondRadius, finecosine[an]) << 2; - second->vel.y = FixedMul (secondRadius, finesine[an]) << 2; - A_FaceTarget (second); + second = Spawn("EntitySecond", pos, ALLOW_REPLACE); + second->CopyFriendliness(self, true); + A_FaceTarget(second); + second->VelFromAngle(an, velmul[i]); + } return 0; } diff --git a/src/g_strife/a_inquisitor.cpp b/src/g_strife/a_inquisitor.cpp index 8a44add95..368df7621 100644 --- a/src/g_strife/a_inquisitor.cpp +++ b/src/g_strife/a_inquisitor.cpp @@ -42,7 +42,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorDecide) } if (self->target->Z() != self->Z()) { - if (self->Top() + 54*FRACUNIT < self->ceilingz) + if (self->Top() + 54 < self->ceilingz) { self->SetState (self->FindState("Jump")); } @@ -61,20 +61,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorAttack) A_FaceTarget (self); - self->AddZ(32*FRACUNIT); - self->angle -= ANGLE_45/32; - proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindActor("InquisitorShot")); + self->_f_AddZ(32*FRACUNIT); + self->Angles.Yaw -= 45./32; + proj = P_SpawnMissileZAimed (self, self->_f_Z(), self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { - proj->vel.z += 9*FRACUNIT; + proj->Vel.Z += 9; } - self->angle += ANGLE_45/16; - proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindActor("InquisitorShot")); + self->Angles.Yaw += 45./16; + proj = P_SpawnMissileZAimed (self, self->_f_Z(), self->target, PClass::FindActor("InquisitorShot")); if (proj != NULL) { - proj->vel.z += 16*FRACUNIT; + proj->Vel.Z += 16; } - self->AddZ(-32*FRACUNIT); + self->_f_AddZ(-32*FRACUNIT); return 0; } @@ -82,27 +82,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorJump) { PARAM_ACTION_PROLOGUE; - fixed_t dist; - fixed_t speed; - angle_t an; + double dist; + double speed; if (self->target == NULL) return 0; S_Sound (self, CHAN_ITEM|CHAN_LOOP, "inquisitor/jump", 1, ATTN_NORM); - self->AddZ(64*FRACUNIT); + self->_f_AddZ(64*FRACUNIT); A_FaceTarget (self); - an = self->angle >> ANGLETOFINESHIFT; - speed = self->Speed * 2/3; - self->vel.x += FixedMul (speed, finecosine[an]); - self->vel.y += FixedMul (speed, finesine[an]); - dist = self->AproxDistance (self->target); - dist /= speed; - if (dist < 1) - { - dist = 1; - } - self->vel.z = (self->target->Z() - self->Z()) / dist; + speed = self->Speed * (2./3); + self->VelFromAngle(speed); + dist = self->DistanceBySpeed(self->target, speed); + self->Vel.Z = (self->target->Z() - self->Z()) / dist; self->reactiontime = 60; self->flags |= MF_NOGRAVITY; return 0; @@ -114,8 +106,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorCheckLand) self->reactiontime--; if (self->reactiontime < 0 || - self->vel.x == 0 || - self->vel.y == 0 || + self->Vel.X == 0 || + self->Vel.Y == 0 || self->Z() <= self->floorz) { self->SetState (self->SeeState); @@ -136,10 +128,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_TossArm) PARAM_ACTION_PROLOGUE; AActor *foo = Spawn("InquisitorArm", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); - foo->angle = self->angle - ANGLE_90 + (pr_inq.Random2() << 22); - foo->vel.x = FixedMul (foo->Speed, finecosine[foo->angle >> ANGLETOFINESHIFT]) >> 3; - foo->vel.y = FixedMul (foo->Speed, finesine[foo->angle >> ANGLETOFINESHIFT]) >> 3; - foo->vel.z = pr_inq() << 10; + foo->Angles.Yaw = self->Angles.Yaw - 90. + pr_inq.Random2() * (360./1024.); + foo->VelFromAngle(foo->Speed / 8); + foo->Vel.Z = pr_inq() / 64.; return 0; } diff --git a/src/g_strife/a_loremaster.cpp b/src/g_strife/a_loremaster.cpp index 5b2f7fd90..85ef0ba2b 100644 --- a/src/g_strife/a_loremaster.cpp +++ b/src/g_strife/a_loremaster.cpp @@ -24,15 +24,9 @@ int ALoreShot::DoSpecialDamage (AActor *victim, int damage, FName damagetype) if (victim != NULL && target != NULL && !(victim->flags7 & MF7_DONTTHRUST)) { - fixedvec3 fixthrust = victim->Vec3To(target); - DVector3 thrust(fixthrust.x, fixthrust.y, fixthrust.z); - - thrust.MakeUnit(); - thrust *= double((255*50*FRACUNIT) / (victim->Mass ? victim->Mass : 1)); - - victim->vel.x += fixed_t(thrust.X); - victim->vel.y += fixed_t(thrust.Y); - victim->vel.z += fixed_t(thrust.Z); + DVector3 thrust = victim->Vec3To(target); + thrust.MakeResize(255. * 50 / MAX(victim->Mass, 1)); + victim->Vel += thrust; } return damage; } @@ -43,7 +37,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LoremasterChain) S_Sound (self, CHAN_BODY, "loremaster/active", 1, ATTN_NORM); Spawn("LoreShot2", self->Pos(), ALLOW_REPLACE); - Spawn("LoreShot2", self->Vec3Offset(-(self->vel.x >> 1), -(self->vel.y >> 1), -(self->vel.z >> 1)), ALLOW_REPLACE); - Spawn("LoreShot2", self->Vec3Offset(-self->vel.x, -self->vel.y, -self->vel.z), ALLOW_REPLACE); + Spawn("LoreShot2", self->Vec3Offset(-(self->_f_velx() >> 1), -(self->_f_vely() >> 1), -(self->_f_velz() >> 1)), ALLOW_REPLACE); + Spawn("LoreShot2", self->Vec3Offset(-self->_f_velx(), -self->_f_vely(), -self->_f_velz()), ALLOW_REPLACE); return 0; } diff --git a/src/g_strife/a_programmer.cpp b/src/g_strife/a_programmer.cpp index 214641e03..cbdc4a14c 100644 --- a/src/g_strife/a_programmer.cpp +++ b/src/g_strife/a_programmer.cpp @@ -109,7 +109,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpotLightning) if (self->target == NULL) return 0; - spot = Spawn("SpectralLightningSpot", self->target->X(), self->target->Y(), self->target->floorz, ALLOW_REPLACE); + spot = Spawn("SpectralLightningSpot", self->target->PosAtZ(self->target->floorz), ALLOW_REPLACE); if (spot != NULL) { spot->threshold = 25; @@ -133,10 +133,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnProgrammerBase) AActor *foo = Spawn("ProgrammerBase", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); if (foo != NULL) { - foo->angle = self->angle + ANGLE_180 + (pr_prog.Random2() << 22); - foo->vel.x = FixedMul (foo->Speed, finecosine[foo->angle >> ANGLETOFINESHIFT]); - foo->vel.y = FixedMul (foo->Speed, finesine[foo->angle >> ANGLETOFINESHIFT]); - foo->vel.z = pr_prog() << 9; + foo->Angles.Yaw = self->Angles.Yaw + 180. + pr_prog.Random2() * (360. / 1024.); + foo->VelFromAngle(); + foo->Vel.Z = pr_prog() / 128.; } return 0; } diff --git a/src/g_strife/a_reaver.cpp b/src/g_strife/a_reaver.cpp index 393670f06..372aea794 100644 --- a/src/g_strife/a_reaver.cpp +++ b/src/g_strife/a_reaver.cpp @@ -17,17 +17,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_ReaverRanged) if (self->target != NULL) { - angle_t bangle; - int pitch; + DAngle bangle; + DAngle pitch; A_FaceTarget (self); S_Sound (self, CHAN_WEAPON, "reaver/attack", 1, ATTN_NORM); - bangle = self->angle; + bangle = self->Angles.Yaw; pitch = P_AimLineAttack (self, bangle, MISSILERANGE); for (int i = 0; i < 3; ++i) { - angle_t angle = bangle + (pr_reaverattack.Random2() << 20); + DAngle angle = bangle + pr_reaverattack.Random2() * (22.5 / 256); int damage = ((pr_reaverattack() & 7) + 1) * 3; P_LineAttack (self, angle, MISSILERANGE, pitch, damage, NAME_Hitscan, NAME_StrifePuff); } diff --git a/src/g_strife/a_rebels.cpp b/src/g_strife/a_rebels.cpp index 6a93ef91e..ba9213471 100644 --- a/src/g_strife/a_rebels.cpp +++ b/src/g_strife/a_rebels.cpp @@ -24,15 +24,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShootGun) { PARAM_ACTION_PROLOGUE; - int pitch; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "monsters/rifle", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); - P_LineAttack (self, self->angle + (pr_shootgun.Random2() << 19), + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); + P_LineAttack (self, self->Angles.Yaw + pr_shootgun.Random2() * (11.25 / 256), MISSILERANGE, pitch, 3*(pr_shootgun() % 5 + 1), NAME_Hitscan, NAME_StrifePuff); return 0; @@ -80,7 +80,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon) AActor *rebel; angle_t an; - rebel = Spawn("Rebel1", self->X(), self->Y(), self->floorz, ALLOW_REPLACE); + rebel = Spawn("Rebel1", self->PosAtZ(self->floorz), ALLOW_REPLACE); if (!P_TryMove (rebel, rebel->X(), rebel->Y(), true)) { rebel->Destroy (); @@ -115,8 +115,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon) } rebel->SetState (rebel->SeeState); - rebel->angle = self->angle; - an = self->angle >> ANGLETOFINESHIFT; + rebel->Angles.Yaw = self->Angles.Yaw; + an = self->_f_angle() >> ANGLETOFINESHIFT; Spawn (rebel->Vec3Offset(20*finecosine[an], 20*finesine[an], TELEFOGHEIGHT), ALLOW_REPLACE); if (--self->health < 0) { diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp index 21eaa9993..eb282fcce 100644 --- a/src/g_strife/a_sentinel.cpp +++ b/src/g_strife/a_sentinel.cpp @@ -13,29 +13,29 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelBob) { PARAM_ACTION_PROLOGUE; - fixed_t minz, maxz; + double minz, maxz; if (self->flags & MF_INFLOAT) { - self->vel.z = 0; + self->Vel.Z = 0; return 0; } if (self->threshold != 0) return 0; - maxz = self->ceilingz - self->height - 16*FRACUNIT; - minz = self->floorz + 96*FRACUNIT; + maxz = self->ceilingz - self->Height - 16; + minz = self->floorz + 96; if (minz > maxz) { minz = maxz; } if (minz < self->Z()) { - self->vel.z -= FRACUNIT; + self->Vel.Z -= 1; } else { - self->vel.z += FRACUNIT; + self->Vel.Z += 1; } self->reactiontime = (minz >= self->Z()) ? 4 : 0; return 0; @@ -53,24 +53,22 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack) return 0; } - missile = P_SpawnMissileZAimed (self, self->Z() + 32*FRACUNIT, self->target, PClass::FindActor("SentinelFX2")); + missile = P_SpawnMissileZAimed (self, self->_f_Z() + 32*FRACUNIT, self->target, PClass::FindActor("SentinelFX2")); - if (missile != NULL && (missile->vel.x | missile->vel.y) != 0) + if (missile != NULL && (missile->Vel.X != 0 || missile->Vel.Y != 0)) { for (int i = 8; i > 1; --i) { trail = Spawn("SentinelFX1", - self->Vec3Angle(missile->radius*i, missile->angle, (missile->vel.z / 4 * i)), ALLOW_REPLACE); + self->_f_Vec3Angle(missile->_f_radius()*i, missile->_f_angle(), (missile->_f_velz() / 4 * i)), ALLOW_REPLACE); if (trail != NULL) { trail->target = self; - trail->vel.x = missile->vel.x; - trail->vel.y = missile->vel.y; - trail->vel.z = missile->vel.z; + trail->Vel = missile->Vel; P_CheckMissileSpawn (trail, self->radius); } } - missile->AddZ(missile->vel.z >> 2); + missile->_f_AddZ(missile->_f_velz() >> 2); } return 0; } diff --git a/src/g_strife/a_spectral.cpp b/src/g_strife/a_spectral.cpp index b5003105c..9e06433a1 100644 --- a/src/g_strife/a_spectral.cpp +++ b/src/g_strife/a_spectral.cpp @@ -28,9 +28,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightningTail) { PARAM_ACTION_PROLOGUE; - AActor *foo = Spawn("SpectralLightningHTail", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE); + AActor *foo = Spawn("SpectralLightningHTail", self->Vec3Offset(-self->_f_velx(), -self->_f_vely(), 0), ALLOW_REPLACE); - foo->angle = self->angle; + foo->Angles.Yaw = self->Angles.Yaw; foo->FriendPlayer = self->FriendPlayer; return 0; } @@ -42,11 +42,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralBigBallLightning) PClassActor *cls = PClass::FindActor("SpectralLightningH3"); if (cls) { - self->angle += ANGLE_90; + self->Angles.Yaw += 90.; P_SpawnSubMissile (self, cls, self->target); - self->angle += ANGLE_180; + self->Angles.Yaw += 180.; P_SpawnSubMissile (self, cls, self->target); - self->angle += ANGLE_90; + self->Angles.Yaw -= 270.; P_SpawnSubMissile (self, cls, self->target); } return 0; @@ -63,8 +63,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightning) if (self->threshold != 0) --self->threshold; - self->vel.x += pr_zap5.Random2(3) << FRACBITS; - self->vel.y += pr_zap5.Random2(3) << FRACBITS; + self->Vel.X += pr_zap5.Random2(3); + self->Vel.Y += pr_zap5.Random2(3); fixedvec2 pos = self->Vec2Offset( pr_zap5.Random2(3) * FRACUNIT * 50, @@ -74,27 +74,26 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightning) PClass::FindActor(NAME_SpectralLightningV1), pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE); flash->target = self->target; - flash->vel.z = -18*FRACUNIT; + flash->Vel.Z = -18*FRACUNIT; flash->FriendPlayer = self->FriendPlayer; - flash = Spawn(NAME_SpectralLightningV2, self->X(), self->Y(), ONCEILINGZ, ALLOW_REPLACE); + flash = Spawn(NAME_SpectralLightningV2, self->_f_X(), self->_f_Y(), ONCEILINGZ, ALLOW_REPLACE); flash->target = self->target; - flash->vel.z = -18*FRACUNIT; + flash->Vel.Z = -18 * FRACUNIT; flash->FriendPlayer = self->FriendPlayer; return 0; } // In Strife, this number is stored in the data segment, but it doesn't seem to be // altered anywhere. -#define TRACEANGLE (0xe000000) +#define TRACEANGLE (19.6875) DEFINE_ACTION_FUNCTION(AActor, A_Tracer2) { PARAM_ACTION_PROLOGUE; AActor *dest; - angle_t exact; fixed_t dist; fixed_t slope; @@ -103,53 +102,48 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer2) if (!dest || dest->health <= 0 || self->Speed == 0 || !self->CanSeek(dest)) return 0; - // change angle - exact = self->AngleTo(dest); + DAngle exact = self->AngleTo(dest); + DAngle diff = deltaangle(self->Angles.Yaw, exact); - if (exact != self->angle) + if (diff < 0) { - if (exact - self->angle > 0x80000000) - { - self->angle -= TRACEANGLE; - if (exact - self->angle < 0x80000000) - self->angle = exact; - } - else - { - self->angle += TRACEANGLE; - if (exact - self->angle > 0x80000000) - self->angle = exact; - } + self->Angles.Yaw -= TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) > 0) + self->Angles.Yaw = exact; + } + else if (diff > 0) + { + self->Angles.Yaw += TRACEANGLE; + if (deltaangle(self->Angles.Yaw, exact) < 0.) + self->Angles.Yaw = exact; } - exact = self->angle >> ANGLETOFINESHIFT; - self->vel.x = FixedMul (self->Speed, finecosine[exact]); - self->vel.y = FixedMul (self->Speed, finesine[exact]); + self->VelFromAngle(); if (!(self->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // change slope - dist = self->AproxDistance (dest) / self->Speed; + dist = self->AproxDistance (dest) / self->_f_speed(); if (dist < 1) { dist = 1; } - if (dest->height >= 56*FRACUNIT) + if (dest->_f_height() >= 56*FRACUNIT) { - slope = (dest->Z()+40*FRACUNIT - self->Z()) / dist; + slope = (dest->_f_Z()+40*FRACUNIT - self->_f_Z()) / dist; } else { - slope = (dest->Z() + self->height*2/3 - self->Z()) / dist; + slope = (dest->_f_Z() + self->_f_height()*2/3 - self->_f_Z()) / dist; } - if (slope < self->vel.z) + if (slope < self->_f_velz()) { - self->vel.z -= FRACUNIT/8; + self->Vel.Z -= 1 / 8.; } else { - self->vel.z += FRACUNIT/8; + self->Vel.Z += 1 / 8.; } } return 0; diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index abbfc2300..beb64e2dd 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -600,20 +600,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_TossGib) const char *gibtype = (self->flags & MF_NOBLOOD) ? "Junk" : "Meat"; AActor *gib = Spawn (gibtype, self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); - angle_t an; - int speed; if (gib == NULL) { return 0; } - an = pr_gibtosser() << 24; - gib->angle = an; - speed = pr_gibtosser() & 15; - gib->vel.x = speed * finecosine[an >> ANGLETOFINESHIFT]; - gib->vel.y = speed * finesine[an >> ANGLETOFINESHIFT]; - gib->vel.z = (pr_gibtosser() & 15) << FRACBITS; + gib->Angles.Yaw = pr_gibtosser() * (360 / 256.f); + gib->VelFromAngle(pr_gibtosser() & 15); + gib->Vel.Z = pr_gibtosser() & 15; return 0; } @@ -659,7 +654,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) sector_t *sec = self->Sector; - if (self->Z() == sec->floorplane.ZatPoint(self) && sec->PortalBlocksMovement(sector_t::floor)) + if (self->_f_Z() == sec->floorplane.ZatPoint(self) && sec->PortalBlocksMovement(sector_t::floor)) { if (sec->special == Damage_InstantDeath) { @@ -668,11 +663,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain) else if (sec->special == Scroll_StrifeCurrent) { int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; - fixed_t speed = (anglespeed % 10) << (FRACBITS - 4); - angle_t finean = (anglespeed / 10) << (32-3); - finean >>= ANGLETOFINESHIFT; - self->vel.x += FixedMul (speed, finecosine[finean]); - self->vel.y += FixedMul (speed, finesine[finean]); + double speed = (anglespeed % 10) / 16.; + DAngle an = (anglespeed / 10) * (360 / 8.); + self->VelFromAngle(an, speed); } } return 0; @@ -722,7 +715,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropFire) PARAM_ACTION_PROLOGUE; AActor *drop = Spawn("FireDroplet", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE); - drop->vel.z = -FRACUNIT; + drop->Vel.Z = -FRACUNIT; P_RadiusAttack (self, self, 64, 64, NAME_Fire, 0); return 0; } @@ -748,7 +741,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower) if (self->player != NULL) { pspdef_t *psp = &self->player->psprites[ps_weapon]; - psp->sy += FRACUNIT*9; + psp->sy += 9; if (psp->sy > WEAPONBOTTOM*2) { P_SetPsprite (self->player, ps_weapon, NULL); diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 8129a8bfc..1447603ab 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -96,9 +96,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) { PARAM_ACTION_PROLOGUE; - angle_t angle; + DAngle angle; int damage; - int pitch; + DAngle pitch; int power; FTranslatedLineTarget t; @@ -110,9 +110,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) damage *= 10; } - angle = self->angle + (pr_jabdagger.Random2() << 18); - pitch = P_AimLineAttack (self, angle, 80*FRACUNIT); - P_LineAttack (self, angle, 80*FRACUNIT, pitch, damage, NAME_Melee, "StrifeSpark", true, &t); + angle = self->Angles.Yaw + pr_jabdagger.Random2() * (5.625 / 256); + pitch = P_AimLineAttack (self, angle, 80.); + P_LineAttack (self, angle, 80., pitch, damage, NAME_Melee, "StrifeSpark", true, &t); // turn to face target if (t.linetarget) @@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_JabDagger) S_Sound (self, CHAN_WEAPON, t.linetarget->flags & MF_NOBLOOD ? "misc/metalhit" : "misc/meathit", 1, ATTN_NORM); - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; self->flags |= MF_JUSTATTACKED; P_DaggerAlert (self, t.linetarget); } @@ -251,7 +251,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) PARAM_ACTION_PROLOGUE; PARAM_CLASS(ti, AActor); - angle_t savedangle; + DAngle savedangle; if (self->player == NULL) return 0; @@ -265,11 +265,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) if (ti) { - savedangle = self->angle; - self->angle += pr_electric.Random2 () << (18 - self->player->mo->accuracy * 5 / 100); + savedangle = self->Angles.Yaw; + self->Angles.Yaw += pr_electric.Random2() * (5.625/256) * self->player->mo->AccuracyFactor(); self->player->mo->PlayAttacking2 (); P_SpawnPlayerMissile (self, ti); - self->angle = savedangle; + self->Angles.Yaw = savedangle; S_Sound (self, CHAN_WEAPON, "weapons/xbowshoot", 1, ATTN_NORM); } return 0; @@ -283,17 +283,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) // //============================================================================ -void P_StrifeGunShot (AActor *mo, bool accurate, angle_t pitch) +void P_StrifeGunShot (AActor *mo, bool accurate, DAngle pitch) { - angle_t angle; + DAngle angle; int damage; damage = 4*(pr_sgunshot()%3+1); - angle = mo->angle; + angle = mo->Angles.Yaw; if (mo->player != NULL && !accurate) { - angle += pr_sgunshot.Random2() << (20 - mo->player->mo->accuracy * 5 / 100); + angle += pr_sgunshot.Random2() * (22.5 / 256) * mo->player->mo->AccuracyFactor(); } P_LineAttack (mo, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, NAME_StrifePuff); @@ -346,7 +346,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMiniMissile) PARAM_ACTION_PROLOGUE; player_t *player = self->player; - angle_t savedangle; + DAngle savedangle; if (self->player == NULL) return 0; @@ -358,11 +358,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMiniMissile) return 0; } - savedangle = self->angle; - self->angle += pr_minimissile.Random2() << (19 - player->mo->accuracy * 5 / 100); + savedangle = self->Angles.Yaw; + self->Angles.Yaw += pr_minimissile.Random2() * (11.25 / 256) * player->mo->AccuracyFactor(); player->mo->PlayAttacking2 (); P_SpawnPlayerMissile (self, PClass::FindActor("MiniMissile")); - self->angle = savedangle; + self->Angles.Yaw = savedangle; return 0; } @@ -379,11 +379,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_RocketInFlight) AActor *trail; S_Sound (self, CHAN_VOICE, "misc/missileinflight", 1, ATTN_NORM); - P_SpawnPuff (self, PClass::FindActor("MiniMissilePuff"), self->Pos(), self->angle - ANGLE_180, 2, PF_HITTHING); - trail = Spawn("RocketTrail", self->Vec3Offset(-self->vel.x, -self->vel.y, 0), ALLOW_REPLACE); + P_SpawnPuff (self, PClass::FindActor("MiniMissilePuff"), self->_f_Pos(), self->_f_angle() - ANGLE_180, 2, PF_HITTHING); + trail = Spawn("RocketTrail", self->Vec3Offset(-self->_f_velx(), -self->_f_vely(), 0), ALLOW_REPLACE); if (trail != NULL) { - trail->vel.z = FRACUNIT; + trail->Vel.Z = 1; } return 0; } @@ -401,7 +401,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FlameDie) PARAM_ACTION_PROLOGUE; self->flags |= MF_NOGRAVITY; - self->vel.z = (pr_flamedie() & 3) << FRACBITS; + self->Vel.Z = pr_flamedie() & 3; return 0; } @@ -428,11 +428,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireFlamer) player->mo->PlayAttacking2 (); } - self->angle += pr_flamethrower.Random2() << 18; + self->Angles.Yaw += pr_flamethrower.Random2() * (5.625/256.); self = P_SpawnPlayerMissile (self, PClass::FindActor("FlameMissile")); if (self != NULL) { - self->vel.z += 5*FRACUNIT; + self->Vel.Z += 5; } return 0; } @@ -467,13 +467,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler1) S_Sound (self, CHAN_WEAPON, "weapons/mauler1", 1, ATTN_NORM); - int bpitch = P_BulletSlope (self); + DAngle bpitch = P_BulletSlope (self); for (int i = 0; i < 20; ++i) { int damage = 5 * (pr_mauler1() % 3 + 1); - angle_t angle = self->angle + (pr_mauler1.Random2() << 19); - int pitch = bpitch + (pr_mauler1.Random2() * 332063); + DAngle angle = self->Angles.Yaw + pr_mauler1.Random2() * (11.25 / 256); + DAngle pitch = bpitch + pr_mauler1.Random2() * (7.097 / 256); // Strife used a range of 2112 units for the mauler to signal that // it should use a different puff. ZDoom's default range is longer @@ -500,8 +500,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2Pre) if (self->player != NULL) { - self->player->psprites[ps_weapon].sx += pr_mauler2.Random2() << 10; - self->player->psprites[ps_weapon].sy += pr_mauler2.Random2() << 10; + self->player->psprites[ps_weapon].sx += pr_mauler2.Random2() / 64.; + self->player->psprites[ps_weapon].sy += pr_mauler2.Random2() / 64.; } return 0; } @@ -530,7 +530,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2) } P_SpawnPlayerMissile (self, PClass::FindActor("MaulerTorpedo")); P_DamageMobj (self, self, NULL, 20, self->DamageType); - P_ThrustMobj (self, self->angle + ANGLE_180, 0x7D000); + self->Thrust(self->Angles.Yaw+180., 7.8125); return 0; } @@ -548,27 +548,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaulerTorpedoWave) AActor *wavedef = GetDefaultByName("MaulerTorpedoWave"); fixed_t savedz; - self->angle += ANGLE_180; + self->Angles.Yaw += 180.; // If the torpedo hit the ceiling, it should still spawn the wave - savedz = self->Z(); - if (wavedef && self->ceilingz - self->Z() < wavedef->height) + savedz = self->_f_Z(); + if (wavedef && self->ceilingz < wavedef->Top()) { - self->SetZ(self->ceilingz - wavedef->height); + self->SetZ(self->ceilingz - wavedef->Height); } for (int i = 0; i < 80; ++i) { - self->angle += ANGLE_45/10; + self->Angles.Yaw += 4.5; P_SpawnSubMissile (self, PClass::FindActor("MaulerTorpedoWave"), self->target); } - self->SetZ(savedz); + self->_f_SetZ(savedz); return 0; } AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target) { - AActor *other = Spawn (type, source->Pos(), ALLOW_REPLACE); + AActor *other = Spawn (type, source->_f_Pos(), ALLOW_REPLACE); if (other == NULL) { @@ -576,10 +576,8 @@ AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target) } other->target = target; - other->angle = source->angle; - - other->vel.x = FixedMul (other->Speed, finecosine[source->angle >> ANGLETOFINESHIFT]); - other->vel.y = FixedMul (other->Speed, finesine[source->angle >> ANGLETOFINESHIFT]); + other->Angles.Yaw = source->Angles.Yaw; + other->VelFromAngle(); if (other->flags4 & MF4_SPECTRAL) { @@ -595,8 +593,8 @@ AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target) if (P_CheckMissileSpawn (other, source->radius)) { - angle_t pitch = P_AimLineAttack (source, source->angle, 1024*FRACUNIT); - other->vel.z = FixedMul (-finesine[pitch>>ANGLETOFINESHIFT], other->Speed); + DAngle pitch = P_AimLineAttack (source, source->Angles.Yaw, 1024.); + other->Vel.Z = -other->Speed * pitch.Cos(); return other; } return NULL; @@ -632,9 +630,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burnination) { PARAM_ACTION_PROLOGUE; - self->vel.z -= 8*FRACUNIT; - self->vel.x += (pr_phburn.Random2 (3)) << FRACBITS; - self->vel.y += (pr_phburn.Random2 (3)) << FRACBITS; + self->Vel.Z -= 8; + self->Vel.X += (pr_phburn.Random2 (3)); + self->Vel.Y += (pr_phburn.Random2 (3)); S_Sound (self, CHAN_VOICE, "world/largefire", 1, ATTN_NORM); // Only the main fire spawns more. @@ -664,20 +662,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burnination) sector_t * sector = P_PointInSector(pos.x, pos.y); // The sector's floor is too high so spawn the flame elsewhere. - if (sector->floorplane.ZatPoint(pos.x, pos.y) > self->Z() + self->MaxStepHeight) + if (sector->floorplane.ZatPoint(pos.x, pos.y) > self->_f_Z() + self->MaxStepHeight) { - pos.x = self->X(); - pos.y = self->Y(); + pos.x = self->_f_X(); + pos.y = self->_f_Y(); } AActor *drop = Spawn ( pos.x, pos.y, - self->Z() + 4*FRACUNIT, ALLOW_REPLACE); + self->_f_Z() + 4*FRACUNIT, ALLOW_REPLACE); if (drop != NULL) { - drop->vel.x = self->vel.x + ((pr_phburn.Random2 (7)) << FRACBITS); - drop->vel.y = self->vel.y + ((pr_phburn.Random2 (7)) << FRACBITS); - drop->vel.z = self->vel.z - FRACUNIT; + drop->Vel.X = self->Vel.X + pr_phburn.Random2 (7); + drop->Vel.Y = self->Vel.Y + pr_phburn.Random2 (7); + drop->Vel.Z = self->Vel.Z - 1; drop->reactiontime = (pr_phburn() & 3) + 2; drop->flags |= MF_DROPPED; } @@ -717,9 +715,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) if (grenadetype != NULL) { - self->AddZ(32*FRACUNIT); + self->_f_AddZ(32*FRACUNIT); grenade = P_SpawnSubMissile (self, grenadetype, self); - self->AddZ(-32*FRACUNIT); + self->_f_AddZ(-32*FRACUNIT); if (grenade == NULL) return 0; @@ -728,22 +726,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) S_Sound (grenade, CHAN_VOICE, grenade->SeeSound, 1, ATTN_NORM); } - grenade->vel.z = FixedMul (finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], grenade->Speed) + 8*FRACUNIT; + grenade->Vel.Z = (-self->Angles.Pitch.TanClamped()) * grenade->Speed + 8; fixedvec2 offset; - an = self->angle >> ANGLETOFINESHIFT; - tworadii = self->radius + grenade->radius; + an = self->_f_angle() >> ANGLETOFINESHIFT; + tworadii = self->_f_radius() + grenade->_f_radius(); offset.x = FixedMul (finecosine[an], tworadii); offset.y = FixedMul (finesine[an], tworadii); - an = self->angle + angleofs; + an = self->_f_angle() + angleofs; an >>= ANGLETOFINESHIFT; offset.x += FixedMul (finecosine[an], 15*FRACUNIT); offset.y += FixedMul (finesine[an], 15*FRACUNIT); fixedvec2 newpos = grenade->Vec2Offset(offset.x, offset.y); - grenade->SetOrigin(newpos.x, newpos.y, grenade->Z(), false); + grenade->SetOrigin(newpos.x, newpos.y, grenade->_f_Z(), false); } return 0; } @@ -989,7 +987,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1) P_BulletSlope (self, &t, ALF_PORTALRESTRICT); if (t.linetarget != NULL) { - spot = Spawn("SpectralLightningSpot", t.linetarget->X(), t.linetarget->Y(), t.linetarget->floorz, ALLOW_REPLACE); + spot = Spawn("SpectralLightningSpot", t.linetarget->PosAtZ(t.linetarget->floorz), ALLOW_REPLACE); if (spot != NULL) { spot->tracer = t.linetarget; @@ -997,11 +995,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1) } else { - spot = Spawn("SpectralLightningSpot", self->Pos(), ALLOW_REPLACE); + spot = Spawn("SpectralLightningSpot", self->_f_Pos(), ALLOW_REPLACE); if (spot != NULL) { - spot->vel.x += 28 * finecosine[self->angle >> ANGLETOFINESHIFT]; - spot->vel.y += 28 * finesine[self->angle >> ANGLETOFINESHIFT]; + spot->VelFromAngle(self->Angles.Yaw, 28.); } } if (spot != NULL) @@ -1054,17 +1051,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil3) P_DamageMobj (self, self, NULL, 3*4, 0, DMG_NO_ARMOR); S_Sound (self, CHAN_WEAPON, "weapons/sigilcharge", 1, ATTN_NORM); - self->angle -= ANGLE_90; + self->Angles.Yaw -= 90.; for (i = 0; i < 20; ++i) { - self->angle += ANGLE_180/20; + self->Angles.Yaw += 9.; spot = P_SpawnSubMissile (self, PClass::FindActor("SpectralLightningBall1"), self); if (spot != NULL) { - spot->SetZ(self->Z() + 32*FRACUNIT); + spot->_f_SetZ(self->_f_Z() + 32*FRACUNIT); } } - self->angle -= (ANGLE_180/20)*10; + self->Angles.Yaw -= 90.; return 0; } @@ -1091,7 +1088,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) P_BulletSlope (self, &t, ALF_PORTALRESTRICT); if (t.linetarget != NULL) { - spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->angle, &t, NULL, false, false, ALF_PORTALRESTRICT); + spot = P_SpawnPlayerMissile (self, 0,0,0, PClass::FindActor("SpectralLightningBigV1"), self->Angles.Yaw, &t, NULL, false, false, ALF_PORTALRESTRICT); if (spot != NULL) { spot->tracer = t.linetarget; @@ -1102,8 +1099,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil4) spot = P_SpawnPlayerMissile (self, PClass::FindActor("SpectralLightningBigV1")); if (spot != NULL) { - spot->vel.x += FixedMul (spot->Speed, finecosine[self->angle >> ANGLETOFINESHIFT]); - spot->vel.y += FixedMul (spot->Speed, finesine[self->angle >> ANGLETOFINESHIFT]); + spot->VelFromAngle(self->Angles.Yaw, spot->Speed); } } return 0; diff --git a/src/g_strife/a_templar.cpp b/src/g_strife/a_templar.cpp index 554ca141d..547d4d73e 100644 --- a/src/g_strife/a_templar.cpp +++ b/src/g_strife/a_templar.cpp @@ -16,23 +16,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_TemplarAttack) PARAM_ACTION_PROLOGUE; int damage; - angle_t angle; - int pitch; - int pitchdiff; + DAngle angle; + DAngle pitch; if (self->target == NULL) return 0; S_Sound (self, CHAN_WEAPON, "templar/shoot", 1, ATTN_NORM); A_FaceTarget (self); - pitch = P_AimLineAttack (self, self->angle, MISSILERANGE); + pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); for (int i = 0; i < 10; ++i) { damage = (pr_templar() & 4) * 2; - angle = self->angle + (pr_templar.Random2() << 19); - pitchdiff = pr_templar.Random2() * 332063; - P_LineAttack (self, angle, MISSILERANGE+64*FRACUNIT, pitch+pitchdiff, damage, NAME_Hitscan, NAME_MaulerPuff); + angle = self->Angles.Yaw + pr_templar.Random2() * (11.25 / 256); + P_LineAttack (self, angle, MISSILERANGE+64., pitch + pr_templar.Random2() * (7.097 / 256), damage, NAME_Hitscan, NAME_MaulerPuff); } return 0; } diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index 55b00e6b9..5e4b5deff 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Explode512) { self->target->player->extralight = 5; } - P_CheckSplash(self, 512<RenderStyle = STYLE_Add; @@ -112,9 +112,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut) if (foo != NULL) { int t = pr_lightout() & 15; - foo->vel.x = (t - (pr_lightout() & 7)) << FRACBITS; - foo->vel.y = (pr_lightout.Random2() & 7) << FRACBITS; - foo->vel.z = (7 + (pr_lightout() & 3)) << FRACBITS; + foo->Vel.X = t - (pr_lightout() & 7); + foo->Vel.Y = pr_lightout.Random2() & 7; + foo->Vel.Z = 7 + (pr_lightout() & 3); } } return 0; diff --git a/src/info.cpp b/src/info.cpp index 40a600884..09e8a576b 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -229,9 +229,9 @@ PClassActor::PClassActor() GibHealth = INT_MIN; WoundHealth = 6; PoisonDamage = 0; - FastSpeed = FIXED_MIN; + FastSpeed = -1.; RDFactor = FRACUNIT; - CameraHeight = FIXED_MIN; + CameraHeight = INT_MIN; DropItems = NULL; diff --git a/src/info.h b/src/info.h index 1f2537d47..4fb150155 100644 --- a/src/info.h +++ b/src/info.h @@ -242,15 +242,15 @@ public: FString Obituary; // Player was killed by this actor FString HitObituary; // Player was killed by this actor in melee - fixed_t DeathHeight; // Height on normal death - fixed_t BurnHeight; // Height on burning death + double DeathHeight; // Height on normal death + double BurnHeight; // Height on burning death PalEntry BloodColor; // Colorized blood int GibHealth; // Negative health below which this monster dies an extreme death int WoundHealth; // Health needed to enter wound state int PoisonDamage; // Amount of poison damage - fixed_t FastSpeed; // Speed in fast mode + double FastSpeed; // speed in fast mode fixed_t RDFactor; // Radius damage factor - fixed_t CameraHeight; // Height of camera when used as such + double CameraHeight; // Height of camera when used as such FSoundID HowlSound; // Sound being played when electrocuted or poisoned FName BloodType; // Blood replacement type FName BloodType2; // Bloopsplatter replacement type @@ -266,7 +266,7 @@ public: int MeleeDamage; FSoundID MeleeSound; FName MissileName; - fixed_t MissileHeight; + double MissileHeight; // For those times when being able to scan every kind of actor is convenient static TArray AllActorClasses; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index cceb2cb8c..3fe677da6 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -591,8 +591,7 @@ void DIntermissionScreenCast::Drawer () // draw the current frame in the middle of the screen if (caststate != NULL) { - double castscalex = FIXED2DBL(mDefaults->scaleX); - double castscaley = FIXED2DBL(mDefaults->scaleY); + DVector2 castscale = mDefaults->Scale; int castsprite = caststate->sprite; @@ -612,8 +611,7 @@ void DIntermissionScreenCast::Drawer () if (!(mDefaults->flags4 & MF4_NOSKIN)) { - castscaley = FIXED2DBL(skin->ScaleY); - castscalex = FIXED2DBL(skin->ScaleX); + castscale = skin->Scale; } } @@ -626,8 +624,8 @@ void DIntermissionScreenCast::Drawer () screen->DrawTexture (pic, 160, 170, DTA_320x200, true, DTA_FlipX, sprframe->Flip & 1, - DTA_DestHeightF, pic->GetScaledHeightDouble() * castscaley, - DTA_DestWidthF, pic->GetScaledWidthDouble() * castscalex, + DTA_DestHeightF, pic->GetScaledHeightDouble() * castscale.Y, + DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X, DTA_RenderStyle, mDefaults->RenderStyle, DTA_Alpha, mDefaults->alpha, DTA_Translation, casttranslation, diff --git a/src/m_bbox.h b/src/m_bbox.h index a48b6fecb..fe73432da 100644 --- a/src/m_bbox.h +++ b/src/m_bbox.h @@ -23,6 +23,7 @@ #define __M_BBOX_H__ #include "doomtype.h" +#include "m_fixed.h" struct line_t; struct node_t; @@ -43,13 +44,31 @@ public: m_Box[BOXBOTTOM] = bottom; } + FBoundingBox(double left, double bottom, double right, double top) + { + m_Box[BOXTOP] = FLOAT2FIXED(top); + m_Box[BOXLEFT] = FLOAT2FIXED(left); + m_Box[BOXRIGHT] = FLOAT2FIXED(right); + m_Box[BOXBOTTOM] = FLOAT2FIXED(bottom); + } + FBoundingBox(fixed_t x, fixed_t y, fixed_t radius) { setBox(x, y, radius); } + FBoundingBox(double x, double y, double radius) + { + setBox(x, y, radius); + } + void setBox(fixed_t x, fixed_t y, fixed_t radius); + void setBox(double x, double y, double radius) + { + setBox(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(radius)); + } + void ClearBox () { m_Box[BOXTOP] = m_Box[BOXRIGHT] = FIXED_MIN; @@ -72,6 +91,8 @@ public: inline fixed_t Left () const { return m_Box[BOXLEFT]; } inline fixed_t Right () const { return m_Box[BOXRIGHT]; } + bool inRange(const line_t *ld) const; + int BoxOnLineSide (const line_t *ld) const; void Set(int index, fixed_t value) {m_Box[index] = value;} diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 25f8cfca2..595b19e82 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -138,7 +138,7 @@ void cht_DoCheat (player_t *player, int cheat) player->cheats &= ~CF_NOCLIP; msg = GStrings("STSTR_NCOFF"); } - if (player->mo->vel.x == 0) player->mo->vel.x = 1; // force some lateral movement so that internal variables are up to date + if (player->mo->Vel.X == 0) player->mo->Vel.X = MinVel; // force some lateral movement so that internal variables are up to date break; case CHT_NOVELOCITY: @@ -333,7 +333,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->flags6 = player->mo->GetDefault()->flags6; player->mo->flags7 = player->mo->GetDefault()->flags7; player->mo->renderflags &= ~RF_INVISIBLE; - player->mo->height = player->mo->GetDefault()->height; + player->mo->Height = player->mo->GetDefault()->Height; player->mo->radius = player->mo->GetDefault()->radius; player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. @@ -469,8 +469,8 @@ void cht_DoCheat (player_t *player, int cheat) { // Don't allow this in deathmatch even with cheats enabled, because it's // a very very cheap kill. - P_LineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE, - P_AimLineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, + P_LineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE, + P_AimLineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, NAME_MDK, NAME_BulletPuff); } break; @@ -583,7 +583,7 @@ void GiveSpawner (player_t *player, PClassInventory *type, int amount) } AInventory *item = static_cast - (Spawn (type, player->mo->X(), player->mo->Y(), player->mo->Z(), NO_REPLACE)); + (Spawn (type, player->mo->Pos(), NO_REPLACE)); if (item != NULL) { if (amount > 0) diff --git a/src/m_joy.cpp b/src/m_joy.cpp index d2a067846..46c0b9006 100644 --- a/src/m_joy.cpp +++ b/src/m_joy.cpp @@ -1,5 +1,6 @@ // HEADER FILES ------------------------------------------------------------ +#include #include "m_joy.h" #include "gameconfigfile.h" #include "d_event.h" diff --git a/src/math/asin.c b/src/math/asin.c new file mode 100644 index 000000000..50419597f --- /dev/null +++ b/src/math/asin.c @@ -0,0 +1,315 @@ +/* asin.c + * + * Inverse circular sine + * + * + * + * SYNOPSIS: + * + * double x, y, asin(); + * + * y = asin( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between -pi/2 and +pi/2 whose sine is x. + * + * A rational function of the form x + x**3 P(x**2)/Q(x**2) + * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is + * transformed by the identity + * + * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -1, 1 40000 2.6e-17 7.1e-18 + * IEEE -1, 1 10^6 1.9e-16 5.4e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * asin domain |x| > 1 NAN + * + */ + /* acos() + * + * Inverse circular cosine + * + * + * + * SYNOPSIS: + * + * double x, y, acos(); + * + * y = acos( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between 0 and pi whose cosine + * is x. + * + * Analytically, acos(x) = pi/2 - asin(x). However if |x| is + * near 1, there is cancellation error in subtracting asin(x) + * from pi/2. Hence if x < -0.5, + * + * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); + * + * or if x > +0.5, + * + * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -1, 1 50000 3.3e-17 8.2e-18 + * IEEE -1, 1 10^6 2.2e-16 6.5e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * asin domain |x| > 1 NAN + */ + +/* asin.c */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +/* arcsin(x) = x + x^3 P(x^2)/Q(x^2) + 0 <= x <= 0.625 + Peak relative error = 1.2e-18 */ +#if UNK +static double P[6] = { + 4.253011369004428248960E-3, +-6.019598008014123785661E-1, + 5.444622390564711410273E0, +-1.626247967210700244449E1, + 1.956261983317594739197E1, +-8.198089802484824371615E0, +}; +static double Q[5] = { +/* 1.000000000000000000000E0, */ +-1.474091372988853791896E1, + 7.049610280856842141659E1, +-1.471791292232726029859E2, + 1.395105614657485689735E2, +-4.918853881490881290097E1, +}; +#endif +#if DEC +static short P[24] = { +0036213,0056330,0057244,0053234, +0140032,0015011,0114762,0160255, +0040656,0035130,0136121,0067313, +0141202,0014616,0170474,0101731, +0041234,0100076,0151674,0111310, +0141003,0025540,0033165,0077246, +}; +static short Q[20] = { +/* 0040200,0000000,0000000,0000000, */ +0141153,0155310,0055360,0072530, +0041614,0177001,0027764,0101237, +0142023,0026733,0064653,0133266, +0042013,0101264,0023775,0176351, +0141504,0140420,0050660,0036543, +}; +#endif +#if IBMPC +static short P[24] = { +0x8ad3,0x0bd4,0x6b9b,0x3f71, +0x5c16,0x333e,0x4341,0xbfe3, +0x2dd9,0x178a,0xc74b,0x4015, +0x907b,0xde27,0x4331,0xc030, +0x9259,0xda77,0x9007,0x4033, +0xafd5,0x06ce,0x656c,0xc020, +}; +static short Q[20] = { +/* 0x0000,0x0000,0x0000,0x3ff0, */ +0x0eab,0x0b5e,0x7b59,0xc02d, +0x9054,0x25fe,0x9fc0,0x4051, +0x76d7,0x6d35,0x65bb,0xc062, +0xbf9d,0x84ff,0x7056,0x4061, +0x07ac,0x0a36,0x9822,0xc048, +}; +#endif +#if MIEEE +static short P[24] = { +0x3f71,0x6b9b,0x0bd4,0x8ad3, +0xbfe3,0x4341,0x333e,0x5c16, +0x4015,0xc74b,0x178a,0x2dd9, +0xc030,0x4331,0xde27,0x907b, +0x4033,0x9007,0xda77,0x9259, +0xc020,0x656c,0x06ce,0xafd5, +}; +static short Q[20] = { +/* 0x3ff0,0x0000,0x0000,0x0000, */ +0xc02d,0x7b59,0x0b5e,0x0eab, +0x4051,0x9fc0,0x25fe,0x9054, +0xc062,0x65bb,0x6d35,0x76d7, +0x4061,0x7056,0x84ff,0xbf9d, +0xc048,0x9822,0x0a36,0x07ac, +}; +#endif + +/* arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) + 0 <= x <= 0.5 + Peak relative error = 4.2e-18 */ +#if UNK +static double R[5] = { + 2.967721961301243206100E-3, +-5.634242780008963776856E-1, + 6.968710824104713396794E0, +-2.556901049652824852289E1, + 2.853665548261061424989E1, +}; +static double S[4] = { +/* 1.000000000000000000000E0, */ +-2.194779531642920639778E1, + 1.470656354026814941758E2, +-3.838770957603691357202E2, + 3.424398657913078477438E2, +}; +#endif +#if DEC +static short R[20] = { +0036102,0077034,0142164,0174103, +0140020,0036222,0147711,0044173, +0040736,0177655,0153631,0171523, +0141314,0106525,0060015,0055474, +0041344,0045422,0003630,0040344, +}; +static short S[16] = { +/* 0040200,0000000,0000000,0000000, */ +0141257,0112425,0132772,0166136, +0042023,0010315,0075523,0175020, +0142277,0170104,0126203,0017563, +0042253,0034115,0102662,0022757, +}; +#endif +#if IBMPC +static short R[20] = { +0x9f08,0x988e,0x4fc3,0x3f68, +0x290f,0x59f9,0x0792,0xbfe2, +0x3e6a,0xbaf3,0xdff5,0x401b, +0xab68,0xac01,0x91aa,0xc039, +0x081d,0x40f3,0x8962,0x403c, +}; +static short S[16] = { +/* 0x0000,0x0000,0x0000,0x3ff0, */ +0x5d8c,0xb6bf,0xf2a2,0xc035, +0x7f42,0xaf6a,0x6219,0x4062, +0x63ee,0x9590,0xfe08,0xc077, +0x44be,0xb0b6,0x6709,0x4075, +}; +#endif +#if MIEEE +static short R[20] = { +0x3f68,0x4fc3,0x988e,0x9f08, +0xbfe2,0x0792,0x59f9,0x290f, +0x401b,0xdff5,0xbaf3,0x3e6a, +0xc039,0x91aa,0xac01,0xab68, +0x403c,0x8962,0x40f3,0x081d, +}; +static short S[16] = { +/* 0x3ff0,0x0000,0x0000,0x0000, */ +0xc035,0xf2a2,0xb6bf,0x5d8c, +0x4062,0x6219,0xaf6a,0x7f42, +0xc077,0xfe08,0x9590,0x63ee, +0x4075,0x6709,0xb0b6,0x44be, +}; +#endif + +/* pi/2 = PIO2 + MOREBITS. */ +#ifdef DEC +#define MOREBITS 5.721188726109831840122E-18 +#else +#define MOREBITS 6.123233995736765886130E-17 +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double c_sqrt ( double ); +double c_asin ( double ); +#else +double c_sqrt(), polevl(), p1evl(); +double c_asin(); +#endif +extern double PIO2, PIO4, NAN; + +double c_asin(x) +double x; +{ +double a, p, z, zz; +short sign; + +if( x > 0 ) + { + sign = 1; + a = x; + } +else + { + sign = -1; + a = -x; + } + +if( a > 1.0 ) + { + mtherr( "asin", DOMAIN ); + return( NAN ); + } + +if( a > 0.625 ) + { + /* arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) */ + zz = 1.0 - a; + p = zz * polevl( zz, R, 4)/p1evl( zz, S, 4); + zz = c_sqrt(zz+zz); + z = PIO4 - zz; + zz = zz * p - MOREBITS; + z = z - zz; + z = z + PIO4; + } +else + { + if( a < 1.0e-8 ) + { + return(x); + } + zz = a * a; + z = zz * polevl( zz, P, 5)/p1evl( zz, Q, 5); + z = a * z + a; + } +if( sign < 0 ) + z = -z; +return(z); +} + + + +double c_acos(x) +double x; +{ +if( (x < -1.0) || (x > 1.0) ) + { + mtherr( "acos", DOMAIN ); + return( NAN ); + } + return PIO2 - c_asin(x) + MOREBITS; +} diff --git a/src/math/atan.c b/src/math/atan.c new file mode 100644 index 000000000..3c5d4394c --- /dev/null +++ b/src/math/atan.c @@ -0,0 +1,393 @@ +/* atan.c + * + * Inverse circular tangent + * (arctangent) + * + * + * + * SYNOPSIS: + * + * double x, y, atan(); + * + * y = atan( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between -pi/2 and +pi/2 whose tangent + * is x. + * + * Range reduction is from three intervals into the interval + * from zero to 0.66. The approximant uses a rational + * function of degree 4/5 of the form x + x**3 P(x)/Q(x). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10, 10 50000 2.4e-17 8.3e-18 + * IEEE -10, 10 10^6 1.8e-16 5.0e-17 + * + */ + /* atan2() + * + * Quadrant correct inverse circular tangent + * + * + * + * SYNOPSIS: + * + * double x, y, z, atan2(); + * + * z = atan2( y, x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle whose tangent is y/x. + * Define compile time symbol ANSIC = 1 for ANSI standard, + * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range + * 0 to 2PI, args (x,y). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10, 10 10^6 2.5e-16 6.9e-17 + * See atan.c. + * + */ + +/* atan.c */ + + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + + +#include "mconf.h" + +/* arctan(x) = x + x^3 P(x^2)/Q(x^2) + 0 <= x <= 0.66 + Peak relative error = 2.6e-18 */ +#ifdef UNK +static double P[5] = { +-8.750608600031904122785E-1, +-1.615753718733365076637E1, +-7.500855792314704667340E1, +-1.228866684490136173410E2, +-6.485021904942025371773E1, +}; +static double Q[5] = { +/* 1.000000000000000000000E0, */ + 2.485846490142306297962E1, + 1.650270098316988542046E2, + 4.328810604912902668951E2, + 4.853903996359136964868E2, + 1.945506571482613964425E2, +}; + +/* tan( 3*pi/8 ) */ +static double T3P8 = 2.41421356237309504880; +#endif + +#ifdef DEC +static short P[20] = { +0140140,0001775,0007671,0026242, +0141201,0041242,0155534,0001715, +0141626,0002141,0132100,0011625, +0141765,0142771,0064055,0150453, +0141601,0131517,0164507,0062164, +}; +static short Q[20] = { +/* 0040200,0000000,0000000,0000000, */ +0041306,0157042,0154243,0000742, +0042045,0003352,0016707,0150452, +0042330,0070306,0113425,0170730, +0042362,0130770,0116602,0047520, +0042102,0106367,0156753,0013541, +}; + +/* tan( 3*pi/8 ) = 2.41421356237309504880 */ +static unsigned short T3P8A[] = {040432,0101171,0114774,0167462,}; +#define T3P8 *(double *)T3P8A +#endif + +#ifdef IBMPC +static short P[20] = { +0x2594,0xa1f7,0x007f,0xbfec, +0x807a,0x5b6b,0x2854,0xc030, +0x0273,0x3688,0xc08c,0xc052, +0xba25,0x2d05,0xb8bf,0xc05e, +0xec8e,0xfd28,0x3669,0xc050, +}; +static short Q[20] = { +/* 0x0000,0x0000,0x0000,0x3ff0, */ +0x603c,0x5b14,0xdbc4,0x4038, +0xfa25,0x43b8,0xa0dd,0x4064, +0xbe3b,0xd2e2,0x0e18,0x407b, +0x49ea,0x13b0,0x563f,0x407e, +0x62ec,0xfbbd,0x519e,0x4068, +}; + +/* tan( 3*pi/8 ) = 2.41421356237309504880 */ +static unsigned short T3P8A[] = {0x9de6,0x333f,0x504f,0x4003}; +#define T3P8 *(double *)T3P8A +#endif + +#ifdef MIEEE +static short P[20] = { +0xbfec,0x007f,0xa1f7,0x2594, +0xc030,0x2854,0x5b6b,0x807a, +0xc052,0xc08c,0x3688,0x0273, +0xc05e,0xb8bf,0x2d05,0xba25, +0xc050,0x3669,0xfd28,0xec8e, +}; +static short Q[20] = { +/* 0x3ff0,0x0000,0x0000,0x0000, */ +0x4038,0xdbc4,0x5b14,0x603c, +0x4064,0xa0dd,0x43b8,0xfa25, +0x407b,0x0e18,0xd2e2,0xbe3b, +0x407e,0x563f,0x13b0,0x49ea, +0x4068,0x519e,0xfbbd,0x62ec, +}; + +/* tan( 3*pi/8 ) = 2.41421356237309504880 */ +static unsigned short T3P8A[] = { +0x4003,0x504f,0x333f,0x9de6 +}; +#define T3P8 *(double *)T3P8A +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double atan ( double ); +extern double fabs ( double ); +extern int signbit ( double ); +extern int isnan ( double ); +#else +double polevl(), p1evl(), atan(), fabs(); +int signbit(), isnan(); +#endif +extern double PI, PIO2, PIO4, INFINITY, NEGZERO, MAXNUM; + +/* pi/2 = PIO2 + MOREBITS. */ +#ifdef DEC +#define MOREBITS 5.721188726109831840122E-18 +#else +#define MOREBITS 6.123233995736765886130E-17 +#endif + + +double c_atan(x) +double x; +{ +double y, z; +short sign, flag; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +#ifdef INFINITIES +if(x == INFINITY) + return(PIO2); +if(x == -INFINITY) + return(-PIO2); +#endif +/* make argument positive and save the sign */ +sign = 1; +if( x < 0.0 ) + { + sign = -1; + x = -x; + } +/* range reduction */ +flag = 0; +if( x > T3P8 ) + { + y = PIO2; + flag = 1; + x = -( 1.0/x ); + } +else if( x <= 0.66 ) + { + y = 0.0; + } +else + { + y = PIO4; + flag = 2; + x = (x-1.0)/(x+1.0); + } +z = x * x; +z = z * polevl( z, P, 4 ) / p1evl( z, Q, 5 ); +z = x * z + x; +if( flag == 2 ) + z += 0.5 * MOREBITS; +else if( flag == 1 ) + z += MOREBITS; +y = y + z; +if( sign < 0 ) + y = -y; +return(y); +} + +/* atan2 */ + +#ifdef ANSIC +double c_atan2( y, x ) +#else +double c_atan2( x, y ) +#endif +double x, y; +{ +double z, w; +short code; + +code = 0; + +#ifdef NANS +if( isnan(x) ) + return(x); +if( isnan(y) ) + return(y); +#endif +#ifdef MINUSZERO +if( y == 0.0 ) + { + if( signbit(y) ) + { + if( x > 0.0 ) + z = y; + else if( x < 0.0 ) + z = -PI; + else + { + if( signbit(x) ) + z = -PI; + else + z = y; + } + } + else /* y is +0 */ + { + if( x == 0.0 ) + { + if( signbit(x) ) + z = PI; + else + z = 0.0; + } + else if( x > 0.0 ) + z = 0.0; + else + z = PI; + } + return z; + } +if( x == 0.0 ) + { + if( y > 0.0 ) + z = PIO2; + else + z = -PIO2; + return z; + } +#endif /* MINUSZERO */ +#ifdef INFINITIES +if( x == INFINITY ) + { + if( y == INFINITY ) + z = 0.25 * PI; + else if( y == -INFINITY ) + z = -0.25 * PI; + else if( y < 0.0 ) + z = NEGZERO; + else + z = 0.0; + return z; + } +if( x == -INFINITY ) + { + if( y == INFINITY ) + z = 0.75 * PI; + else if( y <= -INFINITY ) + z = -0.75 * PI; + else if( y >= 0.0 ) + z = PI; + else + z = -PI; + return z; + } +if( y == INFINITY ) + return( PIO2 ); +if( y == -INFINITY ) + return( -PIO2 ); +#endif + +if( x < 0.0 ) + code = 2; +if( y < 0.0 ) + code |= 1; + +#ifdef INFINITIES +if( x == 0.0 ) +#else +if( fabs(x) <= (fabs(y) / MAXNUM) ) +#endif + { + if( code & 1 ) + { +#if ANSIC + return( -PIO2 ); +#else + return( 3.0*PIO2 ); +#endif + } + if( y == 0.0 ) + return( 0.0 ); + return( PIO2 ); + } + +if( y == 0.0 ) + { + if( code & 2 ) + return( PI ); + return( 0.0 ); + } + + +switch( code ) + { +#if ANSIC + default: + case 0: + case 1: w = 0.0; break; + case 2: w = PI; break; + case 3: w = -PI; break; +#else + default: + case 0: w = 0.0; break; + case 1: w = 2.0 * PI; break; + case 2: + case 3: w = PI; break; +#endif + } + +z = w + c_atan( y/x ); +#ifdef MINUSZERO +if( z == 0.0 && y < 0 ) + z = NEGZERO; +#endif +return( z ); +} diff --git a/src/math/cmath.h b/src/math/cmath.h new file mode 100644 index 000000000..b161e2106 --- /dev/null +++ b/src/math/cmath.h @@ -0,0 +1,139 @@ +#ifndef __CMATH_H +#define __CMATH_H + +#include "tables.h" +#include "m_fixed.h" + +#define USE_CUSTOM_MATH // we want reoreducably reliable results, even at the cost of performance +#define USE_FAST_MATH // use faster table-based sin and cos variants with limited precision (sufficient for Doom gameplay) + +extern"C" +{ +double c_asin(double); +double c_acos(double); +double c_atan(double); +double c_atan2(double, double); +double c_sin(double); +double c_cos(double); +double c_tan(double); +double c_cot(double); +double c_sqrt(double); +double c_sinh(double); +double c_cosh(double); +double c_tanh(double); +double c_exp(double); +double c_log(double); +double c_log10(double); +} + + +// This uses a sine table with linear interpolation +// For in-game calculations this is precise enough +// and this code is more than 10x faster than the +// Cephes sin and cos function. + +struct FFastTrig +{ + static const int TBLPERIOD = 8192; + static const int BITSHIFT = 19; + static const int REMAINDER = (1 << BITSHIFT) - 1; + float sinetable[2049]; + + double sinq1(unsigned); + +public: + FFastTrig(); + double sin(unsigned); + double cos(unsigned); +}; + +extern FFastTrig fasttrig; + + +inline double fastcosdeg(double v) +{ + return fasttrig.cos(FLOAT2ANGLE(v)); +} + +inline double fastsindeg(double v) +{ + return fasttrig.sin(FLOAT2ANGLE(v)); +} + +inline double fastcos(double v) +{ + return fasttrig.cos(RAD2ANGLE(v)); +} + +inline double fastsin(double v) +{ + return fasttrig.sin(RAD2ANGLE(v)); +} + +inline double sindeg(double v) +{ +#ifdef USE_CUSTOM_MATH + return c_sin(v * (M_PI / 180.)); +#else + return sin(v * (M_PI / 180.)); +#endif +} + +inline double cosdeg(double v) +{ +#ifdef USE_CUSTOM_MATH + return c_cos(v * (M_PI / 180.)); +#else + return cos(v * (M_PI / 180.)); +#endif +} + + +#ifndef USE_CUSTOM_MATH +#define g_asin asin +#define g_acos acos +#define g_atan atan +#define g_atan2 atan2 +#define g_sin sin +#define g_cos cos +#define g_sindeg sindeg +#define g_cosdeg cosdeg +#define g_tan tan +#define g_cot cot +#define g_sqrt sqrt +#define g_sinh sinh +#define g_cosh cosh +#define g_tanh tanh +#define g_exp exp +#define g_log log +#define g_log10 log10 +#else +#define g_asin c_asin +#define g_acos c_acos +#define g_atan c_atan +#define g_atan2 c_atan2 +#ifndef USE_FAST_MATH +#define g_sindeg sindeg +#define g_cosdeg cosdeg +#define g_sin c_sin +#define g_cos c_cos +#else +#define g_sindeg fastsindeg +#define g_cosdeg fastcosdeg +#define g_sin fastsin +#define g_cos fastcos +#endif +#define g_tan c_tan +#define g_cot c_cot +#define g_sqrt c_sqrt +#define g_sinh c_sinh +#define g_cosh c_cosh +#define g_tanh c_tanh +#define g_exp c_exp +#define g_log c_log +#define g_log10 c_log10 +#endif + + + +#endif \ No newline at end of file diff --git a/src/math/const.c b/src/math/const.c new file mode 100644 index 000000000..2d9ff7b33 --- /dev/null +++ b/src/math/const.c @@ -0,0 +1,252 @@ +/* const.c + * + * Globally declared constants + * + * + * + * SYNOPSIS: + * + * extern double nameofconstant; + * + * + * + * + * DESCRIPTION: + * + * This file contains a number of mathematical constants and + * also some needed size parameters of the computer arithmetic. + * The values are supplied as arrays of hexadecimal integers + * for IEEE arithmetic; arrays of octal constants for DEC + * arithmetic; and in a normal decimal scientific notation for + * other machines. The particular notation used is determined + * by a symbol (DEC, IBMPC, or UNK) defined in the include file + * mconf.h. + * + * The default size parameters are as follows. + * + * For DEC and UNK modes: + * MACHEP = 1.38777878078144567553E-17 2**-56 + * MAXLOG = 8.8029691931113054295988E1 log(2**127) + * MINLOG = -8.872283911167299960540E1 log(2**-128) + * MAXNUM = 1.701411834604692317316873e38 2**127 + * + * For IEEE arithmetic (IBMPC): + * MACHEP = 1.11022302462515654042E-16 2**-53 + * MAXLOG = 7.09782712893383996843E2 log(2**1024) + * MINLOG = -7.08396418532264106224E2 log(2**-1022) + * MAXNUM = 1.7976931348623158E308 2**1024 + * + * The global symbols for mathematical constants are + * PI = 3.14159265358979323846 pi + * PIO2 = 1.57079632679489661923 pi/2 + * PIO4 = 7.85398163397448309616E-1 pi/4 + * SQRT2 = 1.41421356237309504880 sqrt(2) + * SQRTH = 7.07106781186547524401E-1 sqrt(2)/2 + * LOG2E = 1.4426950408889634073599 1/log(2) + * SQ2OPI = 7.9788456080286535587989E-1 sqrt( 2/pi ) + * LOGE2 = 6.93147180559945309417E-1 log(2) + * LOGSQ2 = 3.46573590279972654709E-1 log(2)/2 + * THPIO4 = 2.35619449019234492885 3*pi/4 + * TWOOPI = 6.36619772367581343075535E-1 2/pi + * + * These lists are subject to change. + */ + +/* const.c */ + +/* +Cephes Math Library Release 2.3: March, 1995 +Copyright 1984, 1995 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +#if 1 +double MACHEP = 1.11022302462515654042E-16; /* 2**-53 */ +#else +double MACHEP = 1.38777878078144567553E-17; /* 2**-56 */ +#endif +double UFLOWTHRESH = 2.22507385850720138309E-308; /* 2**-1022 */ +#ifdef DENORMAL +double MAXLOG = 7.09782712893383996732E2; /* log(MAXNUM) */ +/* double MINLOG = -7.44440071921381262314E2; */ /* log(2**-1074) */ +double MINLOG = -7.451332191019412076235E2; /* log(2**-1075) */ +#else +double MAXLOG = 7.08396418532264106224E2; /* log 2**1022 */ +double MINLOG = -7.08396418532264106224E2; /* log 2**-1022 */ +#endif +double MAXNUM = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ +double PI = 3.14159265358979323846; /* pi */ +double PIO2 = 1.57079632679489661923; /* pi/2 */ +double PIO4 = 7.85398163397448309616E-1; /* pi/4 */ +double SQRT2 = 1.41421356237309504880; /* sqrt(2) */ +double SQRTH = 7.07106781186547524401E-1; /* sqrt(2)/2 */ +double LOG2E = 1.4426950408889634073599; /* 1/log(2) */ +double SQ2OPI = 7.9788456080286535587989E-1; /* sqrt( 2/pi ) */ +double LOGE2 = 6.93147180559945309417E-1; /* log(2) */ +double LOGSQ2 = 3.46573590279972654709E-1; /* log(2)/2 */ +double THPIO4 = 2.35619449019234492885; /* 3*pi/4 */ +double TWOOPI = 6.36619772367581343075535E-1; /* 2/pi */ +#ifdef INFINITIES +double INFINITY = 1.0/0.0; /* 99e999; */ +#else +double INFINITY = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ +#endif +#ifdef NANS +double NAN = 1.0/0.0 - 1.0/0.0; +#else +double NAN = 0.0; +#endif +#ifdef MINUSZERO +double NEGZERO = -0.0; +#else +double NEGZERO = 0.0; +#endif +#endif + +#ifdef IBMPC + /* 2**-53 = 1.11022302462515654042E-16 */ +unsigned short MACHEP[4] = {0x0000,0x0000,0x0000,0x3ca0}; +unsigned short UFLOWTHRESH[4] = {0x0000,0x0000,0x0000,0x0010}; +#ifdef DENORMAL + /* log(MAXNUM) = 7.09782712893383996732224E2 */ +unsigned short MAXLOG[4] = {0x39ef,0xfefa,0x2e42,0x4086}; + /* log(2**-1074) = - -7.44440071921381262314E2 */ +/*unsigned short MINLOG[4] = {0x71c3,0x446d,0x4385,0xc087};*/ +unsigned short MINLOG[4] = {0x3052,0xd52d,0x4910,0xc087}; +#else + /* log(2**1022) = 7.08396418532264106224E2 */ +unsigned short MAXLOG[4] = {0xbcd2,0xdd7a,0x232b,0x4086}; + /* log(2**-1022) = - 7.08396418532264106224E2 */ +unsigned short MINLOG[4] = {0xbcd2,0xdd7a,0x232b,0xc086}; +#endif + /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ +unsigned short MAXNUM[4] = {0xffff,0xffff,0xffff,0x7fef}; +unsigned short PI[4] = {0x2d18,0x5444,0x21fb,0x4009}; +unsigned short PIO2[4] = {0x2d18,0x5444,0x21fb,0x3ff9}; +unsigned short PIO4[4] = {0x2d18,0x5444,0x21fb,0x3fe9}; +unsigned short SQRT2[4] = {0x3bcd,0x667f,0xa09e,0x3ff6}; +unsigned short SQRTH[4] = {0x3bcd,0x667f,0xa09e,0x3fe6}; +unsigned short LOG2E[4] = {0x82fe,0x652b,0x1547,0x3ff7}; +unsigned short SQ2OPI[4] = {0x3651,0x33d4,0x8845,0x3fe9}; +unsigned short LOGE2[4] = {0x39ef,0xfefa,0x2e42,0x3fe6}; +unsigned short LOGSQ2[4] = {0x39ef,0xfefa,0x2e42,0x3fd6}; +unsigned short THPIO4[4] = {0x21d2,0x7f33,0xd97c,0x4002}; +unsigned short TWOOPI[4] = {0xc883,0x6dc9,0x5f30,0x3fe4}; +#ifdef INFINITIES +unsigned short INFINITY[4] = {0x0000,0x0000,0x0000,0x7ff0}; +#else +unsigned short INFINITY[4] = {0xffff,0xffff,0xffff,0x7fef}; +#endif +#ifdef NANS +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x7ffc}; +#else +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x8000}; +#else +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#endif + +#ifdef MIEEE + /* 2**-53 = 1.11022302462515654042E-16 */ +unsigned short MACHEP[4] = {0x3ca0,0x0000,0x0000,0x0000}; +unsigned short UFLOWTHRESH[4] = {0x0010,0x0000,0x0000,0x0000}; +#ifdef DENORMAL + /* log(2**1024) = 7.09782712893383996843E2 */ +unsigned short MAXLOG[4] = {0x4086,0x2e42,0xfefa,0x39ef}; + /* log(2**-1074) = - -7.44440071921381262314E2 */ +/* unsigned short MINLOG[4] = {0xc087,0x4385,0x446d,0x71c3}; */ +unsigned short MINLOG[4] = {0xc087,0x4910,0xd52d,0x3052}; +#else + /* log(2**1022) = 7.08396418532264106224E2 */ +unsigned short MAXLOG[4] = {0x4086,0x232b,0xdd7a,0xbcd2}; + /* log(2**-1022) = - 7.08396418532264106224E2 */ +unsigned short MINLOG[4] = {0xc086,0x232b,0xdd7a,0xbcd2}; +#endif + /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ +unsigned short MAXNUM[4] = {0x7fef,0xffff,0xffff,0xffff}; +unsigned short PI[4] = {0x4009,0x21fb,0x5444,0x2d18}; +unsigned short PIO2[4] = {0x3ff9,0x21fb,0x5444,0x2d18}; +unsigned short PIO4[4] = {0x3fe9,0x21fb,0x5444,0x2d18}; +unsigned short SQRT2[4] = {0x3ff6,0xa09e,0x667f,0x3bcd}; +unsigned short SQRTH[4] = {0x3fe6,0xa09e,0x667f,0x3bcd}; +unsigned short LOG2E[4] = {0x3ff7,0x1547,0x652b,0x82fe}; +unsigned short SQ2OPI[4] = {0x3fe9,0x8845,0x33d4,0x3651}; +unsigned short LOGE2[4] = {0x3fe6,0x2e42,0xfefa,0x39ef}; +unsigned short LOGSQ2[4] = {0x3fd6,0x2e42,0xfefa,0x39ef}; +unsigned short THPIO4[4] = {0x4002,0xd97c,0x7f33,0x21d2}; +unsigned short TWOOPI[4] = {0x3fe4,0x5f30,0x6dc9,0xc883}; +#ifdef INFINITIES +unsigned short INFINITY[4] = {0x7ff0,0x0000,0x0000,0x0000}; +#else +unsigned short INFINITY[4] = {0x7fef,0xffff,0xffff,0xffff}; +#endif +#ifdef NANS +unsigned short NAN[4] = {0x7ff8,0x0000,0x0000,0x0000}; +#else +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0x8000,0x0000,0x0000,0x0000}; +#else +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#endif + +#ifdef DEC + /* 2**-56 = 1.38777878078144567553E-17 */ +unsigned short MACHEP[4] = {0022200,0000000,0000000,0000000}; +unsigned short UFLOWTHRESH[4] = {0x0080,0x0000,0x0000,0x0000}; + /* log 2**127 = 88.029691931113054295988 */ +unsigned short MAXLOG[4] = {041660,007463,0143742,025733,}; + /* log 2**-128 = -88.72283911167299960540 */ +unsigned short MINLOG[4] = {0141661,071027,0173721,0147572,}; + /* 2**127 = 1.701411834604692317316873e38 */ +unsigned short MAXNUM[4] = {077777,0177777,0177777,0177777,}; +unsigned short PI[4] = {040511,007732,0121041,064302,}; +unsigned short PIO2[4] = {040311,007732,0121041,064302,}; +unsigned short PIO4[4] = {040111,007732,0121041,064302,}; +unsigned short SQRT2[4] = {040265,002363,031771,0157145,}; +unsigned short SQRTH[4] = {040065,002363,031771,0157144,}; +unsigned short LOG2E[4] = {040270,0125073,024534,013761,}; +unsigned short SQ2OPI[4] = {040114,041051,0117241,0131204,}; +unsigned short LOGE2[4] = {040061,071027,0173721,0147572,}; +unsigned short LOGSQ2[4] = {037661,071027,0173721,0147572,}; +unsigned short THPIO4[4] = {040426,0145743,0174631,007222,}; +unsigned short TWOOPI[4] = {040042,0174603,067116,042025,}; +/* Approximate infinity by MAXNUM. */ +unsigned short INFINITY[4] = {077777,0177777,0177777,0177777,}; +unsigned short NAN[4] = {0000000,0000000,0000000,0000000}; +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0000000,0000000,0000000,0100000}; +#else +unsigned short NEGZERO[4] = {0000000,0000000,0000000,0000000}; +#endif +#endif + +#ifndef UNK +extern unsigned short MACHEP[]; +extern unsigned short UFLOWTHRESH[]; +extern unsigned short MAXLOG[]; +extern unsigned short UNDLOG[]; +extern unsigned short MINLOG[]; +extern unsigned short MAXNUM[]; +extern unsigned short PI[]; +extern unsigned short PIO2[]; +extern unsigned short PIO4[]; +extern unsigned short SQRT2[]; +extern unsigned short SQRTH[]; +extern unsigned short LOG2E[]; +extern unsigned short SQ2OPI[]; +extern unsigned short LOGE2[]; +extern unsigned short LOGSQ2[]; +extern unsigned short THPIO4[]; +extern unsigned short TWOOPI[]; +extern unsigned short INFINITY[]; +extern unsigned short NAN[]; +extern unsigned short NEGZERO[]; +#endif diff --git a/src/math/cosh.c b/src/math/cosh.c new file mode 100644 index 000000000..d69f5b344 --- /dev/null +++ b/src/math/cosh.c @@ -0,0 +1,83 @@ +/* cosh.c + * + * Hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * double x, y, cosh(); + * + * y = cosh( x ); + * + * + * + * DESCRIPTION: + * + * Returns hyperbolic cosine of argument in the range MINLOG to + * MAXLOG. + * + * cosh(x) = ( exp(x) + exp(-x) )/2. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC +- 88 50000 4.0e-17 7.7e-18 + * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * cosh overflow |x| > MAXLOG MAXNUM + * + * + */ + +/* cosh.c */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1985, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" +#ifdef ANSIPROT +extern double c_exp ( double ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double c_exp(); +int isnan(), isfinite(); +#endif +extern double MAXLOG, INFINITY, LOGE2; + +double c_cosh(x) +double x; +{ +double y; + +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +if( x < 0 ) + x = -x; +if( x > (MAXLOG + LOGE2) ) + { + mtherr( "cosh", OVERFLOW ); + return( INFINITY ); + } +if( x >= (MAXLOG - LOGE2) ) + { + y = c_exp(0.5 * x); + y = (0.5 * y) * y; + return(y); + } +y = c_exp(x); +y = 0.5 * (y + 1.0 / y); +return( y ); +} diff --git a/src/math/exp.c b/src/math/exp.c new file mode 100644 index 000000000..7d2b1e88f --- /dev/null +++ b/src/math/exp.c @@ -0,0 +1,182 @@ +/* exp.c + * + * Exponential function + * + * + * + * SYNOPSIS: + * + * double x, y, exp(); + * + * y = exp( x ); + * + * + * + * DESCRIPTION: + * + * Returns e (2.71828...) raised to the x power. + * + * Range reduction is accomplished by separating the argument + * into an integer k and fraction f such that + * + * x k f + * e = 2 e. + * + * A Pade' form 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) + * of degree 2/3 is used to approximate exp(f) in the basic + * interval [-0.5, 0.5]. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC 0, MAXLOG 38000 3.0e-17 6.2e-18 + * IEEE +- 708 40000 2.0e-16 5.6e-17 + * + * + * Error amplification in the exponential function can be + * a serious matter. The error propagation involves + * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), + * which shows that a 1 lsb error in representing X produces + * a relative error of X times 1 lsb in the function. + * While the routine gives an accurate result for arguments + * that are exactly represented by a double precision + * computer number, the result contains amplified roundoff + * error for large arguments not exactly represented. + * + * + * ERROR MESSAGES: + * + * message condition value returned + * exp underflow x < MINLOG 0.0 + * exp overflow x > MAXLOG MAXNUM + * + */ + +/* +Cephes Math Library Release 2.2: January, 1991 +Copyright 1984, 1991 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + + +/* Exponential function */ + +#include "mconf.h" +static char fname[] = {"exp"}; + +#ifdef UNK + +static double P[] = { + 1.26177193074810590878E-4, + 3.02994407707441961300E-2, + 9.99999999999999999910E-1, +}; +static double Q[] = { + 3.00198505138664455042E-6, + 2.52448340349684104192E-3, + 2.27265548208155028766E-1, + 2.00000000000000000009E0, +}; +static double C1 = 6.93145751953125E-1; +static double C2 = 1.42860682030941723212E-6; +#endif + +#ifdef DEC +static short P[] = { +0035004,0047156,0127442,0057502, +0036770,0033210,0063121,0061764, +0040200,0000000,0000000,0000000, +}; +static short Q[] = { +0033511,0072665,0160662,0176377, +0036045,0070715,0124105,0132777, +0037550,0134114,0142077,0001637, +0040400,0000000,0000000,0000000, +}; +static short sc1[] = {0040061,0071000,0000000,0000000}; +#define C1 (*(double *)sc1) +static short sc2[] = {0033277,0137216,0075715,0057117}; +#define C2 (*(double *)sc2) +#endif + +#ifdef IBMPC +static short P[] = { +0x4be8,0xd5e4,0x89cd,0x3f20, +0x2c7e,0x0cca,0x06d1,0x3f9f, +0x0000,0x0000,0x0000,0x3ff0, +}; +static short Q[] = { +0x5fa0,0xbc36,0x2eb6,0x3ec9, +0xb6c0,0xb508,0xae39,0x3f64, +0xe074,0x9887,0x1709,0x3fcd, +0x0000,0x0000,0x0000,0x4000, +}; +static short sc1[] = {0x0000,0x0000,0x2e40,0x3fe6}; +#define C1 (*(double *)sc1) +static short sc2[] = {0xabca,0xcf79,0xf7d1,0x3eb7}; +#define C2 (*(double *)sc2) +#endif + +#ifdef MIEEE +static short P[] = { +0x3f20,0x89cd,0xd5e4,0x4be8, +0x3f9f,0x06d1,0x0cca,0x2c7e, +0x3ff0,0x0000,0x0000,0x0000, +}; +static short Q[] = { +0x3ec9,0x2eb6,0xbc36,0x5fa0, +0x3f64,0xae39,0xb508,0xb6c0, +0x3fcd,0x1709,0x9887,0xe074, +0x4000,0x0000,0x0000,0x0000, +}; +static short sc1[] = {0x3fe6,0x2e40,0x0000,0x0000}; +#define C1 (*(double *)sc1) +static short sc2[] = {0x3eb7,0xf7d1,0xcf79,0xabca}; +#define C2 (*(double *)sc2) +#endif + +extern double LOGE2, LOG2E, MAXLOG, MINLOG, MAXNUM; + +double c_exp(x) +double x; +{ +double px, xx; +int n; +double polevl(), floor(), ldexp(); + +if( x > MAXLOG) + { + mtherr( fname, OVERFLOW ); + return( MAXNUM ); + } + +if( x < MINLOG ) + { + mtherr( fname, UNDERFLOW ); + return(0.0); + } + +/* Express e**x = e**g 2**n + * = e**g e**( n loge(2) ) + * = e**( g + n loge(2) ) + */ +px = floor( LOG2E * x + 0.5 ); /* floor() truncates toward -infinity. */ +n = (int)px; +x -= px * C1; +x -= px * C2; + +/* rational approximation for exponential + * of the fractional part: + * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) + */ +xx = x * x; +px = x * polevl( xx, P, 2 ); +x = px/( polevl( xx, Q, 3 ) - px ); +x = 1.0 + ldexp( x, 1 ); + +/* multiply by power of 2 */ +x = ldexp( x, n ); +return(x); +} diff --git a/src/math/fastsin.cpp b/src/math/fastsin.cpp new file mode 100644 index 000000000..6220585f9 --- /dev/null +++ b/src/math/fastsin.cpp @@ -0,0 +1,102 @@ +/* +** fastsin.cpp +** a table/linear interpolation-based sine function that is both +** precise and fast enough for most purposes. +** +**--------------------------------------------------------------------------- +** Copyright 2015 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include "cmath.h" +#include "m_fixed.h" + +FFastTrig fasttrig; + +FFastTrig::FFastTrig() +{ + const double pimul = M_PI * 2 / TBLPERIOD; + + for (int i = 0; i < 2049; i++) + { + sinetable[i] = (float)c_sin(i*pimul); + } +} + +__forceinline double FFastTrig::sinq1(unsigned bangle) +{ + unsigned int index = bangle >> BITSHIFT; + + if ((bangle &= (REMAINDER)) == 0) // This is to avoid precision problems at 180° + { + return double(sinetable[index]); + } + else + { + return (double(sinetable[index]) * (REMAINDER - bangle) + double(sinetable[index + 1]) * bangle) * (1. / REMAINDER); + } +} + +double FFastTrig::sin(unsigned bangle) +{ + switch (bangle & 0xc0000000) + { + default: + return sinq1(bangle); + + case 0x40000000: + return sinq1(0x80000000 - bangle); + + case 0x80000000: + return -sinq1(bangle - 0x80000000); + + case 0xc0000000: + return -sinq1(0 - bangle); + } +} + + +double FFastTrig::cos(unsigned bangle) +{ + switch (bangle & 0xc0000000) + { + default: + return sinq1(0x40000000 - bangle); + + case 0x40000000: + return -sinq1(bangle - 0x40000000); + + case 0x80000000: + return -sinq1(0xc0000000 - bangle); + + case 0xc0000000: + return sinq1(bangle - 0xc0000000); + } +} + diff --git a/src/math/isnan.c b/src/math/isnan.c new file mode 100644 index 000000000..b5341e650 --- /dev/null +++ b/src/math/isnan.c @@ -0,0 +1,237 @@ +/* isnan() + * signbit() + * isfinite() + * + * Floating point numeric utilities + * + * + * + * SYNOPSIS: + * + * double ceil(), floor(), frexp(), ldexp(); + * int signbit(), isnan(), isfinite(); + * double x, y; + * int expnt, n; + * + * y = floor(x); + * y = ceil(x); + * y = frexp( x, &expnt ); + * y = ldexp( x, n ); + * n = signbit(x); + * n = isnan(x); + * n = isfinite(x); + * + * + * + * DESCRIPTION: + * + * All four routines return a double precision floating point + * result. + * + * floor() returns the largest integer less than or equal to x. + * It truncates toward minus infinity. + * + * ceil() returns the smallest integer greater than or equal + * to x. It truncates toward plus infinity. + * + * frexp() extracts the exponent from x. It returns an integer + * power of two to expnt and the significand between 0.5 and 1 + * to y. Thus x = y * 2**expn. + * + * ldexp() multiplies x by 2**n. + * + * signbit(x) returns 1 if the sign bit of x is 1, else 0. + * + * These functions are part of the standard C run time library + * for many but not all C compilers. The ones supplied are + * written in C for either DEC or IEEE arithmetic. They should + * be used only if your compiler library does not already have + * them. + * + * The IEEE versions assume that denormal numbers are implemented + * in the arithmetic. Some modifications will be required if + * the arithmetic has abrupt rather than gradual underflow. + */ + + +/* +Cephes Math Library Release 2.3: March, 1995 +Copyright 1984, 1995 by Stephen L. Moshier +*/ + + +#include "mconf.h" + +#ifdef UNK +/* ceil(), floor(), frexp(), ldexp() may need to be rewritten. */ +#undef UNK +#if BIGENDIAN +#define MIEEE 1 +#else +#define IBMPC 1 +#endif +#endif + + +/* Return 1 if the sign bit of x is 1, else 0. */ + +int signbit(x) +double x; +{ +union + { + double d; + short s[4]; + int i[2]; + } u; + +u.d = x; + +if( sizeof(int) == 4 ) + { +#ifdef IBMPC + return( u.i[1] < 0 ); +#endif +#ifdef DEC + return( u.s[3] < 0 ); +#endif +#ifdef MIEEE + return( u.i[0] < 0 ); +#endif + } +else + { +#ifdef IBMPC + return( u.s[3] < 0 ); +#endif +#ifdef DEC + return( u.s[3] < 0 ); +#endif +#ifdef MIEEE + return( u.s[0] < 0 ); +#endif + } +} + + +/* Return 1 if x is a number that is Not a Number, else return 0. */ + +int isnan(x) +double x; +{ +#ifdef NANS +union + { + double d; + unsigned short s[4]; + unsigned int i[2]; + } u; + +u.d = x; + +if( sizeof(int) == 4 ) + { +#ifdef IBMPC + if( ((u.i[1] & 0x7ff00000) == 0x7ff00000) + && (((u.i[1] & 0x000fffff) != 0) || (u.i[0] != 0))) + return 1; +#endif +#ifdef DEC + if( (u.s[1] & 0x7fff) == 0) + { + if( (u.s[2] | u.s[1] | u.s[0]) != 0 ) + return(1); + } +#endif +#ifdef MIEEE + if( ((u.i[0] & 0x7ff00000) == 0x7ff00000) + && (((u.i[0] & 0x000fffff) != 0) || (u.i[1] != 0))) + return 1; +#endif + return(0); + } +else + { /* size int not 4 */ +#ifdef IBMPC + if( (u.s[3] & 0x7ff0) == 0x7ff0) + { + if( ((u.s[3] & 0x000f) | u.s[2] | u.s[1] | u.s[0]) != 0 ) + return(1); + } +#endif +#ifdef DEC + if( (u.s[3] & 0x7fff) == 0) + { + if( (u.s[2] | u.s[1] | u.s[0]) != 0 ) + return(1); + } +#endif +#ifdef MIEEE + if( (u.s[0] & 0x7ff0) == 0x7ff0) + { + if( ((u.s[0] & 0x000f) | u.s[1] | u.s[2] | u.s[3]) != 0 ) + return(1); + } +#endif + return(0); + } /* size int not 4 */ + +#else +/* No NANS. */ +return(0); +#endif +} + + +/* Return 1 if x is not infinite and is not a NaN. */ + +int isfinite(x) +double x; +{ +#ifdef INFINITIES +union + { + double d; + unsigned short s[4]; + unsigned int i[2]; + } u; + +u.d = x; + +if( sizeof(int) == 4 ) + { +#ifdef IBMPC + if( (u.i[1] & 0x7ff00000) != 0x7ff00000) + return 1; +#endif +#ifdef DEC + if( (u.s[3] & 0x7fff) != 0) + return 1; +#endif +#ifdef MIEEE + if( (u.i[0] & 0x7ff00000) != 0x7ff00000) + return 1; +#endif + return(0); + } +else + { +#ifdef IBMPC + if( (u.s[3] & 0x7ff0) != 0x7ff0) + return 1; +#endif +#ifdef DEC + if( (u.s[3] & 0x7fff) != 0) + return 1; +#endif +#ifdef MIEEE + if( (u.s[0] & 0x7ff0) != 0x7ff0) + return 1; +#endif + return(0); + } +#else +/* No INFINITY. */ +return(1); +#endif +} diff --git a/src/math/log.c b/src/math/log.c new file mode 100644 index 000000000..34a8faf02 --- /dev/null +++ b/src/math/log.c @@ -0,0 +1,341 @@ +/* log.c + * + * Natural logarithm + * + * + * + * SYNOPSIS: + * + * double x, y, log(); + * + * y = log( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z**3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 150000 1.44e-16 5.06e-17 + * IEEE +-MAXNUM 30000 1.20e-16 4.78e-17 + * DEC 0, 10 170000 1.8e-17 6.3e-18 + * + * In the tests over the interval [+-MAXNUM], the logarithms + * of the random arguments were uniformly distributed over + * [0, MAXLOG]. + * + * ERROR MESSAGES: + * + * log singularity: x = 0; returns -INFINITY + * log domain: x < 0; returns NAN + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" +static char fname[] = {"log"}; + +/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + */ +#ifdef UNK +static double P[] = { + 1.01875663804580931796E-4, + 4.97494994976747001425E-1, + 4.70579119878881725854E0, + 1.44989225341610930846E1, + 1.79368678507819816313E1, + 7.70838733755885391666E0, +}; +static double Q[] = { +/* 1.00000000000000000000E0, */ + 1.12873587189167450590E1, + 4.52279145837532221105E1, + 8.29875266912776603211E1, + 7.11544750618563894466E1, + 2.31251620126765340583E1, +}; +#endif + +#ifdef DEC +static unsigned short P[] = { +0037777,0127270,0162547,0057274, +0041001,0054665,0164317,0005341, +0041451,0034104,0031640,0105773, +0041677,0011276,0123617,0160135, +0041701,0126603,0053215,0117250, +0041420,0115777,0135206,0030232, +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0041220,0144332,0045272,0174241, +0041742,0164566,0035720,0130431, +0042246,0126327,0166065,0116357, +0042372,0033420,0157525,0124560, +0042271,0167002,0066537,0172303, +0041730,0164777,0113711,0044407, +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x1bb0,0x93c3,0xb4c2,0x3f1a, +0x52f2,0x3f56,0xd6f5,0x3fdf, +0x6911,0xed92,0xd2ba,0x4012, +0xeb2e,0xc63e,0xff72,0x402c, +0xc84d,0x924b,0xefd6,0x4031, +0xdcf8,0x7d7e,0xd563,0x401e, +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0xef8e,0xae97,0x9320,0x4026, +0xc033,0x4e19,0x9d2c,0x4046, +0xbdbd,0xa326,0xbf33,0x4054, +0xae21,0xeb5e,0xc9e2,0x4051, +0x25b2,0x9e1f,0x200a,0x4037, +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0x3f1a,0xb4c2,0x93c3,0x1bb0, +0x3fdf,0xd6f5,0x3f56,0x52f2, +0x4012,0xd2ba,0xed92,0x6911, +0x402c,0xff72,0xc63e,0xeb2e, +0x4031,0xefd6,0x924b,0xc84d, +0x401e,0xd563,0x7d7e,0xdcf8, +}; +static unsigned short Q[] = { +/*0x3ff0,0x0000,0x0000,0x0000,*/ +0x4026,0x9320,0xae97,0xef8e, +0x4046,0x9d2c,0x4e19,0xc033, +0x4054,0xbf33,0xa326,0xbdbd, +0x4051,0xc9e2,0xeb5e,0xae21, +0x4037,0x200a,0x9e1f,0x25b2, +}; +#endif + +/* Coefficients for log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + */ + +#ifdef UNK +static double R[3] = { +-7.89580278884799154124E-1, + 1.63866645699558079767E1, +-6.41409952958715622951E1, +}; +static double S[3] = { +/* 1.00000000000000000000E0,*/ +-3.56722798256324312549E1, + 3.12093766372244180303E2, +-7.69691943550460008604E2, +}; +#endif +#ifdef DEC +static unsigned short R[12] = { +0140112,0020756,0161540,0072035, +0041203,0013743,0114023,0155527, +0141600,0044060,0104421,0050400, +}; +static unsigned short S[12] = { +/*0040200,0000000,0000000,0000000,*/ +0141416,0130152,0017543,0064122, +0042234,0006000,0104527,0020155, +0142500,0066110,0146631,0174731, +}; +#endif +#ifdef IBMPC +static unsigned short R[12] = { +0x0e84,0xdc6c,0x443d,0xbfe9, +0x7b6b,0x7302,0x62fc,0x4030, +0x2a20,0x1122,0x0906,0xc050, +}; +static unsigned short S[12] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x6d0a,0x43ec,0xd60d,0xc041, +0xe40e,0x112a,0x8180,0x4073, +0x3f3b,0x19b3,0x0d89,0xc088, +}; +#endif +#ifdef MIEEE +static unsigned short R[12] = { +0xbfe9,0x443d,0xdc6c,0x0e84, +0x4030,0x62fc,0x7302,0x7b6b, +0xc050,0x0906,0x1122,0x2a20, +}; +static unsigned short S[12] = { +/*0x3ff0,0x0000,0x0000,0x0000,*/ +0xc041,0xd60d,0x43ec,0x6d0a, +0x4073,0x8180,0x112a,0xe40e, +0xc088,0x0d89,0x19b3,0x3f3b, +}; +#endif + +#ifdef ANSIPROT +extern double frexp ( double, int * ); +extern double ldexp ( double, int ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double frexp(), ldexp(), polevl(), p1evl(); +int isnan(), isfinite(); +#endif +#define SQRTH 0.70710678118654752440 +extern double INFINITY, NAN; + +double c_log(x) +double x; +{ +int e; +#ifdef DEC +short *q; +#endif +double y, z; + +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +#ifdef INFINITIES +if( x == INFINITY ) + return(x); +#endif +/* Test for domain */ +if( x <= 0.0 ) + { + if( x == 0.0 ) + { + mtherr( fname, SING ); + return( -INFINITY ); + } + else + { + mtherr( fname, DOMAIN ); + return( NAN ); + } + } + +/* separate mantissa from exponent */ + +#ifdef DEC +q = (short *)&x; +e = *q; /* short containing exponent */ +e = ((e >> 7) & 0377) - 0200; /* the exponent */ +*q &= 0177; /* strip exponent from x */ +*q |= 040000; /* x now between 0.5 and 1 */ +#endif + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ +#ifdef IBMPC +x = frexp( x, &e ); +/* +q = (short *)&x; +q += 3; +e = *q; +e = ((e >> 4) & 0x0fff) - 0x3fe; +*q &= 0x0f; +*q |= 0x3fe0; +*/ +#endif + +/* Equivalent C language standard library function: */ +#ifdef UNK +x = frexp( x, &e ); +#endif + +#ifdef MIEEE +x = frexp( x, &e ); +#endif + + + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ + +if( (e > 2) || (e < -2) ) +{ +if( x < SQRTH ) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } +else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + +x = z / y; + + +/* rational form */ +z = x*x; +z = x * ( z * polevl( z, R, 2 ) / p1evl( z, S, 3 ) ); +y = e; +z = z - y * 2.121944400546905827679e-4; +z = z + x; +z = z + e * 0.693359375; +goto ldone; +} + + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ + } +else + { + x = x - 1.0; + } + + +/* rational form */ +z = x*x; +#if DEC +y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 6 ) ); +#else +y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 5 ) ); +#endif +if( e ) + y = y - e * 2.121944400546905827679e-4; +y = y - ldexp( z, -1 ); /* y - 0.5 * z */ +z = x + y; +if( e ) + z = z + e * 0.693359375; + +ldone: + +return( z ); +} diff --git a/src/math/log10.c b/src/math/log10.c new file mode 100644 index 000000000..df67d30b9 --- /dev/null +++ b/src/math/log10.c @@ -0,0 +1,250 @@ +/* log10.c + * + * Common logarithm + * + * + * + * SYNOPSIS: + * + * double x, y, log10(); + * + * y = log10( x ); + * + * + * + * DESCRIPTION: + * + * Returns logarithm to the base 10 of x. + * + * The argument is separated into its exponent and fractional + * parts. The logarithm of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 30000 1.5e-16 5.0e-17 + * IEEE 0, MAXNUM 30000 1.4e-16 4.8e-17 + * DEC 1, MAXNUM 50000 2.5e-17 6.0e-18 + * + * In the tests over the interval [1, MAXNUM], the logarithms + * of the random arguments were uniformly distributed over + * [0, MAXLOG]. + * + * ERROR MESSAGES: + * + * log10 singularity: x = 0; returns -INFINITY + * log10 domain: x < 0; returns NAN + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" +static char fname[] = {"log10"}; + +/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + */ +#ifdef UNK +static double P[] = { + 4.58482948458143443514E-5, + 4.98531067254050724270E-1, + 6.56312093769992875930E0, + 2.97877425097986925891E1, + 6.06127134467767258030E1, + 5.67349287391754285487E1, + 1.98892446572874072159E1 +}; +static double Q[] = { +/* 1.00000000000000000000E0, */ + 1.50314182634250003249E1, + 8.27410449222435217021E1, + 2.20664384982121929218E2, + 3.07254189979530058263E2, + 2.14955586696422947765E2, + 5.96677339718622216300E1 +}; +#endif + +#ifdef DEC +static unsigned short P[] = { +0034500,0046473,0051374,0135174, +0037777,0037566,0145712,0150321, +0040722,0002426,0031543,0123107, +0041356,0046513,0170752,0004346, +0041562,0071553,0023536,0163343, +0041542,0170221,0024316,0114216, +0041237,0016454,0046611,0104602 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0041160,0100260,0067736,0102424, +0041645,0075552,0036563,0147072, +0042134,0125025,0021132,0025320, +0042231,0120211,0046030,0103271, +0042126,0172241,0052151,0120426, +0041556,0125702,0072116,0047103 +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x974f,0x6a5f,0x09a7,0x3f08, +0x5a1a,0xd979,0xe7ee,0x3fdf, +0x74c9,0xc66c,0x40a2,0x401a, +0x411d,0x7e3d,0xc9a9,0x403d, +0xdcdc,0x64eb,0x4e6d,0x404e, +0xd312,0x2519,0x5e12,0x404c, +0x3130,0x89b1,0xe3a5,0x4033 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0xd0a2,0x0dfb,0x1016,0x402e, +0x79c7,0x47ae,0xaf6d,0x4054, +0x455a,0xa44b,0x9542,0x406b, +0x10d7,0x2983,0x3411,0x4073, +0x3423,0x2a8d,0xde94,0x406a, +0xc9c8,0x4e89,0xd578,0x404d +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0x3f08,0x09a7,0x6a5f,0x974f, +0x3fdf,0xe7ee,0xd979,0x5a1a, +0x401a,0x40a2,0xc66c,0x74c9, +0x403d,0xc9a9,0x7e3d,0x411d, +0x404e,0x4e6d,0x64eb,0xdcdc, +0x404c,0x5e12,0x2519,0xd312, +0x4033,0xe3a5,0x89b1,0x3130 +}; +static unsigned short Q[] = { +0x402e,0x1016,0x0dfb,0xd0a2, +0x4054,0xaf6d,0x47ae,0x79c7, +0x406b,0x9542,0xa44b,0x455a, +0x4073,0x3411,0x2983,0x10d7, +0x406a,0xde94,0x2a8d,0x3423, +0x404d,0xd578,0x4e89,0xc9c8 +}; +#endif + +#define SQRTH 0.70710678118654752440 +#define L102A 3.0078125E-1 +#define L102B 2.48745663981195213739E-4 +#define L10EA 4.3359375E-1 +#define L10EB 7.00731903251827651129E-4 + +#ifdef ANSIPROT +extern double frexp ( double, int * ); +extern double ldexp ( double, int ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double frexp(), ldexp(), polevl(), p1evl(); +int isnan(), isfinite(); +#endif +extern double LOGE2, SQRT2, INFINITY, NAN; + +double c_log10(x) +double x; +{ +VOLATILE double z; +double y; +#ifdef DEC +short *q; +#endif +int e; + +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +#ifdef INFINITIES +if( x == INFINITY ) + return(x); +#endif +/* Test for domain */ +if( x <= 0.0 ) + { + if( x == 0.0 ) + { + mtherr( fname, SING ); + return( -INFINITY ); + } + else + { + mtherr( fname, DOMAIN ); + return( NAN ); + } + } + +/* separate mantissa from exponent */ + +#ifdef DEC +q = (short *)&x; +e = *q; /* short containing exponent */ +e = ((e >> 7) & 0377) - 0200; /* the exponent */ +*q &= 0177; /* strip exponent from x */ +*q |= 040000; /* x now between 0.5 and 1 */ +#endif + +#ifdef IBMPC +x = frexp( x, &e ); +/* +q = (short *)&x; +q += 3; +e = *q; +e = ((e >> 4) & 0x0fff) - 0x3fe; +*q &= 0x0f; +*q |= 0x3fe0; +*/ +#endif + +/* Equivalent C language standard library function: */ +#ifdef UNK +x = frexp( x, &e ); +#endif + +#ifdef MIEEE +x = frexp( x, &e ); +#endif + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ + } +else + { + x = x - 1.0; + } + + +/* rational form */ +z = x*x; +y = x * ( z * polevl( x, P, 6 ) / p1evl( x, Q, 6 ) ); +y = y - ldexp( z, -1 ); /* y - 0.5 * x**2 */ + +/* multiply log of fraction by log10(e) + * and base 2 exponent by log10(2) + */ +z = (x + y) * L10EB; /* accumulate terms in order of size */ +z += y * L10EA; +z += x * L10EA; +z += e * L102B; +z += e * L102A; + + +return( z ); +} diff --git a/src/math/mconf.h b/src/math/mconf.h new file mode 100644 index 000000000..6e8e982ff --- /dev/null +++ b/src/math/mconf.h @@ -0,0 +1,199 @@ +/* mconf.h + * + * Common include file for math routines + * + * + * + * SYNOPSIS: + * + * #include "mconf.h" + * + * + * + * DESCRIPTION: + * + * This file contains definitions for error codes that are + * passed to the common error handling routine mtherr() + * (which see). + * + * The file also includes a conditional assembly definition + * for the type of computer arithmetic (IEEE, DEC, Motorola + * IEEE, or UNKnown). + * + * For Digital Equipment PDP-11 and VAX computers, certain + * IBM systems, and others that use numbers with a 56-bit + * significand, the symbol DEC should be defined. In this + * mode, most floating point constants are given as arrays + * of octal integers to eliminate decimal to binary conversion + * errors that might be introduced by the compiler. + * + * For little-endian computers, such as IBM PC, that follow the + * IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE + * Std 754-1985), the symbol IBMPC should be defined. These + * numbers have 53-bit significands. In this mode, constants + * are provided as arrays of hexadecimal 16 bit integers. + * + * Big-endian IEEE format is denoted MIEEE. On some RISC + * systems such as Sun SPARC, double precision constants + * must be stored on 8-byte address boundaries. Since integer + * arrays may be aligned differently, the MIEEE configuration + * may fail on such machines. + * + * To accommodate other types of computer arithmetic, all + * constants are also provided in a normal decimal radix + * which one can hope are correctly converted to a suitable + * format by the available C language compiler. To invoke + * this mode, define the symbol UNK. + * + * An important difference among these modes is a predefined + * set of machine arithmetic constants for each. The numbers + * MACHEP (the machine roundoff error), MAXNUM (largest number + * represented), and several other parameters are preset by + * the configuration symbol. Check the file const.c to + * ensure that these values are correct for your computer. + * + * Configurations NANS, INFINITIES, MINUSZERO, and DENORMAL + * may fail on many systems. Verify that they are supposed + * to work on your computer. + */ +/* +Cephes Math Library Release 2.3: June, 1995 +Copyright 1984, 1987, 1989, 1995 by Stephen L. Moshier +*/ + + +/* Define if the `long double' type works. */ +//#define HAVE_LONG_DOUBLE 0 + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define if floating point words are bigendian. */ +/* #undef FLOAT_WORDS_BIGENDIAN */ + +/* The number of bytes in a int. */ +#define SIZEOF_INT 4 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Name of package */ +#define PACKAGE "cephes" + +/* Version number of package */ +#define VERSION "2.7" + +/* Constant definitions for math error conditions + */ + +#define DOMAIN 1 /* argument domain error */ +#define SING 2 /* argument singularity */ +#define OVERFLOW 3 /* overflow range error */ +#define UNDERFLOW 4 /* underflow range error */ +#define TLOSS 5 /* total loss of precision */ +#define PLOSS 6 /* partial loss of precision */ + +#define EDOM 33 +#define ERANGE 34 +/* Complex numeral. */ +typedef struct + { + double r; + double i; + } cmplx; + +#ifdef HAVE_LONG_DOUBLE +/* Long double complex numeral. */ +typedef struct + { + long double r; + long double i; + } cmplxl; +#endif + + +/* Type of computer arithmetic */ + +/* PDP-11, Pro350, VAX: + */ +/* #define DEC 1 */ + +/* Intel IEEE, low order words come first: + */ +//#define IBMPC 1 + +/* Motorola IEEE, high order words come first + * (Sun 680x0 workstation): + */ +/* #define MIEEE 1 */ + +/* UNKnown arithmetic, invokes coefficients given in + * normal decimal format. Beware of range boundary + * problems (MACHEP, MAXLOG, etc. in const.c) and + * roundoff problems in pow.c: + * (Sun SPARCstation) + */ +#define UNK 1 + +/* If you define UNK, then be sure to set BIGENDIAN properly. */ +#ifdef FLOAT_WORDS_BIGENDIAN +#define BIGENDIAN 1 +#else +#define BIGENDIAN 0 +#endif +/* Define this `volatile' if your compiler thinks + * that floating point arithmetic obeys the associative + * and distributive laws. It will defeat some optimizations + * (but probably not enough of them). + * + * #define VOLATILE volatile + */ +#define VOLATILE + +/* For 12-byte long doubles on an i386, pad a 16-bit short 0 + * to the end of real constants initialized by integer arrays. + * + * #define XPD 0, + * + * Otherwise, the type is 10 bytes long and XPD should be + * defined blank (e.g., Microsoft C). + * + * #define XPD + */ +#define XPD 0, + +/* Define to support tiny denormal numbers, else undefine. */ +#define DENORMAL 1 + +/* Define to ask for infinity support, else undefine. */ +#define INFINITIES 1 + +/* Define to ask for support of numbers that are Not-a-Number, + else undefine. This may automatically define INFINITIES in some files. */ +#define NANS 1 + +/* Define to distinguish between -0.0 and +0.0. */ +#define MINUSZERO 1 + +/* Define 1 for ANSI C atan2() function + See atan.c and clog.c. */ +#define ANSIC 1 + +/* Get ANSI function prototypes, if you want them. */ +#if 1 +/* #ifdef __STDC__ */ +#define ANSIPROT 1 +int mtherr ( char *, int ); +#else +int mtherr(); +#endif + +/* Variable for error reporting. See mtherr.c. */ +extern int merror; diff --git a/src/math/mtherr.c b/src/math/mtherr.c new file mode 100644 index 000000000..0d94cd14d --- /dev/null +++ b/src/math/mtherr.c @@ -0,0 +1,102 @@ +/* mtherr.c + * + * Library common error handling routine + * + * + * + * SYNOPSIS: + * + * char *fctnam; + * int code; + * int mtherr(); + * + * mtherr( fctnam, code ); + * + * + * + * DESCRIPTION: + * + * This routine may be called to report one of the following + * error conditions (in the include file mconf.h). + * + * Mnemonic Value Significance + * + * DOMAIN 1 argument domain error + * SING 2 function singularity + * OVERFLOW 3 overflow range error + * UNDERFLOW 4 underflow range error + * TLOSS 5 total loss of precision + * PLOSS 6 partial loss of precision + * EDOM 33 Unix domain error code + * ERANGE 34 Unix range error code + * + * The default version of the file prints the function name, + * passed to it by the pointer fctnam, followed by the + * error condition. The display is directed to the standard + * output device. The routine then returns to the calling + * program. Users may wish to modify the program to abort by + * calling exit() under severe error conditions such as domain + * errors. + * + * Since all error conditions pass control to this function, + * the display may be easily changed, eliminated, or directed + * to an error logging device. + * + * SEE ALSO: + * + * mconf.h + * + */ + +/* +Cephes Math Library Release 2.0: April, 1987 +Copyright 1984, 1987 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +#include +#include "mconf.h" + +int merror = 0; + +/* Notice: the order of appearance of the following + * messages is bound to the error codes defined + * in mconf.h. + */ +static char *ermsg[7] = { +"unknown", /* error code 0 */ +"domain", /* error code 1 */ +"singularity", /* et seq. */ +"overflow", +"underflow", +"total loss of precision", +"partial loss of precision" +}; + + +int mtherr( name, code ) +char *name; +int code; +{ + +/* Display string passed by calling program, + * which is supposed to be the name of the + * function in which the error occurred: + */ +printf( "\n%s ", name ); + +/* Set global error message word */ +merror = code; + +/* Display error message defined + * by the code argument. + */ +if( (code <= 0) || (code >= 7) ) + code = 0; +printf( "%s error\n", ermsg[code] ); + +/* Return to calling + * program + */ +return( 0 ); +} diff --git a/src/math/polevl.c b/src/math/polevl.c new file mode 100644 index 000000000..4d050fbfc --- /dev/null +++ b/src/math/polevl.c @@ -0,0 +1,97 @@ +/* polevl.c + * p1evl.c + * + * Evaluate polynomial + * + * + * + * SYNOPSIS: + * + * int N; + * double x, y, coef[N+1], polevl[]; + * + * y = polevl( x, coef, N ); + * + * + * + * DESCRIPTION: + * + * Evaluates polynomial of degree N: + * + * 2 N + * y = C + C x + C x +...+ C x + * 0 1 2 N + * + * Coefficients are stored in reverse order: + * + * coef[0] = C , ..., coef[N] = C . + * N 0 + * + * The function p1evl() assumes that coef[N] = 1.0 and is + * omitted from the array. Its calling arguments are + * otherwise the same as polevl(). + * + * + * SPEED: + * + * In the interest of speed, there are no checks for out + * of bounds arithmetic. This routine is used by most of + * the functions in the library. Depending on available + * equipment features, the user may wish to rewrite the + * program in microcode or assembly language. + * + */ + + +/* +Cephes Math Library Release 2.1: December, 1988 +Copyright 1984, 1987, 1988 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + + +double polevl( x, coef, N ) +double x; +double coef[]; +int N; +{ +double ans; +int i; +double *p; + +p = coef; +ans = *p++; +i = N; + +do + ans = ans * x + *p++; +while( --i ); + +return( ans ); +} + +/* p1evl() */ +/* N + * Evaluate polynomial when coefficient of x is 1.0. + * Otherwise same as polevl. + */ + +double p1evl( x, coef, N ) +double x; +double coef[]; +int N; +{ +double ans; +double *p; +int i; + +p = coef; +ans = x + *p++; +i = N-1; + +do + ans = ans * x + *p++; +while( --i ); + +return( ans ); +} diff --git a/src/math/readme.txt b/src/math/readme.txt new file mode 100644 index 000000000..965335ee6 --- /dev/null +++ b/src/math/readme.txt @@ -0,0 +1,15 @@ + Some software in this archive may be from the book _Methods and +Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +International, 1989) or from the Cephes Mathematical Library, a +commercial product. In either event, it is copyrighted by the author. +What you see here may be used freely but it comes with no support or +guarantee. + + The two known misprints in the book are repaired here in the +source listings for the gamma function and the incomplete beta +integral. + + + Stephen L. Moshier + moshier@na-net.ornl.gov + \ No newline at end of file diff --git a/src/math/sin.c b/src/math/sin.c new file mode 100644 index 000000000..3eba0e22f --- /dev/null +++ b/src/math/sin.c @@ -0,0 +1,387 @@ +/* sin.c + * + * Circular sine + * + * + * + * SYNOPSIS: + * + * double x, y, sin(); + * + * y = sin( x ); + * + * + * + * DESCRIPTION: + * + * Range reduction is into intervals of pi/4. The reduction + * error is nearly eliminated by contriving an extended precision + * modular arithmetic. + * + * Two polynomial approximating functions are employed. + * Between 0 and pi/4 the sine is approximated by + * x + x**3 P(x**2). + * Between pi/4 and pi/2 the cosine is represented as + * 1 - x**2 Q(x**2). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC 0, 10 150000 3.0e-17 7.8e-18 + * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 + * + * ERROR MESSAGES: + * + * message condition value returned + * sin total loss x > 1.073741824e9 0.0 + * + * Partial loss of accuracy begins to occur at x = 2**30 + * = 1.074e9. The loss is not gradual, but jumps suddenly to + * about 1 part in 10e7. Results may be meaningless for + * x > 2**49 = 5.6e14. The routine as implemented flags a + * TLOSS error for x > 2**30 and returns 0.0. + */ + /* cos.c + * + * Circular cosine + * + * + * + * SYNOPSIS: + * + * double x, y, cos(); + * + * y = cos( x ); + * + * + * + * DESCRIPTION: + * + * Range reduction is into intervals of pi/4. The reduction + * error is nearly eliminated by contriving an extended precision + * modular arithmetic. + * + * Two polynomial approximating functions are employed. + * Between 0 and pi/4 the cosine is approximated by + * 1 - x**2 Q(x**2). + * Between pi/4 and pi/2 the sine is represented as + * x + x**3 P(x**2). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 + * DEC 0,+1.07e9 17000 3.0e-17 7.2e-18 + */ + +/* sin.c */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1985, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double sincof[] = { + 1.58962301576546568060E-10, +-2.50507477628578072866E-8, + 2.75573136213857245213E-6, +-1.98412698295895385996E-4, + 8.33333333332211858878E-3, +-1.66666666666666307295E-1, +}; +static double coscof[6] = { +-1.13585365213876817300E-11, + 2.08757008419747316778E-9, +-2.75573141792967388112E-7, + 2.48015872888517045348E-5, +-1.38888888888730564116E-3, + 4.16666666666665929218E-2, +}; +static double DP1 = 7.85398125648498535156E-1; +static double DP2 = 3.77489470793079817668E-8; +static double DP3 = 2.69515142907905952645E-15; +/* static double lossth = 1.073741824e9; */ +#endif + +#ifdef DEC +static unsigned short sincof[] = { +0030056,0143750,0177214,0163153, +0131727,0027455,0044510,0175352, +0033470,0167432,0131752,0042414, +0135120,0006400,0146776,0174027, +0036410,0104210,0104207,0137202, +0137452,0125252,0125252,0125103, +}; +static unsigned short coscof[24] = { +0127107,0151115,0002060,0152325, +0031017,0072353,0155161,0174053, +0132623,0171173,0172542,0057056, +0034320,0006400,0147102,0023652, +0135666,0005540,0133012,0076213, +0037052,0125252,0125252,0125126, +}; +/* 7.853981629014015197753906250000E-1 */ +static unsigned short P1[] = {0040111,0007732,0120000,0000000,}; +/* 4.960467869796758577649598009884E-10 */ +static unsigned short P2[] = {0030410,0055060,0100000,0000000,}; +/* 2.860594363054915898381331279295E-18 */ +static unsigned short P3[] = {0021523,0011431,0105056,0001560,}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +#endif + +#ifdef IBMPC +static unsigned short sincof[] = { +0x9ccd,0x1fd1,0xd8fd,0x3de5, +0x1f5d,0xa929,0xe5e5,0xbe5a, +0x48a1,0x567d,0x1de3,0x3ec7, +0xdf03,0x19bf,0x01a0,0xbf2a, +0xf7d0,0x1110,0x1111,0x3f81, +0x5548,0x5555,0x5555,0xbfc5, +}; +static unsigned short coscof[24] = { +0x1a9b,0xa086,0xfa49,0xbda8, +0x3f05,0x7b4e,0xee9d,0x3e21, +0x4bc6,0x7eac,0x7e4f,0xbe92, +0x44f5,0x19c8,0x01a0,0x3efa, +0x4f91,0x16c1,0xc16c,0xbf56, +0x554b,0x5555,0x5555,0x3fa5, +}; +/* + 7.85398125648498535156E-1, + 3.77489470793079817668E-8, + 2.69515142907905952645E-15, +*/ +static unsigned short P1[] = {0x0000,0x4000,0x21fb,0x3fe9}; +static unsigned short P2[] = {0x0000,0x0000,0x442d,0x3e64}; +static unsigned short P3[] = {0x5170,0x98cc,0x4698,0x3ce8}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +#endif + +#ifdef MIEEE +static unsigned short sincof[] = { +0x3de5,0xd8fd,0x1fd1,0x9ccd, +0xbe5a,0xe5e5,0xa929,0x1f5d, +0x3ec7,0x1de3,0x567d,0x48a1, +0xbf2a,0x01a0,0x19bf,0xdf03, +0x3f81,0x1111,0x1110,0xf7d0, +0xbfc5,0x5555,0x5555,0x5548, +}; +static unsigned short coscof[24] = { +0xbda8,0xfa49,0xa086,0x1a9b, +0x3e21,0xee9d,0x7b4e,0x3f05, +0xbe92,0x7e4f,0x7eac,0x4bc6, +0x3efa,0x01a0,0x19c8,0x44f5, +0xbf56,0xc16c,0x16c1,0x4f91, +0x3fa5,0x5555,0x5555,0x554b, +}; +static unsigned short P1[] = {0x3fe9,0x21fb,0x4000,0x0000}; +static unsigned short P2[] = {0x3e64,0x442d,0x0000,0x0000}; +static unsigned short P3[] = {0x3ce8,0x4698,0x98cc,0x5170}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double floor ( double ); +extern double ldexp ( double, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +#else +double polevl(), floor(), ldexp(); +int isnan(), isfinite(); +#endif +extern double PIO4; +static double lossth = 1.073741824e9; +#ifdef NANS +extern double NAN; +#endif +#ifdef INFINITIES +extern double INFINITY; +#endif + + +double c_sin(x) +double x; +{ +double y, z, zz; +int j, sign; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +#ifdef NANS +if( isnan(x) ) + return(x); +if( !isfinite(x) ) + { + mtherr( "sin", DOMAIN ); + return(NAN); + } +#endif +/* make argument positive but save the sign */ +sign = 1; +if( x < 0 ) + { + x = -x; + sign = -1; + } + +if( x > lossth ) + { + mtherr( "sin", TLOSS ); + return(0.0); + } + +y = floor( x/PIO4 ); /* integer part of x/PIO4 */ + +/* strip high bits of integer part to prevent integer overflow */ +z = ldexp( y, -4 ); +z = floor(z); /* integer part of y/8 */ +z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ + +j = (int)z; /* convert to integer for tests on the phase angle */ +/* map zeros to origin */ +if( j & 1 ) + { + j += 1; + y += 1.0; + } +j = j & 07; /* octant modulo 360 degrees */ +/* reflect in x axis */ +if( j > 3) + { + sign = -sign; + j -= 4; + } + +/* Extended precision modular arithmetic */ +z = ((x - y * DP1) - y * DP2) - y * DP3; + +zz = z * z; + +if( (j==1) || (j==2) ) + { + y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); + } +else + { +/* y = z + z * (zz * polevl( zz, sincof, 5 ));*/ + y = z + z * z * z * polevl( zz, sincof, 5 ); + } + +if(sign < 0) + y = -y; + +return(y); +} + + + + + +double c_cos(x) +double x; +{ +double y, z, zz; +int i; +int j, sign; + +#ifdef NANS +if( isnan(x) ) + return(x); +if( !isfinite(x) ) + { + mtherr( "cos", DOMAIN ); + return(NAN); + } +#endif + +/* make argument positive */ +sign = 1; +if( x < 0 ) + x = -x; + +if( x > lossth ) + { + mtherr( "cos", TLOSS ); + return(0.0); + } + +y = floor( x/PIO4 ); +z = ldexp( y, -4 ); +z = floor(z); /* integer part of y/8 */ +z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ + +/* integer and fractional part modulo one octant */ +i = (int)z; +if( i & 1 ) /* map zeros to origin */ + { + i += 1; + y += 1.0; + } +j = i & 07; +if( j > 3) + { + j -=4; + sign = -sign; + } + +if( j > 1 ) + sign = -sign; + +/* Extended precision modular arithmetic */ +z = ((x - y * DP1) - y * DP2) - y * DP3; + +zz = z * z; + +if( (j==1) || (j==2) ) + { +/* y = z + z * (zz * polevl( zz, sincof, 5 ));*/ + y = z + z * z * z * polevl( zz, sincof, 5 ); + } +else + { + y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); + } + +if(sign < 0) + y = -y; + +return(y); +} + + + + + +/* Degrees, minutes, seconds to radians: */ + +/* 1 arc second, in radians = 4.8481368110953599358991410e-5 */ +#ifdef DEC +static unsigned short P648[] = {034513,054170,0176773,0116043,}; +#define P64800 *(double *)P648 +#else +static double P64800 = 4.8481368110953599358991410e-5; +#endif + +double radian(d,m,s) +double d,m,s; +{ + +return( ((d*60.0 + m)*60.0 + s)*P64800 ); +} diff --git a/src/math/sinh.c b/src/math/sinh.c new file mode 100644 index 000000000..b1d2a7500 --- /dev/null +++ b/src/math/sinh.c @@ -0,0 +1,148 @@ +/* sinh.c + * + * Hyperbolic sine + * + * + * + * SYNOPSIS: + * + * double x, y, sinh(); + * + * y = sinh( x ); + * + * + * + * DESCRIPTION: + * + * Returns hyperbolic sine of argument in the range MINLOG to + * MAXLOG. + * + * The range is partitioned into two segments. If |x| <= 1, a + * rational function of the form x + x**3 P(x)/Q(x) is employed. + * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC +- 88 50000 4.0e-17 7.7e-18 + * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double P[] = { +-7.89474443963537015605E-1, +-1.63725857525983828727E2, +-1.15614435765005216044E4, +-3.51754964808151394800E5 +}; +static double Q[] = { +/* 1.00000000000000000000E0,*/ +-2.77711081420602794433E2, + 3.61578279834431989373E4, +-2.11052978884890840399E6 +}; +#endif + +#ifdef DEC +static unsigned short P[] = { +0140112,0015377,0042731,0163255, +0142043,0134721,0146177,0123761, +0143464,0122706,0034353,0006017, +0144653,0140536,0157665,0054045 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0142212,0155404,0133513,0022040, +0044015,0036723,0173271,0011053, +0145400,0150407,0023710,0001034 +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x3cd6,0xe8bb,0x435f,0xbfe9, +0xf4fe,0x398f,0x773a,0xc064, +0x6182,0xc71d,0x94b8,0xc0c6, +0xab05,0xdbf6,0x782b,0xc115 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x6484,0x96e9,0x5b60,0xc071, +0x2245,0x7ed7,0xa7ba,0x40e1, +0x0044,0xe4f9,0x1a20,0xc140 +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0xbfe9,0x435f,0xe8bb,0x3cd6, +0xc064,0x773a,0x398f,0xf4fe, +0xc0c6,0x94b8,0xc71d,0x6182, +0xc115,0x782b,0xdbf6,0xab05 +}; +static unsigned short Q[] = { +0xc071,0x5b60,0x96e9,0x6484, +0x40e1,0xa7ba,0x7ed7,0x2245, +0xc140,0x1a20,0xe4f9,0x0044 +}; +#endif + +#ifdef ANSIPROT +extern double fabs ( double ); +extern double c_exp ( double ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +#else +double fabs(), c_exp(), polevl(), p1evl(); +#endif +extern double INFINITY, MINLOG, MAXLOG, LOGE2; + +double c_sinh(x) +double x; +{ +double a; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +a = fabs(x); +if( (x > (MAXLOG + LOGE2)) || (x > -(MINLOG-LOGE2) ) ) + { + mtherr( "sinh", DOMAIN ); + if( x > 0 ) + return( INFINITY ); + else + return( -INFINITY ); + } +if( a > 1.0 ) + { + if( a >= (MAXLOG - LOGE2) ) + { + a = c_exp(0.5*a); + a = (0.5 * a) * a; + if( x < 0 ) + a = -a; + return(a); + } + a = c_exp(a); + a = 0.5*a - (0.5/a); + if( x < 0 ) + a = -a; + return(a); + } + +a *= a; +return( x + x * a * (polevl(a,P,3)/p1evl(a,Q,3)) ); +} diff --git a/src/math/sqrt.c b/src/math/sqrt.c new file mode 100644 index 000000000..22ebdc669 --- /dev/null +++ b/src/math/sqrt.c @@ -0,0 +1,178 @@ +/* _sqrt.c + * + * Square root + * + * + * + * SYNOPSIS: + * + * double x, y, _sqrt(); + * + * y = _sqrt( x ); + * + * + * + * DESCRIPTION: + * + * Returns the square root of x. + * + * Range reduction involves isolating the power of two of the + * argument and using a polynomial approximation to obtain + * a rough value for the square root. Then Heron's iteration + * is used three times to converge to an accurate value. + * + * + * + * ACCURACY: + * + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC 0, 10 60000 2.1e-17 7.9e-18 + * IEEE 0,1.7e308 30000 1.7e-16 6.3e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * _sqrt domain x < 0 0.0 + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier +*/ + + +#include "mconf.h" +#ifdef ANSIPROT +extern double frexp ( double, int * ); +extern double ldexp ( double, int ); +#else +double frexp(), ldexp(); +#endif +extern double SQRT2; /* _sqrt2 = 1.41421356237309504880 */ + +double c_sqrt(x) +double x; +{ +int e; +#ifndef UNK +short *q; +#endif +double z, w; + +if( x <= 0.0 ) + { + if( x < 0.0 ) + mtherr( "_sqrt", DOMAIN ); + return( 0.0 ); + } +w = x; +/* separate exponent and significand */ +#ifdef UNK +z = frexp( x, &e ); +#endif +#ifdef DEC +q = (short *)&x; +e = ((*q >> 7) & 0377) - 0200; +*q &= 0177; +*q |= 040000; +z = x; +#endif + +/* Note, frexp and ldexp are used in order to + * handle denormal numbers properly. + */ +#ifdef IBMPC +z = frexp( x, &e ); +q = (short *)&x; +q += 3; +/* +e = ((*q >> 4) & 0x0fff) - 0x3fe; +*q &= 0x000f; +*q |= 0x3fe0; +z = x; +*/ +#endif +#ifdef MIEEE +z = frexp( x, &e ); +q = (short *)&x; +/* +e = ((*q >> 4) & 0x0fff) - 0x3fe; +*q &= 0x000f; +*q |= 0x3fe0; +z = x; +*/ +#endif + +/* approximate square root of number between 0.5 and 1 + * relative error of approximation = 7.47e-3 + */ +x = 4.173075996388649989089E-1 + 5.9016206709064458299663E-1 * z; + +/* adjust for odd powers of 2 */ +if( (e & 1) != 0 ) + x *= SQRT2; + +/* re-insert exponent */ +#ifdef UNK +x = ldexp( x, (e >> 1) ); +#endif +#ifdef DEC +*q += ((e >> 1) & 0377) << 7; +*q &= 077777; +#endif +#ifdef IBMPC +x = ldexp( x, (e >> 1) ); +/* +*q += ((e >>1) & 0x7ff) << 4; +*q &= 077777; +*/ +#endif +#ifdef MIEEE +x = ldexp( x, (e >> 1) ); +/* +*q += ((e >>1) & 0x7ff) << 4; +*q &= 077777; +*/ +#endif + +/* Newton iterations: */ +#ifdef UNK +x = 0.5*(x + w/x); +x = 0.5*(x + w/x); +x = 0.5*(x + w/x); +#endif + +/* Note, assume the square root cannot be denormal, + * so it is safe to use integer exponent operations here. + */ +#ifdef DEC +x += w/x; +*q -= 0200; +x += w/x; +*q -= 0200; +x += w/x; +*q -= 0200; +#endif +#ifdef IBMPC +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +#endif +#ifdef MIEEE +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +x += w/x; +*q -= 0x10; +#endif + +return(x); +} diff --git a/src/math/tan.c b/src/math/tan.c new file mode 100644 index 000000000..8ef8af55c --- /dev/null +++ b/src/math/tan.c @@ -0,0 +1,304 @@ +/* tan.c + * + * Circular tangent + * + * + * + * SYNOPSIS: + * + * double x, y, tan(); + * + * y = tan( x ); + * + * + * + * DESCRIPTION: + * + * Returns the circular tangent of the radian argument x. + * + * Range reduction is modulo pi/4. A rational function + * x + x**3 P(x**2)/Q(x**2) + * is employed in the basic interval [0, pi/4]. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC +-1.07e9 44000 4.1e-17 1.0e-17 + * IEEE +-1.07e9 30000 2.9e-16 8.1e-17 + * + * ERROR MESSAGES: + * + * message condition value returned + * tan total loss x > 1.073741824e9 0.0 + * + */ + /* cot.c + * + * Circular cotangent + * + * + * + * SYNOPSIS: + * + * double x, y, cot(); + * + * y = cot( x ); + * + * + * + * DESCRIPTION: + * + * Returns the circular cotangent of the radian argument x. + * + * Range reduction is modulo pi/4. A rational function + * x + x**3 P(x**2)/Q(x**2) + * is employed in the basic interval [0, pi/4]. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE +-1.07e9 30000 2.9e-16 8.2e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * cot total loss x > 1.073741824e9 0.0 + * cot singularity x = 0 INFINITY + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +yright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double P[] = { +-1.30936939181383777646E4, + 1.15351664838587416140E6, +-1.79565251976484877988E7 +}; +static double Q[] = { +/* 1.00000000000000000000E0,*/ + 1.36812963470692954678E4, +-1.32089234440210967447E6, + 2.50083801823357915839E7, +-5.38695755929454629881E7 +}; +static double DP1 = 7.853981554508209228515625E-1; +static double DP2 = 7.94662735614792836714E-9; +static double DP3 = 3.06161699786838294307E-17; +static double lossth = 1.073741824e9; +#endif + +#ifdef DEC +static unsigned short P[] = { +0143514,0113306,0111171,0174674, +0045214,0147545,0027744,0167346, +0146210,0177526,0114514,0105660 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0043525,0142457,0072633,0025617, +0145241,0036742,0140525,0162256, +0046276,0146176,0013526,0143573, +0146515,0077401,0162762,0150607 +}; +/* 7.853981629014015197753906250000E-1 */ +static unsigned short P1[] = {0040111,0007732,0120000,0000000,}; +/* 4.960467869796758577649598009884E-10 */ +static unsigned short P2[] = {0030410,0055060,0100000,0000000,}; +/* 2.860594363054915898381331279295E-18 */ +static unsigned short P3[] = {0021523,0011431,0105056,0001560,}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +static double lossth = 1.073741824e9; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x3f38,0xd24f,0x92d8,0xc0c9, +0x9ddd,0xa5fc,0x99ec,0x4131, +0x9176,0xd329,0x1fea,0xc171 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x6572,0xeeb3,0xb8a5,0x40ca, +0xbc96,0x582a,0x27bc,0xc134, +0xd8ef,0xc2ea,0xd98f,0x4177, +0x5a31,0x3cbe,0xafe0,0xc189 +}; +/* + 7.85398125648498535156E-1, + 3.77489470793079817668E-8, + 2.69515142907905952645E-15, +*/ +static unsigned short P1[] = {0x0000,0x4000,0x21fb,0x3fe9}; +static unsigned short P2[] = {0x0000,0x0000,0x442d,0x3e64}; +static unsigned short P3[] = {0x5170,0x98cc,0x4698,0x3ce8}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +static double lossth = 1.073741824e9; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0xc0c9,0x92d8,0xd24f,0x3f38, +0x4131,0x99ec,0xa5fc,0x9ddd, +0xc171,0x1fea,0xd329,0x9176 +}; +static unsigned short Q[] = { +0x40ca,0xb8a5,0xeeb3,0x6572, +0xc134,0x27bc,0x582a,0xbc96, +0x4177,0xd98f,0xc2ea,0xd8ef, +0xc189,0xafe0,0x3cbe,0x5a31 +}; +static unsigned short P1[] = { +0x3fe9,0x21fb,0x4000,0x0000 +}; +static unsigned short P2[] = { +0x3e64,0x442d,0x0000,0x0000 +}; +static unsigned short P3[] = { +0x3ce8,0x4698,0x98cc,0x5170, +}; +#define DP1 *(double *)P1 +#define DP2 *(double *)P2 +#define DP3 *(double *)P3 +static double lossth = 1.073741824e9; +#endif + +#ifdef ANSIPROT +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +extern double floor ( double ); +extern double ldexp ( double, int ); +extern int isnan ( double ); +extern int isfinite ( double ); +static double tancot(double, int); +#else +double polevl(), p1evl(), floor(), ldexp(); +static double tancot(); +int isnan(), isfinite(); +#endif +extern double PIO4; +extern double INFINITY; +extern double NAN; + +double c_tan(x) +double x; +{ +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +#ifdef NANS +if( isnan(x) ) + return(x); +if( !isfinite(x) ) + { + mtherr( "tan", DOMAIN ); + return(NAN); + } +#endif +return( tancot(x,0) ); +} + + +double c_cot(x) +double x; +{ + +if( x == 0.0 ) + { + mtherr( "cot", SING ); + return( INFINITY ); + } +return( tancot(x,1) ); +} + + +static double tancot( xx, cotflg ) +double xx; +int cotflg; +{ +double x, y, z, zz; +int j, sign; + +/* make argument positive but save the sign */ +if( xx < 0 ) + { + x = -xx; + sign = -1; + } +else + { + x = xx; + sign = 1; + } + +if( x > lossth ) + { + if( cotflg ) + mtherr( "cot", TLOSS ); + else + mtherr( "tan", TLOSS ); + return(0.0); + } + +/* compute x mod PIO4 */ +y = floor( x/PIO4 ); + +/* strip high bits of integer part */ +z = ldexp( y, -3 ); +z = floor(z); /* integer part of y/8 */ +z = y - ldexp( z, 3 ); /* y - 16 * (y/16) */ + +/* integer and fractional part modulo one octant */ +j = (int)z; + +/* map zeros and singularities to origin */ +if( j & 1 ) + { + j += 1; + y += 1.0; + } + +z = ((x - y * DP1) - y * DP2) - y * DP3; + +zz = z * z; + +if( zz > 1.0e-14 ) + y = z + z * (zz * polevl( zz, P, 2 )/p1evl(zz, Q, 4)); +else + y = z; + +if( j & 2 ) + { + if( cotflg ) + y = -y; + else + y = -1.0/y; + } +else + { + if( cotflg ) + y = 1.0/y; + } + +if( sign < 0 ) + y = -y; + +return( y ); +} diff --git a/src/math/tanh.c b/src/math/tanh.c new file mode 100644 index 000000000..7590eca5c --- /dev/null +++ b/src/math/tanh.c @@ -0,0 +1,141 @@ +/* tanh.c + * + * Hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * double x, y, tanh(); + * + * y = tanh( x ); + * + * + * + * DESCRIPTION: + * + * Returns hyperbolic tangent of argument in the range MINLOG to + * MAXLOG. + * + * A rational function is used for |x| < 0.625. The form + * x + x**3 P(x)/Q(x) of Cody _& Waite is employed. + * Otherwise, + * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -2,2 50000 3.3e-17 6.4e-18 + * IEEE -2,2 30000 2.5e-16 5.8e-17 + * + */ + +/* +Cephes Math Library Release 2.8: June, 2000 +Copyright 1984, 1995, 2000 by Stephen L. Moshier +*/ + +#include "mconf.h" + +#ifdef UNK +static double P[] = { +-9.64399179425052238628E-1, +-9.92877231001918586564E1, +-1.61468768441708447952E3 +}; +static double Q[] = { +/* 1.00000000000000000000E0,*/ + 1.12811678491632931402E2, + 2.23548839060100448583E3, + 4.84406305325125486048E3 +}; +#endif +#ifdef DEC +static unsigned short P[] = { +0140166,0161335,0053753,0075126, +0141706,0111520,0070463,0040552, +0142711,0153001,0101300,0025430 +}; +static unsigned short Q[] = { +/*0040200,0000000,0000000,0000000,*/ +0041741,0117624,0051300,0156060, +0043013,0133720,0071251,0127717, +0043227,0060201,0021020,0020136 +}; +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x6f4b,0xaafd,0xdc5b,0xbfee, +0x682d,0x0e26,0xd26a,0xc058, +0x0563,0x3058,0x3ac0,0xc099 +}; +static unsigned short Q[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x1b86,0x8a58,0x33f2,0x405c, +0x35fa,0x0e55,0x76fa,0x40a1, +0x040c,0x2442,0xec10,0x40b2 +}; +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0xbfee,0xdc5b,0xaafd,0x6f4b, +0xc058,0xd26a,0x0e26,0x682d, +0xc099,0x3ac0,0x3058,0x0563 +}; +static unsigned short Q[] = { +0x405c,0x33f2,0x8a58,0x1b86, +0x40a1,0x76fa,0x0e55,0x35fa, +0x40b2,0xec10,0x2442,0x040c +}; +#endif + +#ifdef ANSIPROT +extern double fabs ( double ); +extern double c_exp ( double ); +extern double polevl ( double, void *, int ); +extern double p1evl ( double, void *, int ); +#else +double fabs(), c_exp(), polevl(), p1evl(); +#endif +extern double MAXLOG; + +double c_tanh(x) +double x; +{ +double s, z; + +#ifdef MINUSZERO +if( x == 0.0 ) + return(x); +#endif +z = fabs(x); +if( z > 0.5 * MAXLOG ) + { + if( x > 0 ) + return( 1.0 ); + else + return( -1.0 ); + } +if( z >= 0.625 ) + { + s = c_exp(2.0*z); + z = 1.0 - 2.0/(s + 1.0); + if( x < 0 ) + z = -z; + } +else + { + if( x == 0.0 ) + return(x); + s = x * x; + z = polevl( s, P, 2 )/p1evl(s, Q, 3); + z = x * s * z; + z = x + z; + } +return( z ); +} diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index ccf3f5633..5caf3ce42 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -563,21 +563,19 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected) V_DrawFrame (x, y, 72*CleanXfac, 80*CleanYfac-1); spriteframe_t *sprframe = NULL; - fixed_t scaleX, scaleY; + DVector2 Scale; if (mPlayerState != NULL) { if (mSkin == 0) { sprframe = &SpriteFrames[sprites[mPlayerState->sprite].spriteframes + mPlayerState->GetFrame()]; - scaleX = GetDefaultByType(mPlayerClass->Type)->scaleX; - scaleY = GetDefaultByType(mPlayerClass->Type)->scaleY; + Scale = GetDefaultByType(mPlayerClass->Type)->Scale; } else { sprframe = &SpriteFrames[sprites[skins[mSkin].sprite].spriteframes + mPlayerState->GetFrame()]; - scaleX = skins[mSkin].ScaleX; - scaleY = skins[mSkin].ScaleY; + Scale = skins[mSkin].Scale; } } @@ -590,8 +588,8 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected) if (mTranslate) trans = translationtables[TRANSLATION_Players](MAXPLAYERS); screen->DrawTexture (tex, x + 36*CleanXfac, y + 71*CleanYfac, - DTA_DestWidth, MulScale16 (tex->GetScaledWidth() * CleanXfac, scaleX), - DTA_DestHeight, MulScale16 (tex->GetScaledHeight() * CleanYfac, scaleY), + DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * Scale.X, + DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * Scale.Y, DTA_Translation, trans, DTA_FlipX, sprframe->Flip & (1 << mRotation), TAG_DONE); diff --git a/src/nodebuild_events.cpp b/src/nodebuild_events.cpp index 345a6b6be..84e187081 100644 --- a/src/nodebuild_events.cpp +++ b/src/nodebuild_events.cpp @@ -219,7 +219,7 @@ void FEventTree::PrintTree (const FEvent *event) const { PrintTree(event->Left); sprintf(buff, " Distance %g, vertex %d, seg %u\n", - sqrt(event->Distance/4294967296.0), event->Info.Vertex, (unsigned)event->Info.FrontSeg); + g_sqrt(event->Distance/4294967296.0), event->Info.Vertex, (unsigned)event->Info.FrontSeg); Printf(PRINT_LOG, "%s", buff); PrintTree(event->Right); } diff --git a/src/nodebuild_utility.cpp b/src/nodebuild_utility.cpp index a2edd19b9..d3d560f4c 100644 --- a/src/nodebuild_utility.cpp +++ b/src/nodebuild_utility.cpp @@ -50,6 +50,7 @@ #include "i_system.h" #include "po_man.h" #include "r_state.h" +#include "math/cmath.h" static const int PO_LINE_START = 1; static const int PO_LINE_EXPLICIT = 5; @@ -74,7 +75,7 @@ angle_t FNodeBuilder::PointToAngle (fixed_t x, fixed_t y) // See https://gcc.gnu.org/wiki/Math_Optimization_Flags for details long double ang = atan2l (double(y), double(x)); #else // !__APPLE__ || __llvm__ - double ang = atan2 (double(y), double(x)); + double ang = g_atan2 (double(y), double(x)); #endif // __APPLE__ && !__llvm__ // Convert to signed first since negative double to unsigned is undefined. return angle_t(int(ang * rad2bam)) << 1; diff --git a/src/oplsynth/mlopl_io.cpp b/src/oplsynth/mlopl_io.cpp index 64c4ad962..e6ed3bba8 100644 --- a/src/oplsynth/mlopl_io.cpp +++ b/src/oplsynth/mlopl_io.cpp @@ -37,6 +37,7 @@ * Cleaned up the source */ +#include #ifdef _WIN32 #include #include @@ -45,7 +46,7 @@ #include "opl.h" #include "c_cvars.h" -#define HALF_PI (PI*0.5) +const double HALF_PI = (M_PI*0.5); EXTERN_CVAR(Int, opl_core) extern int current_opl_core; diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 833f5a4b4..fe1553fef 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -339,13 +339,13 @@ void P_PlayerOnSpecial3DFloor(player_t* player) if(rover->flags & FF_SOLID) { // Player must be on top of the floor to be affected... - if(player->mo->Z() != rover->top.plane->ZatPoint(player->mo)) continue; + if(player->mo->_f_Z() != rover->top.plane->ZatPoint(player->mo)) continue; } else { //Water and DEATH FOG!!! heh - if (player->mo->Z() > rover->top.plane->ZatPoint(player->mo) || - player->mo->Top() < rover->bottom.plane->ZatPoint(player->mo)) + if (player->mo->_f_Z() > rover->top.plane->ZatPoint(player->mo) || + player->mo->_f_Top() < rover->bottom.plane->ZatPoint(player->mo)) continue; } @@ -380,7 +380,7 @@ bool P_CheckFor3DFloorHit(AActor * mo) if(rover->flags & FF_SOLID && rover->model->SecActTarget) { - if(mo->floorz == rover->top.plane->ZatPoint(mo)) + if(mo->_f_floorz() == rover->top.plane->ZatPoint(mo)) { rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor); return true; @@ -410,7 +410,7 @@ bool P_CheckFor3DCeilingHit(AActor * mo) if(rover->flags & FF_SOLID && rover->model->SecActTarget) { - if(mo->ceilingz == rover->bottom.plane->ZatPoint(mo)) + if(mo->_f_ceilingz() == rover->bottom.plane->ZatPoint(mo)) { rover->model->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling); return true; @@ -761,8 +761,8 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li { fixed_t thingbot, thingtop; - thingbot = thing->Z(); - thingtop = thingbot + (thing->height==0? 1:thing->height); + thingbot = thing->_f_Z(); + thingtop = thingbot + (thing->_f_height()==0? 1:thing->_f_height()); extsector_t::xfloor *xf[2] = {&linedef->frontsector->e->XFloor, &linedef->backsector->e->XFloor}; @@ -805,7 +805,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li lowestceilingsec = j == 0 ? linedef->frontsector : linedef->backsector; } - if(ff_top > highestfloor && delta1 < delta2 && (!restrict || thing->Z() >= ff_top)) + if(ff_top > highestfloor && delta1 < delta2 && (!restrict || thing->_f_Z() >= ff_top)) { highestfloor = ff_top; highestfloorpic = *rover->top.texture; @@ -813,7 +813,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li highestfloorsec = j == 0 ? linedef->frontsector : linedef->backsector; highestfloorplanes[j] = rover->top.plane; } - if(ff_top > lowestfloor[j] && ff_top <= thing->Z() + thing->MaxStepHeight) lowestfloor[j] = ff_top; + if(ff_top > lowestfloor[j] && ff_top <= thing->_f_Z() + thing->MaxStepHeight) lowestfloor[j] = ff_top; } } diff --git a/src/p_3dfloors.h b/src/p_3dfloors.h index 4b8829d32..baf7dd130 100644 --- a/src/p_3dfloors.h +++ b/src/p_3dfloors.h @@ -147,6 +147,13 @@ inline int P_Find3DFloor(sector_t * sec, const fixedvec3 &pos, bool above, bool { return P_Find3DFloor(sec, pos.x, pos.y, pos.z, above, floor, cmpz); } - +inline int P_Find3DFloor(sector_t * sec, const DVector3 &pos, bool above, bool floor, double &cmpz) +{ + fixed_t fr = FLOAT2FIXED(cmpz); + int ret = P_Find3DFloor(sec, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), above, floor, fr); + cmpz = FIXED2DBL(fr); + return ret; +} + #endif \ No newline at end of file diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 1fc741915..eeef7e7fe 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -278,7 +278,7 @@ bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening & open.abovemidtex = false; if (P_GetMidTexturePosition(linedef, 0, &tt, &tb)) { - if (thing->Z() + (thing->height/2) < (tt + tb)/2) + if (thing->_f_Z() + (thing->_f_height()/2) < (tt + tb)/2) { if (tb < open.top) { @@ -288,7 +288,7 @@ bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening & } else { - if (tt > open.bottom && (!restrict || thing->Z() >= tt)) + if (tt > open.bottom && (!restrict || thing->_f_Z() >= tt)) { open.bottom = tt; open.abovemidtex = true; @@ -299,7 +299,7 @@ bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening & } // returns true if it touches the midtexture - return (abs(thing->Z() - tt) <= thing->MaxStepHeight); + return (abs(thing->_f_Z() - tt) <= thing->MaxStepHeight); } } return false; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 11b169e6a..db588efba 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -148,6 +148,36 @@ enum PICKAF_RETURNTID = 2, }; +// ACS specific conversion functions to and from fixed point. +// These should be used to convert from and to sctipt variables +// so that there is a clear distinction between leftover fixed point code +// and genuinely needed conversions. + +inline double ACSToDouble(int acsval) +{ + return acsval / 65536.; +} + +inline float ACSToFloat(int acsval) +{ + return acsval / 65536.f; +} + +inline int DoubleToACS(double val) +{ + return xs_Fix<16>::ToFix(val); +} + +inline DAngle ACSToAngle(int acsval) +{ + return acsval * (360. / 65536.); +} + +inline int AngleToACS(DAngle ang) +{ + xs_CRoundToInt(ang.Degrees * (65536. / 360.)); +} + struct CallReturn { CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway) @@ -3455,7 +3485,7 @@ int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, i actor->flags2 |= MF2_PASSMOBJ; if (force || P_TestMobjLocation (actor)) { - actor->angle = angle << 24; + actor->Angles.Yaw = angle * (360. / 256); actor->tid = tid; actor->AddToHash (); if (actor->flags & MF_SPECIAL) @@ -3487,12 +3517,12 @@ int DLevelScript::DoSpawnSpot (int type, int spot, int tid, int angle, bool forc while ( (aspot = iterator.Next ()) ) { - spawned += DoSpawn (type, aspot->X(), aspot->Y(), aspot->Z(), tid, angle, force); + spawned += DoSpawn (type, aspot->_f_X(), aspot->_f_Y(), aspot->_f_Z(), tid, angle, force); } } else if (activator != NULL) { - spawned += DoSpawn (type, activator->X(), activator->Y(), activator->Z(), tid, angle, force); + spawned += DoSpawn (type, activator->_f_X(), activator->_f_Y(), activator->_f_Z(), tid, angle, force); } return spawned; } @@ -3508,12 +3538,12 @@ int DLevelScript::DoSpawnSpotFacing (int type, int spot, int tid, bool force) while ( (aspot = iterator.Next ()) ) { - spawned += DoSpawn (type, aspot->X(), aspot->Y(), aspot->Z(), tid, aspot->angle >> 24, force); + spawned += DoSpawn (type, aspot->_f_X(), aspot->_f_Y(), aspot->_f_Z(), tid, aspot->_f_angle() >> 24, force); } } else if (activator != NULL) { - spawned += DoSpawn (type, activator->X(), activator->Y(), activator->Z(), tid, activator->angle >> 24, force); + spawned += DoSpawn (type, activator->_f_X(), activator->_f_Y(), activator->_f_Z(), tid, activator->_f_angle() >> 24, force); } return spawned; } @@ -3805,7 +3835,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_Speed: - actor->Speed = value; + actor->Speed = ACSToDouble(value); break; case APROP_Damage: @@ -3849,7 +3879,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) - static_cast(actor)->JumpZ = value; + static_cast(actor)->JumpZ = ACSToDouble(value); break; // [GRB] case APROP_ChaseGoal: @@ -3888,7 +3918,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_Gravity: - actor->gravity = value; + actor->Gravity = ACSToDouble(value); break; case APROP_SeeSound: @@ -3938,11 +3968,11 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) break; case APROP_ScaleX: - actor->scaleX = value; + actor->Scale.X = ACSToDouble(value); break; case APROP_ScaleY: - actor->scaleY = value; + actor->Scale.Y = ACSToDouble(value); break; case APROP_Mass: @@ -4005,7 +4035,7 @@ int DLevelScript::GetActorProperty (int tid, int property) switch (property) { case APROP_Health: return actor->health; - case APROP_Speed: return actor->Speed; + case APROP_Speed: return DoubleToACS(actor->Speed); case APROP_Damage: return actor->GetMissileDamage(0,1); case APROP_DamageFactor:return actor->DamageFactor; case APROP_DamageMultiplier: return actor->DamageMultiply; @@ -4020,7 +4050,7 @@ int DLevelScript::GetActorProperty (int tid, int property) // The current render style isn't expressable as a legacy style, // so pretends it's normal. return STYLE_Normal; - case APROP_Gravity: return actor->gravity; + case APROP_Gravity: return DoubleToACS(actor->Gravity); case APROP_Invulnerable:return !!(actor->flags2 & MF2_INVULNERABLE); case APROP_Ambush: return !!(actor->flags & MF_AMBUSH); case APROP_Dropped: return !!(actor->flags & MF_DROPPED); @@ -4041,7 +4071,7 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) { - return static_cast(actor)->JumpZ; // [GRB] + return DoubleToACS(static_cast(actor)->JumpZ); // [GRB] } else { @@ -4052,13 +4082,13 @@ int DLevelScript::GetActorProperty (int tid, int property) case APROP_TargetTID: return (actor->target != NULL)? actor->target->tid : 0; case APROP_TracerTID: return (actor->tracer != NULL)? actor->tracer->tid : 0; case APROP_WaterLevel: return actor->waterlevel; - case APROP_ScaleX: return actor->scaleX; - case APROP_ScaleY: return actor->scaleY; + case APROP_ScaleX: return DoubleToACS(actor->Scale.X); + case APROP_ScaleY: return DoubleToACS(actor->Scale.Y); case APROP_Mass: return actor->Mass; case APROP_Accuracy: return actor->accuracy; case APROP_Stamina: return actor->stamina; - case APROP_Height: return actor->height; - case APROP_Radius: return actor->radius; + case APROP_Height: return actor->_f_height(); + case APROP_Radius: return actor->_f_radius(); case APROP_ReactionTime:return actor->reactiontime; case APROP_MeleeRange: return actor->meleerange; case APROP_ViewHeight: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn))) @@ -4184,12 +4214,12 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b if (floor) { - actor->Sector->NextLowestFloorAt(actor->X(), actor->Y(), actor->Z(), 0, actor->MaxStepHeight, &resultsec, &resffloor); + actor->Sector->NextLowestFloorAt(actor->_f_X(), actor->_f_Y(), actor->_f_Z(), 0, actor->MaxStepHeight, &resultsec, &resffloor); secpic = resffloor ? *resffloor->top.texture : resultsec->planes[sector_t::floor].Texture; } else { - actor->Sector->NextHighestCeilingAt(actor->X(), actor->Y(), actor->Z(), actor->Top(), 0, &resultsec, &resffloor); + actor->Sector->NextHighestCeilingAt(actor->_f_X(), actor->_f_Y(), actor->_f_Z(), actor->_f_Top(), 0, &resultsec, &resffloor); secpic = resffloor ? *resffloor->bottom.texture : resultsec->planes[sector_t::ceiling].Texture; } return tex == TexMan[secpic]; @@ -4603,7 +4633,7 @@ static void DoSetCVar(FBaseCVar *cvar, int value, bool is_string, bool force=fal } else if (cvar->GetRealType() == CVAR_Float) { - val.Float = FIXED2FLOAT(value); + val.Float = ACSToFloat(value); type = CVAR_Float; } else @@ -4634,7 +4664,7 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string) else if (cvar->GetRealType() == CVAR_Float) { val = cvar->GetGenericRep(CVAR_Float); - return FLOAT2FIXED(val.Float); + return DoubleToACS(val.Float); } else { @@ -4736,20 +4766,21 @@ static bool DoSpawnDecal(AActor *actor, const FDecalTemplate *tpl, int flags, an { if (!(flags & SDF_ABSANGLE)) { - angle += actor->angle; + angle += actor->_f_angle(); } - return NULL != ShootDecal(tpl, actor, actor->Sector, actor->X(), actor->Y(), - actor->Z() + (actor->height>>1) - actor->floorclip + actor->GetBobOffset() + zofs, + return NULL != ShootDecal(tpl, actor, actor->Sector, actor->_f_X(), actor->_f_Y(), + actor->_f_Z() + (actor->_f_height()>>1) - actor->_f_floorclip() + actor->GetBobOffset() + zofs, angle, distance, !!(flags & SDF_PERMANENT)); } static void SetActorAngle(AActor *activator, int tid, int angle, bool interpolate) { + DAngle an = ACSToAngle(angle); if (tid == 0) { if (activator != NULL) { - activator->SetAngle(angle << 16, interpolate); + activator->SetAngle(an, interpolate); } } else @@ -4759,18 +4790,19 @@ static void SetActorAngle(AActor *activator, int tid, int angle, bool interpolat while ((actor = iterator.Next())) { - actor->SetAngle(angle << 16, interpolate); + actor->SetAngle(an, interpolate); } } } static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolate) { + DAngle an = ACSToAngle(angle); if (tid == 0) { if (activator != NULL) { - activator->SetPitch(angle << 16, interpolate); + activator->SetPitch(an, interpolate); } } else @@ -4780,18 +4812,19 @@ static void SetActorPitch(AActor *activator, int tid, int angle, bool interpolat while ((actor = iterator.Next())) { - actor->SetPitch(angle << 16, interpolate); + actor->SetPitch(an, interpolate); } } } static void SetActorRoll(AActor *activator, int tid, int angle, bool interpolate) { + DAngle an = ACSToAngle(angle); if (tid == 0) { if (activator != NULL) { - activator->SetRoll(angle << 16, interpolate); + activator->SetRoll(an, interpolate); } } else @@ -4801,7 +4834,7 @@ static void SetActorRoll(AActor *activator, int tid, int angle, bool interpolate while ((actor = iterator.Next())) { - actor->SetRoll(angle << 16, interpolate); + actor->SetRoll(an, interpolate); } } } @@ -4897,15 +4930,15 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_GetActorVelX: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->vel.x : 0; + return actor != NULL? DoubleToACS(actor->Vel.X) : 0; case ACSF_GetActorVelY: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->vel.y : 0; + return actor != NULL? DoubleToACS(actor->Vel.Y) : 0; case ACSF_GetActorVelZ: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->vel.z : 0; + return actor != NULL? DoubleToACS(actor->Vel.Z) : 0; case ACSF_SetPointer: if (activator) @@ -4965,7 +4998,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) } else { - return actor->GetCameraHeight(); + return DoubleToACS(actor->GetCameraHeight()); } } else return 0; @@ -5010,8 +5043,8 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_SetSkyScrollSpeed: { - if (args[0] == 1) level.skyspeed1 = FIXED2FLOAT(args[1]); - else if (args[0] == 2) level.skyspeed2 = FIXED2FLOAT(args[1]); + if (args[0] == 1) level.skyspeed1 = ACSToFloat(args[1]); + else if (args[0] == 2) level.skyspeed2 = ACSToFloat(args[1]); return 1; } @@ -5075,20 +5108,23 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return (CheckActorProperty(args[0], args[1], args[2])); case ACSF_SetActorVelocity: - if (args[0] == 0) - { - P_Thing_SetVelocity(activator, args[1], args[2], args[3], !!args[4], !!args[5]); - } - else - { - TActorIterator iterator (args[0]); - - while ( (actor = iterator.Next ()) ) - { - P_Thing_SetVelocity(actor, args[1], args[2], args[3], !!args[4], !!args[5]); - } - } - return 0; + { + DVector3 vel(ACSToDouble(args[1]), ACSToDouble(args[2]), ACSToDouble(args[3])); + if (args[0] == 0) + { + P_Thing_SetVelocity(activator, vel, !!args[4], !!args[5]); + } + else + { + TActorIterator iterator(args[0]); + + while ((actor = iterator.Next())) + { + P_Thing_SetVelocity(actor, vel, !!args[4], !!args[5]); + } + } + return 0; + } case ACSF_SetUserVariable: { @@ -5335,13 +5371,13 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return P_IsTIDUsed(args[0]); case ACSF_Sqrt: - return xs_FloorToInt(sqrt(double(args[0]))); + return xs_FloorToInt(g_sqrt(double(args[0]))); case ACSF_FixedSqrt: - return FLOAT2FIXED(sqrt(FIXED2DBL(args[0]))); + return DoubleToACS(g_sqrt(ACSToDouble(args[0]))); case ACSF_VectorLength: - return FLOAT2FIXED(DVector2(FIXED2DBL(args[0]), FIXED2DBL(args[1])).Length()); + return DoubleToACS(DVector2(ACSToDouble(args[0]), ACSToDouble(args[1])).Length()); case ACSF_SetHUDClipRect: ClipRectLeft = argCount > 0 ? args[0] : 0; @@ -5408,12 +5444,12 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) //[RC] A bullet firing function for ACS. Thanks to DavidPH. case ACSF_LineAttack: { - fixed_t angle = args[1] << FRACBITS; - fixed_t pitch = args[2] << FRACBITS; + DAngle angle = ACSToAngle(args[1]); + DAngle pitch = ACSToAngle(args[2]); int damage = args[3]; FName pufftype = argCount > 4 && args[4]? FName(FBehavior::StaticLookupString(args[4])) : NAME_BulletPuff; FName damagetype = argCount > 5 && args[5]? FName(FBehavior::StaticLookupString(args[5])) : NAME_None; - fixed_t range = argCount > 6 && args[6]? args[6] : MISSILERANGE; + double range = argCount > 6 && args[6]? ACSToDouble(args[6]) : MISSILERANGE; int flags = argCount > 7 && args[7]? args[7] : 0; int pufftid = argCount > 8 && args[8]? args[8] : 0; @@ -5468,9 +5504,9 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) AActor *spot; int chan = argCount > 2 ? args[2] : CHAN_BODY; - float vol = argCount > 3 ? FIXED2FLOAT(args[3]) : 1.f; + float vol = argCount > 3 ? ACSToFloat(args[3]) : 1.f; INTBOOL looping = argCount > 4 ? args[4] : false; - float atten = argCount > 5 ? FIXED2FLOAT(args[5]) : ATTN_NORM; + float atten = argCount > 5 ? ACSToFloat(args[5]) : ATTN_NORM; if (args[0] == 0) { @@ -5524,7 +5560,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // SoundVolume(int tid, int channel, fixed volume) { int chan = args[1]; - float volume = FIXED2FLOAT(args[2]); + float volume = ACSToFloat(args[2]); if (args[0] == 0) { @@ -5745,9 +5781,9 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) { return P_StartQuakeXYZ(activator, args[0], args[1], args[2], args[3], args[4], args[5], args[6], FBehavior::StaticLookupString(args[7]), argCount > 8 ? args[8] : 0, - argCount > 9 ? FIXED2DBL(args[9]) : 1.0, - argCount > 10 ? FIXED2DBL(args[10]) : 1.0, - argCount > 11 ? FIXED2DBL(args[11]) : 1.0 ); + argCount > 9 ? ACSToDouble(args[9]) : 1.0, + argCount > 10 ? ACSToDouble(args[10]) : 1.0, + argCount > 11 ? ACSToDouble(args[11]) : 1.0 ); } case ACSF_SetLineActivation: @@ -5901,11 +5937,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) // [Nash] Actor roll functions. Let's roll! case ACSF_SetActorRoll: - actor = SingleActorFromTID(args[0], activator); - if (actor != NULL) - { - actor->SetRoll(args[1] << 16, false); - } + SetActorRoll(activator, args[0], args[1], false); return 0; case ACSF_ChangeActorRoll: @@ -5917,7 +5949,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_GetActorRoll: actor = SingleActorFromTID(args[0], activator); - return actor != NULL? actor->roll >> 16 : 0; + return actor != NULL? actor->Angles.Roll.FixedAngle() : 0; // [ZK] A_Warp in ACS case ACSF_Warp: @@ -7737,7 +7769,7 @@ scriptwait: break; case PCD_PRINTFIXED: - work.AppendFormat ("%g", FIXED2FLOAT(STACK(1))); + work.AppendFormat ("%g", ACSToDouble(STACK(1))); --sp; break; @@ -7950,9 +7982,9 @@ scriptwait: int type = Stack[optstart-6]; int id = Stack[optstart-5]; EColorRange color; - float x = FIXED2FLOAT(Stack[optstart-3]); - float y = FIXED2FLOAT(Stack[optstart-2]); - float holdTime = FIXED2FLOAT(Stack[optstart-1]); + float x = ACSToFloat(Stack[optstart-3]); + float y = ACSToFloat(Stack[optstart-2]); + float holdTime = ACSToFloat(Stack[optstart-1]); fixed_t alpha; DHUDMessage *msg; @@ -7973,23 +8005,23 @@ scriptwait: break; case 1: // fade out { - float fadeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f; + float fadeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; alpha = (optstart < sp-1) ? Stack[optstart+1] : FRACUNIT; msg = new DHUDMessageFadeOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime); } break; case 2: // type on, then fade out { - float typeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.05f; - float fadeTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f; + float typeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.05f; + float fadeTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT; msg = new DHUDMessageTypeOnFadeOut (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); } break; case 3: // fade in, then fade out { - float inTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f; - float outTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f; + float inTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; + float outTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT; msg = new DHUDMessageFadeInOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); } @@ -8350,23 +8382,23 @@ scriptwait: break; case PCD_SETGRAVITY: - level.gravity = (float)STACK(1) / 65536.f; + level.gravity = ACSToDouble(STACK(1)); sp--; break; case PCD_SETGRAVITYDIRECT: - level.gravity = (float)uallong(pc[0]) / 65536.f; + level.gravity = ACSToDouble(uallong(pc[0])); pc++; break; case PCD_SETAIRCONTROL: - level.aircontrol = STACK(1); + level.aircontrol = ACSToDouble(STACK(1)); sp--; G_AirControlChanged (); break; case PCD_SETAIRCONTROLDIRECT: - level.aircontrol = uallong(pc[0]); + level.aircontrol = ACSToDouble(uallong(pc[0])); pc++; G_AirControlChanged (); break; @@ -8664,11 +8696,11 @@ scriptwait: } else if (pcd == PCD_GETACTORZ) { - STACK(1) = actor->Z() + actor->GetBobOffset(); + STACK(1) = actor->_f_Z() + actor->GetBobOffset(); } else { - STACK(1) = pcd == PCD_GETACTORX ? actor->X() : pcd == PCD_GETACTORY ? actor->Y() : actor->Z(); + STACK(1) = pcd == PCD_GETACTORX ? actor->_f_X() : pcd == PCD_GETACTORY ? actor->_f_Y() : actor->_f_Z(); } } break; @@ -8676,28 +8708,28 @@ scriptwait: case PCD_GETACTORFLOORZ: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->floorz; + STACK(1) = actor == NULL ? 0 : DoubleToACS(actor->floorz); } break; case PCD_GETACTORCEILINGZ: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->ceilingz; + STACK(1) = actor == NULL ? 0 : DoubleToACS(actor->ceilingz); } break; case PCD_GETACTORANGLE: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->angle >> 16; + STACK(1) = actor == NULL ? 0 : actor->Angles.Yaw.FixedAngle(); } break; case PCD_GETACTORPITCH: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : actor->pitch >> 16; + STACK(1) = actor == NULL ? 0 : actor->Angles.Pitch.FixedAngle(); } break; @@ -8833,8 +8865,8 @@ scriptwait: if (translation != NULL) translation->AddDesaturation(start, end, - FIXED2DBL(r1), FIXED2DBL(g1), FIXED2DBL(b1), - FIXED2DBL(r2), FIXED2DBL(g2), FIXED2DBL(b2)); + ACSToDouble(r1), ACSToDouble(g1), ACSToDouble(b1), + ACSToDouble(r2), ACSToDouble(g2), ACSToDouble(b2)); } break; @@ -9034,15 +9066,15 @@ scriptwait: // Like Thing_Projectile(Gravity) specials, but you can give the // projectile a TID. // Thing_Projectile2 (tid, type, angle, speed, vspeed, gravity, newtid); - P_Thing_Projectile (STACK(7), activator, STACK(6), NULL, ((angle_t)(STACK(5)<<24)), - STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false); + P_Thing_Projectile(STACK(7), activator, STACK(6), NULL, STACK(5) * (360. / 256.), + STACK(4) << (FRACBITS - 3), STACK(3) << (FRACBITS - 3), 0, NULL, STACK(2), STACK(1), false); sp -= 7; break; case PCD_SPAWNPROJECTILE: // Same, but takes an actor name instead of a spawn ID. - P_Thing_Projectile (STACK(7), activator, 0, FBehavior::StaticLookupString (STACK(6)), ((angle_t)(STACK(5)<<24)), - STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false); + P_Thing_Projectile(STACK(7), activator, 0, FBehavior::StaticLookupString(STACK(6)), STACK(5) * (360. / 256.), + STACK(4) << (FRACBITS - 3), STACK(3) << (FRACBITS - 3), 0, NULL, STACK(2), STACK(1), false); sp -= 7; break; @@ -9221,12 +9253,12 @@ scriptwait: switch (STACK(1)) { case PLAYERINFO_TEAM: STACK(2) = userinfo->GetTeam(); break; - case PLAYERINFO_AIMDIST: STACK(2) = userinfo->GetAimDist(); break; + case PLAYERINFO_AIMDIST: STACK(2) = (SDWORD)(userinfo->GetAimDist() * (0x40000000/90.)); break; // Yes, this has been returning a BAM since its creation. case PLAYERINFO_COLOR: STACK(2) = userinfo->GetColor(); break; case PLAYERINFO_GENDER: STACK(2) = userinfo->GetGender(); break; case PLAYERINFO_NEVERSWITCH: STACK(2) = userinfo->GetNeverSwitch(); break; - case PLAYERINFO_MOVEBOB: STACK(2) = userinfo->GetMoveBob(); break; - case PLAYERINFO_STILLBOB: STACK(2) = userinfo->GetStillBob(); break; + case PLAYERINFO_MOVEBOB: STACK(2) = DoubleToACS(userinfo->GetMoveBob()); break; + case PLAYERINFO_STILLBOB: STACK(2) = DoubleToACS(userinfo->GetStillBob()); break; case PLAYERINFO_PLAYERCLASS: STACK(2) = userinfo->GetPlayerClassNum(); break; case PLAYERINFO_DESIREDFOV: STACK(2) = (int)pl->DesiredFOV; break; case PLAYERINFO_FOV: STACK(2) = (int)pl->FOV; break; diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 3da00fbaf..d2258eb53 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -45,7 +45,7 @@ struct sectortype { SWORD wallptr, wallnum; - SDWORD ceilingz, floorz; + SDWORD ceilingZ, floorZ; SWORD ceilingstat, floorstat; SWORD ceilingpicnum, ceilingheinum; SBYTE ceilingshade; @@ -402,7 +402,7 @@ static void LoadSectors (sectortype *bsec) bsec->floorstat = WORD(bsec->floorstat); sec->e = §ors[0].e[i]; - sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8)); + sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorZ) << 8)); sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor); sec->floorplane.c = FRACUNIT; sec->floorplane.ic = FRACUNIT; @@ -415,7 +415,7 @@ static void LoadSectors (sectortype *bsec) sec->SetPlaneLight(sector_t::floor, SHADE2LIGHT (bsec->floorshade)); sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING); - sec->SetPlaneTexZ(sector_t::ceiling, -(LittleLong(bsec->ceilingz) << 8)); + sec->SetPlaneTexZ(sector_t::ceiling, -(LittleLong(bsec->ceilingZ) << 8)); sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling); sec->ceilingplane.c = -FRACUNIT; sec->ceilingplane.ic = -FRACUNIT; @@ -639,7 +639,7 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) slope.wal2 = &walls[slope.wal->point2]; slope.dx = slope.wal2->x - slope.wal->x; slope.dy = slope.wal2->y - slope.wal->y; - slope.i = long (sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5; + slope.i = long (g_sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5; if (slope.i == 0) { continue; @@ -647,13 +647,13 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) if ((bsec->floorstat & 2) && (bsec->floorheinum != 0)) { // floor is sloped slope.heinum = -LittleShort(bsec->floorheinum); - slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorz; + slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorZ; CalcPlane (slope, sectors[i].floorplane); } if ((bsec->ceilingstat & 2) && (bsec->ceilingheinum != 0)) { // ceiling is sloped slope.heinum = -LittleShort(bsec->ceilingheinum); - slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingz; + slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingZ; CalcPlane (slope, sectors[i].ceilingplane); } int linenum = int(intptr_t(sides[bsec->wallptr].linedef)); @@ -699,13 +699,13 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, mapthings[count].thingid = 0; mapthings[count].x = (sprites[i].x << 12); mapthings[count].y = -(sprites[i].y << 12); - mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8; + mapthings[count].z = (bsectors[sprites[i].sectnum].floorZ - sprites[i].z) << 8; mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11; mapthings[count].ClassFilter = 0xffff; mapthings[count].SkillFilter = 0xffff; mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH; mapthings[count].special = 0; - mapthings[count].gravity = FRACUNIT; + mapthings[count].Gravity = 1.; mapthings[count].RenderStyle = STYLE_Count; mapthings[count].alpha = -1; mapthings[count].health = -1; @@ -883,8 +883,8 @@ void ACustomSprite::BeginPlay () mysnprintf (name, countof(name), "BTIL%04d", args[0] & 0xffff); picnum = TexMan.GetTexture (name, FTexture::TEX_Build); - scaleX = args[2] * (FRACUNIT/64); - scaleY = args[3] * (FRACUNIT/64); + Scale.X = args[2] / 64.; + Scale.Y = args[3] / 64.; int cstat = args[4]; if (cstat & 2) diff --git a/src/p_checkposition.h b/src/p_checkposition.h index 4ab67634e..0950efd66 100644 --- a/src/p_checkposition.h +++ b/src/p_checkposition.h @@ -19,8 +19,8 @@ struct FCheckPosition // out sector_t *sector; - fixed_t floorz; - fixed_t ceilingz; + double floorz; + double ceilingz; fixed_t dropoffz; FTextureID floorpic; int floorterrain; @@ -46,6 +46,16 @@ struct FCheckPosition PushTime = 0; FromPMove = false; } + + inline fixed_t _f_ceilingz() + { + return FLOAT2FIXED(ceilingz); + } + inline fixed_t _f_floorz() + { + return FLOAT2FIXED(floorz); + } + }; diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 77de53345..79cb3385d 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1091,8 +1091,8 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang return; } - pc->vel.x = pc->vel.y = 0; // Stop moving - pc->player->vel.x = pc->player->vel.y = 0; + pc->Vel.Zero(); + pc->player->Vel.Zero(); static_cast(pc)->PlayIdle (); pc->player->ConversationPC = pc; @@ -1110,14 +1110,14 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang pc->player->ConversationFaceTalker = facetalker; if (saveangle) { - pc->player->ConversationNPCAngle = npc->angle; + pc->player->ConversationNPCAngle = npc->Angles.Yaw; } oldtarget = npc->target; npc->target = pc; if (facetalker) { A_FaceTarget (npc); - pc->angle = pc->AngleTo(npc); + pc->Angles.Yaw = pc->AngleTo(npc); } if ((npc->flags & MF_FRIENDLY) || (npc->flags4 & MF4_NOHATEPLAYERS)) { @@ -1227,7 +1227,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply if (reply == NULL) { // The default reply was selected - npc->angle = player->ConversationNPCAngle; + npc->Angles.Yaw = player->ConversationNPCAngle; npc->flags5 &= ~MF5_INCONVERSATION; return; } @@ -1243,7 +1243,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply TerminalResponse(reply->QuickNo); } npc->ConversationAnimation(2); - npc->angle = player->ConversationNPCAngle; + npc->Angles.Yaw = player->ConversationNPCAngle; npc->flags5 &= ~MF5_INCONVERSATION; return; } @@ -1371,7 +1371,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply } } - npc->angle = player->ConversationNPCAngle; + npc->Angles.Yaw = player->ConversationNPCAngle; // [CW] Set these to NULL because we're not using to them // anymore. However, this can interfere with slideshows @@ -1382,7 +1382,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply player->ConversationFaceTalker = false; player->ConversationNPC = NULL; player->ConversationPC = NULL; - player->ConversationNPCAngle = 0; + player->ConversationNPCAngle = 0.; } if (isconsole) @@ -1421,7 +1421,7 @@ void P_ConversationCommand (int netcode, int pnum, BYTE **stream) assert(netcode == DEM_CONVNULL || netcode == DEM_CONVCLOSE); if (player->ConversationNPC != NULL) { - player->ConversationNPC->angle = player->ConversationNPCAngle; + player->ConversationNPC->Angles.Yaw = player->ConversationNPCAngle; player->ConversationNPC->flags5 &= ~MF5_INCONVERSATION; } if (netcode == DEM_CONVNULL) @@ -1429,7 +1429,7 @@ void P_ConversationCommand (int netcode, int pnum, BYTE **stream) player->ConversationFaceTalker = false; player->ConversationNPC = NULL; player->ConversationPC = NULL; - player->ConversationNPCAngle = 0; + player->ConversationNPCAngle = 0.; } } } diff --git a/src/p_effect.cpp b/src/p_effect.cpp index bf1490825..4108be2d5 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -292,20 +292,20 @@ void P_ThinkParticles () if (!particle->subsector->sector->PortalBlocksMovement(sector_t::ceiling)) { AActor *skybox = particle->subsector->sector->SkyBoxes[sector_t::ceiling]; - if (particle->z > skybox->threshold) + if (particle->z > FLOAT2FIXED(skybox->specialf1)) { - particle->x += skybox->scaleX; - particle->y += skybox->scaleY; + particle->x += FLOAT2FIXED(skybox->Scale.X); + particle->y += FLOAT2FIXED(skybox->Scale.Y); particle->subsector = NULL; } } else if (!particle->subsector->sector->PortalBlocksMovement(sector_t::floor)) { AActor *skybox = particle->subsector->sector->SkyBoxes[sector_t::floor]; - if (particle->z < skybox->threshold) + if (particle->z < FLOAT2FIXED(skybox->specialf1)) { - particle->x += skybox->scaleX; - particle->y += skybox->scaleY; + particle->x += FLOAT2FIXED(skybox->Scale.X); + particle->y += FLOAT2FIXED(skybox->Scale.Y); particle->subsector = NULL; } } @@ -408,13 +408,13 @@ static void MakeFountain (AActor *actor, int color1, int color2) if (particle) { angle_t an = M_Random()<<(24-ANGLETOFINESHIFT); - fixed_t out = FixedMul (actor->radius, M_Random()<<8); + fixed_t out = FixedMul (actor->_f_radius(), M_Random()<<8); - fixedvec3 pos = actor->Vec3Offset(FixedMul(out, finecosine[an]), FixedMul(out, finesine[an]), actor->height + FRACUNIT); + fixedvec3 pos = actor->Vec3Offset(FixedMul(out, finecosine[an]), FixedMul(out, finesine[an]), actor->_f_height() + FRACUNIT); particle->x = pos.x; particle->y = pos.y; particle->z = pos.z; - if (out < actor->radius/8) + if (out < actor->_f_radius()/8) particle->vel.z += FRACUNIT*10/3; else particle->vel.z += FRACUNIT*3; @@ -431,17 +431,7 @@ static void MakeFountain (AActor *actor, int color1, int color2) void P_RunEffect (AActor *actor, int effects) { - angle_t moveangle; - - // 512 is the limit below which R_PointToAngle2 does no longer returns usable values. - if (abs(actor->vel.x) > 512 || abs(actor->vel.y) > 512) - { - moveangle = R_PointToAngle2(0,0,actor->vel.x,actor->vel.y); - } - else - { - moveangle = actor->angle; - } + DAngle moveangle = actor->Vel.Angle(); particle_t *particle; int i; @@ -449,28 +439,26 @@ void P_RunEffect (AActor *actor, int effects) if ((effects & FX_ROCKET) && (cl_rockettrails & 1)) { // Rocket trail + double backx = -actor->radius * 2 * moveangle.Cos(); + double backy = -actor->radius * 2 * moveangle.Sin(); + double backz = actor->Height * ((2. / 3) - actor->Vel.Z / 8); - - fixed_t backx = - FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2); - fixed_t backy = - FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], actor->radius*2); - fixed_t backz = - (actor->height>>3) * (actor->vel.z>>16) + (2*actor->height)/3; - - angle_t an = (moveangle + ANG90) >> ANGLETOFINESHIFT; + DAngle an = moveangle + 90.; int speed; particle = JitterParticle (3 + (M_Random() & 31)); if (particle) { fixed_t pathdist = M_Random()<<8; fixedvec3 pos = actor->Vec3Offset( - backx - FixedMul(actor->vel.x, pathdist), - backy - FixedMul(actor->vel.y, pathdist), - backz - FixedMul(actor->vel.z, pathdist)); + FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist), + FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist), + FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist)); particle->x = pos.x; particle->y = pos.y; particle->z = pos.z; speed = (M_Random () - 128) * (FRACUNIT/200); - particle->vel.x += FixedMul (speed, finecosine[an]); - particle->vel.y += FixedMul (speed, finesine[an]); + particle->vel.x += fixed_t(speed * an.Cos()); + particle->vel.y += fixed_t(speed * an.Sin()); particle->vel.z -= FRACUNIT/36; particle->accz -= FRACUNIT/20; particle->color = yellow; @@ -481,15 +469,15 @@ void P_RunEffect (AActor *actor, int effects) if (particle) { fixed_t pathdist = M_Random()<<8; fixedvec3 pos = actor->Vec3Offset( - backx - FixedMul(actor->vel.x, pathdist), - backy - FixedMul(actor->vel.y, pathdist), - backz - FixedMul(actor->vel.z, pathdist) + (M_Random() << 10)); + FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist), + FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist), + FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist) + (M_Random() << 10)); particle->x = pos.x; particle->y = pos.y; particle->z = pos.z; speed = (M_Random () - 128) * (FRACUNIT/200); - particle->vel.x += FixedMul (speed, finecosine[an]); - particle->vel.y += FixedMul (speed, finesine[an]); + particle->vel.x += fixed_t(speed * an.Cos()); + particle->vel.y += fixed_t(speed * an.Sin()); particle->vel.z += FRACUNIT/80; particle->accz += FRACUNIT/40; if (M_Random () & 7) @@ -505,11 +493,11 @@ void P_RunEffect (AActor *actor, int effects) { // Grenade trail - fixedvec3 pos = actor->Vec3Angle(-actor->radius * 2, moveangle, - -(actor->height >> 3) * (actor->vel.z >> 16) + (2 * actor->height) / 3); + fixedvec3 pos = actor->_f_Vec3Angle(-actor->_f_radius() * 2, moveangle.BAMs(), + fixed_t(-(actor->_f_height() >> 3) * (actor->Vel.Z) + (2 * actor->_f_height()) / 3)); P_DrawSplash2 (6, pos.x, pos.y, pos.z, - moveangle + ANG180, 2, 2); + moveangle.BAMs() + ANG180, 2, 2); } if (effects & FX_FOUNTAINMASK) { @@ -540,7 +528,7 @@ void P_RunEffect (AActor *actor, int effects) if (particle != NULL) { angle_t ang = M_Random () << (32-ANGLETOFINESHIFT-8); - fixedvec3 pos = actor->Vec3Offset(FixedMul (actor->radius, finecosine[ang]), FixedMul (actor->radius, finesine[ang]), 0); + fixedvec3 pos = actor->Vec3Offset(FixedMul (actor->_f_radius(), finecosine[ang]), FixedMul (actor->_f_radius(), finesine[ang]), 0); particle->x = pos.x; particle->y = pos.y; particle->z = pos.z; @@ -550,7 +538,7 @@ void P_RunEffect (AActor *actor, int effects) particle->size = 1; if (M_Random () < 128) { // make particle fall from top of actor - particle->z += actor->height; + particle->z += actor->_f_height(); particle->vel.z = -particle->vel.z; particle->accz = -particle->accz; } @@ -662,7 +650,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, dir = end - start; lengthsquared = dir | dir; - length = sqrt(lengthsquared); + length = g_sqrt(lengthsquared); steps = xs_FloorToInt(length / 3); fullbright = !!(flags & RAF_FULLBRIGHT); @@ -685,8 +673,8 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, double r; double dirz; - if (abs(mo->X() - FLOAT2FIXED(start.X)) < 20 * FRACUNIT - && (mo->Y() - FLOAT2FIXED(start.Y)) < 20 * FRACUNIT) + if (fabs(mo->X() - start.X) < 20 + && fabs(mo->Y() - start.Y) < 20) { // This player (probably) fired the railgun S_Sound (mo, CHAN_WEAPON, sound, 1, ATTN_NORM); } @@ -696,7 +684,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, // Only consider sound in 2D (for now, anyway) // [BB] You have to divide by lengthsquared here, not multiply with it. - r = ((start.Y - FIXED2DBL(mo->Y())) * (-dir.Y) - (start.X - FIXED2DBL(mo->X())) * (dir.X)) / lengthsquared; + r = ((start.Y - mo->Y()) * (-dir.Y) - (start.X - mo->X()) * (dir.X)) / lengthsquared; r = clamp(r, 0., 1.); dirz = dir.Z; @@ -744,7 +732,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, color1 = color1 == 0 ? -1 : ParticleColor(color1); pos = start; - deg = TAngle(SpiralOffset); + deg = (double)SpiralOffset; for (i = spiral_steps; i; i--) { particle_t *p = NewParticle (); @@ -770,7 +758,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, p->y = FLOAT2FIXED(tempvec.Y); p->z = FLOAT2FIXED(tempvec.Z); pos += spiral_step; - deg += TAngle(r_rail_spiralsparsity * 14); + deg += double(r_rail_spiralsparsity * 14); if (color1 == -1) { @@ -878,7 +866,7 @@ void P_DrawRailTrail(AActor *source, const DVector3 &start, const DVector3 &end, AActor *thing = Spawn (spawnclass, FLOAT2FIXED(postmp.X), FLOAT2FIXED(postmp.Y), FLOAT2FIXED(postmp.Z), ALLOW_REPLACE); if (thing) - thing->angle = angle; + thing->Angles.Yaw = ANGLE2DBL(angle); pos += trail_step; } } @@ -899,9 +887,9 @@ void P_DisconnectEffect (AActor *actor) break; - fixed_t xo = ((M_Random() - 128) << 9) * (actor->radius >> FRACBITS); - fixed_t yo = ((M_Random() - 128) << 9) * (actor->radius >> FRACBITS); - fixed_t zo = (M_Random() << 8) * (actor->height >> FRACBITS); + fixed_t xo = ((M_Random() - 128) << 9) * (actor->_f_radius() >> FRACBITS); + fixed_t yo = ((M_Random() - 128) << 9) * (actor->_f_radius() >> FRACBITS); + fixed_t zo = (M_Random() << 8) * (actor->_f_height() >> FRACBITS); fixedvec3 pos = actor->Vec3Offset(xo, yo, zo); p->x = pos.x; p->y = pos.y; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index addaf12ea..8c3a857bc 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -52,6 +52,7 @@ #include "teaminfo.h" #include "p_spec.h" #include "p_checkposition.h" +#include "math/cmath.h" #include "gi.h" @@ -161,16 +162,16 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun if (checkabove) { sector_t *upper = - P_PointInSector(check->v1->x + check->dx / 2 + sec->SkyBoxes[sector_t::ceiling]->scaleX, - check->v1->y + check->dy / 2 + sec->SkyBoxes[sector_t::ceiling]->scaleY); + P_PointInSector(check->v1->x + check->dx / 2 + FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->Scale.X), + check->v1->y + check->dy / 2 + FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->Scale.Y)); P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist); } if (checkbelow) { sector_t *lower = - P_PointInSector(check->v1->x + check->dx / 2 + sec->SkyBoxes[sector_t::floor]->scaleX, - check->v1->y + check->dy / 2 + sec->SkyBoxes[sector_t::floor]->scaleY); + P_PointInSector(check->v1->x + check->dx / 2 + FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->Scale.X), + check->v1->y + check->dy / 2 + FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->Scale.Y)); P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist); } @@ -270,7 +271,7 @@ bool AActor::CheckMeleeRange () dist = AproxDistance (pl); - if (dist >= meleerange + pl->radius) + if (dist >= meleerange + pl->_f_radius()) return false; // [RH] If moving toward goal, then we've reached it. @@ -307,13 +308,14 @@ bool P_CheckMeleeRange2 (AActor *actor) AActor *mo; fixed_t dist; + if (!actor->target) { return false; } mo = actor->target; dist = mo->AproxDistance (actor); - if (dist >= MELEERANGE*2 || dist < MELEERANGE-20*FRACUNIT + mo->radius) + if (dist >= (128 << FRACBITS) || dist < actor->meleerange + mo->_f_radius()) { return false; } @@ -429,9 +431,9 @@ bool P_HitFriend(AActor * self) if (self->flags&MF_FRIENDLY && self->target != NULL) { - angle_t angle = self->AngleTo(self->target); - fixed_t dist = self->AproxDistance (self->target); - P_AimLineAttack (self, angle, dist, &t, 0, true); + DAngle angle = self->AngleTo(self->target); + double dist = self->Distance2D(self->target); + P_AimLineAttack (self, angle, dist, &t, 0., true); if (t.linetarget != NULL && t.linetarget != self->target) { return self->IsFriend (t.linetarget); @@ -451,7 +453,7 @@ bool P_Move (AActor *actor) fixed_t tryx, tryy, deltax, deltay, origx, origy; bool try_ok; - int speed = actor->Speed; + int speed = actor->_f_speed(); int movefactor = ORIG_FRICTION_FACTOR; int friction = ORIG_FRICTION; int dropoff = 0; @@ -505,17 +507,17 @@ bool P_Move (AActor *actor) * speed) / ORIG_FRICTION_FACTOR; if (speed == 0) { // always give the monster a little bit of speed - speed = ksgn(actor->Speed); + speed = ksgn(actor->_f_speed()); } } } - tryx = (origx = actor->X()) + (deltax = FixedMul (speed, xspeed[actor->movedir])); - tryy = (origy = actor->Y()) + (deltay = FixedMul (speed, yspeed[actor->movedir])); + tryx = (origx = actor->_f_X()) + (deltax = FixedMul (speed, xspeed[actor->movedir])); + tryy = (origy = actor->_f_Y()) + (deltay = FixedMul (speed, yspeed[actor->movedir])); // Like P_XYMovement this should do multiple moves if the step size is too large - fixed_t maxmove = actor->radius - FRACUNIT; + fixed_t maxmove = actor->_f_radius() - FRACUNIT; int steps = 1; if (maxmove > 0) @@ -561,10 +563,10 @@ bool P_Move (AActor *actor) if (try_ok && friction > ORIG_FRICTION) { - actor->SetOrigin(origx, origy, actor->Z(), false); + actor->SetOrigin(origx, origy, actor->_f_Z(), false); movefactor *= FRACUNIT / ORIG_FRICTION_FACTOR / 4; - actor->vel.x += FixedMul (deltax, movefactor); - actor->vel.y += FixedMul (deltay, movefactor); + actor->Vel.X += FIXED2DBL(FixedMul (deltax, movefactor)); + actor->Vel.Y += FIXED2DBL(FixedMul (deltay, movefactor)); } // [RH] If a walking monster is no longer on the floor, move it down @@ -572,11 +574,11 @@ bool P_Move (AActor *actor) // actually walking down a step. if (try_ok && !((actor->flags & MF_NOGRAVITY) || (actor->flags6 & MF6_CANJUMP)) - && actor->Z() > actor->floorz && !(actor->flags2 & MF2_ONMOBJ)) + && actor->Z() > actor->floorz && !(actor->flags2 & MF2_ONMOBJ)) { - if (actor->Z() <= actor->floorz + actor->MaxStepHeight) + if (actor->_f_Z() <= actor->_f_floorz() + actor->MaxStepHeight) { - fixed_t savedz = actor->Z(); + double savedz = actor->Z(); actor->SetZ(actor->floorz); // Make sure that there isn't some other actor between us and // the floor we could get stuck in. The old code did not do this. @@ -587,7 +589,7 @@ bool P_Move (AActor *actor) else { // The monster just hit the floor, so trigger any actions. if (actor->floorsector->SecActTarget != NULL && - actor->floorz == actor->floorsector->floorplane.ZatPoint(actor->PosRelative(actor->floorsector))) + actor->_f_floorz() == actor->floorsector->floorplane.ZatPoint(actor->PosRelative(actor->floorsector))) { actor->floorsector->SecActTarget->TriggerAction(actor, SECSPAC_HitFloor); } @@ -600,7 +602,7 @@ bool P_Move (AActor *actor) { if (((actor->flags6 & MF6_CANJUMP)||(actor->flags & MF_FLOAT)) && tm.floatok) { // must adjust height - fixed_t savedz = actor->Z(); + double savedz = actor->Z(); if (actor->Z() < tm.floorz) actor->AddZ(actor->FloatSpeed); @@ -852,11 +854,11 @@ void P_NewChaseDir(AActor * actor) if ((actor->flags5&MF5_CHASEGOAL || actor->goal == actor->target) && actor->goal!=NULL) { - delta = actor->Vec2To(actor->goal); + delta = actor->_f_Vec2To(actor->goal); } else if (actor->target != NULL) { - delta = actor->Vec2To(actor->target); + delta = actor->_f_Vec2To(actor->target); if (!(actor->flags6 & MF6_NOFEAR)) { @@ -877,12 +879,12 @@ void P_NewChaseDir(AActor * actor) } // Try to move away from a dropoff - if (actor->floorz - actor->dropoffz > actor->MaxDropOffHeight && + if (actor->_f_floorz() - actor->dropoffz > actor->MaxDropOffHeight && actor->Z() <= actor->floorz && !(actor->flags & MF_DROPOFF) && !(actor->flags2 & MF2_ONMOBJ) && !(actor->flags & MF_FLOAT) && !(i_compatflags & COMPATF_DROPOFF)) { - FBoundingBox box(actor->X(), actor->Y(), actor->radius); + FBoundingBox box(actor->_f_X(), actor->_f_Y(), actor->_f_radius()); FBlockLinesIterator it(box); line_t *line; @@ -904,11 +906,11 @@ void P_NewChaseDir(AActor * actor) // The monster must contact one of the two floors, // and the other must be a tall dropoff. - if (back == actor->Z() && front < actor->Z() - actor->MaxDropOffHeight) + if (back == actor->_f_Z() && front < actor->_f_Z() - actor->MaxDropOffHeight) { angle = R_PointToAngle2(0,0,line->dx,line->dy); // front side dropoff } - else if (front == actor->Z() && back < actor->Z() - actor->MaxDropOffHeight) + else if (front == actor->_f_Z() && back < actor->_f_Z() - actor->MaxDropOffHeight) { angle = R_PointToAngle2(line->dx,line->dy,0,0); // back side dropoff } @@ -966,13 +968,13 @@ void P_NewChaseDir(AActor * actor) fixed_t dist = actor->AproxDistance(target); if (target->player == NULL) { - ismeleeattacker = (target->MissileState == NULL && dist < (target->meleerange + target->radius)*2); + ismeleeattacker = (target->MissileState == NULL && dist < (target->meleerange + target->_f_radius())*2); } else if (target->player->ReadyWeapon != NULL) { // melee range of player weapon is a parameter of the action function and cannot be checked here. // Add a new weapon property? - ismeleeattacker = (target->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON && dist < MELEERANGE*3); + ismeleeattacker = (target->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON && dist < (192 << FRACBITS)); } if (ismeleeattacker) { @@ -1036,7 +1038,7 @@ void P_RandomChaseDir (AActor *actor) { if (pr_newchasedir() & 1 || !P_CheckSight (actor, player)) { - delta = actor->Vec2To(player); + delta = actor->_f_Vec2To(player); if (delta.x>128*FRACUNIT) d[1]= DI_EAST; @@ -1190,13 +1192,13 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams if (fov && fov < ANGLE_MAX) { - angle_t an = lookee->AngleTo(other) - lookee->angle; + angle_t an = lookee->__f_AngleTo(other) - lookee->_f_angle(); if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) { // if real close, react anyway // [KS] but respect minimum distance rules - if (mindist || dist > MELEERANGE) + if (mindist || dist > lookee->meleerange + lookee->_f_radius()) return false; // outside of fov } } @@ -1731,8 +1733,8 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) || player->mo->flags3 & MF3_GHOST) { - if ((player->mo->AproxDistance (actor) > 2*MELEERANGE) - && P_AproxDistance (player->mo->vel.x, player->mo->vel.y) < 5*FRACUNIT) + if ((player->mo->AproxDistance (actor) > (128 << FRACBITS)) + && P_AproxDistance (player->mo->_f_velx(), player->mo->_f_vely()) < 5*FRACUNIT) { // Player is sneaking - can't detect continue; } @@ -2134,15 +2136,15 @@ void A_Wander(AActor *self, int flags) // turn towards movement direction if not there yet if (!(flags & CHF_NODIRECTIONTURN) && (self->movedir < DI_NODIR)) { - self->angle &= (angle_t)(7 << 29); - int delta = self->angle - (self->movedir << 29); - if (delta > 0) + self->Angles.Yaw = floor(self->Angles.Yaw.Degrees / 45) * 45.; + DAngle delta = deltaangle(self->Angles.Yaw, (self->movedir * 45)); + if (delta < 0) { - self->angle -= ANG90 / 2; + self->Angles.Yaw -= 45; } - else if (delta < 0) + else if (delta > 0) { - self->angle += ANG90 / 2; + self->Angles.Yaw += 45; } } @@ -2227,7 +2229,6 @@ nosee: void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove, int flags) { - int delta; if (actor->flags5 & MF5_INCONVERSATION) return; @@ -2289,15 +2290,15 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele } else if (!(flags & CHF_NODIRECTIONTURN) && actor->movedir < 8) { - actor->angle &= (angle_t)(7<<29); - delta = actor->angle - (actor->movedir << 29); - if (delta > 0) + actor->Angles.Yaw = floor(actor->Angles.Yaw.Degrees / 45) * 45.; + DAngle delta = deltaangle(actor->Angles.Yaw, (actor->movedir * 45)); + if (delta < 0) { - actor->angle -= ANG90/2; + actor->Angles.Yaw -= 45; } - else if (delta < 0) + else if (delta > 0) { - actor->angle += ANG90/2; + actor->Angles.Yaw += 45; } } @@ -2413,7 +2414,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele spec->args[1], spec->args[2], spec->args[3], spec->args[4]); } - angle_t lastgoalang = actor->goal->angle; + DAngle lastgoalang = actor->goal->Angles.Yaw; int delay; AActor * newgoal = iterator.Next (); if (newgoal != NULL && actor->goal == actor->target) @@ -2425,7 +2426,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele { delay = 0; actor->reactiontime = actor->GetDefault()->reactiontime; - actor->angle = lastgoalang; // Look in direction of last goal + actor->Angles.Yaw = lastgoalang; // Look in direction of last goal } if (actor->target == actor->goal) actor->target = NULL; actor->flags |= MF_JUSTATTACKED; @@ -2455,18 +2456,16 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele else { actor->FastChaseStrafeCount = 0; - actor->vel.x = 0; - actor->vel.y = 0; + actor->Vel.X = actor->Vel.Y = 0; fixed_t dist = actor->AproxDistance (actor->target); if (dist < CLASS_BOSS_STRAFE_RANGE) { if (pr_chase() < 100) { - angle_t ang = actor->AngleTo(actor->target); - if (pr_chase() < 128) ang += ANGLE_90; - else ang -= ANGLE_90; - actor->vel.x = 13 * finecosine[ang>>ANGLETOFINESHIFT]; - actor->vel.y = 13 * finesine[ang>>ANGLETOFINESHIFT]; + DAngle ang = actor->AngleTo(actor->target); + if (pr_chase() < 128) ang += 90.; + else ang -= 90.; + actor->VelFromAngle(ang, 13.); actor->FastChaseStrafeCount = 3; // strafe time } } @@ -2547,8 +2546,8 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove) { // CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions. - fixed_t oldX = actor->X(); - fixed_t oldY = actor->Y(); + fixed_t oldX = actor->_f_X(); + fixed_t oldY = actor->_f_Y(); int oldgroup = actor->PrevPortalGroup; FTextureID oldFloor = actor->floorpic; @@ -2600,14 +2599,14 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) if (self->movedir != DI_NODIR) { - const fixed_t absSpeed = abs (self->Speed); + const fixed_t absSpeed = abs (self->_f_speed()); fixedvec2 viletry = self->Vec2Offset( FixedMul (absSpeed, xspeed[self->movedir]), FixedMul (absSpeed, yspeed[self->movedir]), true); FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(check, viletry.x, viletry.y, self->Z() - 64* FRACUNIT, self->Top() + 64 * FRACUNIT, 32 * FRACUNIT, false, NULL); + FMultiBlockThingsIterator it(check, viletry.x, viletry.y, self->_f_Z() - 64* FRACUNIT, self->_f_Top() + 64 * FRACUNIT, 32 * FRACUNIT, false, NULL); FMultiBlockThingsIterator::CheckResult cres; while (it.Next(&cres)) { @@ -2615,11 +2614,11 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) FState *raisestate = corpsehit->GetRaiseState(); if (raisestate != NULL) { - // use the current actor's radius instead of the Arch Vile's default. - fixed_t maxdist = corpsehit->GetDefault()->radius + self->radius; + // use the current actor's _f_radius() instead of the Arch Vile's default. + fixed_t maxdist = corpsehit->GetDefault()->_f_radius() + self->_f_radius(); - if (abs(corpsehit->Pos().x - cres.position.x) > maxdist || - abs(corpsehit->Pos().y - cres.position.y) > maxdist) + if (abs(corpsehit->_f_Pos().x - cres.position.x) > maxdist || + abs(corpsehit->_f_Pos().y - cres.position.y) > maxdist) continue; // not actually touching // Let's check if there are floors in between the archvile and its target @@ -2639,29 +2638,29 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) if (testsec) { fixed_t zdist1, zdist2; - if (P_Find3DFloor(testsec, corpsehit->Pos(), false, true, zdist1) - != P_Find3DFloor(testsec, self->Pos(), false, true, zdist2)) + if (P_Find3DFloor(testsec, corpsehit->_f_Pos(), false, true, zdist1) + != P_Find3DFloor(testsec, self->_f_Pos(), false, true, zdist2)) { // Not on same floor - if (vilesec == corpsec || abs(zdist1 - self->Z()) > self->height) + if (vilesec == corpsec || abs(zdist1 - self->_f_Z()) > self->_f_height()) continue; } } } - corpsehit->vel.x = corpsehit->vel.y = 0; - // [RH] Check against real height and radius + corpsehit->Vel.X = corpsehit->Vel.Y = 0; + // [RH] Check against real height and _f_radius() - fixed_t oldheight = corpsehit->height; - fixed_t oldradius = corpsehit->radius; + double oldheight = corpsehit->Height; + double oldradius = corpsehit->radius; ActorFlags oldflags = corpsehit->flags; corpsehit->flags |= MF_SOLID; - corpsehit->height = corpsehit->GetDefault()->height; + corpsehit->Height = corpsehit->GetDefault()->Height; bool check = P_CheckPosition(corpsehit, corpsehit->Pos()); corpsehit->flags = oldflags; corpsehit->radius = oldradius; - corpsehit->height = oldheight; + corpsehit->Height = oldheight; if (!check) continue; // got one! @@ -2703,10 +2702,10 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) } if (ib_compatflags & BCOMPATF_VILEGHOSTS) { - corpsehit->height <<= 2; + corpsehit->Height *= 4; // [GZ] This was a commented-out feature, so let's make use of it, // but only for ghost monsters so that they are visibly different. - if (corpsehit->height == 0) + if (corpsehit->Height == 0) { // Make raised corpses look ghostly if (corpsehit->alpha > TRANSLUC50) @@ -2722,7 +2721,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) } else { - corpsehit->height = info->height; // [RH] Use real mobj height + corpsehit->Height = info->Height; // [RH] Use real mobj height corpsehit->radius = info->radius; // [RH] Use real radius } @@ -2819,7 +2818,7 @@ enum FAF_Flags FAF_TOP = 4, FAF_NODISTFACTOR = 8, // deprecated }; -void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, angle_t ang_offset, angle_t pitch_offset, int flags, fixed_t z_add) +void A_Face (AActor *self, AActor *other, angle_t _max_turn, angle_t _max_pitch, angle_t _ang_offset, angle_t _pitch_offset, int flags, fixed_t z_add) { if (!other) return; @@ -2832,99 +2831,92 @@ void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch, a self->flags &= ~MF_AMBUSH; - angle_t other_angle = self->AngleTo(other); + DAngle max_turn = ANGLE2DBL(_max_turn); + DAngle ang_offset = ANGLE2DBL(_ang_offset); + DAngle max_pitch = ANGLE2DBL(_max_pitch); + DAngle pitch_offset = ANGLE2DBL(_pitch_offset); + DAngle other_angle = self->AngleTo(other); + + DAngle delta = deltaangle(self->Angles.Yaw, other_angle); // 0 means no limit. Also, if we turn in a single step anyways, no need to go through the algorithms. // It also means that there is no need to check for going past the other. - if (max_turn && (max_turn < absangle(self->angle - other_angle))) + if (max_turn != 0 && (max_turn < fabs(delta))) { - if (self->angle > other_angle) + if (delta > 0) { - if (self->angle - other_angle < ANGLE_180) - { - self->angle -= max_turn + ang_offset; - } - else - { - self->angle += max_turn + ang_offset; - } + self->Angles.Yaw -= max_turn + ang_offset; } else { - if (other_angle - self->angle < ANGLE_180) - { - self->angle += max_turn + ang_offset; - } - else - { - self->angle -= max_turn + ang_offset; - } + self->Angles.Yaw += max_turn + ang_offset; } } else { - self->angle = other_angle + ang_offset; + self->Angles.Yaw = other_angle + ang_offset; } // [DH] Now set pitch. In order to maintain compatibility, this can be // disabled and is so by default. - if (max_pitch <= ANGLE_180) + if (max_pitch <= 180.) { - fixedvec2 pos = self->Vec2To(other); + fixedvec2 pos = self->_f_Vec2To(other); DVector2 dist(pos.x, pos.y); // Positioning ala missile spawning, 32 units above foot level - fixed_t source_z = self->Z() + 32*FRACUNIT + self->GetBobOffset(); - fixed_t target_z = other->Z() + 32*FRACUNIT + other->GetBobOffset(); + fixed_t source_z = self->_f_Z() + 32*FRACUNIT + self->GetBobOffset(); + fixed_t target_z = other->_f_Z() + 32*FRACUNIT + other->GetBobOffset(); // If the target z is above the target's head, reposition to the middle of // its body. - if (target_z >= other->Top()) + if (target_z >= other->_f_Top()) { - target_z = other->Z() + (other->height / 2); + target_z = other->_f_Z() + (other->_f_height() / 2); } //Note there is no +32*FRACUNIT on purpose. This is for customization sake. //If one doesn't want this behavior, just don't use FAF_BOTTOM. if (flags & FAF_BOTTOM) - target_z = other->Z() + other->GetBobOffset(); + target_z = other->_f_Z() + other->GetBobOffset(); if (flags & FAF_MIDDLE) - target_z = other->Z() + (other->height / 2) + other->GetBobOffset(); + target_z = other->_f_Z() + (other->_f_height() / 2) + other->GetBobOffset(); if (flags & FAF_TOP) - target_z = other->Z() + (other->height) + other->GetBobOffset(); + target_z = other->_f_Z() + (other->_f_height()) + other->GetBobOffset(); target_z += z_add; double dist_z = target_z - source_z; - double ddist = sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); - int other_pitch = (int)RAD2ANGLE(asin(dist_z / ddist)); + double ddist = g_sqrt(dist.X*dist.X + dist.Y*dist.Y + dist_z*dist_z); + + DAngle other_pitch = DAngle(ToDegrees(g_asin(dist_z / ddist))).Normalized180(); if (max_pitch != 0) { - if (self->pitch > other_pitch) + if (self->Angles.Pitch > other_pitch) { - max_pitch = MIN(max_pitch, unsigned(self->pitch - other_pitch)); - self->pitch -= max_pitch; + max_pitch = MIN(max_pitch, (self->Angles.Pitch - other_pitch).Normalized360()); + self->Angles.Pitch -= max_pitch; } else { - max_pitch = MIN(max_pitch, unsigned(other_pitch - self->pitch)); - self->pitch += max_pitch; + max_pitch = MIN(max_pitch, (other_pitch - self->Angles.Pitch).Normalized360()); + self->Angles.Pitch += max_pitch; } } else { - self->pitch = other_pitch; + self->Angles.Pitch = other_pitch; } - self->pitch += pitch_offset; + self->Angles.Pitch += pitch_offset; } // This will never work well if the turn angle is limited. - if (max_turn == 0 && (self->angle == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) ) + if (max_turn == 0 && (self->Angles.Yaw == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) ) { - self->angle += pr_facetarget.Random2() << 21; + self->Angles.Yaw += pr_facetarget.Random2() * (45 / 256.); } } @@ -2989,7 +2981,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) if (!self->target) return 0; - fixed_t saved_pitch = self->pitch; + DAngle saved_pitch = self->Angles.Pitch; FTranslatedLineTarget t; // [RH] Andy Baker's stealth monsters @@ -3000,28 +2992,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) self->flags &= ~MF_AMBUSH; - self->angle = self->AngleTo(self->target); + self->Angles.Yaw = self->AngleTo(self->target); - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &t, ANGLE_1*60, 0, self->target); + self->Angles.Pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE, &t, 60., 0, self->target); if (t.linetarget == NULL) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. - fixedvec2 pos = self->Vec2To(self->target); - DVector2 xydiff(pos.x, pos.y); - double zdiff = (self->target->Z() + (self->target->height>>1)) - (self->Z() + (self->height>>1) - self->floorclip); - self->pitch = int(atan2(zdiff, xydiff.Length()) * ANGLE_180 / -M_PI); + DVector2 xydiff = self->Vec2To(self->target); + double zdiff = self->target->Center() - self->Center() - self->Floorclip; + self->Angles.Pitch = -VecToAngle(xydiff.Length(), zdiff); } // Let the aim trail behind the player - self->angle = self->AngleTo(self->target, -self->target->vel.x * 3, -self->target->vel.y * 3); + self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3); if (self->target->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE)) { - self->angle += pr_railface.Random2() << 21; + self->Angles.Yaw += pr_railface.Random2() * 45./256; } P_RailAttack (self, self->GetMissileDamage (0, 1), 0); - self->pitch = saved_pitch; + self->Angles.Pitch = saved_pitch; return 0; } @@ -3172,7 +3163,7 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c AActor *mo; fixed_t spawnz; - spawnz = source->Z(); + spawnz = source->_f_Z(); if (!(i_compatflags & COMPATF_NOTOSSDROPS)) { int style = sv_dropstyle; @@ -3186,10 +3177,10 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c } else { - spawnz += source->height / 2; + spawnz += source->_f_height() / 2; } } - mo = Spawn(type, source->X(), source->Y(), spawnz, ALLOW_REPLACE); + mo = Spawn(type, source->_f_X(), source->_f_Y(), spawnz, ALLOW_REPLACE); if (mo != NULL) { mo->flags |= MF_DROPPED; @@ -3230,14 +3221,14 @@ void P_TossItem (AActor *item) if (style==2) { - item->vel.x += pr_dropitem.Random2(7) << FRACBITS; - item->vel.y += pr_dropitem.Random2(7) << FRACBITS; + item->Vel.X += pr_dropitem.Random2(7); + item->Vel.Y += pr_dropitem.Random2(7); } else { - item->vel.x = pr_dropitem.Random2() << 8; - item->vel.y = pr_dropitem.Random2() << 8; - item->vel.z = FRACUNIT*5 + (pr_dropitem() << 10); + item->Vel.X += pr_dropitem.Random2() / 256.; + item->Vel.Y += pr_dropitem.Random2() / 256.; + item->Vel.Z = 5. + pr_dropitem() / 64.; } } @@ -3309,7 +3300,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Detonate) PARAM_ACTION_PROLOGUE; int damage = self->GetMissileDamage(0, 1); P_RadiusAttack (self, self->target, damage, damage, self->DamageType, RADF_HURTSOURCE); - P_CheckSplash(self, damage<floorclip < actor->height) + if (actor->Floorclip < actor->Height) { - actor->floorclip += speed; + actor->Floorclip += speed; return false; } return true; @@ -3504,17 +3495,17 @@ bool A_SinkMobj (AActor *actor, fixed_t speed) // Raise a mobj incrementally from the floor to // -bool A_RaiseMobj (AActor *actor, fixed_t speed) +bool A_RaiseMobj (AActor *actor, double speed) { bool done = true; // Raise a mobj from the ground - if (actor->floorclip > 0) + if (actor->Floorclip > 0) { - actor->floorclip -= speed; - if (actor->floorclip <= 0) + actor->Floorclip -= speed; + if (actor->Floorclip <= 0) { - actor->floorclip = 0; + actor->Floorclip = 0; done = true; } else diff --git a/src/p_enemy.h b/src/p_enemy.h index 7535f13a3..ed1c9fcbc 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -75,14 +75,14 @@ void A_Chase(VMFrameStack *stack, AActor *self); void A_FaceTarget(AActor *actor); void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270, angle_t ang_offset = 0, angle_t pitch_offset = 0, int flags = 0, fixed_t z_add = 0); -bool A_RaiseMobj (AActor *, fixed_t speed); -bool A_SinkMobj (AActor *, fixed_t speed); +bool A_RaiseMobj (AActor *, double speed); +bool A_SinkMobj (AActor *, double speed); bool CheckBossDeath (AActor *); int P_Massacre (); bool P_CheckMissileRange (AActor *actor); -#define SKULLSPEED (20*FRACUNIT) -void A_SkullAttack(AActor *self, fixed_t speed); +#define SKULLSPEED (20.) +void A_SkullAttack(AActor *self, double speed); #endif //__P_ENEMY_H__ diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index ed4b1d345..84951a3a3 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1388,7 +1388,7 @@ static bool PointOnLine (int x, int y, int x1, int y1, int dx, int dy) // Either the point is very near the line, or the segment defining // the line is very short: Do a more expensive test to determine // just how far from the line the point is. - double l = sqrt(d_dx*d_dx+d_dy*d_dy); + double l = g_sqrt(d_dx*d_dx+d_dy*d_dy); double dist = fabs(s_num)/l; if (dist < SIDE_EPSILON) { diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 90b43323c..ba3d3af5d 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -85,11 +85,11 @@ FName MeansOfDeath; // void P_TouchSpecialThing (AActor *special, AActor *toucher) { - fixed_t delta = special->Z() - toucher->Z(); + fixed_t delta = special->_f_Z() - toucher->_f_Z(); // The pickup is at or above the toucher's feet OR // The pickup is below the toucher. - if (delta > toucher->height || delta < MIN(-32*FRACUNIT, -special->height)) + if (delta > toucher->_f_height() || delta < MIN(-32*FRACUNIT, -special->_f_height())) { // out of reach return; } @@ -393,7 +393,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) flags6 |= MF6_KILLED; // [RH] Allow the death height to be overridden using metadata. - fixed_t metaheight = -1; + double metaheight = -1; if (DamageType == NAME_Fire) { metaheight = GetClass()->BurnHeight; @@ -404,11 +404,11 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) } if (metaheight < 0) { - height >>= 2; + Height *= 0.25; } else { - height = MAX (metaheight, 0); + Height = MAX (metaheight, 0); } // [RH] If the thing has a special, execute and remove it @@ -927,9 +927,9 @@ static inline bool isFakePain(AActor *target, AActor *inflictor, int damage) // Returns the amount of damage actually inflicted upon the target, or -1 if // the damage was cancelled. -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, angle_t angle) +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags, DAngle angle) { - unsigned ang; + DAngle ang; player_t *player = NULL; fixed_t thrust; int temp; @@ -974,7 +974,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, { target->tics = 1; target->flags6 |= MF6_SHATTERING; - target->vel.x = target->vel.y = target->vel.z = 0; + target->Vel.Zero(); } return -1; } @@ -1029,7 +1029,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } if (target->flags & MF_SKULLFLY) { - target->vel.x = target->vel.y = target->vel.z = 0; + target->Vel.Zero(); } player = target->player; @@ -1160,7 +1160,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // If the origin and target are in exactly the same spot, choose a random direction. // (Most likely cause is from telefragging somebody during spawning because they // haven't moved from their spawn spot at all.) - ang = pr_kickbackdir.GenRand32(); + ang = pr_kickbackdir.GenRand_Real2() * 360.; } else { @@ -1184,7 +1184,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // make fall forwards sometimes if ((damage < 40) && (damage > target->health) - && (target->Z() - origin->Z() > 64*FRACUNIT) + && (target->Z() - origin->Z() > 64) && (pr_damagemobj()&1) // [RH] But only if not too fast and not flying && thrust < 10*FRACUNIT @@ -1192,26 +1192,23 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, && (inflictor == NULL || !(inflictor->flags5 & MF5_NOFORWARDFALL)) ) { - ang += ANG180; + ang += 180.; thrust *= 4; } - ang >>= ANGLETOFINESHIFT; if (source && source->player && (flags & DMG_INFLICTOR_IS_PUFF) && source->player->ReadyWeapon != NULL && (source->player->ReadyWeapon->WeaponFlags & WIF_STAFF2_KICKBACK)) { // Staff power level 2 - target->vel.x += FixedMul (10*FRACUNIT, finecosine[ang]); - target->vel.y += FixedMul (10*FRACUNIT, finesine[ang]); + target->Thrust(ang, 10); if (!(target->flags & MF_NOGRAVITY)) { - target->vel.z += 5*FRACUNIT; + target->Vel.Z += 5.; } } else { - target->vel.x += FixedMul (thrust, finecosine[ang]); - target->vel.y += FixedMul (thrust, finesine[ang]); + target->Thrust(ang, FIXED2DBL(thrust)); } } } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 926a475b3..ecdb73a5d 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -86,7 +86,8 @@ int LS_SetGlobalFogParameter(line_t *ln, AActor *it, bool backSide, int arg0, in #define SPEED(a) ((a)*(FRACUNIT/8)) #define TICS(a) (((a)*TICRATE)/35) #define OCTICS(a) (((a)*TICRATE)/8) -#define BYTEANGLE(a) ((angle_t)((a)<<24)) +#define _f_BYTEANGLE(a) ((angle_t)((a)<<24)) +#define BYTEANGLE(a) ((a) * (360./256.)) #define CRUSH(a) ((a) > 0? (a) : -1) #define CRUSHTYPE(a) ((a)==1? false : (a)==2? true : gameinfo.gametype == GAME_Hexen) #define CHANGE(a) (((a) >= 0 && (a)<=7)? ChangeMap[a]:0) @@ -150,13 +151,13 @@ FUNC(LS_Polyobj_RotateRight) FUNC(LS_Polyobj_Move) // Polyobj_Move (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT, false); + return EV_MovePoly (ln, arg0, SPEED(arg1), _f_BYTEANGLE(arg2), arg3 * FRACUNIT, false); } FUNC(LS_Polyobj_MoveTimes8) // Polyobj_MoveTimes8 (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT * 8, false); + return EV_MovePoly (ln, arg0, SPEED(arg1), _f_BYTEANGLE(arg2), arg3 * FRACUNIT * 8, false); } FUNC(LS_Polyobj_MoveTo) @@ -171,19 +172,19 @@ FUNC(LS_Polyobj_MoveToSpot) FActorIterator iterator (arg2); AActor *spot = iterator.Next(); if (spot == NULL) return false; - return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->X(), spot->Y(), false); + return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->_f_X(), spot->_f_Y(), false); } FUNC(LS_Polyobj_DoorSwing) // Polyobj_DoorSwing (po, speed, angle, delay) { - return EV_OpenPolyDoor (ln, arg0, arg1, BYTEANGLE(arg2), arg3, 0, PODOOR_SWING); + return EV_OpenPolyDoor (ln, arg0, arg1, _f_BYTEANGLE(arg2), arg3, 0, PODOOR_SWING); } FUNC(LS_Polyobj_DoorSlide) // Polyobj_DoorSlide (po, speed, angle, distance, delay) { - return EV_OpenPolyDoor (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg4, arg3*FRACUNIT, PODOOR_SLIDE); + return EV_OpenPolyDoor (ln, arg0, SPEED(arg1), _f_BYTEANGLE(arg2), arg4, arg3*FRACUNIT, PODOOR_SLIDE); } FUNC(LS_Polyobj_OR_RotateLeft) @@ -201,13 +202,13 @@ FUNC(LS_Polyobj_OR_RotateRight) FUNC(LS_Polyobj_OR_Move) // Polyobj_OR_Move (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT, true); + return EV_MovePoly (ln, arg0, SPEED(arg1), _f_BYTEANGLE(arg2), arg3 * FRACUNIT, true); } FUNC(LS_Polyobj_OR_MoveTimes8) // Polyobj_OR_MoveTimes8 (po, speed, angle, distance) { - return EV_MovePoly (ln, arg0, SPEED(arg1), BYTEANGLE(arg2), arg3 * FRACUNIT * 8, true); + return EV_MovePoly (ln, arg0, SPEED(arg1), _f_BYTEANGLE(arg2), arg3 * FRACUNIT * 8, true); } FUNC(LS_Polyobj_OR_MoveTo) @@ -222,7 +223,7 @@ FUNC(LS_Polyobj_OR_MoveToSpot) FActorIterator iterator (arg2); AActor *spot = iterator.Next(); if (spot == NULL) return false; - return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->X(), spot->Y(), true); + return EV_MovePolyTo (ln, arg0, SPEED(arg1), spot->_f_X(), spot->_f_Y(), true); } FUNC(LS_Polyobj_Stop) @@ -1104,7 +1105,16 @@ FUNC(LS_Teleport_Line) return EV_SilentLineTeleport (ln, backSide, it, arg1, arg2); } -static void ThrustThingHelper (AActor *it, angle_t angle, int force, INTBOOL nolimit); +static void ThrustThingHelper(AActor *it, DAngle angle, double force, INTBOOL nolimit) +{ + it->VelFromAngle(angle, force); + if (!nolimit) + { + it->Vel.X = clamp(it->Vel.X, -MAXMOVE, MAXMOVE); + it->Vel.Y = clamp(it->Vel.Y, -MAXMOVE, MAXMOVE); + } +} + FUNC(LS_ThrustThing) // ThrustThing (angle, force, nolimit, tid) { @@ -1129,23 +1139,11 @@ FUNC(LS_ThrustThing) return false; } -static void ThrustThingHelper (AActor *it, angle_t angle, int force, INTBOOL nolimit) -{ - angle >>= ANGLETOFINESHIFT; - it->vel.x += force * finecosine[angle]; - it->vel.y += force * finesine[angle]; - if (!nolimit) - { - it->vel.x = clamp (it->vel.x, -MAXMOVE, MAXMOVE); - it->vel.y = clamp (it->vel.y, -MAXMOVE, MAXMOVE); - } -} - FUNC(LS_ThrustThingZ) // [BC] // ThrustThingZ (tid, zthrust, down/up, set) { AActor *victim; - fixed_t thrust = arg1*FRACUNIT/4; + double thrust = arg1/4.; // [BC] Up is default if (arg2) @@ -1158,18 +1156,18 @@ FUNC(LS_ThrustThingZ) // [BC] while ( (victim = iterator.Next ()) ) { if (!arg3) - victim->vel.z = thrust; + victim->Vel.Z = thrust; else - victim->vel.z += thrust; + victim->Vel.Z += thrust; } return true; } else if (it) { if (!arg3) - it->vel.z = thrust; + it->Vel.Z = thrust; else - it->vel.z += thrust; + it->Vel.Z += thrust; return true; } return false; @@ -1640,13 +1638,13 @@ FUNC(LS_Thing_Hate) FUNC(LS_Thing_ProjectileAimed) // Thing_ProjectileAimed (tid, type, speed, target, newtid) { - return P_Thing_Projectile (arg0, it, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false); + return P_Thing_Projectile (arg0, it, arg1, NULL, 0., arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false); } FUNC(LS_Thing_ProjectileIntercept) // Thing_ProjectileIntercept (tid, type, speed, target, newtid) { - return P_Thing_Projectile (arg0, it, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true); + return P_Thing_Projectile (arg0, it, arg1, NULL, 0., arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true); } // [BC] added newtid for next two @@ -1665,7 +1663,7 @@ FUNC(LS_Thing_SpawnNoFog) FUNC(LS_Thing_SpawnFacing) // Thing_SpawnFacing (tid, type, nofog, newtid) { - return P_Thing_Spawn (arg0, it, arg1, ANGLE_MAX, arg2 ? false : true, arg3); + return P_Thing_Spawn (arg0, it, arg1, 1000000., arg2 ? false : true, arg3); } FUNC(LS_Thing_Raise) @@ -1700,8 +1698,8 @@ FUNC(LS_Thing_Stop) { if (it != NULL) { - it->vel.x = it->vel.y = it->vel.z = 0; - if (it->player != NULL) it->player->vel.x = it->player->vel.y = 0; + it->Vel.Zero(); + if (it->player != NULL) it->player->Vel.Zero(); ok = true; } } @@ -1711,8 +1709,8 @@ FUNC(LS_Thing_Stop) while ( (target = iterator.Next ()) ) { - target->vel.x = target->vel.y = target->vel.z = 0; - if (target->player != NULL) target->player->vel.x = target->player->vel.y = 0; + target->Vel.Zero(); + if (target->player != NULL) target->player->Vel.Zero(); ok = true; } } @@ -2470,11 +2468,11 @@ FUNC(LS_Sector_SetDamage) FUNC(LS_Sector_SetGravity) // Sector_SetGravity (tag, intpart, fracpart) { - float gravity; + double gravity; if (arg2 > 99) arg2 = 99; - gravity = (float)arg1 + (float)arg2 * 0.01f; + gravity = (double)arg1 + (double)arg2 * 0.01; FSectorTagIterator itr(arg0); int secnum; @@ -3221,7 +3219,7 @@ FUNC(LS_ForceField) if (it != NULL) { P_DamageMobj (it, NULL, NULL, 16, NAME_None); - P_ThrustMobj (it, it->angle + ANGLE_180, 0x7D000); + it->Thrust(it->Angles.Yaw + 180, 7.8125); } return true; } @@ -3276,8 +3274,6 @@ FUNC(LS_GlassBreak) { // Break some glass fixed_t x, y; AActor *glass; - angle_t an; - int speed; x = ln->v1->x + ln->dx/2; y = ln->v1->y + ln->dy/2; @@ -3288,15 +3284,12 @@ FUNC(LS_GlassBreak) { glass = Spawn("GlassJunk", x, y, ONFLOORZ, ALLOW_REPLACE); - glass->AddZ(24 * FRACUNIT); + glass->_f_AddZ(24 * FRACUNIT); glass->SetState (glass->SpawnState + (pr_glass() % glass->health)); - an = pr_glass() << (32-8); - glass->angle = an; - an >>= ANGLETOFINESHIFT; - speed = pr_glass() & 3; - glass->vel.x = finecosine[an] * speed; - glass->vel.y = finesine[an] * speed; - glass->vel.z = (pr_glass() & 7) << FRACBITS; + + glass->Angles.Yaw = pr_glass() * (360 / 256.); + glass->VelFromAngle(pr_glass() & 3); + glass->Vel.Z = (pr_glass() & 7); // [RH] Let the shards stick around longer than they did in Strife. glass->tics += pr_glass(); } diff --git a/src/p_local.h b/src/p_local.h index 8acfe2d34..aa691d4ce 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -25,6 +25,7 @@ #include "doomtype.h" #include "tables.h" +#include "vectors.h" class player_t; class AActor; @@ -79,19 +80,17 @@ inline int GetSafeBlockY(long long blocky) return int((blocky <= bmapnegy) ? blocky & 0x1FF: blocky); } -// MAXRADIUS is for precalculated sector block boxes -// the spider demon is larger, -// but we do not have any moving sectors nearby -#define MAXRADIUS 0/*32*FRACUNIT*/ - //#define GRAVITY FRACUNIT -#define MAXMOVE (30*FRACUNIT) +#define _f_MAXMOVE (30*FRACUNIT) +#define MAXMOVE (30.) -#define TALKRANGE (128*FRACUNIT) +#define TALKRANGE (128.) #define USERANGE (64*FRACUNIT) -#define MELEERANGE (64*FRACUNIT) -#define MISSILERANGE (32*64*FRACUNIT) -#define PLAYERMISSILERANGE (8192*FRACUNIT) // [RH] New MISSILERANGE for players + +#define MELEERANGE (64.) +#define SAWRANGE (64.+(1./65536.)) // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) +#define MISSILERANGE (32*64.) +#define PLAYERMISSILERANGE (8192.) // [RH] New MISSILERANGE for players // follow a player exlusively for 3 seconds // No longer used. @@ -119,17 +118,12 @@ void P_PredictionLerpReset(); // P_MOBJ // -#define ONFLOORZ FIXED_MIN -#define ONCEILINGZ FIXED_MAX -#define FLOATRANDZ (FIXED_MAX-1) - #define SPF_TEMPPLAYER 1 // spawning a short-lived dummy player #define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags=0); -void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); -int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); +int P_FaceMobj (AActor *source, AActor *target, DAngle *delta); bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false); enum EPuffFlags @@ -146,6 +140,10 @@ inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec { return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, hitdir, particledir, updown, flags, vict); } +inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const DVector3 &pos, DAngle hitdir, DAngle particledir, int updown, int flags = 0, AActor *vict = NULL) +{ + return P_SpawnPuff(source, pufftype, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), hitdir.BAMs(), particledir.BAMs(), updown, flags, vict); +} void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator); inline void P_SpawnBlood(const fixedvec3 &pos, angle_t dir, int damage, AActor *originator) { @@ -160,20 +158,33 @@ void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target); AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassActor *type); AActor *P_SpawnMissile (AActor* source, AActor* dest, PClassActor *type, AActor* owner = NULL); AActor *P_SpawnMissileZ (AActor* source, fixed_t z, AActor* dest, PClassActor *type); +inline AActor *P_SpawnMissileZ(AActor* source, double z, AActor* dest, PClassActor *type) +{ + return P_SpawnMissileZ(source, FLOAT2FIXED(z), dest, type); +} + AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, PClassActor *type, bool checkspawn = true, AActor *owner = NULL); inline AActor *P_SpawnMissileXYZ(const fixedvec3 &pos, AActor *source, AActor *dest, PClassActor *type, bool checkspawn = true, AActor *owner = NULL) { return P_SpawnMissileXYZ(pos.x, pos.y, pos.z, source, dest, type, checkspawn, owner); } AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, angle_t angle, fixed_t vz); +inline AActor *P_SpawnMissileAngle(AActor *source, PClassActor *type, DAngle angle, double vz) +{ + return P_SpawnMissileAngle(source, type, angle.BAMs(), FLOAT2FIXED(vz)); +} AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed); AActor *P_SpawnMissileAngleZ (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t vz); +inline AActor *P_SpawnMissileAngleZ(AActor *source, double z, PClassActor *type, DAngle angle, double vz) +{ + return P_SpawnMissileAngleZ(source, FLOAT2FIXED(z), type, angle.BAMs(), FLOAT2FIXED(vz)); +} AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, PClassActor *type, angle_t angle, fixed_t vz, fixed_t speed, AActor *owner=NULL, bool checkspawn = true); AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassActor *type); AActor *P_SpawnPlayerMissile (AActor* source, PClassActor *type); -AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle); -AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, PClassActor *type, angle_t angle, +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, DAngle angle); +AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, PClassActor *type, DAngle angle, FTranslatedLineTarget *pLineTarget = NULL, AActor **MissileActor = NULL, bool nofreeaim = false, bool noautoaim = false, int aimflags = 0); void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheight=false); @@ -187,14 +198,14 @@ AActor *P_SpawnSubMissile (AActor *source, PClassActor *type, AActor *target); / extern FClassMap SpawnableThings; extern FClassMap StrifeTypes; -bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid); -bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle, +bool P_Thing_Spawn (int tid, AActor *source, int type, DAngle angle, bool fog, int newtid); +bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, DAngle angle, fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid, bool leadTarget); bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog); bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog); int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type); -void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob); +void P_Thing_SetVelocity(AActor *actor, const DVector3 &vec, bool add, bool setbob); void P_RemoveThing(AActor * actor); bool P_Thing_Raise(AActor *thing, AActor *raiser); bool P_Thing_CanRaise(AActor *thing); @@ -238,7 +249,7 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false) // If "floatok" true, move would be ok -// if within "tmfloorz - tmceilingz". +// if within "tmfloorz - tm_f_ceilingz()". extern msecnode_t *sector_list; // phares 3/16/98 struct spechit_t @@ -260,10 +271,18 @@ inline bool P_CheckPosition(AActor *thing, const fixedvec3 &pos, bool actorsonly { return P_CheckPosition(thing, pos.x, pos.y, actorsonly); } +inline bool P_CheckPosition(AActor *thing, const DVector3 &pos, bool actorsonly = false) +{ + return P_CheckPosition(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), actorsonly); +} AActor *P_CheckOnmobj (AActor *thing); void P_FakeZMovement (AActor *mo); bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL); +inline bool P_TryMove(AActor* thing, double x, double y, int dropoff, const secplane_t * onfloor = NULL) +{ + return P_TryMove(thing, FLOAT2FIXED(x), FLOAT2FIXED(y), dropoff, onfloor); +} bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y); void P_ApplyTorque(AActor *mo); bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag, bool modifyactor = true); // [RH] Added z and telefrag parameters @@ -271,6 +290,10 @@ inline bool P_TeleportMove(AActor* thing, const fixedvec3 &pos, bool telefrag, b { return P_TeleportMove(thing, pos.x, pos.y, pos.z, telefrag, modifyactor); } +inline bool P_TeleportMove(AActor* thing, const DVector3 &pos, bool telefrag, bool modifyactor = true) +{ + return P_TeleportMove(thing, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), telefrag, modifyactor); +} void P_PlayerStartStomp (AActor *actor, bool mononly=false); // [RH] Stomp on things for a newly spawned player void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); bool P_BounceWall (AActor *mo); @@ -306,7 +329,7 @@ void P_FindFloorCeiling (AActor *actor, int flags=0); bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, FTranslatedLineTarget *pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL, AActor *friender=NULL); +DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLineTarget *pLineTarget = NULL, DAngle vrange = 0., int flags = 0, AActor *target = NULL, AActor *friender = NULL); enum // P_AimLineAttack flags { @@ -325,14 +348,19 @@ enum // P_LineAttack flags LAF_NOIMPACTDECAL = 4 }; -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); -AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, DAngle pitch, int damage, FName damageType, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); + void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); inline void P_TraceBleed(int damage, const fixedvec3 &pos, AActor *target, angle_t angle, int pitch) { P_TraceBleed(damage, pos.x, pos.y, pos.z, target, angle, pitch); } void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); +inline void P_TraceBleed(int damage, AActor *target, DAngle angle, DAngle pitch) +{ + P_TraceBleed(damage, target, angle.BAMs(), pitch.BAMs()); +} void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff); // hitscan version void P_TraceBleed (int damage, AActor *target); // random direction version @@ -342,7 +370,7 @@ inline bool P_HitWater(AActor *thing, sector_t *sec, const fixedvec3 &pos, bool { return P_HitWater(thing, sec, pos.x, pos.y, pos.z, checkabove, alert, force); } -void P_CheckSplash(AActor *self, fixed_t distance); +void P_CheckSplash(AActor *self, double distance); void P_RailAttack (AActor *source, int damage, int offset_xy, fixed_t offset_z = 0, int color1 = 0, int color2 = 0, double maxdiff = 0, int flags = 0, PClassActor *puff = NULL, angle_t angleoffset = 0, angle_t pitchoffset = 0, fixed_t distance = 8192*FRACUNIT, int duration = 0, double sparsity = 1.0, double drift = 1.0, PClassActor *spawnclass = NULL, int SpiralOffset = 270); // [RH] Shoot a railgun enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags @@ -355,7 +383,8 @@ enum // P_RailAttack / A_RailAttack / A_CustomRailgun / P_DrawRailTrail flags }; -bool P_CheckMissileSpawn (AActor *missile, fixed_t maxdist); +bool P_CheckMissileSpawn(AActor *missile, double maxdist); + void P_PlaySpawnSound(AActor *missile, AActor *spawner); // [RH] Position the chasecam @@ -377,6 +406,14 @@ void P_DelSeclist(msecnode_t *); // phares 3/16/98 msecnode_t* P_DelSecnode(msecnode_t *); void P_CreateSecNodeList(AActor*,fixed_t,fixed_t); // phares 3/14/98 int P_GetMoveFactor(const AActor *mo, int *frictionp); // phares 3/6/98 +inline double P_GetMoveFactor(const AActor *mo, double *frictionp) +{ + int rv, fp; + rv = P_GetMoveFactor(mo, &fp); + *frictionp = FIXED2DBL(fp); + return FIXED2DBL(rv); +} + int P_GetFriction(const AActor *mo, int *frictionfactor); bool Check_Sides(AActor *, int, int); // phares @@ -394,7 +431,7 @@ extern BYTE* rejectmatrix; // for fast sight rejection // P_INTER // void P_TouchSpecialThing (AActor *special, AActor *toucher); -int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0, angle_t angle = 0); +int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FName mod, int flags=0, DAngle angle = 0.); void P_PoisonMobj (AActor *target, AActor *inflictor, AActor *source, int damage, int duration, int period, FName type); bool P_GiveBody (AActor *actor, int num, int max=0); bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poison); diff --git a/src/p_map.cpp b/src/p_map.cpp index aafe2d125..993180b1f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -31,6 +31,7 @@ #include "m_random.h" #include "i_system.h" #include "c_dispatch.h" +#include "math/cmath.h" #include "doomdef.h" #include "p_local.h" @@ -241,7 +242,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines // adjust floor / ceiling heights if (!(flags & FFCF_NOCEILING)) { - if (open.top < tmf.ceilingz) + if (open.top < tmf._f_ceilingz()) { tmf.ceilingz = open.top; if (open.topsec != NULL) tmf.ceilingsector = open.topsec; @@ -252,16 +253,16 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines if (!(flags & FFCF_NOFLOOR)) { - if (open.bottom > tmf.floorz) + if (open.bottom > tmf._f_floorz()) { - tmf.floorz = open.bottom; + tmf.floorz = FIXED2DBL(open.bottom); if (open.bottomsec != NULL) tmf.floorsector = open.bottomsec; tmf.touchmidtex = open.touchmidtex; tmf.abovemidtex = open.abovemidtex; if (ffcf_verbose) Printf(" Adjust floorz to %f\n", FIXED2FLOAT(open.bottom)); - if (tmf.floorz > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); + if (tmf._f_floorz() > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); } - else if (open.bottom == tmf.floorz) + else if (open.bottom == tmf._f_floorz()) { tmf.touchmidtex |= open.touchmidtex; tmf.abovemidtex |= open.abovemidtex; @@ -271,7 +272,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines { tmf.dropoffz = open.lowfloor; if (ffcf_verbose) Printf(" Adjust dropoffz to %f\n", FIXED2FLOAT(open.bottom)); - if (tmf.floorz > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); + if (tmf._f_floorz() > tmf.dropoffz + tmf.thing->MaxDropOffHeight) mit.StopDown(); } } return true; @@ -290,8 +291,9 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) sector_t *sec = (!(flags & FFCF_SAMESECTOR) || tmf.thing->Sector == NULL)? P_PointInSector(tmf.x, tmf.y) : tmf.sector; F3DFloor *ffc, *fff; - tmf.ceilingz = sec->NextHighestCeilingAt(tmf.x, tmf.y, tmf.z, tmf.z + tmf.thing->height, flags, &tmf.ceilingsector, &ffc); - tmf.floorz = tmf.dropoffz = sec->NextLowestFloorAt(tmf.x, tmf.y, tmf.z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff); + tmf.ceilingz = FIXED2DBL(sec->NextHighestCeilingAt(tmf.x, tmf.y, tmf.z, tmf.z + tmf.thing->_f_height(), flags, &tmf.ceilingsector, &ffc)); + tmf.dropoffz = sec->NextLowestFloorAt(tmf.x, tmf.y, tmf.z, flags, tmf.thing->MaxStepHeight, &tmf.floorsector, &fff); + tmf.floorz = FIXED2DBL(tmf.dropoffz); if (fff) { @@ -319,9 +321,9 @@ void P_FindFloorCeiling(AActor *actor, int flags) FCheckPosition tmf; tmf.thing = actor; - tmf.x = actor->X(); - tmf.y = actor->Y(); - tmf.z = actor->Z(); + tmf.x = actor->_f_X(); + tmf.y = actor->_f_Y(); + tmf.z = actor->_f_Z(); if (flags & FFCF_ONLYSPAWNPOS) { @@ -342,7 +344,7 @@ void P_FindFloorCeiling(AActor *actor, int flags) actor->floorsector = tmf.floorsector; actor->ceilingpic = tmf.ceilingpic; actor->ceilingsector = tmf.ceilingsector; - if (ffcf_verbose) Printf("Starting with ceilingz = %f, floorz = %f\n", FIXED2FLOAT(tmf.ceilingz), FIXED2FLOAT(tmf.floorz)); + if (ffcf_verbose) Printf("Starting with ceilingz = %f, floorz = %f\n", tmf.ceilingz, tmf.floorz); tmf.touchmidtex = false; tmf.abovemidtex = false; @@ -362,7 +364,7 @@ void P_FindFloorCeiling(AActor *actor, int flags) PIT_FindFloorCeiling(mit, cres, mit.Box(), tmf, flags|cres.portalflags); } - if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; + if (tmf.touchmidtex) tmf.dropoffz = tmf._f_floorz(); bool usetmf = !(flags & FFCF_ONLYSPAWNPOS) || (tmf.abovemidtex && (tmf.floorz <= actor->Z())); @@ -429,23 +431,23 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); // P_LineOpening requires the thing's z to be the destination z in order to work. - fixed_t savedz = thing->Z(); - thing->SetZ(z); + fixed_t savedz = thing->_f_Z(); + thing->_f_SetZ(z); sector_t *sector = P_PointInSector(x, y); FPortalGroupArray grouplist; - FMultiBlockLinesIterator mit(grouplist, x, y, z, thing->height, thing->radius, sector); + FMultiBlockLinesIterator mit(grouplist, x, y, z, thing->_f_height(), thing->_f_radius(), sector); FMultiBlockLinesIterator::CheckResult cres; while (mit.Next(&cres)) { PIT_FindFloorCeiling(mit, cres, mit.Box(), tmf, 0); } - thing->SetZ(savedz); + thing->_f_SetZ(savedz); - if (tmf.touchmidtex) tmf.dropoffz = tmf.floorz; + if (tmf.touchmidtex) tmf.dropoffz = tmf._f_floorz(); - FMultiBlockThingsIterator mit2(grouplist, x, y, z, thing->height, thing->radius, false, sector); + FMultiBlockThingsIterator mit2(grouplist, x, y, z, thing->_f_height(), thing->_f_radius(), false, sector); FMultiBlockThingsIterator::CheckResult cres2; while (mit2.Next(&cres2)) @@ -459,8 +461,8 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra if (th == thing) continue; - fixed_t blockdist = th->radius + tmf.thing->radius; - if (abs(th->X() - cres2.position.x) >= blockdist || abs(th->Y() - cres2.position.y) >= blockdist) + fixed_t blockdist = th->_f_radius() + tmf.thing->_f_radius(); + if (abs(th->_f_X() - cres2.position.x) >= blockdist || abs(th->_f_Y() - cres2.position.y) >= blockdist) continue; if ((th->flags2 | tmf.thing->flags2) & MF2_THRUACTORS) @@ -476,8 +478,8 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra { if (!(th->flags3 & thing->flags3 & MF3_DONTOVERLAP)) { - if (z > th->Top() || // overhead - z + thing->height < th->Z()) // underneath + if (z > th->_f_Top() || // overhead + z + thing->_f_height() < th->_f_Z()) // underneath continue; } } @@ -556,8 +558,8 @@ void P_PlayerStartStomp(AActor *actor, bool mononly) if (th == actor || (th->player == actor->player && th->player != NULL)) continue; - fixed_t blockdist = th->radius + actor->radius; - if (abs(th->X() - cres.position.x) >= blockdist || abs(th->Y() - cres.position.y) >= blockdist) + fixed_t blockdist = th->_f_radius() + actor->_f_radius(); + if (abs(th->_f_X() - cres.position.x) >= blockdist || abs(th->_f_Y() - cres.position.y) >= blockdist) continue; // only kill monsters and other players @@ -576,26 +578,6 @@ void P_PlayerStartStomp(AActor *actor, bool mononly) } } -//========================================================================== -// -// -// -//========================================================================== - -inline fixed_t secfriction(const sector_t *sec, int plane = sector_t::floor) -{ - if (sec->Flags & SECF_FRICTION) return sec->friction; - fixed_t friction = Terrains[sec->GetTerrain(plane)].Friction; - return friction != 0 ? friction : ORIG_FRICTION; -} - -inline fixed_t secmovefac(const sector_t *sec, int plane = sector_t::floor) -{ - if (sec->Flags & SECF_FRICTION) return sec->movefactor; - fixed_t movefactor = Terrains[sec->GetTerrain(plane)].MoveFactor; - return movefactor != 0 ? movefactor : ORIG_FRICTION_FACTOR; -} - //========================================================================== // // killough 8/28/98: @@ -613,6 +595,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) fixed_t newfriction; const msecnode_t *m; sector_t *sec; + fixed_t newmf; if (mo->IsNoClip2()) { @@ -623,29 +606,29 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) friction = FRICTION_FLY; } else if ((!(mo->flags & MF_NOGRAVITY) && mo->waterlevel > 1) || - (mo->waterlevel == 1 && mo->Z() > mo->floorz + 6 * FRACUNIT)) + (mo->waterlevel == 1 && mo->Z() > mo->floorz+ 6)) { - friction = secfriction(mo->Sector); - movefactor = secmovefac(mo->Sector) >> 1; + friction = mo->Sector->GetFriction(sector_t::floor, &movefactor); + movefactor >>= 1; - // Check 3D floors -- might be the source of the waterlevel - for (unsigned i = 0; i < mo->Sector->e->XFloor.ffloors.Size(); i++) + // Check 3D floors -- might be the source of the waterlevel + for (unsigned i = 0; i < mo->Sector->e->XFloor.ffloors.Size(); i++) + { + F3DFloor *rover = mo->Sector->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_SWIMMABLE)) continue; + + if (mo->_f_Z() > rover->top.plane->ZatPoint(mo) || + mo->_f_Z() < rover->bottom.plane->ZatPoint(mo)) + continue; + + newfriction = rover->model->GetFriction(rover->top.isceiling, &newmf); + if (newfriction < friction || friction == ORIG_FRICTION) { - F3DFloor *rover = mo->Sector->e->XFloor.ffloors[i]; - if (!(rover->flags & FF_EXISTS)) continue; - if (!(rover->flags & FF_SWIMMABLE)) continue; - - if (mo->Z() > rover->top.plane->ZatPoint(mo) || - mo->Z() < rover->bottom.plane->ZatPoint(mo)) - continue; - - newfriction = secfriction(rover->model, rover->top.isceiling); - if (newfriction < friction || friction == ORIG_FRICTION) - { - friction = newfriction; - movefactor = secmovefac(rover->model, rover->top.isceiling) >> 1; - } + friction = newfriction; + movefactor = newmf >> 1; } + } } else if (var_friction && !(mo->flags & (MF_NOCLIP | MF_NOGRAVITY))) { // When the object is straddling sectors with the same @@ -666,23 +649,23 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) if (rover->flags & FF_SOLID) { // Must be standing on a solid floor - if (mo->Z() != rover->top.plane->ZatPoint(pos)) continue; + if (mo->_f_Z() != rover->top.plane->ZatPoint(pos)) continue; } else if (rover->flags & FF_SWIMMABLE) { // Or on or inside a swimmable floor (e.g. in shallow water) - if (mo->Z() > rover->top.plane->ZatPoint(pos) || - (mo->Top()) < rover->bottom.plane->ZatPoint(pos)) + if (mo->_f_Z() > rover->top.plane->ZatPoint(pos) || + (mo->_f_Top()) < rover->bottom.plane->ZatPoint(pos)) continue; } else continue; - newfriction = secfriction(rover->model, rover->top.isceiling); + newfriction = rover->model->GetFriction(rover->top.isceiling, &newmf); if (newfriction < friction || friction == ORIG_FRICTION) { friction = newfriction; - movefactor = secmovefac(rover->model, rover->top.isceiling); + movefactor = newmf >> 1; } } @@ -691,14 +674,14 @@ int P_GetFriction(const AActor *mo, int *frictionfactor) { continue; } - newfriction = secfriction(sec); + newfriction = sec->GetFriction(sector_t::floor, &newmf); if ((newfriction < friction || friction == ORIG_FRICTION) && - (mo->Z() <= sec->floorplane.ZatPoint(pos) || + (mo->_f_Z() <= sec->floorplane.ZatPoint(pos) || (sec->GetHeightSec() != NULL && - mo->Z() <= sec->heightsec->floorplane.ZatPoint(pos)))) + mo->_f_Z() <= sec->heightsec->floorplane.ZatPoint(pos)))) { friction = newfriction; - movefactor = secmovefac(sec); + movefactor = newmf; } } } @@ -738,11 +721,11 @@ int P_GetMoveFactor(const AActor *mo, int *frictionp) // phares 3/11/98: you start off slowly, then increase as // you get better footing - int velocity = P_AproxDistance(mo->vel.x, mo->vel.y); + double velocity = mo->VelXYToSpeed(); - if (velocity > MORE_FRICTION_VELOCITY << 2) + if (velocity > MORE_FRICTION_VELOCITY * 4) movefactor <<= 3; - else if (velocity > MORE_FRICTION_VELOCITY << 1) + else if (velocity > MORE_FRICTION_VELOCITY * 2) movefactor <<= 2; else if (velocity > MORE_FRICTION_VELOCITY) movefactor <<= 1; @@ -769,14 +752,14 @@ static int LineIsAbove(line_t *line, AActor *actor) { AActor *point = line->frontsector->SkyBoxes[sector_t::floor]; if (point == NULL) return -1; - return point->threshold >= actor->Top(); + return point->specialf1 >= actor->Top(); } static int LineIsBelow(line_t *line, AActor *actor) { AActor *point = line->frontsector->SkyBoxes[sector_t::ceiling]; if (point == NULL) return -1; - return point->threshold <= actor->Z(); + return point->specialf1 <= actor->Z(); } // @@ -787,7 +770,7 @@ static int LineIsBelow(line_t *line, AActor *actor) // // // PIT_CheckLine -// Adjusts tmfloorz and tmceilingz as lines are contacted +// Adjusts tmfloorz and tm_f_ceilingz() as lines are contacted // // //========================================================================== @@ -875,7 +858,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (state == 1) { // the line should not block but we should set the ceilingz to the portal boundary so that we can't float up into that line. - fixed_t portalz = cres.line->frontsector->SkyBoxes[sector_t::floor]->threshold; + double portalz = cres.line->frontsector->SkyBoxes[sector_t::floor]->specialf1; if (portalz < tm.ceilingz) { tm.ceilingz = portalz; @@ -891,7 +874,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (state == -1) return true; if (state == 1) { - fixed_t portalz = cres.line->frontsector->SkyBoxes[sector_t::ceiling]->threshold; + double portalz = cres.line->frontsector->SkyBoxes[sector_t::ceiling]->specialf1; if (portalz > tm.floorz) { tm.floorz = portalz; @@ -954,9 +937,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec // adjust floor / ceiling heights if (!(cres.portalflags & FFCF_NOCEILING)) { - if (open.top < tm.ceilingz) + if (open.top < tm._f_ceilingz()) { - tm.ceilingz = open.top; + tm.ceilingz = FIXED2DBL(open.top); tm.ceilingsector = open.topsec; tm.ceilingpic = open.ceilingpic; tm.ceilingline = ld; @@ -966,9 +949,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (!(cres.portalflags & FFCF_NOFLOOR)) { - if (open.bottom > tm.floorz) + if (open.bottom > tm._f_floorz()) { - tm.floorz = open.bottom; + tm.floorz = FIXED2DBL(open.bottom); tm.floorsector = open.bottomsec; tm.floorpic = open.floorpic; tm.floorterrain = open.floorterrain; @@ -976,7 +959,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec tm.abovemidtex = open.abovemidtex; tm.thing->BlockingLine = ld; } - else if (open.bottom == tm.floorz) + else if (open.bottom == tm._f_floorz()) { tm.touchmidtex |= open.touchmidtex; tm.abovemidtex |= open.abovemidtex; @@ -1047,9 +1030,9 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera // fudge a bit with the portal line so that this gets included in the checks that normally only get run on two-sided lines sector_t *sec = lp->backsector; if (lp->backsector == NULL) lp->backsector = lp->frontsector; - tm.thing->AddZ(zofs); + tm.thing->_f_AddZ(zofs); - FBoundingBox pbox(cres.position.x, cres.position.y, tm.thing->radius); + FBoundingBox pbox(cres.position.x, cres.position.y, tm.thing->_f_radius()); FBlockLinesIterator it(pbox); bool ret = false; line_t *ld; @@ -1075,9 +1058,9 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera P_LineOpening(open, tm.thing, ld, ref.x, ref.y, cres.position.x, cres.position.y, 0); // adjust floor / ceiling heights - if (open.top - zofs < tm.ceilingz) + if (open.top - zofs < tm._f_ceilingz()) { - tm.ceilingz = open.top - zofs; + tm.ceilingz = FIXED2FLOAT(open.top - zofs); tm.ceilingpic = open.ceilingpic; /* tm.ceilingsector = open.topsec; @@ -1087,9 +1070,9 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera ret = true; } - if (open.bottom - zofs > tm.floorz) + if (open.bottom - zofs > tm._f_floorz()) { - tm.floorz = open.bottom - zofs; + tm.floorz = FIXED2DBL(open.bottom - zofs); tm.floorpic = open.floorpic; tm.floorterrain = open.floorterrain; /* @@ -1104,7 +1087,7 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera if (open.lowfloor - zofs < tm.dropoffz) tm.dropoffz = open.lowfloor - zofs; } - tm.thing->AddZ(-zofs); + tm.thing->_f_AddZ(-zofs); lp->backsector = sec; return ret; @@ -1217,8 +1200,8 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY)) return true; // can't hit thing - fixed_t blockdist = thing->radius + tm.thing->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + fixed_t blockdist = thing->_f_radius() + tm.thing->_f_radius(); + if (abs(thing->_f_X() - cres.position.x) >= blockdist || abs(thing->_f_Y() - cres.position.y) >= blockdist) return true; if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS) @@ -1228,7 +1211,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch return true; tm.thing->BlockingMobj = thing; - topz = thing->Top(); + topz = thing->_f_Top(); // Both things overlap in x or y direction bool unblocking = false; @@ -1241,7 +1224,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // [RH] Let monsters walk on actors as well as floors if ((tm.thing->flags3 & MF3_ISMONSTER) && - topz >= tm.floorz && topz <= tm.thing->Z() + tm.thing->MaxStepHeight) + topz >= tm._f_floorz() && topz <= tm.thing->_f_Z() + tm.thing->MaxStepHeight) { // The commented-out if is an attempt to prevent monsters from walking off a // thing further than they would walk off a ledge. I can't think of an easy @@ -1252,7 +1235,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch // abs(thing->y - tmy) <= thing->radius) { tm.stepthing = thing; - tm.floorz = topz; + tm.floorz = FIXED2DBL(topz); } } } @@ -1262,12 +1245,12 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch fixedvec3 oldpos = tm.thing->PosRelative(thing); // Both actors already overlap. To prevent them from remaining stuck allow the move if it // takes them further apart or the move does not change the position (when called from P_ChangeSector.) - if (oldpos.x == thing->X() && oldpos.y == thing->Y()) + if (oldpos.x == thing->_f_X() && oldpos.y == thing->_f_Y()) { unblocking = true; } - else if (abs(thing->X() - oldpos.x) < (thing->radius + tm.thing->radius) && - abs(thing->Y() - oldpos.y) < (thing->radius + tm.thing->radius)) + else if (abs(thing->_f_X() - oldpos.x) < (thing->_f_radius() + tm.thing->_f_radius()) && + abs(thing->_f_Y() - oldpos.y) < (thing->_f_radius() + tm.thing->_f_radius())) { fixed_t newdist = thing->AproxDistance(cres.position.x, cres.position.y); @@ -1276,7 +1259,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (newdist > olddist) { // unblock only if there's already a vertical overlap (or both actors are flagged not to overlap) - unblocking = (tm.thing->Top() > thing->Z() && tm.thing->Z() < topz) || (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP); + unblocking = (tm.thing->_f_Top() > thing->_f_Z() && tm.thing->_f_Z() < topz) || (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP); } } } @@ -1295,7 +1278,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // Some things prefer not to overlap each other, if possible return unblocking; } - if ((tm.thing->Z() >= topz) || (tm.thing->Top() <= thing->Z())) + if ((tm.thing->_f_Z() >= topz) || (tm.thing->_f_Top() <= thing->_f_Z())) return true; } } @@ -1311,7 +1294,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch // or different species if DONTHARMSPECIES (!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) && // touches vertically - topz >= tm.thing->Z() && tm.thing->Top() >= thing->Z() && + topz >= tm.thing->_f_Z() && tm.thing->_f_Top() >= thing->_f_Z() && // prevents lost souls from exploding when fired by pain elementals (thing->master != tm.thing && tm.thing->master != thing)) // Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species @@ -1358,9 +1341,8 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch if (!(thing->flags2 & MF2_BOSS) && (thing->flags3 & MF3_ISMONSTER) && !(thing->flags3 & MF3_DONTBLAST)) { // ideally this should take the mass factor into account - thing->vel.x += tm.thing->vel.x; - thing->vel.y += tm.thing->vel.y; - if ((thing->vel.x + thing->vel.y) > 3 * FRACUNIT) + thing->Vel += tm.thing->Vel.XY(); + if ((thing->Vel.X + thing->Vel.Y) > 3.) { int newdam; damage = (tm.thing->Mass / 100) + 1; @@ -1398,7 +1380,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch return true; } - int clipheight; + double clipheight; if (thing->projectilepassheight > 0) { @@ -1410,7 +1392,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch } else { - clipheight = thing->height; + clipheight = thing->Height; } // Check if it went over / under @@ -1496,8 +1478,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // Push thing if (thing->lastpush != tm.PushTime) { - thing->vel.x += FixedMul(tm.thing->vel.x, thing->pushfactor); - thing->vel.y += FixedMul(tm.thing->vel.y, thing->pushfactor); + thing->Vel += tm.thing->Vel.XY() * thing->_pushfactor(); thing->lastpush = tm.PushTime; } } @@ -1527,7 +1508,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && (pr_checkthing() < 192)) { - P_BloodSplatter(tm.thing->Pos(), thing); + P_BloodSplatter(tm.thing->_f_Pos(), thing); } if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) { @@ -1555,8 +1536,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch { // Push thing if (thing->lastpush != tm.PushTime) { - thing->vel.x += FixedMul(tm.thing->vel.x, thing->pushfactor); - thing->vel.y += FixedMul(tm.thing->vel.y, thing->pushfactor); + thing->Vel += tm.thing->Vel.XY() * thing->_pushfactor(); thing->lastpush = tm.PushTime; } } @@ -1569,7 +1549,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch // [RH] The next condition is to compensate for the extra height // that gets added by P_CheckPosition() so that you cannot pick // up things that are above your true height. - && thing->Z() < tm.thing->Top() - tm.thing->MaxStepHeight) + && thing->_f_Z() < tm.thing->_f_Top() - tm.thing->MaxStepHeight) { // Can be picked up by tmthing P_TouchSpecialThing(thing, tm.thing); // can remove thing } @@ -1611,7 +1591,7 @@ MOVEMENT CLIPPING // // out: // newsubsec -// floorz +// _f_floorz() // ceilingz // tmdropoffz = the lowest point contacted (monsters won't move to a dropoff) // speciallines[] @@ -1625,13 +1605,13 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo { sector_t *newsec; AActor *thingblocker; - fixed_t realheight = thing->height; + double realHeight = thing->Height; tm.thing = thing; tm.x = x; tm.y = y; - tm.z = thing->Z(); + tm.z = thing->_f_Z(); newsec = tm.sector = P_PointInSector(x, y); tm.ceilingline = thing->BlockingLine = NULL; @@ -1645,8 +1625,9 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo else { // With noclip2, we must ignore 3D floors and go right to the uppermost ceiling and lowermost floor. - tm.floorz = tm.dropoffz = newsec->LowestFloorAt(x, y, &tm.floorsector); - tm.ceilingz = newsec->HighestCeilingAt(x, y, &tm.ceilingsector); + tm.dropoffz = newsec->_f_LowestFloorAt(x, y, &tm.floorsector); + tm.floorz = FIXED2DBL(tm.dropoffz); + tm.ceilingz = FIXED2DBL(newsec->_f_HighestCeilingAt(x, y, &tm.ceilingsector)); tm.floorpic = tm.floorsector->GetTexture(sector_t::floor); tm.floorterrain = tm.floorsector->GetTerrain(sector_t::floor); tm.ceilingpic = tm.ceilingsector->GetTexture(sector_t::ceiling); @@ -1664,14 +1645,14 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo thingblocker = NULL; if (thing->player) { // [RH] Fake taller height to catch stepping up into things. - thing->height = realheight + thing->MaxStepHeight; + thing->Height = realHeight + FIXED2DBL(thing->MaxStepHeight); } tm.stepthing = NULL; - FBoundingBox box(x, y, thing->radius); + FBoundingBox box(x, y, thing->_f_radius()); FPortalGroupArray pcheck; - FMultiBlockThingsIterator it2(pcheck, x, y, thing->Z(), thing->height, thing->radius, false, newsec); + FMultiBlockThingsIterator it2(pcheck, x, y, thing->_f_Z(), thing->_f_height(), thing->_f_radius(), false, newsec); FMultiBlockThingsIterator::CheckResult tcres; while ((it2.Next(&tcres))) @@ -1686,26 +1667,26 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo // If this blocks through a restricted line portal, it will always completely block. if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ) || (tcres.portalflags & FFCF_RESTRICTEDPORTAL)) { // Thing slammed into something; don't let it move now. - thing->height = realheight; + thing->Height = realHeight; return false; } else if (!BlockingMobj->player && !(thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY)) && - BlockingMobj->Top() - thing->Z() <= thing->MaxStepHeight) + BlockingMobj->_f_Top() - thing->_f_Z() <= thing->MaxStepHeight) { if (thingblocker == NULL || - BlockingMobj->Z() > thingblocker->Z()) + BlockingMobj->_f_Z() > thingblocker->_f_Z()) { thingblocker = BlockingMobj; } thing->BlockingMobj = NULL; } else if (thing->player && - thing->Top() - BlockingMobj->Z() <= thing->MaxStepHeight) + thing->_f_Top() - BlockingMobj->_f_Z() <= thing->MaxStepHeight) { if (thingblocker) { // There is something to step up on. Return this thing as // the blocker so that we don't step up. - thing->height = realheight; + thing->Height = realHeight; return false; } // Nothing is blocking us, but this actor potentially could @@ -1714,7 +1695,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo } else { // Definitely blocking - thing->height = realheight; + thing->Height = realHeight; return false; } } @@ -1734,19 +1715,19 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo validcount++; thing->BlockingMobj = NULL; - thing->height = realheight; + thing->Height = realHeight; if (actorsonly || (thing->flags & MF_NOCLIP)) return (thing->BlockingMobj = thingblocker) == NULL; spechit.Clear(); portalhit.Clear(); - FMultiBlockLinesIterator it(pcheck, x, y, thing->Z(), thing->height, thing->radius, newsec); + FMultiBlockLinesIterator it(pcheck, x, y, thing->_f_Z(), thing->_f_height(), thing->_f_radius(), newsec); FMultiBlockLinesIterator::CheckResult lcres; - fixed_t thingdropoffz = tm.floorz; + fixed_t thingdropoffz = tm._f_floorz(); //bool onthing = (thingdropoffz != tmdropoffz); - tm.floorz = tm.dropoffz; + tm.floorz = FIXED2DBL(tm.dropoffz); bool good = true; @@ -1773,13 +1754,13 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo { return false; } - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) { return false; } if (tm.touchmidtex) { - tm.dropoffz = tm.floorz; + tm.dropoffz = tm._f_floorz(); } else if (tm.stepthing != NULL) { @@ -1810,7 +1791,7 @@ bool P_TestMobjLocation(AActor *mobj) flags = mobj->flags; mobj->flags &= ~MF_PICKUP; - if (P_CheckPosition(mobj, mobj->X(), mobj->Y())) + if (P_CheckPosition(mobj, mobj->Pos())) { // XY is ok, now check Z mobj->flags = flags; if ((mobj->Z() < mobj->floorz) || (mobj->Top() > mobj->ceilingz)) @@ -1837,10 +1818,10 @@ AActor *P_CheckOnmobj(AActor *thing) bool good; AActor *onmobj; - oldz = thing->Z(); + oldz = thing->_f_Z(); P_FakeZMovement(thing); good = P_TestMobjZ(thing, false, &onmobj); - thing->SetZ(oldz); + thing->_f_SetZ(oldz); return good ? NULL : onmobj; } @@ -1868,8 +1849,8 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj) { AActor *thing = cres.thing; - fixed_t blockdist = thing->radius + actor->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + fixed_t blockdist = thing->_f_radius() + actor->_f_radius(); + if (abs(thing->_f_X() - cres.position.x) >= blockdist || abs(thing->_f_Y() - cres.position.y) >= blockdist) { continue; } @@ -1914,7 +1895,7 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj) { // under thing continue; } - else if (!quick && onmobj != NULL && thing->Top() < onmobj->Top()) + else if (!quick && onmobj != NULL && thing->_f_Top() < onmobj->_f_Top()) { // something higher is in the way continue; } @@ -1938,22 +1919,22 @@ void P_FakeZMovement(AActor *mo) // // adjust height // - mo->AddZ(mo->vel.z); + mo->_f_AddZ(mo->_f_velz()); if ((mo->flags&MF_FLOAT) && mo->target) { // float down towards target if too close if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT)) { fixed_t dist = mo->AproxDistance(mo->target); - fixed_t delta = (mo->target->Z() + (mo->height >> 1)) - mo->Z(); + fixed_t delta = (mo->target->_f_Z() + (mo->_f_height() >> 1)) - mo->_f_Z(); if (delta < 0 && dist < -(delta * 3)) - mo->AddZ(-mo->FloatSpeed); + mo->_f_AddZ(-mo->_f_floatspeed()); else if (delta > 0 && dist < (delta * 3)) - mo->AddZ(mo->FloatSpeed); + mo->_f_AddZ(mo->_f_floatspeed()); } } if (mo->player && mo->flags&MF_NOGRAVITY && (mo->Z() > mo->floorz) && !mo->IsNoClip2()) { - mo->AddZ(finesine[(FINEANGLES / 80 * level.maptime)&FINEMASK] / 8); + mo->_f_AddZ(finesine[(FINEANGLES / 80 * level.maptime)&FINEMASK] / 8); } // @@ -1966,7 +1947,7 @@ void P_FakeZMovement(AActor *mo) if (mo->Top() > mo->ceilingz) { // hit the ceiling - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz - mo->Height); } } @@ -1988,8 +1969,8 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 fixed_t fzb = line->frontsector->floorplane.ZatPoint(*posforwindowcheck); fixed_t bzt = line->backsector->ceilingplane.ZatPoint(*posforwindowcheck); fixed_t bzb = line->backsector->floorplane.ZatPoint(*posforwindowcheck); - if (fzt >= mobj->Top() && bzt >= mobj->Top() && - fzb <= mobj->Z() && bzb <= mobj->Z()) + if (fzt >= mobj->_f_Top() && bzt >= mobj->_f_Top() && + fzb <= mobj->_f_Z() && bzb <= mobj->_f_Z()) { // we must also check if some 3D floor in the backsector may be blocking for (unsigned int i = 0; ibacksector->e->XFloor.ffloors.Size(); i++) @@ -2001,7 +1982,7 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 fixed_t ff_bottom = rover->bottom.plane->ZatPoint(*posforwindowcheck); fixed_t ff_top = rover->top.plane->ZatPoint(*posforwindowcheck); - if (ff_bottom < mobj->Top() && ff_top > mobj->Z()) + if (ff_bottom < mobj->_f_Top() && ff_top > mobj->_f_Z()) { goto isblocking; } @@ -2053,10 +2034,10 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, sector_t* newsec; tm.floatok = false; - oldz = thing->Z(); + oldz = thing->_f_Z(); if (onfloor) { - thing->SetZ(onfloor->ZatPoint(x, y)); + thing->_f_SetZ(onfloor->ZatPoint(x, y)); } thing->flags6 |= MF6_INTRYMOVE; if (!P_CheckPosition(thing, x, y, tm)) @@ -2073,16 +2054,16 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { goto pushline; } - else if (BlockingMobj->Top() - thing->Z() > thing->MaxStepHeight - || (BlockingMobj->Sector->ceilingplane.ZatPoint(x, y) - (BlockingMobj->Top()) < thing->height) - || (tm.ceilingz - (BlockingMobj->Top()) < thing->height)) + else if (BlockingMobj->_f_Top() - thing->_f_Z() > thing->MaxStepHeight + || (BlockingMobj->Sector->ceilingplane.ZatPoint(x, y) - (BlockingMobj->_f_Top()) < thing->_f_height()) + || (tm.ceilingz - (BlockingMobj->Top()) < thing->Height)) { goto pushline; } } if (!(tm.thing->flags2 & MF2_PASSMOBJ) || (i_compatflags & COMPATF_NO_PASSMOBJ)) { - thing->SetZ(oldz); + thing->_f_SetZ(oldz); thing->flags6 &= ~MF6_INTRYMOVE; return false; } @@ -2094,7 +2075,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else if (thing->flags3 & MF3_CEILINGHUGGER) { - thing->SetZ(tm.ceilingz - thing->height); + thing->SetZ(tm.ceilingz - thing->Height); } if (onfloor && tm.floorsector == thing->floorsector) @@ -2103,7 +2084,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } if (!(thing->flags & MF_NOCLIP)) { - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) { goto pushline; // doesn't fit } @@ -2111,7 +2092,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, tm.floatok = true; if (!(thing->flags & MF_TELEPORT) - && tm.ceilingz - thing->Z() < thing->height + && tm.ceilingz < thing->Top() && !(thing->flags3 & MF3_CEILINGHUGGER) && (!(thing->flags2 & MF2_FLY) || !(thing->flags & MF_NOGRAVITY))) { @@ -2127,12 +2108,12 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // is not blocked. if (thing->Top() > tm.ceilingz) { - thing->vel.z = -8 * FRACUNIT; + thing->Vel.Z = -8; goto pushline; } - else if (thing->Z() < tm.floorz && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight) + else if (thing->Z() < tm.floorz && tm._f_floorz() - tm.dropoffz > thing->MaxDropOffHeight) { - thing->vel.z = 8 * FRACUNIT; + thing->Vel.Z = 8; goto pushline; } #endif @@ -2143,13 +2124,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { // [RH] Don't let normal missiles climb steps goto pushline; } - if (tm.floorz - thing->Z() > thing->MaxStepHeight) + if (tm._f_floorz() - thing->_f_Z() > thing->MaxStepHeight) { // too big a step up goto pushline; } else if (thing->Z() < tm.floorz) { // [RH] Check to make sure there's nothing in the way for the step up - fixed_t savedz = thing->Z(); + double savedz = thing->Z(); bool good; thing->SetZ(tm.floorz); good = P_TestMobjZ(thing); @@ -2162,7 +2143,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { thing->SetZ(tm.floorz); // If moving down, cancel vertical component of the velocity - if (thing->vel.z < 0) + if (thing->Vel.Z < 0) { // If it's a bouncer, let it bounce off its new floor, too. if (thing->BounceFlags & BOUNCE_Floors) @@ -2171,7 +2152,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else { - thing->vel.z = 0; + thing->Vel.Z = 0; } } } @@ -2186,7 +2167,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } if (dropoff == 2 && // large jump down (e.g. dogs) - (tm.floorz - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->Z() >tm.dropoffz)) + (tm._f_floorz() - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->_f_Z() >tm.dropoffz)) { dropoff = false; } @@ -2197,7 +2178,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { if (!(thing->flags5&MF5_AVOIDINGDROPOFF)) { - fixed_t floorz = tm.floorz; + double floorz = tm.floorz; // [RH] If the thing is standing on something, use its current z as the floorz. // This is so that it does not walk off of things onto a drop off. if (thing->flags2 & MF2_ONMOBJ) @@ -2205,11 +2186,11 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, floorz = MAX(thing->Z(), tm.floorz); } - if (floorz - tm.dropoffz > thing->MaxDropOffHeight && + if (FLOAT2FIXED(floorz) - tm.dropoffz > thing->MaxDropOffHeight && !(thing->flags2 & MF2_BLASTED) && !missileCheck) { // Can't move over a dropoff unless it's been blasted // [GZ] Or missile-spawned - thing->SetZ(oldz); + thing->_f_SetZ(oldz); thing->flags6 &= ~MF6_INTRYMOVE; return false; } @@ -2218,7 +2199,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { // special logic to move a monster off a dropoff // this intentionally does not check for standing on things. - if (thing->floorz - tm.floorz > thing->MaxDropOffHeight || + if (thing->_f_floorz() - tm._f_floorz() > thing->MaxDropOffHeight || thing->dropoffz - tm.dropoffz > thing->MaxDropOffHeight) { thing->flags6 &= ~MF6_INTRYMOVE; @@ -2230,7 +2211,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, && (tm.floorpic != thing->floorpic || tm.floorz - thing->Z() != 0)) { // must stay within a sector of a certain floor type - thing->SetZ(oldz); + thing->_f_SetZ(oldz); thing->flags6 &= ~MF6_INTRYMOVE; return false; } @@ -2243,9 +2224,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { thing->player->Bot->prev = thing->player->Bot->dest; thing->player->Bot->dest = NULL; - thing->vel.x = 0; - thing->vel.y = 0; - thing->SetZ(oldz); + thing->Vel.X = thing->Vel.Y = 0; + thing->_f_SetZ(oldz); thing->flags6 &= ~MF6_INTRYMOVE; return false; } @@ -2258,7 +2238,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, bool oldAboveFakeFloor, oldAboveFakeCeiling; fixed_t viewheight; - viewheight = thing->player ? thing->player->viewheight : thing->height / 2; + viewheight = thing->player ? thing->player->viewheight : thing->_f_height() / 2; oldAboveFakeFloor = oldAboveFakeCeiling = false; // pacify GCC if (oldsec->heightsec) @@ -2272,7 +2252,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // Borrowed from MBF: if (thing->BounceFlags & BOUNCE_MBF && // killough 8/13/98 !(thing->flags & (MF_MISSILE | MF_NOGRAVITY)) && - !thing->IsSentient() && tm.floorz - thing->Z() > 16 * FRACUNIT) + !thing->IsSentient() && tm.floorz - thing->Z() > 16) { // too big a step up for MBF bouncers under gravity thing->flags6 &= ~MF6_INTRYMOVE; return false; @@ -2330,8 +2310,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else if (!portalcrossed) { - fixedvec3 pos = { tm.x, tm.y, thing->Z() }; - fixedvec3 oldthingpos = thing->Pos(); + fixedvec3 pos = { tm.x, tm.y, thing->_f_Z() }; + fixedvec3 oldthingpos = thing->_f_Pos(); fixedvec2 thingpos = oldthingpos; P_TranslatePortalXY(ld, pos.x, pos.y); @@ -2346,8 +2326,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } thing->UnlinkFromWorld(); thing->SetXYZ(pos); - P_TranslatePortalVXVY(ld, thing->vel.x, thing->vel.y); - P_TranslatePortalAngle(ld, thing->angle); + P_TranslatePortalVXVY(ld, thing->Vel.X, thing->Vel.Y); + P_TranslatePortalAngle(ld, thing->Angles.Yaw); thing->LinkToWorld(); P_FindFloorCeiling(thing); thing->ClearInterpolation(); @@ -2358,7 +2338,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (thing == players[consoleplayer].camera) { divline_t dl1 = { besthit.oldrefpos.x,besthit. oldrefpos.y, besthit.refpos.x - besthit.oldrefpos.x, besthit.refpos.y - besthit.oldrefpos.y }; - fixedvec3a hit = { dl1.x + FixedMul(dl1.dx, bestfrac), dl1.y + FixedMul(dl1.dy, bestfrac), 0, 0 }; + fixedvec3a hit = { dl1.x + FixedMul(dl1.dx, bestfrac), dl1.y + FixedMul(dl1.dy, bestfrac), 0, 0. }; R_AddInterpolationPoint(hit); if (port->mType == PORTT_LINKED) @@ -2378,7 +2358,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (port->mType == PORTT_LINKED) { continue; - } + } } break; } @@ -2390,10 +2370,10 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // the move is ok, so link the thing into its new position thing->UnlinkFromWorld(); - oldpos = thing->Pos(); + oldpos = thing->_f_Pos(); oldsector = thing->Sector; thing->floorz = tm.floorz; - thing->ceilingz = tm.ceilingz; + thing->ceilingz= tm.ceilingz; thing->dropoffz = tm.dropoffz; // killough 11/98: keep track of dropoffs thing->floorpic = tm.floorpic; thing->floorterrain = tm.floorterrain; @@ -2414,7 +2394,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) { spechit_t spec; - fixedvec3 lastpos = thing->Pos(); + fixedvec3 lastpos = thing->_f_Pos(); while (spechit.Pop(spec)) { line_t *ld = spec.line; @@ -2425,7 +2405,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, // we use the thing's actual position, including all the side effects of the original. // If some portal transition has to be considered here, we cannot do that and use the reference position stored with the spechit. bool posisoriginal = (spec.refpos.x == lastpos.x && spec.refpos.y == lastpos.y); - side = posisoriginal? P_PointOnLineSide(thing->X(), thing->Y(), ld) : P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld); + side = posisoriginal? P_PointOnLineSide(thing->_f_X(), thing->_f_Y(), ld) : P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld); oldside = P_PointOnLineSide(spec.oldrefpos.x, spec.oldrefpos.y, ld); if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER)) { @@ -2471,7 +2451,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget) { const sector_t *hs = newsec->heightsec; - fixed_t eyez = thing->Z() + viewheight; + fixed_t eyez = thing->_f_Z() + viewheight; fixed_t fakez = hs->floorplane.ZatPoint(x, y); if (!oldAboveFakeFloor && eyez > fakez) @@ -2511,7 +2491,7 @@ pushline: return false; } - thing->SetZ(oldz); + thing->_f_SetZ(oldz); if (!(thing->flags&(MF_TELEPORT | MF_NOCLIP))) { int numSpecHitTemp; @@ -2552,7 +2532,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) { FCheckPosition tm; - fixed_t newz = thing->Z(); + fixed_t newz = thing->_f_Z(); if (!P_CheckPosition(thing, x, y, tm)) { @@ -2561,22 +2541,22 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) if (thing->flags3 & MF3_FLOORHUGGER) { - newz = tm.floorz; + newz = tm._f_floorz(); } else if (thing->flags3 & MF3_CEILINGHUGGER) { - newz = tm.ceilingz - thing->height; + newz = tm._f_ceilingz() - thing->_f_height(); } if (!(thing->flags & MF_NOCLIP)) { - if (tm.ceilingz - tm.floorz < thing->height) + if (tm.ceilingz - tm.floorz < thing->Height) { return false; } if (!(thing->flags & MF_TELEPORT) - && tm.ceilingz - newz < thing->height + && tm.ceilingz - newz < thing->Height && !(thing->flags3 & MF3_CEILINGHUGGER) && (!(thing->flags2 & MF2_FLY) || !(thing->flags & MF_NOGRAVITY))) { @@ -2589,20 +2569,20 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) } if (!(thing->flags & MF_TELEPORT) && !(thing->flags3 & MF3_FLOORHUGGER)) { - if (tm.floorz - newz > thing->MaxStepHeight) + if (tm._f_floorz() - newz > thing->MaxStepHeight) { // too big a step up return false; } - else if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > newz) + else if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm._f_floorz() > newz) { // [RH] Don't let normal missiles climb steps return false; } - else if (newz < tm.floorz) + else if (newz < tm._f_floorz()) { // [RH] Check to make sure there's nothing in the way for the step up - fixed_t savedz = thing->Z(); - thing->SetZ(newz = tm.floorz); + fixed_t savedz = thing->_f_Z(); + thing->_f_SetZ(newz = tm._f_floorz()); bool good = P_TestMobjZ(thing); - thing->SetZ(savedz); + thing->_f_SetZ(savedz); if (!good) { return false; @@ -2612,7 +2592,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) if (thing->flags2 & MF2_CANTLEAVEFLOORPIC && (tm.floorpic != thing->floorpic - || tm.floorz - newz != 0)) + || tm._f_floorz() - newz != 0)) { // must stay within a sector of a certain floor type return false; } @@ -2852,22 +2832,22 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t // set openrange, opentop, openbottom P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); - if (open.range < slidemo->height) + if (open.range < slidemo->_f_height()) goto isblocking; // doesn't fit - if (open.top - slidemo->Z() < slidemo->height) + if (open.top - slidemo->_f_Z() < slidemo->_f_height()) goto isblocking; // mobj is too high - if (open.bottom - slidemo->Z() > slidemo->MaxStepHeight) + if (open.bottom - slidemo->_f_Z() > slidemo->MaxStepHeight) { goto isblocking; // too big a step up } - else if (slidemo->Z() < open.bottom) + else if (slidemo->_f_Z() < open.bottom) { // [RH] Check to make sure there's nothing in the way for the step up - fixed_t savedz = slidemo->Z(); - slidemo->SetZ(open.bottom); + fixed_t savedz = slidemo->_f_Z(); + slidemo->_f_SetZ(open.bottom); bool good = P_TestMobjZ(slidemo); - slidemo->SetZ(savedz); + slidemo->_f_SetZ(savedz); if (!good) { goto isblocking; @@ -2928,24 +2908,24 @@ retry: // trace along the three leading corners if (tryx > 0) { - leadx = mo->X() + mo->radius; - trailx = mo->X() - mo->radius; + leadx = mo->_f_X() + mo->_f_radius(); + trailx = mo->_f_X() - mo->_f_radius(); } else { - leadx = mo->X() - mo->radius; - trailx = mo->X() + mo->radius; + leadx = mo->_f_X() - mo->_f_radius(); + trailx = mo->_f_X() + mo->_f_radius(); } if (tryy > 0) { - leady = mo->Y() + mo->radius; - traily = mo->Y() - mo->radius; + leady = mo->_f_Y() + mo->_f_radius(); + traily = mo->_f_Y() - mo->_f_radius(); } else { - leady = mo->Y() - mo->radius; - traily = mo->Y() + mo->radius; + leady = mo->_f_Y() - mo->_f_radius(); + traily = mo->_f_Y() + mo->_f_radius(); } bestslidefrac = FRACUNIT + 1; @@ -2962,11 +2942,11 @@ retry: // killough 3/15/98: Allow objects to drop off ledges xmove = 0, ymove = tryy; walkplane = P_CheckSlopeWalk(mo, xmove, ymove); - if (!P_TryMove(mo, mo->X() + xmove, mo->Y() + ymove, true, walkplane)) + if (!P_TryMove(mo, mo->_f_X() + xmove, mo->_f_Y() + ymove, true, walkplane)) { xmove = tryx, ymove = 0; walkplane = P_CheckSlopeWalk(mo, xmove, ymove); - P_TryMove(mo, mo->X() + xmove, mo->Y() + ymove, true, walkplane); + P_TryMove(mo, mo->_f_X() + xmove, mo->_f_Y() + ymove, true, walkplane); } return; } @@ -2979,14 +2959,14 @@ retry: newy = FixedMul(tryy, bestslidefrac); // [BL] We need to abandon this function if we end up going through a teleporter - const fixed_t startvelx = mo->vel.x; - const fixed_t startvely = mo->vel.y; + const fixed_t startvelx = mo->_f_velx(); + const fixed_t startvely = mo->_f_vely(); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove(mo, mo->X() + newx, mo->Y() + newy, true)) + if (!P_TryMove(mo, mo->_f_X() + newx, mo->_f_Y() + newy, true)) goto stairstep; - if (mo->vel.x != startvelx || mo->vel.y != startvely) + if (mo->_f_velx() != startvelx || mo->_f_vely() != startvely) return; } @@ -3002,22 +2982,22 @@ retry: HitSlideLine(bestslideline); // clip the moves - mo->vel.x = tmxmove * numsteps; - mo->vel.y = tmymove * numsteps; + mo->Vel.X = FIXED2DBL(tmxmove * numsteps); + mo->Vel.Y = FIXED2DBL(tmymove * numsteps); // killough 10/98: affect the bobbing the same way (but not voodoo dolls) if (mo->player && mo->player->mo == mo) { - if (abs(mo->player->vel.x) > abs(mo->vel.x)) - mo->player->vel.x = mo->vel.x; - if (abs(mo->player->vel.y) > abs(mo->vel.y)) - mo->player->vel.y = mo->vel.y; + if (fabs(mo->player->Vel.X) > fabs(mo->Vel.X)) + mo->player->Vel.X = mo->Vel.X; + if (fabs(mo->player->Vel.Y) > fabs(mo->Vel.Y)) + mo->player->Vel.Y = mo->Vel.Y; } walkplane = P_CheckSlopeWalk(mo, tmxmove, tmymove); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove(mo, mo->X() + tmxmove, mo->Y() + tmymove, true, walkplane)) + if (!P_TryMove(mo, mo->_f_X() + tmxmove, mo->_f_Y() + tmymove, true, walkplane)) { goto retry; } @@ -3054,7 +3034,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov fixed_t thisplanez = rover->top.plane->ZatPoint(pos); - if (thisplanez>planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight) + if (thisplanez>planezhere && thisplanez <= actor->_f_Z() + actor->MaxStepHeight) { copyplane = *rover->top.plane; if (copyplane.c<0) copyplane.FlipVert(); @@ -3072,7 +3052,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov fixed_t thisplanez = rover->top.plane->ZatPoint(actor); - if (thisplanez>planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight) + if (thisplanez>planezhere && thisplanez <= actor->_f_Z() + actor->MaxStepHeight) { copyplane = *rover->top.plane; if (copyplane.c<0) copyplane.FlipVert(); @@ -3085,11 +3065,11 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov if (actor->floorsector != actor->Sector) { // this additional check prevents sliding on sloped dropoffs - if (planezhere>actor->floorz + 4 * FRACUNIT) + if (planezhere>actor->_f_floorz() + 4 * FRACUNIT) return NULL; } - if (actor->Z() - planezhere > FRACUNIT) + if (actor->_f_Z() - planezhere > FRACUNIT) { // not on floor return NULL; } @@ -3099,9 +3079,9 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov fixed_t destx, desty; fixed_t t; - destx = actor->X() + xmove; - desty = actor->Y() + ymove; - t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->Z()) + plane->d; + destx = actor->_f_X() + xmove; + desty = actor->_f_Y() + ymove; + t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->_f_Z()) + plane->d; if (t < 0) { // Desired location is behind (below) the plane // (i.e. Walking up the plane) @@ -3127,7 +3107,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov pos.x += xmove; pos.y += ymove; - if (sec->floorplane.ZatPoint(pos) >= actor->Z() - actor->MaxStepHeight) + if (sec->floorplane.ZatPoint(pos) >= actor->_f_Z() - actor->MaxStepHeight) { dopush = false; break; @@ -3137,8 +3117,10 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov } if (dopush) { - xmove = actor->vel.x = plane->a * 2; - ymove = actor->vel.y = plane->b * 2; + xmove = plane->a * 2; + ymove = plane->b * 2; + actor->Vel.X = FIXED2DBL(xmove); + actor->Vel.Y = FIXED2DBL(ymove); } return (actor->floorsector == actor->Sector) ? plane : NULL; } @@ -3147,19 +3129,19 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov // so that it lies on the plane's surface destx -= FixedMul(plane->a, t); desty -= FixedMul(plane->b, t); - xmove = destx - actor->X(); - ymove = desty - actor->Y(); + xmove = destx - actor->_f_X(); + ymove = desty - actor->_f_Y(); return (actor->floorsector == actor->Sector) ? plane : NULL; } else if (t > 0) { // Desired location is in front of (above) the plane - if (planezhere == actor->Z()) + if (planezhere == actor->_f_Z()) { // Actor's current spot is on/in the plane, so walk down it // Same principle as walking up, except reversed destx += FixedMul(plane->a, t); desty += FixedMul(plane->b, t); - xmove = destx - actor->X(); - ymove = desty - actor->Y(); + xmove = destx - actor->_f_X(); + ymove = desty - actor->_f_Y(); return (actor->floorsector == actor->Sector) ? plane : NULL; } } @@ -3198,20 +3180,20 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_ } if (!(li->flags&ML_TWOSIDED) || !li->backsector) { - if (P_PointOnLineSide(slidemo->X(), slidemo->Y(), li)) + if (P_PointOnLineSide(slidemo->_f_X(), slidemo->_f_Y(), li)) continue; // don't hit the back side goto bounceblocking; } P_LineOpening(open, slidemo, li, it.InterceptPoint(in)); // set openrange, opentop, openbottom - if (open.range < slidemo->height) + if (open.range < slidemo->_f_height()) goto bounceblocking; // doesn't fit - if (open.top - slidemo->Z() < slidemo->height) + if (open.top - slidemo->_f_Z() < slidemo->_f_height()) goto bounceblocking; // mobj is too high - if (open.bottom > slidemo->Z()) + if (open.bottom > slidemo->_f_Z()) goto bounceblocking; // mobj is too low continue; // this line doesn't block movement @@ -3253,28 +3235,28 @@ bool FSlide::BounceWall(AActor *mo) // // trace along the three leading corners // - if (mo->vel.x > 0) + if (mo->Vel.X > 0) { - leadx = mo->X() + mo->radius; + leadx = mo->_f_X() + mo->_f_radius(); } else { - leadx = mo->X() - mo->radius; + leadx = mo->_f_X() - mo->_f_radius(); } - if (mo->vel.y > 0) + if (mo->Vel.Y > 0) { - leady = mo->Y() + mo->radius; + leady = mo->_f_Y() + mo->_f_radius(); } else { - leady = mo->Y() - mo->radius; + leady = mo->_f_Y() - mo->_f_radius(); } bestslidefrac = FRACUNIT + 1; bestslideline = mo->BlockingLine; - if (BounceTraverse(leadx, leady, leadx + mo->vel.x, leady + mo->vel.y) && mo->BlockingLine == NULL) + if (BounceTraverse(leadx, leady, leadx + mo->_f_velx(), leady + mo->_f_vely()) && mo->BlockingLine == NULL) { // Could not find a wall, so bounce off the floor/ceiling instead. - fixed_t floordist = mo->Z() - mo->floorz; - fixed_t ceildist = mo->ceilingz - mo->Z(); + double floordist = mo->Z() - mo->floorz; + double ceildist = mo->ceilingz - mo->Z(); if (floordist <= ceildist) { mo->FloorBounceMissile(mo->Sector->floorplane); @@ -3305,27 +3287,27 @@ bool FSlide::BounceWall(AActor *mo) return true; } - side = P_PointOnLineSide(mo->X(), mo->Y(), line); + side = P_PointOnLineSide(mo->_f_X(), mo->_f_Y(), line); lineangle = R_PointToAngle2(0, 0, line->dx, line->dy); if (side == 1) { lineangle += ANG180; } - moveangle = R_PointToAngle2(0, 0, mo->vel.x, mo->vel.y); + moveangle = R_PointToAngle2(0, 0, mo->_f_velx(), mo->_f_vely()); deltaangle = (2 * lineangle) - moveangle; - mo->angle = deltaangle; + mo->Angles.Yaw = ANGLE2DBL(deltaangle); deltaangle >>= ANGLETOFINESHIFT; - movelen = fixed_t(sqrt(double(mo->vel.x)*mo->vel.x + double(mo->vel.y)*mo->vel.y)); + movelen = fixed_t(g_sqrt(double(mo->_f_velx())*mo->_f_velx() + double(mo->_f_vely())*mo->_f_vely())); movelen = FixedMul(movelen, mo->wallbouncefactor); - FBoundingBox box(mo->X(), mo->Y(), mo->radius); + FBoundingBox box(mo->_f_X(), mo->_f_Y(), mo->_f_radius()); if (box.BoxOnLineSide(line) == -1) { fixedvec3 pos = mo->Vec3Offset( - FixedMul(mo->radius, finecosine[deltaangle]), - FixedMul(mo->radius, finesine[deltaangle]), 0); + FixedMul(mo->_f_radius(), finecosine[deltaangle]), + FixedMul(mo->_f_radius(), finesine[deltaangle]), 0); mo->SetOrigin(pos, true); } @@ -3333,8 +3315,8 @@ bool FSlide::BounceWall(AActor *mo) { movelen = 2 * FRACUNIT; } - mo->vel.x = FixedMul(movelen, finecosine[deltaangle]); - mo->vel.y = FixedMul(movelen, finesine[deltaangle]); + mo->Vel.X = FIXED2DBL(FixedMul(movelen, finecosine[deltaangle])); + mo->Vel.Y = FIXED2DBL(FixedMul(movelen, finesine[deltaangle])); if (mo->BounceFlags & BOUNCE_UseBounceState) { FState *bouncestate = mo->FindState(NAME_Bounce, NAME_Wall); @@ -3377,14 +3359,10 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) if (!ontop) { - fixed_t speed; - angle_t angle = BlockingMobj->AngleTo(mo) + ANGLE_1*((pr_bounce() % 16) - 8); - speed = P_AproxDistance(mo->vel.x, mo->vel.y); - speed = FixedMul(speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->vel.x = FixedMul(speed, finecosine[angle]); - mo->vel.y = FixedMul(speed, finesine[angle]); + DAngle angle = BlockingMobj->AngleTo(mo) + ((pr_bounce() % 16) - 8); + double speed = mo->VelXYToSpeed() * FIXED2DBL(mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent + mo->Angles.Yaw = ANGLE2DBL(angle); + mo->VelFromAngle(speed); mo->PlayBounceSound(true); if (mo->BounceFlags & BOUNCE_UseBounceState) { @@ -3405,11 +3383,11 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) } else { - fixed_t dot = mo->vel.z; + double dot = mo->Vel.Z; if (mo->BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) { - mo->vel.z -= MulScale15(FRACUNIT, dot); + mo->Vel.Z -= 2. / dot; if (!(mo->BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. { mo->flags |= MF_INBOUNCE; @@ -3419,24 +3397,24 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) } else { - mo->vel.z = FixedMul(mo->vel.z, mo->bouncefactor); + mo->Vel.Z *= mo->_bouncefactor(); } } else // Don't run through this for MBF-style bounces { // The reflected velocity keeps only about 70% of its original speed - mo->vel.z = FixedMul(mo->vel.z - MulScale15(FRACUNIT, dot), mo->bouncefactor); + mo->Vel.Z = (mo->Vel.Z - 2. / dot) * mo->_bouncefactor(); } mo->PlayBounceSound(true); if (mo->BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed { - if (abs(mo->vel.z) < (fixed_t)(mo->Mass * mo->GetGravity() / 64)) - mo->vel.z = 0; + if (fabs(mo->Vel.Z) < mo->Mass * mo->GetGravity() / 64) + mo->Vel.Z = 0; } else if (mo->BounceFlags & (BOUNCE_AutoOff | BOUNCE_AutoOffFloorOnly)) { - if (!(mo->flags & MF_NOGRAVITY) && (mo->vel.z < 3 * FRACUNIT)) + if (!(mo->flags & MF_NOGRAVITY) && (mo->Vel.Z < 3.)) mo->BounceFlags &= ~BOUNCE_TypeMask; } } @@ -3532,7 +3510,7 @@ struct aim_t { res.linetarget = th; res.pitch = pitch; - res.angleFromSource = R_PointToAngle2(startpos.x, startpos.y, th->X(), th->Y()); + res.angleFromSource = VecToAngle(th->_f_X() - startpos.x, th->_f_Y() - startpos.y); res.unlinked = unlinked; res.frac = frac; } @@ -3683,18 +3661,18 @@ struct aim_t { AActor *portal = entersec->SkyBoxes[position]; - if (position == sector_t::ceiling && portal->threshold < limitz) return; - else if (position == sector_t::floor && portal->threshold > limitz) return; + if (position == sector_t::ceiling && FLOAT2FIXED(portal->specialf1) < limitz) return; + else if (position == sector_t::floor && FLOAT2FIXED(portal->specialf1) > limitz) return; aim_t newtrace = Clone(); newtrace.toppitch = newtoppitch; newtrace.bottompitch = newbottompitch; newtrace.aimdir = position == sector_t::ceiling? aim_t::aim_up : aim_t::aim_down; - newtrace.startpos = { startpos.x + portal->scaleX, startpos.y + portal->scaleY, startpos.z }; + newtrace.startpos = { startpos.x + FLOAT2FIXED(portal->Scale.X), startpos.y + FLOAT2FIXED(portal->Scale.Y), startpos.z }; newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening newtrace.lastsector = P_PointInSector(newtrace.startpos.x + FixedMul(aimtrace.x, newtrace.startfrac) , newtrace.startpos.y + FixedMul(aimtrace.y, newtrace.startfrac)); - newtrace.limitz = portal->threshold; + newtrace.limitz = FLOAT2FIXED(portal->specialf1); if (aimdebug) Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum); newtrace.AimTraverse(); @@ -3771,7 +3749,7 @@ struct aim_t fixed_t bottomz = rover->bottom.plane->ZatPoint(startpos); - if (bottomz >= startpos.z + shootthing->height) + if (bottomz >= startpos.z + shootthing->_f_height()) { lastceilingplane = rover->bottom.plane; // no ceiling portal if below a 3D floor @@ -3938,12 +3916,12 @@ struct aim_t // check angles to see if the thing can be aimed at - thingtoppitch = -(int)R_PointToAngle2(0, shootz, dist, th->Z() + th->height); + thingtoppitch = -(int)R_PointToAngle2(0, shootz, dist, th->_f_Z() + th->_f_height()); if (thingtoppitch > bottompitch) continue; // shot over the thing - thingbottompitch = -(int)R_PointToAngle2(0, shootz, dist, th->Z()); + thingbottompitch = -(int)R_PointToAngle2(0, shootz, dist, th->_f_Z()); if (thingbottompitch < toppitch) continue; // shot under the thing @@ -4007,7 +3985,7 @@ struct aim_t { // friends don't aim at friends (except players), at least not first if (aimdebug) - Printf("Hit friend %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + Printf("Hit friend %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); SetResult(thing_friend, in->frac, th, thingpitch); } } @@ -4017,14 +3995,14 @@ struct aim_t { // don't autoaim at barrels and other shootable stuff unless no monsters have been found if (aimdebug) - Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); SetResult(thing_other, in->frac, th, thingpitch); } } else { if (aimdebug) - Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); SetResult(linetarget, in->frac, th, thingpitch); return; } @@ -4032,7 +4010,7 @@ struct aim_t else { if (aimdebug) - Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z()); SetResult(linetarget, in->frac, th, thingpitch); return; } @@ -4046,13 +4024,13 @@ struct aim_t // //============================================================================ -fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslatedLineTarget *pLineTarget, fixed_t vrange, +DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLineTarget *pLineTarget, DAngle vrange, int flags, AActor *target, AActor *friender) { - fixed_t shootz = t1->Z() + (t1->height >> 1) - t1->floorclip; + fixed_t shootz = t1->_f_Z() + (t1->_f_height() >> 1) - t1->_f_floorclip(); if (t1->player != NULL) { - shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += fixed_t(t1->player->mo->AttackZOffset * t1->player->crouchfactor); } else { @@ -4064,7 +4042,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated { if (t1->player == NULL || !level.IsFreelookAllowed()) { - vrange = ANGLE_1 * 35; + vrange = 35.; } else { @@ -4072,7 +4050,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated AWeapon *weapon = t1->player->ReadyWeapon; if (weapon && (weapon->WeaponFlags & WIF_NOAUTOAIM)) { - vrange = ANGLE_1 / 2; + vrange = 0.5; } else { @@ -4080,7 +4058,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated // vrange of 0 degrees, because then toppitch and bottompitch will // be equal, and PTR_AimTraverse will never find anything to shoot at // if it crosses a line. - vrange = clamp(t1->player->userinfo.GetAimDist(), ANGLE_1 / 2, ANGLE_1 * 35); + vrange = clamp(t1->player->userinfo.GetAimDist(), 0.5, 35.); } } } @@ -4091,13 +4069,13 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated aim.shootthing = t1; aim.friender = (friender == NULL) ? t1 : friender; aim.aimdir = aim_t::aim_up | aim_t::aim_down; - aim.startpos = t1->Pos(); - aim.aimtrace = Vec2Angle(distance, angle); + aim.startpos = t1->_f_Pos(); + aim.aimtrace = Vec2Angle(FLOAT2FIXED(distance), angle); aim.limitz = aim.shootz = shootz; - aim.toppitch = t1->pitch - vrange; - aim.bottompitch = t1->pitch + vrange; - aim.attackrange = distance; - aim.aimpitch = t1->pitch; + aim.toppitch = (t1->Angles.Pitch - vrange).BAMs(); + aim.bottompitch = (t1->Angles.Pitch + vrange).BAMs(); + aim.attackrange = FLOAT2FIXED(distance); + aim.aimpitch = t1->_f_pitch(); aim.lastsector = t1->Sector; aim.startfrac = 0; aim.unlinked = false; @@ -4111,7 +4089,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated { *pLineTarget = *result; } - return result->linetarget ? result->pitch : t1->pitch; + return result->linetarget ? DAngle(ANGLE2DBL(result->pitch)) : t1->Angles.Pitch; } @@ -4163,15 +4141,15 @@ static ETraceStatus CheckForActor(FTraceResults &res, void *userdata) // //========================================================================== -AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, + DAngle pitch, int damage, FName damageType, PClassActor *pufftype, int flags, FTranslatedLineTarget*victim, int *actualdamage) { fixed_t vx, vy, vz, shootz; FTraceResults trace; Origin TData; TData.Caller = t1; - angle_t srcangle = angle; - int srcpitch = pitch; + angle_t srcangle = angle.BAMs(); + int srcpitch = pitch.BAMs(); bool killPuff = false; AActor *puff = NULL; int pflag = 0; @@ -4188,17 +4166,16 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, *actualdamage = 0; } - angle >>= ANGLETOFINESHIFT; - pitch = (angle_t)(pitch) >> ANGLETOFINESHIFT; + double pc = pitch.Cos(); - vx = FixedMul(finecosine[pitch], finecosine[angle]); - vy = FixedMul(finecosine[pitch], finesine[angle]); - vz = -finesine[pitch]; + vx = FLOAT2FIXED(pc * angle.Cos()); + vy = FLOAT2FIXED(pc * angle.Sin()); + vz = FLOAT2FIXED(-pitch.Sin()); - shootz = t1->Z() - t1->floorclip + (t1->height >> 1); + shootz = t1->_f_Z() - t1->_f_floorclip() + (t1->_f_height() >> 1); if (t1->player != NULL) { - shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += fixed_t(t1->player->mo->AttackZOffset * t1->player->crouchfactor); if (damageType == NAME_Melee || damageType == NAME_Hitscan) { // this is coming from a weapon attack function which needs to transfer information to the obituary code, @@ -4233,7 +4210,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky; else tflags = TRACE_NoSky | TRACE_Impact; - if (!Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance, + if (!Trace(t1->_f_X(), t1->_f_Y(), shootz, t1->Sector, vx, vy, vz, FLOAT2FIXED(distance), MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace, tflags, CheckForActor, &TData)) { // hit nothing @@ -4263,7 +4240,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, fixedvec2 pos = P_GetOffsetPosition(trace.HitPos.x, trace.HitPos.y, -trace.HitVector.x * 4, -trace.HitVector.y * 4); puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, trace.HitPos.z - trace.HitVector.z * 4, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 0, puffFlags); - puff->radius = 1; + puff->radius = 1/65536.; } // [RH] Spawn a decal @@ -4358,7 +4335,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, puff = P_SpawnPuff(t1, pufftype, bleedpos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); killPuff = true; } - newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleToTarget); + newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, ANGLE2DBL(trace.SrcAngleToTarget)); if (actualdamage != NULL) { *actualdamage = newdam; @@ -4398,7 +4375,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, if (victim != NULL) { victim->linetarget = trace.Actor; - victim->angleFromSource = trace.SrcAngleToTarget; + victim->angleFromSource = ANGLE2DBL(trace.SrcAngleToTarget); victim->unlinked = trace.unlinked; } } @@ -4420,8 +4397,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, return puff; } -AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, - int pitch, int damage, FName damageType, FName pufftype, int flags, FTranslatedLineTarget *victim, int *actualdamage) +AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, + DAngle pitch, int damage, FName damageType, FName pufftype, int flags, FTranslatedLineTarget *victim, int *actualdamage) { PClassActor *type = PClass::FindActor(pufftype); if (type == NULL) @@ -4457,10 +4434,10 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, vy = FixedMul(finecosine[pitch], finesine[angle]); vz = -finesine[pitch]; - shootz = t1->Z() - t1->floorclip + (t1->height >> 1); + shootz = t1->_f_Z() - t1->_f_floorclip() + (t1->_f_height() >> 1); if (t1->player != NULL) { - shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor); + shootz += fixed_t(t1->player->mo->AttackZOffset * t1->player->crouchfactor); } else { @@ -4473,7 +4450,7 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, TData.Caller = t1; TData.hitGhosts = true; - if (Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance, + if (Trace(t1->_f_X(), t1->_f_Y(), shootz, t1->Sector, vx, vy, vz, distance, actorMask, wallMask, t1, trace, TRACE_NoSky | TRACE_PortalRestrict, CheckForActor, &TData)) { if (trace.HitType == TRACE_HitActor) @@ -4574,7 +4551,7 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch) { - P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2, + P_TraceBleed(damage, target->_f_X(), target->_f_Y(), target->_f_Z() + target->_f_height() / 2, target, angle, pitch); } @@ -4593,19 +4570,19 @@ void P_TraceBleed(int damage, AActor *target, AActor *missile) return; } - if (missile->vel.z != 0) + if (missile->Vel.Z != 0) { double aim; - aim = atan((double)missile->vel.z / (double)target->AproxDistance(missile)); + aim = g_atan((double)missile->_f_velz() / (double)target->AproxDistance(missile)); pitch = -(int)(aim * ANGLE_180 / PI); } else { pitch = 0; } - P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2, - target, missile->AngleTo(target), + P_TraceBleed(damage, target->_f_X(), target->_f_Y(), target->_f_Z() + target->_f_height() / 2, + target, missile->__f_AngleTo(target), pitch); } @@ -4623,8 +4600,8 @@ void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff) } fixed_t randpitch = (pr_tracebleed() - 128) << 16; - P_TraceBleed(damage, t->linetarget->X(), t->linetarget->Y(), t->linetarget->Z() + t->linetarget->height / 2, - t->linetarget, t->angleFromSource, 0); + P_TraceBleed(damage, t->linetarget->_f_X(), t->linetarget->_f_Y(), t->linetarget->_f_Z() + t->linetarget->_f_height() / 2, + t->linetarget, FLOAT2ANGLE(t->angleFromSource.Degrees), 0); } //========================================================================== @@ -4640,7 +4617,7 @@ void P_TraceBleed(int damage, AActor *target) fixed_t one = pr_tracebleed() << 24; fixed_t two = (pr_tracebleed() - 128) << 16; - P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2, + P_TraceBleed(damage, target->_f_X(), target->_f_Y(), target->_f_Z() + target->_f_height() / 2, target, one, two); } } @@ -4721,20 +4698,20 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i puffclass = PClass::FindActor(NAME_BulletPuff); } - pitch = ((angle_t)(-source->pitch) + pitchoffset) >> ANGLETOFINESHIFT; - angle = (source->angle + angleoffset) >> ANGLETOFINESHIFT; + pitch = ((angle_t)(-source->_f_pitch()) + pitchoffset) >> ANGLETOFINESHIFT; + angle = (source->_f_angle() + angleoffset) >> ANGLETOFINESHIFT; vx = FixedMul(finecosine[pitch], finecosine[angle]); vy = FixedMul(finecosine[pitch], finesine[angle]); vz = finesine[pitch]; - shootz = source->Z() - source->floorclip + (source->height >> 1) + offset_z; + shootz = source->_f_Z() - source->_f_floorclip() + (source->_f_height() >> 1) + offset_z; if (!(railflags & RAF_CENTERZ)) { if (source->player != NULL) { - shootz += FixedMul(source->player->mo->AttackZOffset, source->player->crouchfactor); + shootz += fixed_t(source->player->mo->AttackZOffset * source->player->crouchfactor); } else { @@ -4742,7 +4719,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i } } - angle = ((source->angle + angleoffset) - ANG90) >> ANGLETOFINESHIFT; + angle = ((source->_f_angle() + angleoffset) - ANG90) >> ANGLETOFINESHIFT; fixedvec2 xy = source->Vec2Offset(offset_xy * finecosine[angle], offset_xy * finesine[angle]); @@ -4773,7 +4750,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i // used as damage inflictor AActor *thepuff = NULL; - if (puffclass != NULL) thepuff = Spawn(puffclass, source->Pos(), ALLOW_REPLACE); + if (puffclass != NULL) thepuff = Spawn(puffclass, source->_f_Pos(), ALLOW_REPLACE); for (i = 0; i < rail_data.RailHits.Size(); i++) { @@ -4816,12 +4793,12 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i if (puffDefaults->flags3 & MF3_FOILINVUL) dmgFlagPass |= DMG_FOILINVUL; if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA; } - int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass|DMG_USEANGLE, hitangle); + int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass|DMG_USEANGLE, ANGLE2DBL(hitangle)); if (bleed) { P_SpawnBlood(hitpos, hitangle, newdam > 0 ? newdam : damage, hitactor); - P_TraceBleed(newdam > 0 ? newdam : damage, hitpos, hitactor, source->angle, pitch); + P_TraceBleed(newdam > 0 ? newdam : damage, hitpos, hitactor, source->_f_angle(), pitch); } } @@ -4873,7 +4850,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i end.X = FIXED2DBL(trace.HitPos.x); end.Y = FIXED2DBL(trace.HitPos.y); end.Z = FIXED2DBL(trace.HitPos.z); - P_DrawRailTrail(source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->angle + angleoffset, duration, sparsity, drift, SpiralOffset); + P_DrawRailTrail(source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->_f_angle() + angleoffset, duration, sparsity, drift, SpiralOffset); } //========================================================================== @@ -4888,8 +4865,8 @@ CVAR(Float, chase_dist, 90.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &CameraZ, sector_t *&CameraSector, bool &unlinked) { fixed_t distance = (fixed_t)(clamp(chase_dist, 0, 30000) * FRACUNIT); - angle_t angle = (t1->angle - ANG180) >> ANGLETOFINESHIFT; - angle_t pitch = (angle_t)(t1->pitch) >> ANGLETOFINESHIFT; + angle_t angle = (t1->_f_angle() - ANG180) >> ANGLETOFINESHIFT; + angle_t pitch = (angle_t)(t1->_f_pitch()) >> ANGLETOFINESHIFT; FTraceResults trace; fixed_t vx, vy, vz, sz; @@ -4897,16 +4874,16 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera vy = FixedMul(finecosine[pitch], finesine[angle]); vz = finesine[pitch]; - sz = t1->Z() - t1->floorclip + t1->height + (fixed_t)(clamp(chase_height, -1000, 1000) * FRACUNIT); + sz = t1->_f_Z() - t1->_f_floorclip() + t1->_f_height() + (fixed_t)(clamp(chase_height, -1000, 1000) * FRACUNIT); - if (Trace(t1->X(), t1->Y(), sz, t1->Sector, + if (Trace(t1->_f_X(), t1->_f_Y(), sz, t1->Sector, vx, vy, vz, distance, 0, 0, NULL, trace) && trace.Distance > 10 * FRACUNIT) { // Position camera slightly in front of hit thing fixed_t dist = trace.Distance - 5 * FRACUNIT; - CameraX = t1->X() + FixedMul(vx, dist); - CameraY = t1->Y() + FixedMul(vy, dist); + CameraX = t1->_f_X() + FixedMul(vx, dist); + CameraY = t1->_f_Y() + FixedMul(vy, dist); CameraZ = sz + FixedMul(vz, dist); } else @@ -4931,12 +4908,12 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera bool P_TalkFacing(AActor *player) { - static const int angleofs[] = { 0, ANGLE_90 >> 4, - ANGLE_90 >> 4 }; + static const double angleofs[] = { 0, 90./16, -90./16 }; FTranslatedLineTarget t; - for (int angle : angleofs) + for (double angle : angleofs) { - P_AimLineAttack(player, player->angle + angle, TALKRANGE, &t, ANGLE_1 * 35, ALF_FORCENOSMART | ALF_CHECKCONVERSATION | ALF_PORTALRESTRICT); + P_AimLineAttack(player, player->Angles.Yaw + angle, TALKRANGE, &t, 35., ALF_FORCENOSMART | ALF_CHECKCONVERSATION | ALF_PORTALRESTRICT); if (t.linetarget != NULL) { if (t.linetarget->health > 0 && // Dead things can't talk. @@ -4964,7 +4941,7 @@ bool P_UseTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t end { FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES | PT_ADDTHINGS); intercept_t *in; - fixedvec3 xpos = { startx, starty, usething->Z() }; + fixedvec3 xpos = { startx, starty, usething->_f_Z() }; while ((in = it.Next())) { @@ -5109,8 +5086,8 @@ bool P_NoWayTraverse(AActor *usething, fixed_t startx, fixed_t starty, fixed_t e if (ld->flags&(ML_BLOCKING | ML_BLOCKEVERYTHING | ML_BLOCK_PLAYERS)) return true; P_LineOpening(open, NULL, ld, it.InterceptPoint(in)); if (open.range <= 0 || - open.bottom > usething->Z() + usething->MaxStepHeight || - open.top < usething->Top()) return true; + open.bottom > usething->_f_Z() + usething->MaxStepHeight || + open.top < usething->_f_Top()) return true; } return false; } @@ -5130,9 +5107,9 @@ void P_UseLines(player_t *player) bool foundline = false; // If the player is transitioning a portal, use the group that is at its vertical center. - fixedvec2 start = player->mo->GetPortalTransition(player->mo->height / 2); + fixedvec2 start = player->mo->GetPortalTransition(player->mo->_f_height() / 2); // [NS] Now queries the Player's UseRange. - fixedvec2 end = start + Vec2Angle(userange > 0? fixed_t(userange<mo->UseRange, player->mo->angle); + fixedvec2 end = start + Vec2Angle(userange > 0? fixed_t(userange<mo->UseRange, player->mo->_f_angle()); // old code: // @@ -5166,9 +5143,9 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) int angle; fixed_t x1, y1, x2, y2, usedist; - angle = PuzzleItemUser->angle >> ANGLETOFINESHIFT; - x1 = PuzzleItemUser->X(); - y1 = PuzzleItemUser->Y(); + angle = PuzzleItemUser->_f_angle() >> ANGLETOFINESHIFT; + x1 = PuzzleItemUser->_f_X(); + y1 = PuzzleItemUser->_f_Y(); // [NS] If it's a Player, get their UseRange. if (PuzzleItemUser->player) @@ -5198,7 +5175,7 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) } continue; } - if (P_PointOnLineSide(PuzzleItemUser->X(), PuzzleItemUser->Y(), in->d.line) == 1) + if (P_PointOnLineSide(PuzzleItemUser->_f_X(), PuzzleItemUser->_f_Y(), in->d.line) == 1) { // Don't use back sides return false; } @@ -5267,7 +5244,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo double bombdamagefloat = (double)bombdamage; FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d); - FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistfix, bombspot->height + bombdistfix*2, bombdistfix, false, bombspot->Sector); + FMultiBlockThingsIterator it(grouplist, bombspot->_f_X(), bombspot->_f_Y(), bombspot->_f_Z() - bombdistfix, bombspot->_f_height() + bombdistfix*2, bombdistfix, false, bombspot->Sector); FMultiBlockThingsIterator::CheckResult cres; if (flags & RADF_SOURCEISSPOT) @@ -5278,7 +5255,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo while ((it.Next(&cres))) { AActor *thing = cres.thing; - // Vulnerable actors can be damaged by radius attacks even if not shootable + // Vulnerable actors can be damaged by _f_radius() attacks even if not shootable // Used to emulate MBF's vulnerability of non-missile bouncers to explosions. if (!((thing->flags & MF_SHOOTABLE) || (thing->flags6 & MF6_VULNERABLE))) continue; @@ -5317,25 +5294,25 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo fixed_t dx, dy; double boxradius; - fixedvec2 vec = bombspot->Vec2To(thing); + fixedvec2 vec = bombspot->_f_Vec2To(thing); dx = abs(vec.x); dy = abs(vec.y); - boxradius = double(thing->radius); + boxradius = double(thing->_f_radius()); // The damage pattern is square, not circular. len = double(dx > dy ? dx : dy); - if (bombspot->Z() < thing->Z() || bombspot->Z() >= thing->Top()) + if (bombspot->_f_Z() < thing->_f_Z() || bombspot->_f_Z() >= thing->_f_Top()) { double dz; - if (bombspot->Z() > thing->Z()) + if (bombspot->_f_Z() > thing->_f_Z()) { - dz = double(bombspot->Z() - thing->Top()); + dz = double(bombspot->_f_Z() - thing->_f_Top()); } else { - dz = double(thing->Z() - bombspot->Z()); + dz = double(thing->_f_Z() - bombspot->_f_Z()); } if (len <= boxradius) { @@ -5344,7 +5321,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo else { len -= boxradius; - len = sqrt(len*len + dz*dz); + len = g_sqrt(len*len + dz*dz); } } else @@ -5387,25 +5364,23 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo if (!(thing->flags7 & MF7_DONTTHRUST)) { - thrust = points * 0.5f / (double)thing->Mass; + thrust = points * 0.5 / (double)thing->Mass; if (bombsource == thing) { thrust *= selfthrustscale; } - vz = (double)(thing->Z() + (thing->height >> 1) - bombspot->Z()) * thrust; + vz = (thing->Center() - bombspot->Z()) * thrust; if (bombsource != thing) { - vz *= 0.5f; + vz *= 0.5; } else { - vz *= 0.8f; + vz *= 0.8; } - angle_t ang = bombspot->AngleTo(thing) >> ANGLETOFINESHIFT; - thing->vel.x += fixed_t(finecosine[ang] * thrust); - thing->vel.y += fixed_t(finesine[ang] * thrust); + thing->Thrust(bombspot->AngleTo(thing), thrust); if (!(flags & RADF_NODAMAGE)) - thing->vel.z += (fixed_t)vz; // this really doesn't work well + thing->Vel.Z += vz; // this really doesn't work well } } } @@ -5417,12 +5392,12 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo // [RH] Old code just for barrels fixed_t dx, dy, dist; - fixedvec2 vec = bombspot->Vec2To(thing); + fixedvec2 vec = bombspot->_f_Vec2To(thing); dx = abs(vec.x); dy = abs(vec.y); dist = dx>dy ? dx : dy; - dist = (dist - thing->radius) >> FRACBITS; + dist = (dist - thing->_f_radius()) >> FRACBITS; if (dist < 0) dist = 0; @@ -5506,7 +5481,7 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos) thing->flags2 |= MF2_PASSMOBJ; } - bool isgood = P_CheckPosition(thing, thing->X(), thing->Y(), tm); + bool isgood = P_CheckPosition(thing, thing->_f_X(), thing->_f_Y(), tm); thing->floorz = tm.floorz; thing->ceilingz = tm.ceilingz; thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs @@ -5542,8 +5517,8 @@ void P_FindAboveIntersectors(AActor *actor) while (it.Next(&cres)) { AActor *thing = cres.thing; - fixed_t blockdist = actor->radius + thing->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + fixed_t blockdist = actor->_f_radius() + thing->_f_radius(); + if (abs(thing->_f_X() - cres.position.x) >= blockdist || abs(thing->_f_Y() - cres.position.y) >= blockdist) continue; if (!(thing->flags & MF_SOLID)) @@ -5598,8 +5573,8 @@ void P_FindBelowIntersectors(AActor *actor) while (it.Next(&cres)) { AActor *thing = cres.thing; - fixed_t blockdist = actor->radius + thing->radius; - if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist) + fixed_t blockdist = actor->_f_radius() + thing->_f_radius(); + if (abs(thing->_f_X() - cres.position.x) >= blockdist || abs(thing->_f_Y() - cres.position.y) >= blockdist) continue; if (!(thing->flags & MF_SOLID)) @@ -5662,10 +5637,10 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos) { AActor *mo; - mo = Spawn(bloodcls, thing->PosPlusZ(thing->height / 2), ALLOW_REPLACE); + mo = Spawn(bloodcls, thing->PosPlusZ(thing->_f_height() / 2), ALLOW_REPLACE); - mo->vel.x = pr_crunch.Random2() << 12; - mo->vel.y = pr_crunch.Random2() << 12; + mo->Vel.X = pr_crunch.Random2() / 16.; + mo->Vel.Y = pr_crunch.Random2() / 16.; if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) { mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); @@ -5678,7 +5653,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos) an = (M_Random() - 128) << 24; if (cl_bloodtype >= 1) { - P_DrawSplash2(32, thing->X(), thing->Y(), thing->Z() + thing->height / 2, an, 2, bloodcolor); + P_DrawSplash2(32, thing->_f_X(), thing->_f_Y(), thing->_f_Z() + thing->_f_height() / 2, an, 2, bloodcolor); } } if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound)) @@ -5735,13 +5710,13 @@ int P_PushUp(AActor *thing, FChangePosition *cpos) return 2; } fixed_t oldz; - oldz = intersect->Z(); + oldz = intersect->_f_Z(); P_AdjustFloorCeil(intersect, cpos); - intersect->SetZ(thing->Top() + 1); + intersect->_f_SetZ(thing->_f_Top() + 1); if (P_PushUp(intersect, cpos)) { // Move blocked P_DoCrunch(intersect, cpos); - intersect->SetZ(oldz); + intersect->_f_SetZ(oldz); return 2; } } @@ -5780,15 +5755,15 @@ int P_PushDown(AActor *thing, FChangePosition *cpos) // Can't push bridges or things more massive than ourself return 2; } - fixed_t oldz = intersect->Z(); + fixed_t oldz = intersect->_f_Z(); P_AdjustFloorCeil(intersect, cpos); - if (oldz > thing->Z() - intersect->height) + if (oldz > thing->_f_Z() - intersect->_f_height()) { // Only push things down, not up. - intersect->SetZ(thing->Z() - intersect->height); + intersect->_f_SetZ(thing->_f_Z() - intersect->_f_height()); if (P_PushDown(intersect, cpos)) { // Move blocked P_DoCrunch(intersect, cpos); - intersect->SetZ(oldz); + intersect->_f_SetZ(oldz); return 2; } } @@ -5805,40 +5780,40 @@ int P_PushDown(AActor *thing, FChangePosition *cpos) void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) { - fixed_t oldfloorz = thing->floorz; - fixed_t oldz = thing->Z(); + fixed_t oldfloorz = thing->_f_floorz(); + fixed_t oldz = thing->_f_Z(); P_AdjustFloorCeil(thing, cpos); - if (oldfloorz == thing->floorz) return; + if (oldfloorz == thing->_f_floorz()) return; if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things - if (thing->vel.z == 0 && + if (thing->_f_velz() == 0 && (!(thing->flags & MF_NOGRAVITY) || - (thing->Z() == oldfloorz && !(thing->flags & MF_NOLIFTDROP)))) + (thing->_f_Z() == oldfloorz && !(thing->flags & MF_NOLIFTDROP)))) { - fixed_t oldz = thing->Z(); + fixed_t oldz = thing->_f_Z(); if ((thing->flags & MF_NOGRAVITY) || (thing->flags5 & MF5_MOVEWITHSECTOR) || (((cpos->sector->Flags & SECF_FLOORDROP) || cpos->moveamt < 9 * FRACUNIT) - && thing->Z() - thing->floorz <= cpos->moveamt)) + && thing->_f_Z() - thing->_f_floorz() <= cpos->moveamt)) { thing->SetZ(thing->floorz); P_CheckFakeFloorTriggers(thing, oldz); } } - else if ((thing->Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) + else if ((thing->_f_Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP))) { - fixed_t oldz = thing->Z(); + fixed_t oldz = thing->_f_Z(); if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) { - thing->AddZ(-oldfloorz + thing->floorz); + thing->_f_AddZ(-oldfloorz + thing->_f_floorz()); P_CheckFakeFloorTriggers(thing, oldz); } } if (thing->player && thing->player->mo == thing) { - //thing->player->viewz += thing->Z() - oldz; + //thing->player->viewz += thing->_f_Z() - oldz; } } @@ -5850,12 +5825,12 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) { - fixed_t oldfloorz = thing->floorz; - fixed_t oldz = thing->Z(); + fixed_t oldfloorz = thing->_f_floorz(); + fixed_t oldz = thing->_f_Z(); P_AdjustFloorCeil(thing, cpos); - if (oldfloorz == thing->floorz) return; + if (oldfloorz == thing->_f_floorz()) return; // Move things intersecting the floor up if (thing->Z() <= thing->floorz) @@ -5873,7 +5848,7 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR)) { intersectors.Clear(); - thing->AddZ(-oldfloorz + thing->floorz); + thing->_f_AddZ(-oldfloorz + thing->_f_floorz()); } else return; } @@ -5888,12 +5863,12 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) break; case 2: P_DoCrunch(thing, cpos); - thing->SetZ(oldz); + thing->_f_SetZ(oldz); break; } if (thing->player && thing->player->mo == thing) { - thing->player->viewz += thing->Z() - oldz; + thing->player->viewz += thing->_f_Z() - oldz; } } @@ -5906,7 +5881,7 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos) void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) { bool onfloor; - fixed_t oldz = thing->Z(); + fixed_t oldz = thing->_f_Z(); onfloor = thing->Z() <= thing->floorz; P_AdjustFloorCeil(thing, cpos); @@ -5919,10 +5894,10 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) return; // do not move bridge things } intersectors.Clear(); - fixed_t oldz = thing->Z(); - if (thing->ceilingz - thing->height >= thing->floorz) + fixed_t oldz = thing->_f_Z(); + if (thing->ceilingz - thing->Height >= thing->floorz) { - thing->SetZ(thing->ceilingz - thing->height); + thing->SetZ(thing->ceilingz - thing->Height); } else { @@ -5945,7 +5920,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) } if (thing->player && thing->player->mo == thing) { - thing->player->viewz += thing->Z() - oldz; + thing->player->viewz += thing->_f_Z() - oldz; } } @@ -5958,22 +5933,22 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos) void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) { bool isgood = P_AdjustFloorCeil(thing, cpos); - fixed_t oldz = thing->Z(); + fixed_t oldz = thing->_f_Z(); if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things // For DOOM compatibility, only move things that are inside the floor. // (or something else?) Things marked as hanging from the ceiling will // stay where they are. - if (thing->Z() < thing->floorz && - thing->Top() >= thing->ceilingz - cpos->moveamt && + if (thing->_f_Z() < thing->_f_floorz() && + thing->_f_Top() >= thing->_f_ceilingz() - cpos->moveamt && !(thing->flags & MF_NOLIFTDROP)) { - fixed_t oldz = thing->Z(); + fixed_t oldz = thing->_f_Z(); thing->SetZ(thing->floorz); if (thing->Top() > thing->ceilingz) { - thing->SetZ(thing->ceilingz - thing->height); + thing->SetZ(thing->ceilingz - thing->Height); } P_CheckFakeFloorTriggers(thing, oldz); } @@ -5982,12 +5957,12 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos) AActor *onmobj; if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->Z() <= thing->Z()) { - thing->SetZ( MIN(thing->ceilingz - thing->height, onmobj->Top())); + thing->SetZ(MIN(thing->ceilingz - thing->Height, onmobj->Top())); } } if (thing->player && thing->player->mo == thing) { - thing->player->viewz += thing->Z() - oldz; + thing->player->viewz += thing->_f_Z() - oldz; } } @@ -6146,8 +6121,8 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool { n->visited = true; // mark thing as processed - n->m_thing->UpdateWaterLevel(n->m_thing->Z(), false); - P_CheckFakeFloorTriggers(n->m_thing, n->m_thing->Z() - amt); + n->m_thing->UpdateWaterLevel(n->m_thing->_f_Z(), false); + P_CheckFakeFloorTriggers(n->m_thing, n->m_thing->_f_Z() - amt); } } } while (n); // repeat from scratch until all things left are marked valid @@ -6367,7 +6342,7 @@ void P_CreateSecNodeList(AActor *thing, fixed_t x, fixed_t y) node = node->m_tnext; } - FBoundingBox box(thing->X(), thing->Y(), thing->radius); + FBoundingBox box(thing->_f_X(), thing->_f_Y(), thing->_f_radius()); FBlockLinesIterator it(box); line_t *ld; @@ -6392,7 +6367,7 @@ void P_CreateSecNodeList(AActor *thing, fixed_t x, fixed_t y) sector_list = P_AddSecnode(ld->frontsector, thing, sector_list); // Don't assume all lines are 2-sided, since some Things - // like MT_TFOG are allowed regardless of whether their radius takes + // like MT_TFOG are allowed regardless of whether their _f_radius() takes // them beyond an impassable linedef. // killough 3/27/98, 4/4/98: diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 2670ead2c..46a0cda5f 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -214,7 +214,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, { // We must check through the portal for the actual dropoff. // If there's no lines in the lower sections we'd never get a usable value otherwise. - open.lowfloor = back->NextLowestFloorAt(refx, refy, back->SkyBoxes[sector_t::floor]->threshold-1); + open.lowfloor = back->NextLowestFloorAt(refx, refy, FLOAT2FIXED(back->SkyBoxes[sector_t::floor]->specialf1)-1); } } else @@ -228,7 +228,7 @@ void P_LineOpening (FLineOpening &open, AActor *actor, const line_t *linedef, { // We must check through the portal for the actual dropoff. // If there's no lines in the lower sections we'd never get a usable value otherwise. - open.lowfloor = front->NextLowestFloorAt(refx, refy, front->SkyBoxes[sector_t::floor]->threshold - 1); + open.lowfloor = front->NextLowestFloorAt(refx, refy, FLOAT2FIXED(front->SkyBoxes[sector_t::floor]->specialf1) - 1); } } open.frontfloorplane = front->floorplane; @@ -351,10 +351,10 @@ void AActor::UnlinkFromWorld () bool AActor::FixMapthingPos() { - sector_t *secstart = P_PointInSectorBuggy(X(), Y()); + sector_t *secstart = P_PointInSectorBuggy(_f_X(), _f_Y()); - int blockx = GetSafeBlockX(X() - bmaporgx); - int blocky = GetSafeBlockY(Y() - bmaporgy); + int blockx = GetSafeBlockX(_f_X() - bmaporgx); + int blocky = GetSafeBlockY(_f_Y() - bmaporgy); bool success = false; if ((unsigned int)blockx < (unsigned int)bmapwidth && @@ -380,29 +380,29 @@ bool AActor::FixMapthingPos() } // Not inside the line's bounding box - if (X() + radius <= ldef->bbox[BOXLEFT] - || X() - radius >= ldef->bbox[BOXRIGHT] - || Y() + radius <= ldef->bbox[BOXBOTTOM] - || Y() - radius >= ldef->bbox[BOXTOP]) + if (_f_X() + _f_radius() <= ldef->bbox[BOXLEFT] + || _f_X() - _f_radius() >= ldef->bbox[BOXRIGHT] + || _f_Y() + _f_radius() <= ldef->bbox[BOXBOTTOM] + || _f_Y() - _f_radius() >= ldef->bbox[BOXTOP]) continue; // Get the exact distance to the line divline_t dll, dlv; - fixed_t linelen = (fixed_t)sqrt((double)ldef->dx*ldef->dx + (double)ldef->dy*ldef->dy); + fixed_t linelen = (fixed_t)g_sqrt((double)ldef->dx*ldef->dx + (double)ldef->dy*ldef->dy); P_MakeDivline(ldef, &dll); - dlv.x = X(); - dlv.y = Y(); + dlv.x = _f_X(); + dlv.y = _f_Y(); dlv.dx = FixedDiv(dll.dy, linelen); dlv.dy = -FixedDiv(dll.dx, linelen); fixed_t distance = abs(P_InterceptVector(&dlv, &dll)); - if (distance < radius) + if (distance < _f_radius()) { DPrintf("%s at (%d,%d) lies on %s line %td, distance = %f\n", - this->GetClass()->TypeName.GetChars(), X() >> FRACBITS, Y() >> FRACBITS, + this->GetClass()->TypeName.GetChars(), _f_X() >> FRACBITS, _f_Y() >> FRACBITS, ldef->dx == 0 ? "vertical" : ldef->dy == 0 ? "horizontal" : "diagonal", ldef - lines, FIXED2DBL(distance)); angle_t finean = R_PointToAngle2(0, 0, ldef->dx, ldef->dy); @@ -417,8 +417,8 @@ bool AActor::FixMapthingPos() finean >>= ANGLETOFINESHIFT; // Get the distance we have to move the object away from the wall - distance = radius - distance; - SetXY(X() + FixedMul(distance, finecosine[finean]), Y() + FixedMul(distance, finesine[finean])); + distance = _f_radius() - distance; + SetXY(_f_X() + FixedMul(distance, finecosine[finean]), _f_Y() + FixedMul(distance, finesine[finean])); ClearInterpolation(); success = true; } @@ -446,16 +446,16 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) { if (!spawningmapthing || numgamenodes == 0) { - sector = P_PointInSector(X(), Y()); + sector = P_PointInSector(_f_X(), _f_Y()); } else { - sector = P_PointInSectorBuggy(X(), Y()); + sector = P_PointInSectorBuggy(_f_X(), _f_Y()); } } Sector = sector; - subsector = R_PointInSubsector(X(), Y()); // this is from the rendering nodes, not the gameplay nodes! + subsector = R_PointInSubsector(_f_X(), _f_Y()); // this is from the rendering nodes, not the gameplay nodes! if (!(flags & MF_NOSECTOR)) { @@ -482,7 +482,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) // When a node is deleted, its sector links (the links starting // at sector_t->touching_thinglist) are broken. When a node is // added, new sector links are created. - P_CreateSecNodeList(this, X(), Y()); + P_CreateSecNodeList(this, _f_X(), _f_Y()); touching_sectorlist = sector_list; // Attach to thing sector_list = NULL; // clear for next time } @@ -493,16 +493,16 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector) { FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); - P_CollectConnectedGroups(Sector->PortalGroup, Pos(), Top(), radius, check); + P_CollectConnectedGroups(Sector->PortalGroup, _f_Pos(), _f_Top(), _f_radius(), check); for (int i = -1; i < (int)check.Size(); i++) { - fixedvec3 pos = i==-1? Pos() : PosRelative(check[i]); + fixedvec3 pos = i==-1? _f_Pos() : PosRelative(check[i]); - int x1 = GetSafeBlockX(pos.x - radius - bmaporgx); - int x2 = GetSafeBlockX(pos.x + radius - bmaporgx); - int y1 = GetSafeBlockY(pos.y - radius - bmaporgy); - int y2 = GetSafeBlockY(pos.y + radius - bmaporgy); + int x1 = GetSafeBlockX(pos.x - _f_radius() - bmaporgx); + int x2 = GetSafeBlockX(pos.x + _f_radius() - bmaporgx); + int y1 = GetSafeBlockY(pos.y - _f_radius() - bmaporgy); + int y2 = GetSafeBlockY(pos.y + _f_radius() - bmaporgy); if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0) { // thing is off the map @@ -737,9 +737,9 @@ line_t *FBlockLinesIterator::Next() FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius) : checklist(check) { - checkpoint = origin->Pos(); - if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); - checkpoint.z = checkradius == -1? origin->radius : checkradius; + checkpoint = origin->_f_Pos(); + if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist); + checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius; basegroup = origin->Sector->PortalGroup; startsector = origin->Sector; Reset(); @@ -1007,8 +1007,8 @@ AActor *FBlockThingsIterator::Next(bool centeronly) fixed_t blocktop = blockbottom + MAPBLOCKSIZE; // only return actors with the center in this block - if (me->X() >= blockleft && me->X() < blockright && - me->Y() >= blockbottom && me->Y() < blocktop) + if (me->_f_X() >= blockleft && me->_f_X() < blockright && + me->_f_Y() >= blockbottom && me->_f_Y() < blocktop) { return me; } @@ -1072,9 +1072,9 @@ AActor *FBlockThingsIterator::Next(bool centeronly) FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius, bool ignorerestricted) : checklist(check) { - checkpoint = origin->Pos(); - if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist); - checkpoint.z = checkradius == -1? origin->radius : checkradius; + checkpoint = origin->_f_Pos(); + if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist); + checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius; basegroup = origin->Sector->PortalGroup; Reset(); } @@ -1260,31 +1260,31 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it switch (i) { case 0: // Top edge - line.x = thing->X() + thing->radius; - line.y = thing->Y() + thing->radius; - line.dx = -thing->radius * 2; + line.x = thing->_f_X() + thing->_f_radius(); + line.y = thing->_f_Y() + thing->_f_radius(); + line.dx = -thing->_f_radius() * 2; line.dy = 0; break; case 1: // Right edge - line.x = thing->X() + thing->radius; - line.y = thing->Y() - thing->radius; + line.x = thing->_f_X() + thing->_f_radius(); + line.y = thing->_f_Y() - thing->_f_radius(); line.dx = 0; - line.dy = thing->radius * 2; + line.dy = thing->_f_radius() * 2; break; case 2: // Bottom edge - line.x = thing->X() - thing->radius; - line.y = thing->Y() - thing->radius; - line.dx = thing->radius * 2; + line.x = thing->_f_X() - thing->_f_radius(); + line.y = thing->_f_Y() - thing->_f_radius(); + line.dx = thing->_f_radius() * 2; line.dy = 0; break; case 3: // Left edge - line.x = thing->X() - thing->radius; - line.y = thing->Y() + thing->radius; + line.x = thing->_f_X() - thing->_f_radius(); + line.y = thing->_f_Y() + thing->_f_radius(); line.dx = 0; - line.dy = thing->radius * -2; + line.dy = thing->_f_radius() * -2; break; } // Check if this side is facing the trace origin @@ -1306,19 +1306,19 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it switch (i) { case 0: - line.y -= 2 * thing->radius; + line.y -= 2 * thing->_f_radius(); break; case 1: - line.x -= 2 * thing->radius; + line.x -= 2 * thing->_f_radius(); break; case 2: - line.y += 2 * thing->radius; + line.y += 2 * thing->_f_radius(); break; case 3: - line.x += 2 * thing->radius; + line.x += 2 * thing->_f_radius(); break; } fixed_t frac2 = P_InterceptVector(&trace, &line); @@ -1363,19 +1363,19 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it // check a corner to corner crossection for hit if (tracepositive) { - x1 = thing->X() - thing->radius; - y1 = thing->Y() + thing->radius; + x1 = thing->_f_X() - thing->_f_radius(); + y1 = thing->_f_Y() + thing->_f_radius(); - x2 = thing->X() + thing->radius; - y2 = thing->Y() - thing->radius; + x2 = thing->_f_X() + thing->_f_radius(); + y2 = thing->_f_Y() - thing->_f_radius(); } else { - x1 = thing->X() - thing->radius; - y1 = thing->Y() - thing->radius; + x1 = thing->_f_X() - thing->_f_radius(); + y1 = thing->_f_Y() - thing->_f_radius(); - x2 = thing->X() + thing->radius; - y2 = thing->Y() + thing->radius; + x2 = thing->_f_X() + thing->_f_radius(); + y2 = thing->_f_Y() + thing->_f_radius(); } s1 = P_PointOnDivlineSide (x1, y1, &trace); @@ -1725,8 +1725,8 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in int count; AActor *target; - startX = GetSafeBlockX(mo->X()-bmaporgx); - startY = GetSafeBlockY(mo->Y()-bmaporgy); + startX = GetSafeBlockX(mo->_f_X()-bmaporgx); + startY = GetSafeBlockY(mo->_f_Y()-bmaporgy); validcount++; if (startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight) diff --git a/src/p_maputl.h b/src/p_maputl.h index 6ef5aa6c8..ddfed2fa6 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -49,6 +49,20 @@ inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line) return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; } +inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line) +{ + return DMulScale32(FLOAT2FIXED(y) - line->v1->y, line->dx, line->v1->x - FLOAT2FIXED(x), line->dy) > 0; +} + +inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line) +{ + return DMulScale32(FLOAT2FIXED(pt.Y) - line->v1->y, line->dx, line->v1->x - FLOAT2FIXED(pt.X), line->dy) > 0; +} + +inline int P_PointOnLineSidePrecise(const DVector3 &pt, const line_t *line) +{ + return DMulScale32(FLOAT2FIXED(pt.Y) - line->v1->y, line->dx, line->v1->x - FLOAT2FIXED(pt.X), line->dy) > 0; +} //========================================================================== // diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 43ba4355d..4b665bf53 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -73,10 +73,10 @@ // MACROS ------------------------------------------------------------------ -#define WATER_SINK_FACTOR 3 -#define WATER_SINK_SMALL_FACTOR 4 -#define WATER_SINK_SPEED (FRACUNIT/2) -#define WATER_JUMP_SPEED (FRACUNIT*7/2) +#define WATER_SINK_FACTOR 0.125 +#define WATER_SINK_SMALL_FACTOR 0.25 +#define WATER_SINK_SPEED 0.5 +#define WATER_JUMP_SPEED 3.5 // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -221,26 +221,25 @@ static VMFunction *UncalcDamageValue(int dmg, VMFunction *def) // //========================================================================== -void AActor::Serialize (FArchive &arc) +void AActor::Serialize(FArchive &arc) { - Super::Serialize (arc); + Super::Serialize(arc); - if (arc.IsStoring ()) + if (arc.IsStoring()) { - arc.WriteSprite (sprite); + arc.WriteSprite(sprite); } else { - sprite = arc.ReadSprite (); + sprite = arc.ReadSprite(); } arc << __pos.x << __pos.y << __pos.z - << angle + << Angles.Yaw << frame - << scaleX - << scaleY + << Scale << RenderStyle << renderflags << picnum @@ -252,8 +251,8 @@ void AActor::Serialize (FArchive &arc) << effects << alpha << fillcolor - << pitch - << roll + << Angles.Pitch // move these up when savegame compatibility is broken! + << Angles.Roll // For now they have to remain here. << Sector << floorz << ceilingz @@ -261,11 +260,9 @@ void AActor::Serialize (FArchive &arc) << floorsector << ceilingsector << radius - << height + << Height << projectilepassheight - << vel.x - << vel.y - << vel.z + << Vel << tics << state; if (arc.IsStoring()) @@ -304,6 +301,8 @@ void AActor::Serialize (FArchive &arc) } arc << special1 << special2 + << specialf1 + << specialf2 << health << movedir << visdir @@ -323,7 +322,7 @@ void AActor::Serialize (FArchive &arc) } arc << skillrespawncount << tracer - << floorclip + << Floorclip << tid << special; if (P_IsACSSpecial(special)) @@ -389,7 +388,7 @@ void AActor::Serialize (FArchive &arc) << PainType << DeathType; } - arc << gravity + arc << Gravity << FastChaseStrafeCount << master << smokecounter @@ -474,7 +473,7 @@ void AActor::Serialize (FArchive &arc) } } ClearInterpolation(); - UpdateWaterLevel(Z(), false); + UpdateWaterLevel(_f_Z(), false); } } @@ -832,19 +831,17 @@ bool AActor::UseInventory (AInventory *item) AInventory *AActor::DropInventory (AInventory *item) { - angle_t an; AInventory *drop = item->CreateTossable (); if (drop == NULL) { return NULL; } - an = angle >> ANGLETOFINESHIFT; drop->SetOrigin(PosPlusZ(10*FRACUNIT), false); - drop->angle = angle; - drop->vel.x = vel.x + 5 * finecosine[an]; - drop->vel.y = vel.y + 5 * finesine[an]; - drop->vel.z = vel.z + FRACUNIT; + drop->Angles.Yaw = Angles.Yaw; + drop->VelFromAngle(5.); + drop->Vel.Z = 1.; + drop->Vel += Vel; drop->flags &= ~MF_NOGRAVITY; // Don't float drop->ClearCounters(); // do not count for statistics again return drop; @@ -1203,7 +1200,8 @@ bool AActor::Grind(bool items) { flags &= ~MF_SOLID; flags3 |= MF3_DONTGIB; - height = radius = 0; + Height = 0; + radius = 0; return false; } @@ -1229,7 +1227,8 @@ bool AActor::Grind(bool items) } flags &= ~MF_SOLID; flags3 |= MF3_DONTGIB; - height = radius = 0; + Height = 0; + radius = 0; SetState (state); if (isgeneric) // Not a custom crush state, so colorize it appropriately. { @@ -1264,7 +1263,8 @@ bool AActor::Grind(bool items) // if there's no gib sprite don't crunch it. flags &= ~MF_SOLID; flags3 |= MF3_DONTGIB; - height = radius = 0; + Height = 0; + radius = 0; return false; } @@ -1273,7 +1273,7 @@ bool AActor::Grind(bool items) { gib->RenderStyle = RenderStyle; gib->alpha = alpha; - gib->height = 0; + gib->Height = 0; gib->radius = 0; PalEntry bloodcolor = GetBloodColor(); @@ -1285,7 +1285,7 @@ bool AActor::Grind(bool items) if (flags & MF_ICECORPSE) { tics = 1; - vel.x = vel.y = vel.z = 0; + Vel.Zero(); } else if (player) { @@ -1362,7 +1362,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) return; } } - mo->vel.x = mo->vel.y = mo->vel.z = 0; + mo->Vel.Zero(); mo->effects = 0; // [RH] mo->flags &= ~MF_SHOOTABLE; @@ -1530,7 +1530,7 @@ void AActor::PlayBounceSound(bool onfloor) bool AActor::FloorBounceMissile (secplane_t &plane) { - if (Z() <= floorz && P_HitFloor (this)) + if (_f_Z() <= _f_floorz() && P_HitFloor (this)) { // Landed in some sort of liquid if (BounceFlags & BOUNCE_ExplodeOnWater) @@ -1569,14 +1569,12 @@ bool AActor::FloorBounceMissile (secplane_t &plane) return true; } - fixed_t dot = TMulScale16 (vel.x, plane.a, vel.y, plane.b, vel.z, plane.c); + double dot = (Vel | plane.Normal()) * 2; if (BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) { - vel.x -= MulScale15 (plane.a, dot); - vel.y -= MulScale15 (plane.b, dot); - vel.z -= MulScale15 (plane.c, dot); - angle = R_PointToAngle2 (0, 0, vel.x, vel.y); + Vel -= plane.Normal() * dot; + AngleFromVel(); if (!(BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. { flags |= MF_INBOUNCE; @@ -1584,15 +1582,13 @@ bool AActor::FloorBounceMissile (secplane_t &plane) flags &= ~MF_INBOUNCE; return false; } - else vel.z = FixedMul(vel.z, bouncefactor); + else Vel.Z *= _bouncefactor(); } else // Don't run through this for MBF-style bounces { // The reflected velocity keeps only about 70% of its original speed - vel.x = FixedMul (vel.x - MulScale15 (plane.a, dot), bouncefactor); - vel.y = FixedMul (vel.y - MulScale15 (plane.b, dot), bouncefactor); - vel.z = FixedMul (vel.z - MulScale15 (plane.c, dot), bouncefactor); - angle = R_PointToAngle2 (0, 0, vel.x, vel.y); + Vel = (Vel - plane.Normal() * dot) * _bouncefactor(); + AngleFromVel(); } PlayBounceSound(true); @@ -1614,34 +1610,21 @@ bool AActor::FloorBounceMissile (secplane_t &plane) if (BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed { - if (abs(vel.z) < (fixed_t)(Mass * GetGravity() / 64)) - vel.z = 0; + if (fabs(Vel.Z) < Mass * GetGravity() / 64) + Vel.Z = 0; } else if (BounceFlags & (BOUNCE_AutoOff|BOUNCE_AutoOffFloorOnly)) { if (plane.c > 0 || (BounceFlags & BOUNCE_AutoOff)) { // AutoOff only works when bouncing off a floor, not a ceiling (or in compatibility mode.) - if (!(flags & MF_NOGRAVITY) && (vel.z < 3*FRACUNIT)) + if (!(flags & MF_NOGRAVITY) && (Vel.Z < 3)) BounceFlags &= ~BOUNCE_TypeMask; } } return false; } -//---------------------------------------------------------------------------- -// -// PROC P_ThrustMobj -// -//---------------------------------------------------------------------------- - -void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move) -{ - angle >>= ANGLETOFINESHIFT; - mo->vel.x += FixedMul (move, finecosine[angle]); - mo->vel.y += FixedMul (move, finesine[angle]); -} - //---------------------------------------------------------------------------- // // FUNC P_FaceMobj @@ -1652,41 +1635,20 @@ void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move) // //---------------------------------------------------------------------------- -int P_FaceMobj (AActor *source, AActor *target, angle_t *delta) +int P_FaceMobj (AActor *source, AActor *target, DAngle *delta) { - angle_t diff; - angle_t angle1; - angle_t angle2; + DAngle diff; - angle1 = source->angle; - angle2 = source->AngleTo(target); - if (angle2 > angle1) + diff = deltaangle(source->Angles.Yaw, source->AngleTo(target)); + if (diff > 0) { - diff = angle2 - angle1; - if (diff > ANGLE_180) - { - *delta = ANGLE_MAX - diff; - return 0; - } - else - { - *delta = diff; - return 1; - } + *delta = diff; + return 1; } else { - diff = angle1 - angle2; - if (diff > ANGLE_180) - { - *delta = ANGLE_MAX - diff; - return 1; - } - else - { - *delta = diff; - return 0; - } + *delta = -diff; + return 0; } } @@ -1719,16 +1681,17 @@ bool AActor::CanSeek(AActor *target) const // //---------------------------------------------------------------------------- -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise, bool usecurspeed) +bool P_SeekerMissile (AActor *actor, angle_t _thresh, angle_t _turnMax, bool precise, bool usecurspeed) { - int dir; - int dist; - angle_t delta; - angle_t angle; - AActor *target; - fixed_t speed; + DAngle thresh = ANGLE2DBL(_thresh); + DAngle turnMax = ANGLE2DBL(_turnMax); - speed = !usecurspeed ? actor->Speed : xs_CRoundToInt(DVector3(actor->vel.x, actor->vel.y, actor->vel.z).Length()); + int dir; + DAngle delta; + AActor *target; + double speed; + + speed = !usecurspeed ? actor->Speed : actor->VelToSpeed(); target = actor->tracer; if (target == NULL || !actor->CanSeek(target)) { @@ -1746,7 +1709,7 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci dir = P_FaceMobj (actor, target, &delta); if (delta > thresh) { - delta >>= 1; + delta /= 2; if (delta > turnMax) { delta = turnMax; @@ -1754,54 +1717,41 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci } if (dir) { // Turn clockwise - actor->angle += delta; + actor->Angles.Yaw += delta; } else { // Turn counter clockwise - actor->angle -= delta; + actor->Angles.Yaw -= delta; } - angle = actor->angle>>ANGLETOFINESHIFT; if (!precise) { - actor->vel.x = FixedMul (speed, finecosine[angle]); - actor->vel.y = FixedMul (speed, finesine[angle]); + actor->VelFromAngle(speed); if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { if (actor->Top() < target->Z() || target->Top() < actor->Z()) { // Need to seek vertically - dist = actor->AproxDistance (target) / speed; - if (dist < 1) - { - dist = 1; - } - actor->vel.z = ((target->Z() + target->height / 2) - (actor->Z() + actor->height / 2)) / dist; + actor->Vel.Z = (target->Center() - actor->Center()) / actor->DistanceBySpeed(target, speed); } } } else { - angle_t pitch = 0; + DAngle pitch = 0.; if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { // Need to seek vertically - fixedvec2 vec = actor->Vec2To(target); - double dist = MAX(1.0, DVector2(vec.x, vec.y).Length()); + fixed_t dist = MAX(1, FLOAT2FIXED(actor->Distance2D(target))); // Aim at a player's eyes and at the middle of the actor for everything else. - fixed_t aimheight = target->height/2; + fixed_t aimheight = target->_f_height()/2; if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn))) { aimheight = static_cast(target)->ViewHeight; } - pitch = R_PointToAngle2(0, actor->Z() + actor->height/2, xs_CRoundToInt(dist), target->Z() + aimheight); - pitch >>= ANGLETOFINESHIFT; + pitch = ANGLE2DBL(R_PointToAngle2(0, actor->_f_Z() + actor->_f_height()/2, dist, target->_f_Z() + aimheight)); } - - fixed_t xyscale = FixedMul(speed, finecosine[pitch]); - actor->vel.z = FixedMul(speed, finesine[pitch]); - actor->vel.x = FixedMul(xyscale, finecosine[angle]); - actor->vel.y = FixedMul(xyscale, finesine[angle]); + actor->Vel3DFromAngle(pitch, speed); } return true; @@ -1813,25 +1763,25 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci // // Returns the actor's old floorz. // -#define STOPSPEED 0x1000 -#define CARRYSTOPSPEED (STOPSPEED*32/3) +#define STOPSPEED (0x1000/65536.) +#define CARRYSTOPSPEED (0x1000*32/3) fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { static int pushtime = 0; bool bForceSlide = scrollx || scrolly; - angle_t angle; + DAngle Angle; fixed_t ptryx, ptryy; player_t *player; fixed_t xmove, ymove; const secplane_t * walkplane; - static const int windTab[3] = {2048*5, 2048*10, 2048*25}; + static const double windTab[3] = { 5 / 32., 10 / 32., 25 / 32. }; int steps, step, totalsteps; fixed_t startx, starty; - fixed_t oldfloorz = mo->floorz; - fixed_t oldz = mo->Z(); + fixed_t oldfloorz = mo->_f_floorz(); + fixed_t oldz = mo->_f_Z(); - fixed_t maxmove = (mo->waterlevel < 1) || (mo->flags & MF_MISSILE) || + double maxmove = (mo->waterlevel < 1) || (mo->flags & MF_MISSILE) || (mo->player && mo->player->crouchoffset<-10*FRACUNIT) ? MAXMOVE : MAXMOVE/4; if (mo->flags2 & MF2_WINDTHRUST && mo->waterlevel < 2 && !(mo->flags & MF_NOCLIP)) @@ -1840,16 +1790,16 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) switch (special) { case 40: case 41: case 42: // Wind_East - P_ThrustMobj (mo, 0, windTab[special-40]); + mo->Thrust(0., windTab[special-40]); break; case 43: case 44: case 45: // Wind_North - P_ThrustMobj (mo, ANG90, windTab[special-43]); + mo->Thrust(90., windTab[special-43]); break; case 46: case 47: case 48: // Wind_South - P_ThrustMobj (mo, ANG270, windTab[special-46]); + mo->Thrust(270., windTab[special-46]); break; case 49: case 50: case 51: // Wind_West - P_ThrustMobj (mo, ANG180, windTab[special-49]); + mo->Thrust(180., windTab[special-49]); break; } } @@ -1859,24 +1809,18 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // running depends on the player's original movement continuing even after // it gets blocked. if ((mo->player != NULL && (i_compatflags & COMPATF_WALLRUN)) || (mo->waterlevel >= 1) || - (mo->player != NULL && mo->player->crouchfactor < FRACUNIT*3/4)) + (mo->player != NULL && mo->player->crouchfactor < 0.75)) { // preserve the direction instead of clamping x and y independently. - xmove = clamp (mo->vel.x, -maxmove, maxmove); - ymove = clamp (mo->vel.y, -maxmove, maxmove); + double cx = mo->Vel.X == 0 ? 1. : clamp(mo->Vel.X, -maxmove, maxmove) / mo->Vel.X; + double cy = mo->Vel.Y == 0 ? 1. : clamp(mo->Vel.Y, -maxmove, maxmove) / mo->Vel.Y; + double fac = MIN(cx, cy); - fixed_t xfac = FixedDiv(xmove, mo->vel.x); - fixed_t yfac = FixedDiv(ymove, mo->vel.y); - fixed_t fac = MIN(xfac, yfac); - - xmove = mo->vel.x = FixedMul(mo->vel.x, fac); - ymove = mo->vel.y = FixedMul(mo->vel.y, fac); - } - else - { - xmove = mo->vel.x; - ymove = mo->vel.y; + mo->Vel.X *= fac; + mo->Vel.Y *= fac; } + xmove = mo->_f_velx(); + ymove = mo->_f_vely(); // [RH] Carrying sectors didn't work with low speeds in BOOM. This is // because BOOM relied on the speed being fast enough to accumulate // despite friction. If the speed is too low, then its movement will get @@ -1884,14 +1828,14 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) mo->flags4 &= ~MF4_SCROLLMOVE; if (abs(scrollx) > CARRYSTOPSPEED) { - scrollx = FixedMul (scrollx, CARRYFACTOR); - mo->vel.x += scrollx; + scrollx = FixedMul (scrollx, _f_CARRYFACTOR); + mo->Vel.X += FIXED2DBL(scrollx); mo->flags4 |= MF4_SCROLLMOVE; } if (abs(scrolly) > CARRYSTOPSPEED) { - scrolly = FixedMul (scrolly, CARRYFACTOR); - mo->vel.y += scrolly; + scrolly = FixedMul (scrolly, _f_CARRYFACTOR); + mo->Vel.Y += FIXED2DBL(scrolly); mo->flags4 |= MF4_SCROLLMOVE; } xmove += scrollx; @@ -1903,7 +1847,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { // the skull slammed into something mo->flags &= ~MF_SKULLFLY; - mo->vel.x = mo->vel.y = mo->vel.z = 0; + mo->Vel.Zero(); if (!(mo->flags2 & MF2_DORMANT)) { if (mo->SeeState != NULL) mo->SetState (mo->SeeState); @@ -1932,11 +1876,11 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // through the actor. { - maxmove = mo->radius - FRACUNIT; + fixed_t maxmove = mo->_f_radius() - FRACUNIT; if (maxmove <= 0) - { // gibs can have radius 0, so don't divide by zero below! - maxmove = MAXMOVE; + { // gibs can have _f_radius() 0, so don't divide by zero below! + maxmove = _f_MAXMOVE; } const fixed_t xspeed = abs (xmove); @@ -1965,8 +1909,8 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) fixed_t onestepx = startxmove / steps; fixed_t onestepy = startymove / steps; - startx = mo->X(); - starty = mo->Y(); + startx = mo->_f_X(); + starty = mo->_f_Y(); step = 1; totalsteps = steps; @@ -1983,7 +1927,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) FCheckPosition tm(!!(mo->flags2 & MF2_RIP)); - angle_t oldangle = mo->angle; + angle_t oldangle = mo->_f_angle(); do { if (i_compatflags & COMPATF_WALLRUN) pushtime++; @@ -1997,7 +1941,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) */ // [RH] If walking on a slope, stay on the slope // killough 3/15/98: Allow objects to drop off - fixed_t startvelx = mo->vel.x, startvely = mo->vel.y; + fixed_t startvelx = mo->_f_velx(), startvely = mo->_f_vely(); if (!P_TryMove (mo, ptryx, ptryy, true, walkplane, tm)) { @@ -2020,11 +1964,11 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) (mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove) && mo->BlockingLine->sidedef[1] != NULL) { - mo->vel.z = WATER_JUMP_SPEED; + mo->Vel.Z = WATER_JUMP_SPEED; } // If the blocked move executed any push specials that changed the // actor's velocity, do not attempt to slide. - if (mo->vel.x == startvelx && mo->vel.y == startvely) + if (mo->_f_velx() == startvelx && mo->_f_vely() == startvely) { if (player && (i_compatflags & COMPATF_WALLRUN)) { @@ -2032,13 +1976,13 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // If the move is done a second time (because it was too fast for one move), it // is still clipped against the wall at its full speed, so you effectively // execute two moves in one tic. - P_SlideMove (mo, mo->vel.x, mo->vel.y, 1); + P_SlideMove (mo, mo->_f_velx(), mo->_f_vely(), 1); } else { P_SlideMove (mo, onestepx, onestepy, totalsteps); } - if ((mo->vel.x | mo->vel.y) == 0) + if ((mo->_f_velx() | mo->_f_vely()) == 0) { steps = 0; } @@ -2046,14 +1990,14 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { if (!player || !(i_compatflags & COMPATF_WALLRUN)) { - xmove = mo->vel.x; - ymove = mo->vel.y; + xmove = mo->_f_velx(); + ymove = mo->_f_vely(); onestepx = xmove / steps; onestepy = ymove / steps; P_CheckSlopeWalk (mo, xmove, ymove); } - startx = mo->X() - Scale (xmove, step, steps); - starty = mo->Y() - Scale (ymove, step, steps); + startx = mo->_f_X() - Scale (xmove, step, steps); + starty = mo->_f_Y() - Scale (ymove, step, steps); } } else @@ -2066,29 +2010,29 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) fixed_t tx, ty; tx = 0, ty = onestepy; walkplane = P_CheckSlopeWalk (mo, tx, ty); - if (P_TryMove (mo, mo->X() + tx, mo->Y() + ty, true, walkplane, tm)) + if (P_TryMove (mo, mo->_f_X() + tx, mo->_f_Y() + ty, true, walkplane, tm)) { - mo->vel.x = 0; + mo->Vel.X = 0; } else { tx = onestepx, ty = 0; walkplane = P_CheckSlopeWalk (mo, tx, ty); - if (P_TryMove (mo, mo->X() + tx, mo->Y() + ty, true, walkplane, tm)) + if (P_TryMove (mo, mo->_f_X() + tx, mo->_f_Y() + ty, true, walkplane, tm)) { - mo->vel.y = 0; + mo->Vel.Y = 0; } else { - mo->vel.x = mo->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; } } if (player && player->mo == mo) { - if (mo->vel.x == 0) - player->vel.x = 0; - if (mo->vel.y == 0) - player->vel.y = 0; + if (mo->Vel.X == 0) + player->Vel.X = 0; + if (mo->Vel.Y == 0) + player->Vel.Y = 0; } steps = 0; } @@ -2123,7 +2067,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) // Don't change the angle if there's THRUREFLECT on the monster. if (!(BlockingMobj->flags7 & MF7_THRUREFLECT)) { - angle = BlockingMobj->AngleTo(mo); + DAngle angle = BlockingMobj->AngleTo(mo); bool dontReflect = (mo->AdjustReflectionAngle(BlockingMobj, angle)); // Change angle for deflection/reflection @@ -2135,32 +2079,23 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { AActor *origin = tg ? mo->target : BlockingMobj->target; - float speed = (float)(mo->Speed); //dest->x - source->x - fixedvec3 vect = mo->Vec3To(origin); - vect.z += origin->height / 2; - DVector3 velocity(vect.x, vect.y, vect.z); - velocity.Resize(speed); - mo->vel.x = (fixed_t)(velocity.X); - mo->vel.y = (fixed_t)(velocity.Y); - mo->vel.z = (fixed_t)(velocity.Z); + DVector3 vect = mo->Vec3To(origin); + vect.Z += origin->Height / 2; + mo->Vel = vect.Resized(mo->Speed); } else { if ((BlockingMobj->flags7 & MF7_MIRRORREFLECT) && (tg | blockingtg)) { - mo->angle += ANGLE_180; - mo->vel.x = -mo->vel.x / 2; - mo->vel.y = -mo->vel.y / 2; - mo->vel.z = -mo->vel.z / 2; + mo->Angles.Yaw += 180.; + mo->Vel *= -.5; } else { - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->vel.x = FixedMul(mo->Speed >> 1, finecosine[angle]); - mo->vel.y = FixedMul(mo->Speed >> 1, finesine[angle]); - mo->vel.z = -mo->vel.z / 2; + mo->Angles.Yaw = angle; + mo->VelFromAngle(mo->Speed / 2); + mo->Vel.Z *= -.5; } } } @@ -2183,7 +2118,7 @@ explode: if (tm.ceilingline && tm.ceilingline->backsector && tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum && - mo->Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(mo->PosRelative(tm.ceilingline))) + mo->_f_Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(mo->PosRelative(tm.ceilingline))) { // Hack to prevent missiles exploding against the sky. // Does not handle sky floors. @@ -2202,25 +2137,25 @@ explode: } else { - mo->vel.x = mo->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; steps = 0; } } else { - if (mo->X() != ptryx || mo->Y() != ptryy) + if (mo->_f_X() != ptryx || mo->_f_Y() != ptryy) { // If the new position does not match the desired position, the player // must have gone through a teleporter, so stop moving right now if it // was a regular teleporter. If it was a line-to-line or fogless teleporter, // the move should continue, but startx, starty and xmove, ymove need to change. - if (mo->vel.x == 0 && mo->vel.y == 0) + if (mo->Vel.X == 0 && mo->Vel.Y == 0) { step = steps; } else { - angle_t anglediff = (mo->angle - oldangle) >> ANGLETOFINESHIFT; + angle_t anglediff = (mo->_f_angle() - oldangle) >> ANGLETOFINESHIFT; if (anglediff != 0) { @@ -2229,11 +2164,11 @@ explode: xmove = xnew; ymove = ynew; - oldangle = mo->angle; // in case more moves are needed this needs to be updated. + oldangle = mo->_f_angle(); // in case more moves are needed this needs to be updated. } - startx = mo->X() - Scale (xmove, step, steps); - starty = mo->Y() - Scale (ymove, step, steps); + startx = mo->_f_X() - Scale (xmove, step, steps); + starty = mo->_f_Y() - Scale (ymove, step, steps); } } } @@ -2243,8 +2178,8 @@ explode: if (player && player->mo == mo && player->cheats & CF_NOVELOCITY) { // debug option for no sliding at all - mo->vel.x = mo->vel.y = 0; - player->vel.x = player->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; + player->Vel.X = player->Vel.Y = 0; return oldfloorz; } @@ -2258,15 +2193,15 @@ explode: (!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) && !mo->waterlevel) { // [RH] Friction when falling is available for larger aircontrols - if (player != NULL && level.airfriction != FRACUNIT) + if (player != NULL && level.airfriction != 1.) { - mo->vel.x = FixedMul (mo->vel.x, level.airfriction); - mo->vel.y = FixedMul (mo->vel.y, level.airfriction); + mo->Vel.X *= level.airfriction; + mo->Vel.Y *= level.airfriction; if (player->mo == mo) // Not voodoo dolls { - player->vel.x = FixedMul (player->vel.x, level.airfriction); - player->vel.y = FixedMul (player->vel.y, level.airfriction); + player->Vel.X *= level.airfriction; + player->Vel.Y *= level.airfriction; } } return oldfloorz; @@ -2275,13 +2210,13 @@ explode: // killough 8/11/98: add bouncers // killough 9/15/98: add objects falling off ledges // killough 11/98: only include bouncers hanging off ledges - if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->Z() > mo->dropoffz) || (mo->flags6 & MF6_FALLING)) + if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->_f_Z() > mo->dropoffz) || (mo->flags6 & MF6_FALLING)) { // Don't stop sliding if halfway off a step with some velocity - if (mo->vel.x > FRACUNIT/4 || mo->vel.x < -FRACUNIT/4 || mo->vel.y > FRACUNIT/4 || mo->vel.y < -FRACUNIT/4) + if (mo->_f_velx() > FRACUNIT/4 || mo->_f_velx() < -FRACUNIT/4 || mo->_f_vely() > FRACUNIT/4 || mo->_f_vely() < -FRACUNIT/4) { - if (mo->floorz > mo->Sector->floorplane.ZatPoint(mo)) + if (mo->_f_floorz() > mo->Sector->floorplane.ZatPoint(mo)) { - if (mo->dropoffz != mo->floorz) // 3DMidtex or other special cases that must be excluded + if (mo->dropoffz != mo->_f_floorz()) // 3DMidtex or other special cases that must be excluded { unsigned i; for(i=0;iSector->e->XFloor.ffloors.Size();i++) @@ -2290,7 +2225,7 @@ explode: // if the floor comes from one in the current sector stop sliding the corpse! F3DFloor * rover=mo->Sector->e->XFloor.ffloors[i]; if (!(rover->flags&FF_EXISTS)) continue; - if (rover->flags&FF_SOLID && rover->top.plane->ZatPoint(mo) == mo->floorz) break; + if (rover->flags&FF_SOLID && rover->top.plane->ZatPoint(mo) == mo->_f_floorz()) break; } if (i==mo->Sector->e->XFloor.ffloors.Size()) return oldfloorz; @@ -2302,8 +2237,7 @@ explode: // killough 11/98: // Stop voodoo dolls that have come to rest, despite any // moving corresponding player: - if (mo->vel.x > -STOPSPEED && mo->vel.x < STOPSPEED - && mo->vel.y > -STOPSPEED && mo->vel.y < STOPSPEED + if (fabs(mo->Vel.X) < STOPSPEED && fabs(mo->Vel.Y) < STOPSPEED && (!player || (player->mo != mo) || !(player->cmd.ucmd.forwardmove | player->cmd.ucmd.sidemove))) { @@ -2315,12 +2249,12 @@ explode: player->mo->PlayIdle (); } - mo->vel.x = mo->vel.y = 0; + mo->Vel.X = mo->Vel.Y = 0; mo->flags4 &= ~MF4_SCROLLMOVE; // killough 10/98: kill any bobbing velocity too (except in voodoo dolls) if (player && player->mo == mo) - player->vel.x = player->vel.y = 0; + player->Vel.X = player->Vel.Y = 0; } else { @@ -2337,10 +2271,10 @@ explode: // Reducing player velocity is no longer needed to reduce // bobbing, so ice works much better now. - fixed_t friction = P_GetFriction (mo, NULL); + double friction = FIXED2DBL(P_GetFriction (mo, NULL)); - mo->vel.x = FixedMul (mo->vel.x, friction); - mo->vel.y = FixedMul (mo->vel.y, friction); + mo->Vel.X *= friction; + mo->Vel.Y *= friction; // killough 10/98: Always decrease player bobbing by ORIG_FRICTION. // This prevents problems with bobbing on ice, where it was not being @@ -2348,8 +2282,17 @@ explode: if (player && player->mo == mo) // Not voodoo dolls { - player->vel.x = FixedMul (player->vel.x, ORIG_FRICTION); - player->vel.y = FixedMul (player->vel.y, ORIG_FRICTION); + player->Vel.X *= fORIG_FRICTION; + player->Vel.Y *= fORIG_FRICTION; + } + + // Don't let the velocity become less than the smallest representable fixed point value. + if (fabs(mo->Vel.X) < MinVel) mo->Vel.X = 0; + if (fabs(mo->Vel.Y) < MinVel) mo->Vel.Y = 0; + if (player && player->mo == mo) // Not voodoo dolls + { + if (fabs(player->Vel.X) < MinVel) player->Vel.X = 0; + if (fabs(player->Vel.Y) < MinVel) player->Vel.Y = 0; } } return oldfloorz; @@ -2366,7 +2309,7 @@ void P_MonsterFallingDamage (AActor *mo) if (mo->floorsector->Flags & SECF_NOFALLINGDAMAGE) return; - vel = abs(mo->vel.z); + vel = abs(mo->_f_velz()); if (vel > 35*FRACUNIT) { // automatic death damage = TELEFRAG_DAMAGE; @@ -2387,46 +2330,46 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { fixed_t dist; fixed_t delta; - fixed_t oldz = mo->Z(); - fixed_t grav = mo->GetGravity(); + fixed_t oldz = mo->_f_Z(); + double grav = mo->GetGravity(); // // check for smooth step up // if (mo->player && mo->player->mo == mo && mo->Z() < mo->floorz) { - mo->player->viewheight -= mo->floorz - mo->Z(); + mo->player->viewheight -= mo->_f_floorz() - mo->_f_Z(); mo->player->deltaviewheight = mo->player->GetDeltaViewHeight(); } - mo->AddZ(mo->vel.z); + mo->AddZ(mo->Vel.Z); // // apply gravity // if (mo->Z() > mo->floorz && !(mo->flags & MF_NOGRAVITY)) { - fixed_t startvelz = mo->vel.z; + double startvelz = mo->Vel.Z; if (mo->waterlevel == 0 || (mo->player && !(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove))) { // [RH] Double gravity only if running off a ledge. Coming down from // an upward thrust (e.g. a jump) should not double it. - if (mo->vel.z == 0 && oldfloorz > mo->floorz && mo->Z() == oldfloorz) + if (mo->Vel.Z == 0 && oldfloorz > mo->_f_floorz() && mo->_f_Z() == oldfloorz) { - mo->vel.z -= grav + grav; + mo->Vel.Z -= grav + grav; } else { - mo->vel.z -= grav; + mo->Vel.Z -= grav; } } if (mo->player == NULL) { if (mo->waterlevel >= 1) { - fixed_t sinkspeed; + double sinkspeed; if ((mo->flags & MF_SPECIAL) && !(mo->flags3 & MF3_ISMONSTER)) { // Pickup items don't sink if placed and drop slowly if dropped @@ -2440,23 +2383,23 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // 100 being equivalent to a player. if (mo->player == NULL) { - sinkspeed = Scale(sinkspeed, clamp(mo->Mass, 1, 4000), 100); + sinkspeed = sinkspeed * clamp(mo->Mass, 1, 4000) / 100; } } - if (mo->vel.z < sinkspeed) + if (mo->Vel.Z < sinkspeed) { // Dropping too fast, so slow down toward sinkspeed. - mo->vel.z -= MAX(sinkspeed*2, -FRACUNIT*8); - if (mo->vel.z > sinkspeed) + mo->Vel.Z -= MAX(sinkspeed*2, -8.); + if (mo->Vel.Z > sinkspeed) { - mo->vel.z = sinkspeed; + mo->Vel.Z = sinkspeed; } } - else if (mo->vel.z > sinkspeed) + else if (mo->Vel.Z > sinkspeed) { // Dropping too slow/going up, so trend toward sinkspeed. - mo->vel.z = startvelz + MAX(sinkspeed/3, -FRACUNIT*8); - if (mo->vel.z < sinkspeed) + mo->Vel.Z = startvelz + MAX(sinkspeed/3, -8.); + if (mo->Vel.Z < sinkspeed) { - mo->vel.z = sinkspeed; + mo->Vel.Z = sinkspeed; } } } @@ -2465,15 +2408,15 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { if (mo->waterlevel > 1) { - fixed_t sinkspeed = -WATER_SINK_SPEED; + double sinkspeed = -WATER_SINK_SPEED; - if (mo->vel.z < sinkspeed) + if (mo->Vel.Z < sinkspeed) { - mo->vel.z = (startvelz < sinkspeed) ? startvelz : sinkspeed; + mo->Vel.Z = (startvelz < sinkspeed) ? startvelz : sinkspeed; } else { - mo->vel.z = startvelz + ((mo->vel.z - startvelz) >> + mo->Vel.Z = startvelz + ((mo->Vel.Z - startvelz) * (mo->waterlevel == 1 ? WATER_SINK_SMALL_FACTOR : WATER_SINK_FACTOR)); } } @@ -2484,9 +2427,9 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // Hexen yanked all items to the floor, except those being spawned at map start in the air. // Those were kept at their original height. // Do this only if the item was actually spawned by the map above ground to avoid problems. - if (mo->special1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) + if (mo->specialf1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) { - mo->SetZ(mo->floorz + mo->special1); + mo->SetZ(mo->floorz + mo->specialf1); } @@ -2498,24 +2441,42 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) if (!(mo->flags & (MF_SKULLFLY | MF_INFLOAT))) { dist = mo->AproxDistance (mo->target); - delta = (mo->target->Z() + (mo->height>>1)) - mo->Z(); + delta = (mo->target->_f_Z() + (mo->_f_height()>>1)) - mo->_f_Z(); if (delta < 0 && dist < -(delta*3)) - mo->AddZ(-mo->FloatSpeed); + mo->_f_AddZ(-mo->_f_floatspeed()); else if (delta > 0 && dist < (delta*3)) - mo->AddZ(mo->FloatSpeed); + mo->_f_AddZ(mo->_f_floatspeed()); } } if (mo->player && (mo->flags & MF_NOGRAVITY) && (mo->Z() > mo->floorz)) { if (!mo->IsNoClip2()) { - mo->AddZ(finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8); + mo->_f_AddZ(finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8); } - mo->vel.z = FixedMul (mo->vel.z, FRICTION_FLY); + mo->Vel.Z *= fFRICTION_FLY; } if (mo->waterlevel && !(mo->flags & MF_NOGRAVITY)) { - mo->vel.z = FixedMul (mo->vel.z, mo->Sector->friction); + fixed_t friction = FIXED_MIN; + + // Check 3D floors -- might be the source of the waterlevel + for (auto rover : mo->Sector->e->XFloor.ffloors) + { + if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_SWIMMABLE)) continue; + + if (mo->_f_Z() >= rover->top.plane->ZatPoint(mo) || + mo->_f_Z() + mo->_f_height()/2 < rover->bottom.plane->ZatPoint(mo)) + continue; + + friction = rover->model->GetFriction(rover->top.isceiling); + break; + } + if (friction == FIXED_MIN) + friction = mo->Sector->GetFriction(); // get real friction, even if from a terrain definition + + mo->Vel.Z *= FIXED2DBL(friction); } // @@ -2525,7 +2486,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { // Hit the floor if ((!mo->player || !(mo->player->cheats & CF_PREDICTING)) && mo->Sector->SecActTarget != NULL && - mo->Sector->floorplane.ZatPoint(mo) == mo->floorz) + mo->Sector->floorplane.ZatPoint(mo) == mo->_f_floorz()) { // [RH] Let the sector do something to the actor mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitFloor); } @@ -2545,7 +2506,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) else if (mo->flags3 & MF3_NOEXPLODEFLOOR) { P_HitFloor (mo); - mo->vel.z = 0; + mo->Vel.Z = 0; return; } else if (mo->flags3 & MF3_FLOORHUGGER) @@ -2566,41 +2527,39 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) return; } } - else if (mo->BounceFlags & BOUNCE_MBF && mo->vel.z) // check for MBF-like bounce on non-missiles + else if (mo->BounceFlags & BOUNCE_MBF && mo->_f_velz()) // check for MBF-like bounce on non-missiles { mo->FloorBounceMissile(mo->floorsector->floorplane); } if (mo->flags3 & MF3_ISMONSTER) // Blasted mobj falling { - if (mo->vel.z < -(23*FRACUNIT)) + if (mo->_f_velz() < -(23*FRACUNIT)) { P_MonsterFallingDamage (mo); } } mo->SetZ(mo->floorz); - if (mo->vel.z < 0) + if (mo->_f_velz() < 0) { const fixed_t minvel = -8*FRACUNIT; // landing speed from a jump with normal gravity // Spawn splashes, etc. P_HitFloor (mo); - if (mo->DamageType == NAME_Ice && mo->vel.z < minvel) + if (mo->DamageType == NAME_Ice && mo->_f_velz() < minvel) { mo->tics = 1; - mo->vel.x = 0; - mo->vel.y = 0; - mo->vel.z = 0; + mo->Vel.Zero(); return; } // Let the actor do something special for hitting the floor mo->HitFloor (); if (mo->player) { - if (mo->player->jumpTics < 0 || mo->vel.z < minvel) + if (mo->player->jumpTics < 0 || mo->_f_velz() < minvel) { // delay any jumping for a short while mo->player->jumpTics = 7; } - if (mo->vel.z < minvel && !(mo->flags & MF_NOGRAVITY)) + if (mo->_f_velz() < minvel && !(mo->flags & MF_NOGRAVITY)) { // Squat down. // Decrease viewheight for a moment after hitting the ground (hard), @@ -2608,11 +2567,11 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) PlayerLandedOnThing (mo, NULL); } } - mo->vel.z = 0; + mo->Vel.Z = 0; } if (mo->flags & MF_SKULLFLY) { // The skull slammed into something - mo->vel.z = -mo->vel.z; + mo->Vel.Z = -mo->Vel.Z; } mo->Crash(); } @@ -2627,7 +2586,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { // hit the ceiling if ((!mo->player || !(mo->player->cheats & CF_PREDICTING)) && mo->Sector->SecActTarget != NULL && - mo->Sector->ceilingplane.ZatPoint(mo) == mo->ceilingz) + mo->Sector->ceilingplane.ZatPoint(mo) == mo->_f_ceilingz()) { // [RH] Let the sector do something to the actor mo->Sector->SecActTarget->TriggerAction (mo, SECSPAC_HitCeiling); } @@ -2636,7 +2595,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // teleported the actor so it is no longer above the ceiling. if (mo->Top() > mo->ceilingz) { - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz - mo->Height); if (mo->BounceFlags & BOUNCE_Ceilings) { // ceiling bounce mo->FloorBounceMissile (mo->ceilingsector->ceilingplane); @@ -2644,10 +2603,10 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) } if (mo->flags & MF_SKULLFLY) { // the skull slammed into something - mo->vel.z = -mo->vel.z; + mo->Vel.Z = -mo->Vel.Z; } - if (mo->vel.z > 0) - mo->vel.z = 0; + if (mo->Vel.Z > 0) + mo->Vel.Z = 0; if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP)) { if (mo->flags3 & MF3_CEILINGHUGGER) @@ -2692,15 +2651,15 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheigh } else { - viewheight = mo->height / 2; + viewheight = mo->_f_height() / 2; } - if (oldz > waterz && mo->Z() <= waterz) + if (oldz > waterz && mo->_f_Z() <= waterz) { // Feet hit fake floor sec->SecActTarget->TriggerAction (mo, SECSPAC_HitFakeFloor); } - newz = mo->Z() + viewheight; + newz = mo->_f_Z() + viewheight; if (!oldz_has_viewheight) { oldz += viewheight; @@ -2745,7 +2704,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) if (mo->player->mo == mo) { - mo->player->deltaviewheight = mo->vel.z >> 3; + mo->player->deltaviewheight = mo->_f_velz() >> 3; } if (mo->player->cheats & CF_PREDICTING) @@ -2758,7 +2717,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) { grunted = false; // Why should this number vary by gravity? - if (mo->health > 0 && mo->vel.z < -mo->player->mo->GruntSpeed) + if (mo->health > 0 && mo->_f_velz() < -mo->player->mo->GruntSpeed) { S_Sound (mo, CHAN_VOICE, "*grunt", 1, ATTN_NORM); grunted = true; @@ -2802,7 +2761,7 @@ void P_NightmareRespawn (AActor *mobj) if (z == ONFLOORZ) { - mo->AddZ(mobj->SpawnPoint[2]); + mo->_f_AddZ(mobj->SpawnPoint[2]); if (mo->Z() < mo->floorz) { // Do not respawn monsters in the floor, even if that's where they // started. The initial P_ZMovement() call would have put them on @@ -2812,12 +2771,12 @@ void P_NightmareRespawn (AActor *mobj) } if (mo->Top() > mo->ceilingz) { - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz- mo->Height); } } else if (z == ONCEILINGZ) { - mo->AddZ(-mobj->SpawnPoint[2]); + mo->_f_AddZ(-mobj->SpawnPoint[2]); } // If there are 3D floors, we need to find floor/ceiling again. @@ -2834,12 +2793,12 @@ void P_NightmareRespawn (AActor *mobj) } if (mo->Top() > mo->ceilingz) { // Do the same for the ceiling. - mo->SetZ(mo->ceilingz - mo->height); + mo->SetZ(mo->ceilingz - mo->Height); } } // something is occupying its position? - if (!P_CheckPosition(mo, mo->X(), mo->Y(), true)) + if (!P_CheckPosition(mo, mo->_f_X(), mo->_f_Y(), true)) { //[GrafZahl] MF_COUNTKILL still needs to be checked here. mo->ClearCounters(); @@ -2847,7 +2806,7 @@ void P_NightmareRespawn (AActor *mobj) return; // no respawn } - z = mo->Z(); + z = mo->_f_Z(); // inherit attributes from deceased one mo->SpawnPoint[0] = mobj->SpawnPoint[0]; @@ -2855,7 +2814,7 @@ void P_NightmareRespawn (AActor *mobj) mo->SpawnPoint[2] = mobj->SpawnPoint[2]; mo->SpawnAngle = mobj->SpawnAngle; mo->SpawnFlags = mobj->SpawnFlags & ~MTF_DORMANT; // It wasn't dormant when it died, so it's not dormant now, either. - mo->angle = ANG45 * (mobj->SpawnAngle/45); + mo->Angles.Yaw = (double)mobj->SpawnAngle; mo->HandleSpawnFlags (); mo->reactiontime = 18; @@ -3085,7 +3044,7 @@ void AActor::HitFloor () bool AActor::Slam (AActor *thing) { flags &= ~MF_SKULLFLY; - vel.x = vel.y = vel.z = 0; + Vel.Zero(); if (health > 0) { if (!(flags2 & MF2_DORMANT)) @@ -3119,37 +3078,37 @@ int AActor::SpecialMissileHit (AActor *victim) return -1; } -bool AActor::AdjustReflectionAngle (AActor *thing, angle_t &angle) +bool AActor::AdjustReflectionAngle (AActor *thing, DAngle &angle) { if (flags2 & MF2_DONTREFLECT) return true; if (thing->flags7 & MF7_THRUREFLECT) return false; // Change angle for reflection if (thing->flags4&MF4_SHIELDREFLECT) { - // Shield reflection (from the Centaur - if (absangle(angle - thing->angle)>>24 > 45) + // Shield reflection (from the Centaur) + if (diffangle(angle, thing->Angles.Yaw) > 45) return true; // Let missile explode if (thing->IsKindOf (RUNTIME_CLASS(AHolySpirit))) // shouldn't this be handled by another flag??? return true; if (pr_reflect () < 128) - angle += ANGLE_45; + angle += 45; else - angle -= ANGLE_45; + angle -= 45; } else if (thing->flags4&MF4_DEFLECT) { // deflect (like the Heresiarch) if(pr_reflect() < 128) - angle += ANG45; + angle += 45; else - angle -= ANG45; + angle -= 45; } else { - angle += ANGLE_1 * ((pr_reflect() % 16) - 8); + angle += ((pr_reflect() % 16) - 8); } //Always check for AIMREFLECT, no matter what else is checked above. if (thing->flags7 & MF7_AIMREFLECT) @@ -3219,7 +3178,7 @@ bool AActor::IsOkayToAttack (AActor *link) // to only allow the check to succeed if the enemy was in a ~84� FOV of the player if (flags3 & MF3_SCREENSEEKER) { - angle_t angle = Friend->AngleTo(link) - Friend->angle; + angle_t angle = Friend->__f_AngleTo(link) - Friend->_f_angle(); angle >>= 24; if (angle>226 || angle<30) { @@ -3244,11 +3203,11 @@ void AActor::SetShade (int r, int g, int b) fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b); } -void AActor::SetPitch(int p, bool interpolate, bool forceclamp) +void AActor::SetPitch(DAngle p, bool interpolate, bool forceclamp) { if (player != NULL || forceclamp) { // clamp the pitch we set - int min, max; + DAngle min, max; if (player != NULL) { @@ -3257,14 +3216,14 @@ void AActor::SetPitch(int p, bool interpolate, bool forceclamp) } else { - min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); - max = ANGLE_90 - (1 << ANGLETOFINESHIFT); + min = -89.; + max = 89.; } - p = clamp(p, min, max); + p = clamp(p, min, max); } - if (p != pitch) + if (p != Angles.Pitch) { - pitch = p; + Angles.Pitch = p; if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; @@ -3272,11 +3231,11 @@ void AActor::SetPitch(int p, bool interpolate, bool forceclamp) } } -void AActor::SetAngle(angle_t ang, bool interpolate) +void AActor::SetAngle(DAngle ang, bool interpolate) { - if (ang != angle) + if (ang != Angles.Yaw) { - angle = ang; + Angles.Yaw = ang; if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; @@ -3284,11 +3243,11 @@ void AActor::SetAngle(angle_t ang, bool interpolate) } } -void AActor::SetRoll(angle_t r, bool interpolate) +void AActor::SetRoll(DAngle r, bool interpolate) { - if (r != roll) + if (r != Angles.Roll) { - roll = r; + Angles.Roll = r; if (player != NULL && interpolate) { player->cheats |= CF_INTERPVIEW; @@ -3301,13 +3260,13 @@ fixedvec3 AActor::GetPortalTransition(fixed_t byoffset, sector_t **pSec) { bool moved = false; sector_t *sec = Sector; - fixed_t testz = Z() + byoffset; - fixedvec3 pos = Pos(); + double testz = Z() + FIXED2FLOAT(byoffset); + fixedvec3 pos = _f_Pos(); while (!sec->PortalBlocksMovement(sector_t::ceiling)) { AActor *port = sec->SkyBoxes[sector_t::ceiling]; - if (testz > port->threshold) + if (testz > port->specialf1) { pos = PosRelative(port->Sector); sec = P_PointInSector(pos.x, pos.y); @@ -3320,7 +3279,7 @@ fixedvec3 AActor::GetPortalTransition(fixed_t byoffset, sector_t **pSec) while (!sec->PortalBlocksMovement(sector_t::floor)) { AActor *port = sec->SkyBoxes[sector_t::floor]; - if (testz <= port->threshold) + if (testz <= port->specialf1) { pos = PosRelative(port->Sector); sec = P_PointInSector(pos.x, pos.y); @@ -3340,15 +3299,15 @@ void AActor::CheckPortalTransition(bool islinked) while (!Sector->PortalBlocksMovement(sector_t::ceiling)) { AActor *port = Sector->SkyBoxes[sector_t::ceiling]; - if (Z() > port->threshold) + if (Z() > port->specialf1) { - fixedvec3 oldpos = Pos(); + fixedvec3 oldpos = _f_Pos(); if (islinked && !moved) UnlinkFromWorld(); SetXYZ(PosRelative(port->Sector)); - PrevX += X() - oldpos.x; - PrevY += Y() - oldpos.y; - PrevZ += Z() - oldpos.z; - Sector = P_PointInSector(X(), Y()); + PrevX += _f_X() - oldpos.x; + PrevY += _f_Y() - oldpos.y; + PrevZ += _f_Z() - oldpos.z; + Sector = P_PointInSector(_f_X(), _f_Y()); PrevPortalGroup = Sector->PortalGroup; moved = true; } @@ -3359,15 +3318,15 @@ void AActor::CheckPortalTransition(bool islinked) while (!Sector->PortalBlocksMovement(sector_t::floor)) { AActor *port = Sector->SkyBoxes[sector_t::floor]; - if (Z() < port->threshold && floorz < port->threshold) + if (Z() < port->specialf1 && floorz < port->specialf1) { - fixedvec3 oldpos = Pos(); + fixedvec3 oldpos = _f_Pos(); if (islinked && !moved) UnlinkFromWorld(); SetXYZ(PosRelative(port->Sector)); - PrevX += X() - oldpos.x; - PrevY += Y() - oldpos.y; - PrevZ += Z() - oldpos.z; - Sector = P_PointInSector(X(), Y()); + PrevX += _f_X() - oldpos.x; + PrevY += _f_Y() - oldpos.y; + PrevZ += _f_Z() - oldpos.z; + Sector = P_PointInSector(_f_X(), _f_Y()); PrevPortalGroup = Sector->PortalGroup; moved = true; } @@ -3407,8 +3366,7 @@ void AActor::Tick () //assert (state != NULL); if (state == NULL) { - Printf("Actor of type %s at (%f,%f) left without a state\n", GetClass()->TypeName.GetChars(), - X()/65536., Y()/65536.); + Printf("Actor of type %s at (%f,%f) left without a state\n", GetClass()->TypeName.GetChars(), X(), Y()); Destroy(); return; } @@ -3440,7 +3398,7 @@ void AActor::Tick () UnlinkFromWorld (); flags |= MF_NOBLOCKMAP; - SetXYZ(Vec3Offset(vel.x, vel.y, vel.z)); + SetXYZ(Vec3Offset(_f_velx(), _f_vely(), _f_velz())); CheckPortalTransition(false); LinkToWorld (); } @@ -3488,7 +3446,7 @@ void AActor::Tick () { // add some smoke behind the rocket smokecounter = 0; - AActor *th = Spawn("RocketSmokeTrail", Vec3Offset(-vel.x, -vel.y, -vel.z), ALLOW_REPLACE); + AActor *th = Spawn("RocketSmokeTrail", Vec3Offset(-_f_velx(), -_f_vely(), -_f_velz()), ALLOW_REPLACE); if (th) { th->tics -= pr_rockettrail()&3; @@ -3502,10 +3460,11 @@ void AActor::Tick () if (++smokecounter == 8) { smokecounter = 0; - angle_t moveangle = R_PointToAngle2(0,0,vel.x,vel.y); - fixed_t xo = -FixedMul(finecosine[(moveangle) >> ANGLETOFINESHIFT], radius * 2) + (pr_rockettrail() << 10); - fixed_t yo = -FixedMul(finesine[(moveangle) >> ANGLETOFINESHIFT], radius * 2) + (pr_rockettrail() << 10); - AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(xo, yo, - (height>>3) * (vel.z>>16) + (2*height)/3), ALLOW_REPLACE); + DAngle moveangle = Vel.Angle(); + double xo = -moveangle.Cos() * radius * 2 + pr_rockettrail() / 64.; + double yo = -moveangle.Sin() * radius * 2 + pr_rockettrail() / 64.; + double zo = -Height * Vel.Z / 8. + Height * (2 / 3.); + AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (th) { th->tics -= pr_rockettrail()&3; @@ -3515,7 +3474,7 @@ void AActor::Tick () } } - fixed_t oldz = Z(); + fixed_t oldz = _f_Z(); // [RH] Give the pain elemental vertical friction // This used to be in APainElemental::Tick but in order to use @@ -3524,14 +3483,14 @@ void AActor::Tick () { if (health >0) { - if (abs (vel.z) < FRACUNIT/4) + if (abs (_f_velz()) < FRACUNIT/4) { - vel.z = 0; + Vel.Z = 0; flags4 &= ~MF4_VFRICTION; } else { - vel.z = FixedMul (vel.z, 0xe800); + Vel.Z *= (0xe800 / 65536.); } } } @@ -3670,7 +3629,7 @@ void AActor::Tick () if (i_compatflags&COMPATF_RAVENSCROLL) { angle_t fineangle = HexenScrollDirs[scrolltype / 3] * 32; - fixed_t carryspeed = DivScale32 (HexenSpeedMuls[scrolltype % 3], 32*CARRYFACTOR); + fixed_t carryspeed = DivScale32 (HexenSpeedMuls[scrolltype % 3], 32*_f_CARRYFACTOR); scrollx += FixedMul (carryspeed, finecosine[fineangle]); scrolly += FixedMul (carryspeed, finesine[fineangle]); } @@ -3686,7 +3645,7 @@ void AActor::Tick () { // Heretic scroll special scrolltype -= Carry_East5; BYTE dir = HereticScrollDirs[scrolltype / 5]; - fixed_t carryspeed = DivScale32 (HereticSpeedMuls[scrolltype % 5], 32*CARRYFACTOR); + fixed_t carryspeed = DivScale32 (HereticSpeedMuls[scrolltype % 5], 32*_f_CARRYFACTOR); if (scrolltype<=Carry_East35 && !(i_compatflags&COMPATF_RAVENSCROLL)) { // Use speeds that actually match the scrolling textures! @@ -3699,18 +3658,18 @@ void AActor::Tick () { // Special Heretic scroll special if (i_compatflags&COMPATF_RAVENSCROLL) { - scrollx += DivScale32 (28, 32*CARRYFACTOR); + scrollx += DivScale32 (28, 32*_f_CARRYFACTOR); } else { // Use a speed that actually matches the scrolling texture! - scrollx += DivScale32 (12, 32*CARRYFACTOR); + scrollx += DivScale32 (12, 32*_f_CARRYFACTOR); } } else if (scrolltype == Scroll_StrifeCurrent) { // Strife scroll special int anglespeed = tagManager.GetFirstSectorTag(sec) - 100; - fixed_t carryspeed = DivScale32 (anglespeed % 10, 16*CARRYFACTOR); + fixed_t carryspeed = DivScale32 (anglespeed % 10, 16*_f_CARRYFACTOR); angle_t fineangle = (anglespeed / 10) << (32-3); fineangle >>= ANGLETOFINESHIFT; scrollx += FixedMul (carryspeed, finecosine[fineangle]); @@ -3729,7 +3688,7 @@ void AActor::Tick () } fixedvec3 pos = PosRelative(sec); height = sec->floorplane.ZatPoint (pos); - if (Z() > height) + if (_f_Z() > height) { if (heightsec == NULL) { @@ -3737,7 +3696,7 @@ void AActor::Tick () } waterheight = heightsec->floorplane.ZatPoint (pos); - if (waterheight > height && Z() >= waterheight) + if (waterheight > height && _f_Z() >= waterheight) { continue; } @@ -3768,16 +3727,16 @@ void AActor::Tick () // [RH] If standing on a steep slope, fall down it if ((flags & MF_SOLID) && !(flags & (MF_NOCLIP|MF_NOGRAVITY)) && !(flags & MF_NOBLOCKMAP) && - vel.z <= 0 && + Vel.Z <= 0 && floorz == Z()) { secplane_t floorplane; // Check 3D floors as well - floorplane = P_FindFloorPlane(floorsector, X(), Y(), floorz); + floorplane = P_FindFloorPlane(floorsector, _f_X(), _f_Y(), _f_floorz()); if (floorplane.c < STEEPSLOPE && - floorplane.ZatPoint (PosRelative(floorsector)) <= floorz) + floorplane.ZatPoint (PosRelative(floorsector)) <= _f_floorz()) { const msecnode_t *node; bool dopush = true; @@ -3789,7 +3748,7 @@ void AActor::Tick () const sector_t *sec = node->m_sector; if (sec->floorplane.c >= STEEPSLOPE) { - if (floorplane.ZatPoint (PosRelative(node->m_sector)) >= Z() - MaxStepHeight) + if (floorplane.ZatPoint (PosRelative(node->m_sector)) >= _f_Z() - MaxStepHeight) { dopush = false; break; @@ -3799,8 +3758,7 @@ void AActor::Tick () } if (dopush) { - vel.x += floorplane.a; - vel.y += floorplane.b; + Vel += floorplane.Normal().XY(); } } } @@ -3810,19 +3768,21 @@ void AActor::Tick () // still have missiles that go straight up and down through actors without // damaging anything. // (for backwards compatibility this must check for lack of damage function, not for zero damage!) - if ((flags & MF_MISSILE) && (vel.x|vel.y) == 0 && Damage != NULL) + if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && Damage != NULL) { - vel.x = 1; + Vel.X = MinVel; } // Handle X and Y velocities BlockingMobj = NULL; + assert(!player || !isnan(Vel.X)); fixed_t oldfloorz = P_XYMovement (this, cummx, cummy); + assert(!player || !isnan(Vel.X)); if (ObjectFlags & OF_EuthanizeMe) { // actor was destroyed return; } - if ((vel.x | vel.y) == 0) // Actors at rest + if (Vel.X == 0 && Vel.Y == 0) // Actors at rest { if (flags2 & MF2_BLASTED) { // Reset to not blasted when velocities are gone @@ -3834,7 +3794,7 @@ void AActor::Tick () } } - if (vel.z || BlockingMobj || Z() != floorz) + if (Vel.Z != 0 || BlockingMobj || Z() != floorz) { // Handle Z velocity and gravity if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(i_compatflags & COMPATF_NO_PASSMOBJ)) { @@ -3847,24 +3807,24 @@ void AActor::Tick () { if (player) { - if (vel.z < (fixed_t)(level.gravity * Sector->gravity * -655.36f) + if (Vel.Z < level.gravity * Sector->gravity * (-1./100)// -655.36f) && !(flags&MF_NOGRAVITY)) { PlayerLandedOnThing (this, onmo); } } - if (onmo->Top() - Z() <= MaxStepHeight) + if (onmo->_f_Top() - _f_Z() <= MaxStepHeight) { if (player && player->mo == this) { - player->viewheight -= onmo->Top() - Z(); + player->viewheight -= onmo->_f_Top() - _f_Z(); fixed_t deltaview = player->GetDeltaViewHeight(); if (deltaview > player->deltaviewheight) { player->deltaviewheight = deltaview; } } - SetZ(onmo->Top()); + _f_SetZ(onmo->_f_Top()); } // Check for MF6_BUMPSPECIAL // By default, only players can activate things by bumping into them @@ -3883,14 +3843,14 @@ void AActor::Tick () onmo->lastbump = level.maptime + TICRATE; } } - if (vel.z != 0 && (BounceFlags & BOUNCE_Actors)) + if (_f_velz() != 0 && (BounceFlags & BOUNCE_Actors)) { P_BounceActor(this, onmo, true); } else { flags2 |= MF2_ONMOBJ; - vel.z = 0; + Vel.Z = 0; Crash(); } } @@ -4030,15 +3990,15 @@ void AActor::CheckSectorTransition(sector_t *oldsec) if (Sector->SecActTarget != NULL) { int act = SECSPAC_Enter; - if (Z() <= Sector->floorplane.ZatPoint(this)) + if (_f_Z() <= Sector->floorplane.ZatPoint(this)) { act |= SECSPAC_HitFloor; } - if (Z() + height >= Sector->ceilingplane.ZatPoint(this)) + if (_f_Z() + _f_height() >= Sector->ceilingplane.ZatPoint(this)) { act |= SECSPAC_HitCeiling; } - if (Sector->heightsec != NULL && Z() == Sector->heightsec->floorplane.ZatPoint(this)) + if (Sector->heightsec != NULL && _f_Z() == Sector->heightsec->floorplane.ZatPoint(this)) { act |= SECSPAC_HitFakeFloor; } @@ -4088,20 +4048,20 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) fh = hsec->floorplane.ZatPoint (this); //if (hsec->MoreFlags & SECF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors { - if (Z() < fh) + if (_f_Z() < fh) { waterlevel = 1; - if (Z() + height/2 < fh) + if (_f_Z() + _f_height()/2 < fh) { waterlevel = 2; - if ((player && Z() + player->viewheight <= fh) || - (Z() + height <= fh)) + if ((player && _f_Z() + player->viewheight <= fh) || + (_f_Z() + _f_height() <= fh)) { waterlevel = 3; } } } - else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint (this))) + else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (_f_Top() > hsec->ceilingplane.ZatPoint (this))) { waterlevel = 3; } @@ -4130,17 +4090,17 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash) fixed_t ff_bottom=rover->bottom.plane->ZatPoint(this); fixed_t ff_top=rover->top.plane->ZatPoint(this); - if(ff_top <= Z() || ff_bottom > (Z() + (height >> 1))) continue; + if(ff_top <= _f_Z() || ff_bottom > (_f_Z() + (_f_height() >> 1))) continue; fh=ff_top; - if (Z() < fh) + if (_f_Z() < fh) { waterlevel = 1; - if (Z() + height/2 < fh) + if (_f_Z() + _f_height()/2 < fh) { waterlevel = 2; - if ((player && Z() + player->viewheight <= fh) || - (Z() + height <= fh)) + if ((player && _f_Z() + player->viewheight <= fh) || + (_f_Z() + _f_height() <= fh)) { waterlevel = 3; } @@ -4205,7 +4165,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->health = actor->SpawnHealth(); // Actors with zero gravity need the NOGRAVITY flag set. - if (actor->gravity == 0) actor->flags |= MF_NOGRAVITY; + if (actor->Gravity == 0) actor->flags |= MF_NOGRAVITY; FRandom &rng = bglobal.m_Thinking ? pr_botspawnmobj : pr_spawnmobj; @@ -4230,7 +4190,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright()); actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 if (G_SkillProperty(SKILLP_FastMonsters) && actor->GetClass()->FastSpeed >= 0) - actor->Speed = actor->GetClass()->FastSpeed; + actor->Speed = actor->GetClass()->FastSpeed; actor->DamageMultiply = FRACUNIT; // set subsector and/or block links @@ -4238,18 +4198,19 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t actor->ClearInterpolation(); actor->dropoffz = // killough 11/98: for tracking dropoffs - actor->floorz = actor->Sector->floorplane.ZatPoint (ix, iy); - actor->ceilingz = actor->Sector->ceilingplane.ZatPoint (ix, iy); + actor->Sector->floorplane.ZatPoint (ix, iy); + actor->floorz = FIXED2DBL(actor->dropoffz); + actor->ceilingz = FIXED2DBL(actor->Sector->ceilingplane.ZatPoint (ix, iy)); // The z-coordinate needs to be set once before calling P_FindFloorCeiling // For FLOATRANDZ just use the floor here. if (iz == ONFLOORZ || iz == FLOATRANDZ) { - actor->SetZ(actor->floorz, false); + actor->SetZ(actor->floorz); } else if (iz == ONCEILINGZ) { - actor->SetZ(actor->ceilingz - actor->height); + actor->SetZ(actor->ceilingz - actor->Height); } if (SpawningMapThing || !type->IsDescendantOf (RUNTIME_CLASS(APlayerPawn))) @@ -4292,15 +4253,15 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t } else if (iz == ONCEILINGZ) { - actor->SetZ(actor->ceilingz - actor->height); + actor->SetZ(actor->ceilingz - actor->Height); } else if (iz == FLOATRANDZ) { - fixed_t space = actor->ceilingz - actor->height - actor->floorz; - if (space > 48*FRACUNIT) + double space = actor->ceilingz - actor->Height - actor->floorz; + if (space > 48) { - space -= 40*FRACUNIT; - actor->SetZ(MulScale8 (space, rng()) + actor->floorz + 40*FRACUNIT); + space -= 40; + actor->SetZ( space * rng() / 256. + actor->floorz + 40); } else { @@ -4309,7 +4270,7 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t } else { - actor->SpawnPoint[2] = (actor->Z() - actor->Sector->floorplane.ZatPoint(actor)); + actor->SpawnPoint[2] = (actor->_f_Z() - actor->Sector->floorplane.ZatPoint(actor)); } if (actor->FloatBobPhase == (BYTE)-1) actor->FloatBobPhase = rng(); // Don't make everything bob in sync (unless deliberately told to do) @@ -4319,9 +4280,9 @@ AActor *AActor::StaticSpawn (PClassActor *type, fixed_t ix, fixed_t iy, fixed_t } else { - actor->floorclip = 0; + actor->Floorclip = 0; } - actor->UpdateWaterLevel (actor->Z(), false); + actor->UpdateWaterLevel (actor->_f_Z(), false); if (!SpawningMapThing) { actor->BeginPlay (); @@ -4453,7 +4414,7 @@ void AActor::PostBeginPlay () { Renderer->StateChanged(this); } - PrevAngle = angle; + PrevAngles = Angles; flags7 |= MF7_HANDLENODELAY; } @@ -4560,12 +4521,12 @@ void AActor::AdjustFloorClip () return; } - fixed_t oldclip = floorclip; - fixed_t shallowestclip = FIXED_MAX; + double oldclip = _f_floorclip(); + double shallowestclip = INT_MAX; const msecnode_t *m; // possibly standing on a 3D-floor - if (Sector->e->XFloor.ffloors.Size() && Z() > Sector->floorplane.ZatPoint(this)) floorclip = 0; + if (Sector->e->XFloor.ffloors.Size() && Z() > Sector->floorplane.ZatPointF(this)) Floorclip = 0; // [RH] clip based on shallowest floor player is standing on // If the sector has a deep water effect, then let that effect @@ -4574,26 +4535,26 @@ void AActor::AdjustFloorClip () { fixedvec3 pos = PosRelative(m->m_sector); sector_t *hsec = m->m_sector->GetHeightSec(); - if (hsec == NULL && m->m_sector->floorplane.ZatPoint (pos) == Z()) + if (hsec == NULL && m->m_sector->floorplane.ZatPoint (pos) == _f_Z()) { - fixed_t clip = Terrains[m->m_sector->GetTerrain(sector_t::floor)].FootClip; + double clip = Terrains[m->m_sector->GetTerrain(sector_t::floor)].FootClip; if (clip < shallowestclip) { shallowestclip = clip; } } } - if (shallowestclip == FIXED_MAX) + if (shallowestclip == INT_MAX) { - floorclip = 0; + Floorclip = 0; } else { - floorclip = shallowestclip; + Floorclip = shallowestclip; } - if (player && player->mo == this && oldclip != floorclip) + if (player && player->mo == this && oldclip != Floorclip) { - player->viewheight -= oldclip - floorclip; + player->viewheight -= FLOAT2FIXED(oldclip - Floorclip); player->deltaviewheight = player->GetDeltaViewHeight(); } } @@ -4613,7 +4574,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) APlayerPawn *mobj, *oldactor; BYTE state; fixed_t spawn_x, spawn_y, spawn_z; - angle_t spawn_angle; + DAngle SpawnAngle; if (mthing == NULL) { @@ -4668,29 +4629,22 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) ( NULL != p->attacker ) && // don't respawn on damaging floors ( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter... { - spawn_x = p->mo->X(); - spawn_y = p->mo->Y(); - spawn_z = p->mo->Z(); + spawn_x = p->mo->_f_X(); + spawn_y = p->mo->_f_Y(); + spawn_z = p->mo->_f_Z(); - spawn_angle = p->mo->angle; + SpawnAngle = p->mo->Angles.Yaw; } else { spawn_x = mthing->x; spawn_y = mthing->y; - // Allow full angular precision but avoid roundoff errors for multiples of 45 degrees. - if (mthing->angle % 45 != 0) - { - spawn_angle = mthing->angle * (ANG45 / 45); - } - else - { - spawn_angle = ANG45 * (mthing->angle / 45); - } + // Allow full angular precision + SpawnAngle = (double)mthing->angle; if (i_compatflags2 & COMPATF2_BADANGLES) { - spawn_angle += 1 << ANGLETOFINESHIFT; + SpawnAngle += 0.01; } if (GetDefaultByType(p->cls)->flags & MF_SPAWNCEILING) @@ -4707,9 +4661,9 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) if (level.flags & LEVEL_USEPLAYERSTARTZ) { if (spawn_z == ONFLOORZ) - mobj->AddZ(mthing->z); + mobj->_f_AddZ(mthing->z); else if (spawn_z == ONCEILINGZ) - mobj->AddZ(-mthing->z); + mobj->_f_AddZ(-mthing->z); P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); } @@ -4741,8 +4695,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); } - mobj->angle = spawn_angle; - mobj->pitch = mobj->roll = 0; + mobj->Angles.Yaw = SpawnAngle; + mobj->Angles.Pitch = mobj->Angles.Roll = 0.; mobj->health = p->health; // [RH] Set player sprite based on skin @@ -4773,11 +4727,11 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) p->BlendR = p->BlendG = p->BlendB = p->BlendA = 0.f; p->mo->ResetAirSupply(false); p->Uncrouch(); - p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode + p->MinPitch = p->MaxPitch = 0.; // will be filled in by PostBeginPlay()/netcode p->MUSINFOactor = NULL; p->MUSINFOtics = -1; - p->vel.x = p->vel.y = 0; // killough 10/98: initialize bobbing to 0. + p->Vel.Zero(); // killough 10/98: initialize bobbing to 0. for (int ii = 0; ii < MAXPLAYERS; ++ii) { @@ -4829,7 +4783,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) if (multiplayer) { - unsigned an = mobj->angle >> ANGLETOFINESHIFT; + unsigned an = mobj->_f_angle() >> ANGLETOFINESHIFT; Spawn ("TeleportFog", mobj->Vec3Offset(20*finecosine[an], 20*finesine[an], TELEFOGHEIGHT), ALLOW_REPLACE); } @@ -4837,7 +4791,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) // drop down below it, even if that means sinking into the floor. if (mobj->Top() > mobj->ceilingz) { - mobj->SetZ(mobj->ceilingz - mobj->height, false); + mobj->SetZ(mobj->ceilingz - mobj->Height, false); } // [BC] Do script stuff @@ -4946,7 +4900,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) polyspawn->x = mthing->x; polyspawn->y = mthing->y; polyspawn->angle = mthing->angle; - polyspawn->type = mentry->Special; + polyspawn->type = mentry->Special; polyspawns = polyspawn; if (mentry->Special != SMT_PolyAnchor) po_NumPolyobjs++; @@ -5168,14 +5122,14 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (z == ONFLOORZ) { - mobj->AddZ(mthing->z); + mobj->_f_AddZ(mthing->z); if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) { - mobj->special1 = mthing->z; + mobj->specialf1 = FIXED2DBL(mthing->z); } } else if (z == ONCEILINGZ) - mobj->AddZ(-mthing->z); + mobj->_f_AddZ(-mthing->z); mobj->SpawnPoint[0] = mthing->x; mobj->SpawnPoint[1] = mthing->y; @@ -5183,12 +5137,12 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->SpawnAngle = mthing->angle; mobj->SpawnFlags = mthing->flags; if (mthing->FloatbobPhase >= 0 && mthing->FloatbobPhase < 64) mobj->FloatBobPhase = mthing->FloatbobPhase; - if (mthing->gravity < 0) mobj->gravity = -mthing->gravity; - else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity); + if (mthing->Gravity < 0) mobj->Gravity = -mthing->Gravity; + else if (mthing->Gravity > 0) mobj->Gravity *= mthing->Gravity; else mobj->flags &= ~MF_NOGRAVITY; // For Hexen floatbob 'compatibility' we do not really want to alter the floorz. - if (mobj->special1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB)) + if (mobj->specialf1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB)) { P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); } @@ -5205,7 +5159,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->tid = mthing->thingid; mobj->AddToHash (); - mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * CONST64(0x100000000)) / 360); + mobj->PrevAngles.Yaw = mobj->Angles.Yaw = (double)mthing->angle; // Check if this actor's mapthing has a conversation defined if (mthing->Conversation > 0) @@ -5224,14 +5178,14 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->alpha = mthing->alpha; if (mthing->RenderStyle != STYLE_Count) mobj->RenderStyle = (ERenderStyle)mthing->RenderStyle; - if (mthing->scaleX) - mobj->scaleX = FixedMul(mthing->scaleX, mobj->scaleX); - if (mthing->scaleY) - mobj->scaleY = FixedMul(mthing->scaleY, mobj->scaleY); + if (mthing->Scale.X != 0) + mobj->Scale.X = mthing->Scale.X * mobj->Scale.X; + if (mthing->Scale.Y != 0) + mobj->Scale.X = mthing->Scale.Y * mobj->Scale.Y; if (mthing->pitch) - mobj->pitch = ANGLE_1 * mthing->pitch; + mobj->Angles.Pitch = (double)mthing->pitch; if (mthing->roll) - mobj->roll = ANGLE_1 * mthing->roll; + mobj->Angles.Roll = (double)mthing->roll; if (mthing->score) mobj->Score = mthing->score; if (mthing->fillcolor) @@ -5295,7 +5249,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y puff->target = source; // Angle is the opposite of the hit direction (i.e. the puff faces the source.) - puff->angle = hitdir + ANGLE_180; + puff->Angles.Yaw = ANGLE2DBL(hitdir + ANGLE_180); // If a puff has a crash state and an actor was not hit, // it will enter the crash state. This is used by the StrifeSpark @@ -5360,8 +5314,8 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc { z += pr_spawnblood.Random2 () << 10; th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement - th->vel.z = FRACUNIT*2; - th->angle = dir; + th->Vel.Z = 2; + th->Angles.Yaw = ANGLE2DBL(dir); // [NG] Applying PUFFGETSOWNER to the blood will make it target the owner if (th->flags5 & MF5_PUFFGETSOWNER) th->target = originator; if (gameinfo.gametype & GAME_DoomChex) @@ -5456,9 +5410,9 @@ void P_BloodSplatter (fixedvec3 pos, AActor *originator) mo = Spawn(bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement mo->target = originator; - mo->vel.x = pr_splatter.Random2 () << 10; - mo->vel.y = pr_splatter.Random2 () << 10; - mo->vel.z = 3*FRACUNIT; + mo->Vel.X = pr_splatter.Random2 () / 64.; + mo->Vel.Y = pr_splatter.Random2() / 64.; + mo->Vel.Z = 3; // colorize the blood! if (bloodcolor!=0 && !(mo->flags2 & MF2_DONTTRANSLATE)) @@ -5470,7 +5424,7 @@ void P_BloodSplatter (fixedvec3 pos, AActor *originator) } if (bloodtype >= 1) { - P_DrawSplash2 (40, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor); + P_DrawSplash2 (40, pos.x, pos.y, pos.z, 0u - originator->__f_AngleTo(pos), 2, bloodcolor); } } @@ -5510,7 +5464,7 @@ void P_BloodSplatter2 (fixedvec3 pos, AActor *originator) } if (bloodtype >= 1) { - P_DrawSplash2 (100, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor); + P_DrawSplash2 (100, pos.x, pos.y, pos.z, 0u - originator->__f_AngleTo(pos), 2, bloodcolor); } } @@ -5543,8 +5497,8 @@ void P_RipperBlood (AActor *mo, AActor *bleeder) if (th->flags5 & MF5_PUFFGETSOWNER) th->target = bleeder; if (gameinfo.gametype == GAME_Heretic) th->flags |= MF_NOGRAVITY; - th->vel.x = mo->vel.x >> 1; - th->vel.y = mo->vel.y >> 1; + th->Vel.X = mo->Vel.X / 2; + th->Vel.Y = mo->Vel.Y / 2; th->tics += pr_ripperblood () & 3; // colorize the blood! @@ -5599,17 +5553,17 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z int terrainnum; sector_t *hsec = NULL; - if (x == FIXED_MIN) x = thing->X(); - if (y == FIXED_MIN) y = thing->Y(); - if (z == FIXED_MIN) z = thing->Z(); + if (x == FIXED_MIN) x = thing->_f_X(); + if (y == FIXED_MIN) y = thing->_f_Y(); + if (z == FIXED_MIN) z = thing->_f_Z(); // don't splash above the object if (checkabove) { - fixed_t compare_z = thing->Z() + (thing->height >> 1); + fixed_t compare_z = thing->_f_Z() + (thing->_f_height() >> 1); // Missiles are typically small and fast, so they might // end up submerged by the move that calls P_HitWater. if (thing->flags & MF_MISSILE) - compare_z -= thing->vel.z; + compare_z -= thing->_f_velz(); if (z > compare_z) return false; } @@ -5645,7 +5599,7 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z } } planez = rover->bottom.plane->ZatPoint(x, y); - if (planez < z && !(planez < thing->floorz)) return false; + if (planez < z && !(planez < thing->_f_floorz())) return false; } } hsec = sec->GetHeightSec(); @@ -5667,13 +5621,13 @@ foundone: return Terrains[terrainnum].IsLiquid; // don't splash when touching an underwater floor - if (thing->waterlevel>=1 && z<=thing->floorz) return Terrains[terrainnum].IsLiquid; + if (thing->waterlevel>=1 && z<=thing->_f_floorz()) return Terrains[terrainnum].IsLiquid; plane = hsec != NULL? &sec->heightsec->floorplane : &sec->floorplane; // Don't splash for living things with small vertical velocities. // There are levels where the constant splashing from the monsters gets extremely annoying - if (((thing->flags3&MF3_ISMONSTER || thing->player) && thing->vel.z >= -6*FRACUNIT) && !force) + if (((thing->flags3&MF3_ISMONSTER || thing->player) && thing->_f_velz() >= -6*FRACUNIT) && !force) return Terrains[terrainnum].IsLiquid; splash = &Splashes[splashnum]; @@ -5685,7 +5639,7 @@ foundone: if (smallsplash && splash->SmallSplash) { mo = Spawn (splash->SmallSplash, x, y, z, ALLOW_REPLACE); - if (mo) mo->floorclip += splash->SmallSplashClip; + if (mo) mo->Floorclip += FIXED2DBL(splash->SmallSplashClip); } else { @@ -5695,13 +5649,13 @@ foundone: mo->target = thing; if (splash->ChunkXVelShift != 255) { - mo->vel.x = pr_chunk.Random2() << splash->ChunkXVelShift; + mo->Vel.X = (pr_chunk.Random2() << splash->ChunkXVelShift) / 65536.; } if (splash->ChunkYVelShift != 255) { - mo->vel.y = pr_chunk.Random2() << splash->ChunkYVelShift; + mo->Vel.Y = (pr_chunk.Random2() << splash->ChunkYVelShift) / 65536.; } - mo->vel.z = splash->ChunkBaseZVel + (pr_chunk() << splash->ChunkZVelShift); + mo->Vel.Z = splash->ChunkBaseZVel + (pr_chunk() << splash->ChunkZVelShift) / 65536.; } if (splash->SplashBase) { @@ -5742,7 +5696,7 @@ bool P_HitFloor (AActor *thing) // killough 11/98: touchy objects explode on impact // Allow very short drops to be safe, so that a touchy can be summoned without exploding. - if (thing->flags6 & MF6_TOUCHY && ((thing->flags6 & MF6_ARMED) || thing->IsSentient()) && ((thing->vel.z) < (-5 * FRACUNIT))) + if (thing->flags6 & MF6_TOUCHY && ((thing->flags6 & MF6_ARMED) || thing->IsSentient()) && ((thing->_f_velz()) < (-5 * FRACUNIT))) { thing->flags6 &= ~MF6_ARMED; // Disarm P_DamageMobj (thing, NULL, NULL, thing->health, NAME_Crush, DMG_FORCED); // kill object @@ -5757,7 +5711,7 @@ bool P_HitFloor (AActor *thing) for (m = thing->touching_sectorlist; m; m = m->m_tnext) { pos = thing->PosRelative(m->m_sector); - if (thing->Z() == m->m_sector->floorplane.ZatPoint(pos.x, pos.y)) + if (thing->_f_Z() == m->m_sector->floorplane.ZatPoint(pos.x, pos.y)) { break; } @@ -5769,7 +5723,7 @@ bool P_HitFloor (AActor *thing) if (!(rover->flags & FF_EXISTS)) continue; if (rover->flags & (FF_SOLID|FF_SWIMMABLE)) { - if (rover->top.plane->ZatPoint(pos.x, pos.y) == thing->Z()) + if (rover->top.plane->ZatPoint(pos.x, pos.y) == thing->_f_Z()) { return P_HitWater (thing, m->m_sector, pos); } @@ -5792,17 +5746,17 @@ bool P_HitFloor (AActor *thing) // //--------------------------------------------------------------------------- -void P_CheckSplash(AActor *self, fixed_t distance) +void P_CheckSplash(AActor *self, double distance) { sector_t *floorsec; - self->Sector->LowestFloorAt(self, &floorsec); + self->Sector->_f_LowestFloorAt(self, &floorsec); if (self->Z() <= self->floorz + distance && self->floorsector == floorsec && self->Sector->GetHeightSec() == NULL && floorsec->heightsec == NULL) { // Explosion splashes never alert monsters. This is because A_Explode has // a separate parameter for that so this would get in the way of proper // behavior. fixedvec3 pos = self->PosRelative(floorsec); - P_HitWater (self, floorsec, pos.x, pos.y, self->floorz, false, false); + P_HitWater (self, floorsec, pos.x, pos.y, self->_f_floorz(), false, false); } } @@ -5815,7 +5769,7 @@ void P_CheckSplash(AActor *self, fixed_t distance) // //--------------------------------------------------------------------------- -bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) +bool P_CheckMissileSpawn (AActor* th, double maxdist) { // [RH] Don't decrement tics if they are already less than 1 if ((th->flags4 & MF4_RANDOMIZE) && th->tics > 0) @@ -5828,9 +5782,8 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) if (maxdist > 0) { // move a little forward so an angle can be computed if it immediately explodes - DVector3 advance(FIXED2DBL(th->vel.x), FIXED2DBL(th->vel.y), FIXED2DBL(th->vel.z)); - double maxsquared = FIXED2DBL(maxdist); - maxsquared *= maxsquared; + DVector3 advance = th->Vel; + double maxsquared = maxdist*maxdist; // Keep halving the advance vector until we get something less than maxdist // units away, since we still want to spawn the missile inside the shooter. @@ -5838,11 +5791,8 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) { advance *= 0.5f; } - while (DVector2(advance).LengthSquared() >= maxsquared); - th->SetXYZ( - th->X() + FLOAT2FIXED(advance.X), - th->Y() + FLOAT2FIXED(advance.Y), - th->Z() + FLOAT2FIXED(advance.Z)); + while (advance.XY().LengthSquared() >= maxsquared); + th->SetXYZ(th->Pos() + advance); } FCheckPosition tm(!!(th->flags2 & MF2_RIP)); @@ -5866,7 +5816,7 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist) bool MBFGrenade = (!(th->flags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF)); // killough 3/15/98: no dropoff (really = don't care for missiles) - if (!(P_TryMove (th, th->X(), th->Y(), false, NULL, tm, true))) + if (!(P_TryMove (th, th->_f_X(), th->_f_Y(), false, NULL, tm, true))) { // [RH] Don't explode ripping missiles that spawn inside something if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) @@ -5920,7 +5870,7 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner) // If there is no spawner use the spawn position. // But not in a silenced sector. if (!(missile->Sector->Flags & SECF_SILENT)) - S_Sound (missile->X(), missile->Y(), missile->Z(), CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM); + S_Sound (missile->_f_X(), missile->_f_Y(), missile->_f_Z(), CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM); } } } @@ -5930,9 +5880,9 @@ static fixed_t GetDefaultSpeed(PClassActor *type) if (type == NULL) return 0; else if (G_SkillProperty(SKILLP_FastMonsters) && type->FastSpeed >= 0) - return type->FastSpeed; + return FLOAT2FIXED(type->FastSpeed); else - return GetDefaultByType(type)->Speed; + return GetDefaultByType(type)->_f_speed(); } //--------------------------------------------------------------------------- @@ -5950,7 +5900,7 @@ AActor *P_SpawnMissile (AActor *source, AActor *dest, PClassActor *type, AActor { return NULL; } - return P_SpawnMissileXYZ (source->X(), source->Y(), source->Z() + 32*FRACUNIT + source->GetBobOffset(), + return P_SpawnMissileXYZ (source->_f_X(), source->_f_Y(), source->_f_Z() + 32*FRACUNIT + source->GetBobOffset(), source, dest, type, true, owner); } @@ -5960,7 +5910,7 @@ AActor *P_SpawnMissileZ (AActor *source, fixed_t z, AActor *dest, PClassActor *t { return NULL; } - return P_SpawnMissileXYZ (source->X(), source->Y(), z, source, dest, type); + return P_SpawnMissileXYZ (source->_f_X(), source->_f_Y(), z, source, dest, type); } AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, @@ -5980,7 +5930,7 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, if (z != ONFLOORZ && z != ONCEILINGZ) { - z -= source->floorclip; + z -= source->_f_floorclip(); } AActor *th = Spawn (type, x, y, z, ALLOW_REPLACE); @@ -5991,7 +5941,7 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, if (owner == NULL) owner = source; th->target = owner; - float speed = (float)(th->Speed); + double speed = th->Speed; // [RH] // Hexen calculates the missile velocity based on the source's location. @@ -5999,37 +5949,35 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, // missile? // Answer: No, because this way, you can set up sets of parallel missiles. - fixedvec3 fixvel = source->Vec3To(dest); - DVector3 velocity(fixvel.x, fixvel.y, fixvel.z); + DVector3 velocity = source->Vec3To(dest); // Floor and ceiling huggers should never have a vertical component to their velocity if (th->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)) { velocity.Z = 0; } // [RH] Adjust the trajectory if the missile will go over the target's head. - else if (z - source->Z() >= dest->height) + else if (FIXED2FLOAT(z) - source->Z() >= dest->Height) { - velocity.Z += (dest->height - z + source->Z()); + velocity.Z += (dest->Height - FIXED2FLOAT(z) + source->Z()); } - velocity.Resize (speed); - th->vel.x = xs_CRoundToInt(velocity.X); - th->vel.y = xs_CRoundToInt(velocity.Y); - th->vel.z = xs_CRoundToInt(velocity.Z); + th->Vel = velocity.Resized(speed); // invisible target: rotate velocity vector in 2D // [RC] Now monsters can aim at invisible player as if they were fully visible. if (dest->flags & MF_SHADOW && !(source->flags6 & MF6_SEEINVISIBLE)) { - angle_t an = pr_spawnmissile.Random2 () << 20; - an >>= ANGLETOFINESHIFT; + DAngle an = pr_spawnmissile.Random2() * (22.5 / 256); + double c = an.Cos(); + double s = an.Sin(); - fixed_t newx = DMulScale16 (th->vel.x, finecosine[an], -th->vel.y, finesine[an]); - fixed_t newy = DMulScale16 (th->vel.x, finesine[an], th->vel.y, finecosine[an]); - th->vel.x = newx; - th->vel.y = newy; + double newx = th->Vel.X * c - th->Vel.Y * s; + double newy = th->Vel.X * s + th->Vel.Y * c; + + th->Vel.X = newx; + th->Vel.Y = newy; } - th->angle = R_PointToAngle2 (0, 0, th->vel.x, th->vel.y); + th->AngleFromVel(); if (th->flags4 & MF4_SPECTRAL) { @@ -6045,25 +5993,17 @@ AActor *P_OldSpawnMissile(AActor *source, AActor *owner, AActor *dest, PClassAct { return NULL; } - angle_t an; - fixed_t dist; AActor *th = Spawn (type, source->PosPlusZ(4*8*FRACUNIT), ALLOW_REPLACE); P_PlaySpawnSound(th, source); th->target = owner; // record missile's originator - th->angle = an = source->AngleTo(dest); - an >>= ANGLETOFINESHIFT; - th->vel.x = FixedMul (th->Speed, finecosine[an]); - th->vel.y = FixedMul (th->Speed, finesine[an]); + th->Angles.Yaw = source->AngleTo(dest); + th->VelFromAngle(); - dist = source->AproxDistance (dest); - if (th->Speed) dist = dist / th->Speed; - if (dist < 1) - dist = 1; - - th->vel.z = (dest->Z() - source->Z()) / dist; + double dist = source->DistanceBySpeed(dest, MAX(1., th->Speed)); + th->Vel.Z = (dest->Z() - source->Z()) / dist; if (th->flags4 & MF4_SPECTRAL) { @@ -6090,7 +6030,7 @@ AActor *P_SpawnMissileAngle (AActor *source, PClassActor *type, { return NULL; } - return P_SpawnMissileAngleZSpeed (source, source->Z() + 32*FRACUNIT + source->GetBobOffset(), + return P_SpawnMissileAngleZSpeed (source, source->_f_Z() + 32*FRACUNIT + source->GetBobOffset(), type, angle, vz, GetDefaultSpeed (type)); } @@ -6112,7 +6052,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassAct fixed_t speed; fixed_t vz; - an = source->angle; + an = source->_f_angle(); if (dest->flags & MF_SHADOW) { @@ -6121,7 +6061,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, PClassAct dist = source->AproxDistance (dest); speed = GetDefaultSpeed (type); dist /= speed; - vz = dist != 0 ? (dest->Z() - source->Z())/dist : speed; + vz = dist != 0 ? (dest->_f_Z() - source->_f_Z())/dist : speed; return P_SpawnMissileAngleZSpeed (source, z, type, an, vz, speed); } @@ -6141,7 +6081,7 @@ AActor *P_SpawnMissileAngleSpeed (AActor *source, PClassActor *type, { return NULL; } - return P_SpawnMissileAngleZSpeed (source, source->Z() + 32*FRACUNIT + source->GetBobOffset(), + return P_SpawnMissileAngleZSpeed (source, source->_f_Z() + 32*FRACUNIT + source->GetBobOffset(), type, angle, vz, speed); } @@ -6156,19 +6096,17 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z, if (z != ONFLOORZ && z != ONCEILINGZ) { - z -= source->floorclip; + z -= source->_f_floorclip(); } - mo = Spawn (type, source->X(), source->Y(), z, ALLOW_REPLACE); + mo = Spawn (type, source->_f_X(), source->_f_Y(), z, ALLOW_REPLACE); P_PlaySpawnSound(mo, source); if (owner == NULL) owner = source; mo->target = owner; - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->vel.x = FixedMul (speed, finecosine[angle]); - mo->vel.y = FixedMul (speed, finesine[angle]); - mo->vel.z = vz; + mo->Angles.Yaw = ANGLE2DBL(angle); + mo->VelFromAngle(FIXED2DBL(speed)); + mo->Vel.Z = FIXED2DBL(vz); if (mo->flags4 & MF4_SPECTRAL) { @@ -6193,24 +6131,25 @@ AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type) { return NULL; } - return P_SpawnPlayerMissile (source, 0, 0, 0, type, source->angle); + return P_SpawnPlayerMissile (source, 0, 0, 0, type, source->Angles.Yaw); } -AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, angle_t angle) +AActor *P_SpawnPlayerMissile (AActor *source, PClassActor *type, DAngle angle) { return P_SpawnPlayerMissile (source, 0, 0, 0, type, angle); } AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, - PClassActor *type, angle_t angle, FTranslatedLineTarget *pLineTarget, AActor **pMissileActor, + PClassActor *type, DAngle angle, FTranslatedLineTarget *pLineTarget, AActor **pMissileActor, bool nofreeaim, bool noautoaim, int aimflags) { + //static const double angdiff[3] = { -5.625, 5.625, 0 }; static const int angdiff[3] = { -(1<<26), 1<<26, 0 }; - angle_t an = angle; - angle_t pitch; + DAngle an = angle; + DAngle pitch; FTranslatedLineTarget scratch; AActor *defaultobject = GetDefaultByType(type); - int vrange = nofreeaim ? ANGLE_1*35 : 0; + DAngle vrange = nofreeaim ? 35. : 0.; if (source == NULL) { @@ -6221,7 +6160,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, { // Keep exactly the same angle and pitch as the player's own aim an = angle; - pitch = source->pitch; + pitch = source->Angles.Pitch; pLineTarget->linetarget = NULL; } else // see which target is to be aimed at @@ -6229,7 +6168,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, // [XA] If MaxTargetRange is defined in the spawned projectile, use this as the // maximum range for the P_AimLineAttack call later; this allows MaxTargetRange // to function as a "maximum tracer-acquisition range" for seeker missiles. - fixed_t linetargetrange = defaultobject->maxtargetrange > 0 ? defaultobject->maxtargetrange*64 : 16*64*FRACUNIT; + double linetargetrange = defaultobject->maxtargetrange > 0 ? FIXED2DBL(defaultobject->maxtargetrange*64) : 16*64.; int i = 2; do @@ -6240,7 +6179,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, if (source->player != NULL && !nofreeaim && level.IsFreelookAllowed() && - source->player->userinfo.GetAimDist() <= ANGLE_1/2) + source->player->userinfo.GetAimDist() <= 0.5) { break; } @@ -6251,7 +6190,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, an = angle; if (nofreeaim || !level.IsFreelookAllowed()) { - pitch = 0; + pitch = 0.; } } } @@ -6259,19 +6198,19 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, if (z != ONFLOORZ && z != ONCEILINGZ) { // Doom spawns missiles 4 units lower than hitscan attacks for players. - z += source->Z() + (source->height>>1) - source->floorclip; + z += source->_f_Z() + (source->_f_height()>>1) - source->_f_floorclip(); if (source->player != NULL) // Considering this is for player missiles, it better not be NULL. { - z += FixedMul (source->player->mo->AttackZOffset - 4*FRACUNIT, source->player->crouchfactor); + z += fixed_t ((source->player->mo->AttackZOffset - 4*FRACUNIT) * source->player->crouchfactor); } else { z += 4*FRACUNIT; } // Do not fire beneath the floor. - if (z < source->floorz) + if (z < source->_f_floorz()) { - z = source->floorz; + z = source->_f_floorz(); } } fixedvec2 pos = source->Vec2Offset(x, y); @@ -6279,25 +6218,15 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, if (pMissileActor) *pMissileActor = MissileActor; P_PlaySpawnSound(MissileActor, source); MissileActor->target = source; - MissileActor->angle = an; - - fixed_t vx, vy, vz, speed; - - vx = FixedMul (finecosine[pitch>>ANGLETOFINESHIFT], finecosine[an>>ANGLETOFINESHIFT]); - vy = FixedMul (finecosine[pitch>>ANGLETOFINESHIFT], finesine[an>>ANGLETOFINESHIFT]); - vz = -finesine[pitch>>ANGLETOFINESHIFT]; - speed = MissileActor->Speed; - - DVector3 vec(vx, vy, vz); - - if (MissileActor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)) + MissileActor->Angles.Yaw = an; + if (MissileActor->flags3 & (MF3_FLOORHUGGER | MF3_CEILINGHUGGER)) { - vec.Z = 0; + MissileActor->VelFromAngle(); + } + else + { + MissileActor->Vel3DFromAngle(pitch, MissileActor->Speed); } - vec.Resize(speed); - MissileActor->vel.x = xs_CRoundToInt(vec.X); - MissileActor->vel.y = xs_CRoundToInt(vec.Y); - MissileActor->vel.z = xs_CRoundToInt(vec.Z); if (MissileActor->flags4 & MF4_SPECTRAL) { @@ -6619,9 +6548,9 @@ int AActor::GetGibHealth() const } } -fixed_t AActor::GetCameraHeight() const +double AActor::GetCameraHeight() const { - return GetClass()->CameraHeight == FIXED_MIN ? height / 2 : GetClass()->CameraHeight; + return GetClass()->CameraHeight == INT_MIN ? Height / 2 : GetClass()->CameraHeight; } DDropItem *AActor::GetDropItems() const @@ -6629,10 +6558,10 @@ DDropItem *AActor::GetDropItems() const return GetClass()->DropItems; } -fixed_t AActor::GetGravity() const +double AActor::GetGravity() const { if (flags & MF_NOGRAVITY) return 0; - return fixed_t(level.gravity * Sector->gravity * FIXED2DBL(gravity) * 81.92); + return level.gravity * Sector->gravity * Gravity * 0.00125; } // killough 11/98: @@ -6771,10 +6700,9 @@ void PrintMiscActorInfo(AActor *query) query->args[4], query->special1, query->special2); Printf("\nTID: %d", query->tid); Printf("\nCoord= x: %f, y: %f, z:%f, floor:%f, ceiling:%f.", - FIXED2DBL(query->X()), FIXED2DBL(query->Y()), FIXED2DBL(query->Z()), - FIXED2DBL(query->floorz), FIXED2DBL(query->ceilingz)); + query->X(), query->Y(), query->Z(), + FIXED2DBL(query->_f_floorz()), query->ceilingz); Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n", - FIXED2DBL(query->Speed), FIXED2DBL(query->vel.x), FIXED2DBL(query->vel.y), FIXED2DBL(query->vel.z), - sqrt(pow(FIXED2DBL(query->vel.x), 2) + pow(FIXED2DBL(query->vel.y), 2) + pow(FIXED2DBL(query->vel.z), 2))); + query->Speed, query->Vel.X, query->Vel.Y, query->Vel.Z, query->Vel.Length()); } } diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 60eae8731..7b1dbc50d 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -33,8 +33,8 @@ // MACROS ------------------------------------------------------------------ -#define LOWERSPEED FRACUNIT*6 -#define RAISESPEED FRACUNIT*6 +#define LOWERSPEED 6. +#define RAISESPEED 6. // TYPES ------------------------------------------------------------------- @@ -169,11 +169,11 @@ void P_SetPsprite (player_t *player, int position, FState *state, bool nofunctio if (state->GetMisc1()) { // Set coordinates. - psp->sx = state->GetMisc1()<sx = state->GetMisc1(); } if (state->GetMisc2()) { - psp->sy = state->GetMisc2()<sy = state->GetMisc2(); } if (!nofunction && player->mo != NULL) @@ -394,7 +394,7 @@ void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y) // [RH] Smooth transitions between bobbing and not-bobbing frames. // This also fixes the bug where you can "stick" a weapon off-center by // shooting it when it's at the peak of its swing. - bobtarget = (player->WeaponState & WF_WEAPONBOBBING) ? player->bob : 0; + bobtarget = (player->WeaponState & WF_WEAPONBOBBING) ? FLOAT2FIXED(player->bob) : 0; if (curbob != bobtarget) { if (abs (bobtarget - curbob) <= 1*FRACUNIT) @@ -417,8 +417,8 @@ void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y) if (curbob != 0) { - fixed_t bobx = FixedMul(player->bob, rangex); - fixed_t boby = FixedMul(player->bob, rangey); + fixed_t bobx = fixed_t(player->bob * rangex); + fixed_t boby = fixed_t(player->bob * rangey); switch (bobstyle) { case AWeapon::BobNormal: @@ -919,12 +919,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) // the height of the intended target // -angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimflags) +DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimflags) { - static const int angdiff[3] = { -(1<<26), 1<<26, 0 }; + static const double angdiff[3] = { -5.625f, 5.625f, 0 }; int i; - angle_t an; - angle_t pitch; + DAngle an; + DAngle pitch; FTranslatedLineTarget scratch; if (pLineTarget == NULL) pLineTarget = &scratch; @@ -932,12 +932,12 @@ angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimfl i = 2; do { - an = mo->angle + angdiff[i]; - pitch = P_AimLineAttack (mo, an, 16*64*FRACUNIT, pLineTarget, 0, aimflags); + an = mo->Angles.Yaw + angdiff[i]; + pitch = P_AimLineAttack (mo, an, 16.*64, pLineTarget, 0., aimflags); if (mo->player != NULL && level.IsFreelookAllowed() && - mo->player->userinfo.GetAimDist() <= ANGLE_1/2) + mo->player->userinfo.GetAimDist() <= 0.5) { break; } @@ -950,17 +950,17 @@ angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget, int aimfl // // P_GunShot // -void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, angle_t pitch) +void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, DAngle pitch) { - angle_t angle; + DAngle angle; int damage; damage = 5*(pr_gunshot()%3+1); - angle = mo->angle; + angle = mo->Angles.Yaw; if (!accurate) { - angle += pr_gunshot.Random2 () << 18; + angle += pr_gunshot.Random2 () * (5.625 / 256); } P_LineAttack (mo, angle, PLAYERMISSILERANGE, pitch, damage, NAME_Hitscan, pufftype); diff --git a/src/p_pspr.h b/src/p_pspr.h index fda8cbf15..2f19eb4e8 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -28,12 +28,12 @@ #include "tables.h" #include "thingdef/thingdef.h" -#define WEAPONBOTTOM 128*FRACUNIT +#define WEAPONBOTTOM 128. // [RH] +0x6000 helps it meet the screen bottom // at higher resolutions while still being in // the right spot at 320x200. -#define WEAPONTOP (32*FRACUNIT+0x6000) +#define WEAPONTOP (32+6./16) // @@ -66,8 +66,8 @@ struct pspdef_t { FState* state; // a NULL state means not active int tics; - fixed_t sx; - fixed_t sy; + double sx; + double sy; int sprite; int frame; bool processPending; // true: waiting for periodic processing on this tick @@ -88,8 +88,9 @@ void P_BringUpWeapon (player_t *player); void P_FireWeapon (player_t *player); void P_DropWeapon (player_t *player); void P_BobWeapon (player_t *player, pspdef_t *psp, fixed_t *x, fixed_t *y); -angle_t P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0); -void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, angle_t pitch); +DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0); + +void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, DAngle pitch); void DoReadyWeapon(AActor *self); void DoReadyWeaponToBob(AActor *self); diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 27c8493ea..6a91d7072 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -877,9 +877,9 @@ void sector_t::CheckPortalPlane(int plane) AActor *portal = SkyBoxes[plane]; if (!portal || portal->special1 != SKYBOX_LINKEDPORTAL) return; - fixed_t planeh = planes[plane].TexZ; + double planeh = FIXED2DBL(planes[plane].TexZ); int obstructed = PLANEF_OBSTRUCTED * (plane == sector_t::floor ? - planeh > portal->threshold : planeh < portal->threshold); + planeh > portal->specialf1 : planeh < portal->specialf1); planes[plane].Flags = (planes[plane].Flags & ~PLANEF_OBSTRUCTED) | obstructed; } @@ -889,18 +889,18 @@ void sector_t::CheckPortalPlane(int plane) // //=========================================================================== -fixed_t sector_t::HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec) +fixed_t sector_t::_f_HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec) { sector_t *check = this; fixed_t planeheight = FIXED_MIN; // Continue until we find a blocking portal or a portal below where we actually are. - while (!check->PortalBlocksMovement(ceiling) && planeheight < check->SkyBoxes[ceiling]->threshold) + while (!check->PortalBlocksMovement(ceiling) && planeheight < FLOAT2FIXED(check->SkyBoxes[ceiling]->specialf1)) { fixedvec2 pos = check->CeilingDisplacement(); x += pos.x; y += pos.y; - planeheight = check->SkyBoxes[ceiling]->threshold; + planeheight = FLOAT2FIXED(check->SkyBoxes[ceiling]->specialf1); check = P_PointInSector(x, y); } if (resultsec) *resultsec = check; @@ -913,18 +913,18 @@ fixed_t sector_t::HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec) // //=========================================================================== -fixed_t sector_t::LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec) +fixed_t sector_t::_f_LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec) { sector_t *check = this; fixed_t planeheight = FIXED_MAX; // Continue until we find a blocking portal or a portal above where we actually are. - while (!check->PortalBlocksMovement(floor) && planeheight > check->SkyBoxes[floor]->threshold) + while (!check->PortalBlocksMovement(floor) && planeheight > FLOAT2FIXED(check->SkyBoxes[floor]->specialf1)) { fixedvec2 pos = check->FloorDisplacement(); x += pos.x; y += pos.y; - planeheight = check->SkyBoxes[floor]->threshold; + planeheight = FLOAT2FIXED(check->SkyBoxes[floor]->specialf1); check = P_PointInSector(x, y); } if (resultsec) *resultsec = check; @@ -959,7 +959,7 @@ fixed_t sector_t::NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fi return ff_bottom; } } - if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= sec->SkyBoxes[ceiling]->threshold) + if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(ceiling) || planeheight >= FLOAT2FIXED(sec->SkyBoxes[ceiling]->specialf1)) { // Use sector's floor if (resultffloor) *resultffloor = NULL; if (resultsec) *resultsec = sec; @@ -970,7 +970,7 @@ fixed_t sector_t::NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fi fixedvec2 pos = sec->CeilingDisplacement(); x += pos.x; y += pos.y; - planeheight = sec->SkyBoxes[ceiling]->threshold; + planeheight = FLOAT2FIXED(sec->SkyBoxes[ceiling]->specialf1); sec = P_PointInSector(x, y); } } @@ -1004,7 +1004,7 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, } } } - if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::floor) || planeheight <= sec->SkyBoxes[floor]->threshold) + if ((flags & FFCF_NOPORTALS) || sec->PortalBlocksMovement(sector_t::floor) || planeheight <= FLOAT2FIXED(sec->SkyBoxes[floor]->specialf1)) { // Use sector's floor if (resultffloor) *resultffloor = NULL; if (resultsec) *resultsec = sec; @@ -1015,7 +1015,7 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, fixedvec2 pos = sec->FloorDisplacement(); x += pos.x; y += pos.y; - planeheight = sec->SkyBoxes[floor]->threshold; + planeheight = FLOAT2FIXED(sec->SkyBoxes[floor]->specialf1); sec = P_PointInSector(x, y); } } @@ -1027,6 +1027,32 @@ fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, int flags, // //=========================================================================== +fixed_t sector_t::GetFriction(int plane, fixed_t *pMoveFac) const +{ + if (Flags & SECF_FRICTION) + { + if (pMoveFac) *pMoveFac = movefactor; + return friction; + } + FTerrainDef *terrain = &Terrains[GetTerrain(plane)]; + if (terrain->Friction != 0) + { + if (pMoveFac) *pMoveFac = terrain->MoveFactor; + return terrain->Friction; + } + else + { + if (pMoveFac) *pMoveFac = ORIG_FRICTION_FACTOR; + return ORIG_FRICTION; + } +} + +//=========================================================================== +// +// +// +//=========================================================================== + FArchive &operator<< (FArchive &arc, secspecial_t &p) { if (SaveVersion < 4529) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 5232ab37f..eeab02133 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1324,7 +1324,7 @@ void P_LoadSegs (MapData * map) segangle >>= (ANGLETOFINESHIFT-16); dx = (li->v1->x - li->v2->x)>>FRACBITS; dy = (li->v1->y - li->v2->y)>>FRACBITS; - dis = ((int) sqrt((double)(dx*dx + dy*dy)))< vnum1) && (vertchanged[vnum2] == 0)) @@ -1755,7 +1755,7 @@ void P_LoadThings (MapData * map) memset (&mti[i], 0, sizeof(mti[i])); - mti[i].gravity = FRACUNIT; + mti[i].Gravity = 1; mti[i].Conversation = 0; mti[i].SkillFilter = MakeSkill(flags); mti[i].ClassFilter = 0xffff; // Doom map format doesn't have class flags so spawn for all player classes @@ -1854,7 +1854,7 @@ void P_LoadThings2 (MapData * map) mti[i].flags &= 0x7ff; // mask out Strife flags if playing an original Hexen map. } - mti[i].gravity = FRACUNIT; + mti[i].Gravity = 1; mti[i].RenderStyle = STYLE_Count; mti[i].alpha = -1; mti[i].health = 1; @@ -2024,7 +2024,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha) } // [RH] Set some new sidedef properties - int len = (int)(sqrt (dx*dx + dy*dy) + 0.5f); + int len = (int)(g_sqrt (dx*dx + dy*dy) + 0.5f); if (ld->sidedef[0] != NULL) { diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 7669ac888..dfe510f85 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -114,7 +114,7 @@ public: { sightstart = t1->PosRelative(task->portalgroup); sightend = t2->PosRelative(task->portalgroup); - sightstart.z += t1->height - (t1->height >> 2); + sightstart.z += t1->_f_height() - (t1->_f_height() >> 2); startfrac = task->frac; trace = { sightstart.x, sightstart.y, sightend.x - sightstart.x, sightend.y - sightstart.y }; @@ -863,16 +863,16 @@ sightcounts[0]++; if (!(flags & SF_IGNOREWATERBOUNDARY)) { if ((s1->GetHeightSec() && - ((t1->Z() + t1->height <= s1->heightsec->floorplane.ZatPoint(t1) && - t2->Z() >= s1->heightsec->floorplane.ZatPoint(t2)) || - (t1->Z() >= s1->heightsec->ceilingplane.ZatPoint(t1) && - t2->Z() + t1->height <= s1->heightsec->ceilingplane.ZatPoint(t2)))) + ((t1->_f_Z() + t1->_f_height() <= s1->heightsec->floorplane.ZatPoint(t1) && + t2->_f_Z() >= s1->heightsec->floorplane.ZatPoint(t2)) || + (t1->_f_Z() >= s1->heightsec->ceilingplane.ZatPoint(t1) && + t2->_f_Z() + t1->_f_height() <= s1->heightsec->ceilingplane.ZatPoint(t2)))) || (s2->GetHeightSec() && - ((t2->Z() + t2->height <= s2->heightsec->floorplane.ZatPoint(t2) && - t1->Z() >= s2->heightsec->floorplane.ZatPoint(t1)) || - (t2->Z() >= s2->heightsec->ceilingplane.ZatPoint(t2) && - t1->Z() + t2->height <= s2->heightsec->ceilingplane.ZatPoint(t1))))) + ((t2->_f_Z() + t2->_f_height() <= s2->heightsec->floorplane.ZatPoint(t2) && + t1->_f_Z() >= s2->heightsec->floorplane.ZatPoint(t1)) || + (t2->_f_Z() >= s2->heightsec->ceilingplane.ZatPoint(t2) && + t1->_f_Z() + t2->_f_height() <= s2->heightsec->ceilingplane.ZatPoint(t1))))) { res = false; goto done; @@ -886,11 +886,11 @@ sightcounts[0]++; portals.Clear(); { sector_t *sec; - fixed_t lookheight = t1->height - (t1->height >> 2); + fixed_t lookheight = t1->_f_height() - (t1->_f_height() >> 2); t1->GetPortalTransition(lookheight, &sec); - fixed_t bottomslope = t2->Z() - (t1->Z() + lookheight); - fixed_t topslope = bottomslope + t2->height; + fixed_t bottomslope = t2->_f_Z() - (t1->_f_Z() + lookheight); + fixed_t topslope = bottomslope + t2->_f_height(); SightTask task = { 0, topslope, bottomslope, -1, sec->PortalGroup }; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 81b1899ba..22c126855 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -139,12 +139,9 @@ void DPusher::Serialize (FArchive &arc) Super::Serialize (arc); arc << m_Type << m_Source - << m_Xmag - << m_Ymag + << m_PushVec << m_Magnitude << m_Radius - << m_X - << m_Y << m_Affectee; } @@ -439,7 +436,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) { // Falling, not all the way down yet? sector = player->mo->Sector; - if (player->mo->Z() != sector->LowestFloorAt(player->mo) + if (player->mo->_f_Z() != sector->_f_LowestFloorAt(player->mo) && !player->mo->waterlevel) { return; @@ -516,7 +513,7 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type, if (!(flags & DAMAGE_PLAYERS) && actor->player != NULL) return; - if (!(flags & DAMAGE_IN_AIR) && actor->Z() != sec->floorplane.ZatPoint(actor) && !actor->waterlevel) + if (!(flags & DAMAGE_IN_AIR) && actor->_f_Z() != sec->floorplane.ZatPoint(actor) && !actor->waterlevel) return; if (protectClass != NULL) @@ -562,12 +559,12 @@ void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, z1 = z2; z2 = zz; } - if (actor->Z() + actor->height > z1) + if (actor->_f_Z() + actor->_f_height() > z1) { // If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be // damaged (so, anything touching it or above it). Other 3D floors between // the actor and this one will not stop this effect. - if ((flags & DAMAGE_IN_AIR) || actor->Z() <= z2) + if ((flags & DAMAGE_IN_AIR) || actor->_f_Z() <= z2) { // Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it // only works with the real sector's floor. We did the appropriate height checks @@ -1069,9 +1066,9 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha, int linked reference->special1 = linked ? SKYBOX_LINKEDPORTAL : SKYBOX_PORTAL; anchor->special1 = SKYBOX_ANCHOR; // store the portal displacement in the unused scaleX/Y members of the portal reference actor. - anchor->scaleX = -(reference->scaleX = x2 - x1); - anchor->scaleY = -(reference->scaleY = y2 - y1); - anchor->threshold = reference->threshold = z; + anchor->Scale.X = -(reference->Scale.X = FIXED2DBL(x2 - x1)); + anchor->Scale.Y = -(reference->Scale.Y = FIXED2DBL(y2 - y1)); + anchor->specialf1 = reference->specialf1 = FIXED2FLOAT(z); reference->Mate = anchor; anchor->Mate = reference; @@ -1095,7 +1092,7 @@ void P_SpawnSkybox(ASkyViewpoint *origin) if (Sector == NULL) { Printf("Sector not initialized for SkyCamCompat\n"); - origin->Sector = Sector = P_PointInSector(origin->X(), origin->Y()); + origin->Sector = Sector = P_PointInSector(origin->_f_X(), origin->_f_Y()); } if (Sector) { @@ -1493,7 +1490,7 @@ void P_SpawnSpecials (void) { case Init_Gravity: { - float grav = ((float)P_AproxDistance (lines[i].dx, lines[i].dy)) / (FRACUNIT * 100.0f); + double grav = lines[i].Delta().Length() / 100.; FSectorTagIterator itr(lines[i].args[0]); while ((s = itr.Next()) >= 0) sectors[s].gravity = grav; @@ -2189,7 +2186,7 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag) // types 1 & 2 is the sector containing the MT_PUSH/MT_PULL Thing. -#define PUSH_FACTOR 7 +#define PUSH_FACTOR 128 ///////////////////////////// // @@ -2202,9 +2199,8 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, m_Type = type; if (l) { - m_Xmag = l->dx>>FRACBITS; - m_Ymag = l->dy>>FRACBITS; - m_Magnitude = P_AproxDistance (m_Xmag, m_Ymag); + m_PushVec = l->Delta(); + m_Magnitude = m_PushVec.Length(); } else { // [RH] Allow setting magnitude and angle with parameters @@ -2212,9 +2208,7 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle, } if (source) // point source exist? { - m_Radius = (m_Magnitude) << (FRACBITS+1); // where force goes to zero - m_X = m_Source->X(); - m_Y = m_Source->Y(); + m_Radius = m_Magnitude * 2; // where force goes to zero } m_Affectee = affectee; } @@ -2230,7 +2224,7 @@ int DPusher::CheckForSectorMatch (EPusher type, int tag) ///////////////////////////// // -// T_Pusher looks for all objects that are inside the radius of +// T_Pusher looks for all objects that are inside the _f_radius() of // the effect. // void DPusher::Tick () @@ -2238,7 +2232,6 @@ void DPusher::Tick () sector_t *sec; AActor *thing; msecnode_t *node; - int xspeed,yspeed; int ht; if (!var_pushers) @@ -2273,11 +2266,11 @@ void DPusher::Tick () if (m_Type == p_push) { - // Seek out all pushable things within the force radius of this + // Seek out all pushable things within the force _f_radius() of this // point pusher. Crosses sectors, so use blockmap. FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware. - FMultiBlockThingsIterator it(check, m_X, m_Y, 0, 0, m_Radius, false, m_Source->Sector); + FMultiBlockThingsIterator it(check, m_Source, FLOAT2FIXED(m_Radius)); FMultiBlockThingsIterator::CheckResult cres; @@ -2296,22 +2289,18 @@ void DPusher::Tick () if ((pusharound) ) { - int sx = m_X; - int sy = m_Y; - int dist = thing->AproxDistance (sx, sy); - int speed = (m_Magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS-PUSH_FACTOR-1); + DVector2 pos = m_Source->Vec2To(thing); + double dist = pos.Length(); + double speed = (m_Magnitude - (dist/2)) / (PUSH_FACTOR * 2); - // If speed <= 0, you're outside the effective radius. You also have + // If speed <= 0, you're outside the effective _f_radius(). You also have // to be able to see the push/pull source point. if ((speed > 0) && (P_CheckSight (thing, m_Source, SF_IGNOREVISIBILITY))) { - angle_t pushangle = thing->AngleTo(sx, sy); - if (m_Source->GetClass()->TypeName == NAME_PointPusher) - pushangle += ANG180; // away - pushangle >>= ANGLETOFINESHIFT; - thing->vel.x += FixedMul (speed, finecosine[pushangle]); - thing->vel.y += FixedMul (speed, finesine[pushangle]); + DAngle pushangle = pos.Angle(); + if (m_Source->GetClass()->TypeName == NAME_PointPuller) pushangle += 180; + thing->Thrust(pushangle, speed); } } } @@ -2329,37 +2318,34 @@ void DPusher::Tick () sector_t *hsec = sec->GetHeightSec(); fixedvec3 pos = thing->PosRelative(sec); + DVector2 pushvel; if (m_Type == p_wind) { if (hsec == NULL) { // NOT special water sector if (thing->Z() > thing->floorz) // above ground { - xspeed = m_Xmag; // full force - yspeed = m_Ymag; + pushvel = m_PushVec; // full force } else // on ground { - xspeed = (m_Xmag)>>1; // half force - yspeed = (m_Ymag)>>1; + pushvel = m_PushVec / 2; // half force } } else // special water sector { ht = hsec->floorplane.ZatPoint(pos); - if (thing->Z() > ht) // above ground + if (thing->_f_Z() > ht) // above ground { - xspeed = m_Xmag; // full force - yspeed = m_Ymag; + pushvel = m_PushVec; // full force } else if (thing->player->viewz < ht) // underwater { - xspeed = yspeed = 0; // no force + pushvel.Zero(); // no force } else // wading in water { - xspeed = (m_Xmag)>>1; // half force - yspeed = (m_Ymag)>>1; + pushvel = m_PushVec / 2; // full force } } } @@ -2375,18 +2361,16 @@ void DPusher::Tick () { // special water sector floor = &hsec->floorplane; } - if (thing->Z() > floor->ZatPoint(pos)) + if (thing->_f_Z() > floor->ZatPoint(pos)) { // above ground - xspeed = yspeed = 0; // no force + pushvel.Zero(); // no force } else { // on ground/underwater - xspeed = m_Xmag; // full force - yspeed = m_Ymag; + pushvel = m_PushVec; // full force } } - thing->vel.x += xspeed<<(FRACBITS-PUSH_FACTOR); - thing->vel.y += yspeed<<(FRACBITS-PUSH_FACTOR); + thing->Vel += pushvel / PUSH_FACTOR; } } diff --git a/src/p_spec.h b/src/p_spec.h index e3b1c05ad..7fe978476 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -95,7 +95,8 @@ private: // Factor to scale scrolling effect into mobj-carrying properties = 3/32. // (This is so scrolling floors and objects on them can move at same speed.) -enum { CARRYFACTOR = (3*FRACUNIT >> 5) }; +enum { _f_CARRYFACTOR = (3*FRACUNIT >> 5) }; +const double CARRYFACTOR = 3 / 32.; // phares 3/20/98: added new model of Pushers for push/pull effects @@ -118,9 +119,8 @@ public: int CheckForSectorMatch (EPusher type, int tag); void ChangeValues (int magnitude, int angle) { - angle_t ang = ((angle_t)(angle<<24)) >> ANGLETOFINESHIFT; - m_Xmag = (magnitude * finecosine[ang]) >> FRACBITS; - m_Ymag = (magnitude * finesine[ang]) >> FRACBITS; + DAngle ang = angle * (360. / 256.); + m_PushVec = ang.ToVector(magnitude); m_Magnitude = magnitude; } @@ -129,12 +129,9 @@ public: protected: EPusher m_Type; TObjPtr m_Source;// Point source if point pusher - int m_Xmag; // X Strength - int m_Ymag; // Y Strength - int m_Magnitude; // Vector strength for point pusher - int m_Radius; // Effective radius for point pusher - int m_X; // X of point source if point pusher - int m_Y; // Y of point source if point pusher + DVector2 m_PushVec; + double m_Magnitude; // Vector strength for point pusher + double m_Radius; // Effective _f_radius() for point pusher int m_Affectee; // Number of affected sector friend bool PIT_PushThing (AActor *thing); @@ -571,6 +568,14 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing, int tag, int speed, int delay, int lock, int lightTag, bool boomgen = false, int topcountdown = 0); +inline bool EV_DoDoor(DDoor::EVlDoor type, line_t *line, AActor *thing, + int tag, double speed, int delay, int lock, + int lightTag, bool boomgen = false, int topcountdown = 0) +{ + return EV_DoDoor(type, line, thing, tag, FLOAT2FIXED(speed), delay, lock, lightTag, boomgen, topcountdown); +} + + class DAnimatedDoor : public DMovingCeiling { DECLARE_CLASS (DAnimatedDoor, DMovingCeiling) @@ -919,7 +924,11 @@ inline void P_SpawnTeleportFog(AActor *mobj, const fixedvec3 &pos, bool beforeTe { P_SpawnTeleportFog(mobj, pos.x, pos.y, pos.z, beforeTele, setTarget); } -bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false +inline void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTele = true, bool setTarget = false) +{ + P_SpawnTeleportFog(mobj, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), beforeTele, setTarget); +} +bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, DAngle angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags); bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse); bool EV_TeleportOther (int other_tid, int dest_tid, bool fog); diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 254abb0ad..7871b8aaa 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -143,8 +143,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo fixedvec3 pos = optpos? *optpos : user->PosRelative(line); dlu.x = pos.x; dlu.y = pos.y; - dlu.dx = finecosine[user->angle >> ANGLETOFINESHIFT]; - dlu.dy = finesine[user->angle >> ANGLETOFINESHIFT]; + dlu.dx = finecosine[user->_f_angle() >> ANGLETOFINESHIFT]; + dlu.dy = finesine[user->_f_angle() >> ANGLETOFINESHIFT]; inter = P_InterceptVector(&dll, &dlu); @@ -170,7 +170,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo onesided: fixed_t sectorc = front->ceilingplane.ZatPoint(checkx, checky); fixed_t sectorf = front->floorplane.ZatPoint(checkx, checky); - return (user->Top() >= sectorf && user->Z() <= sectorc); + return (user->_f_Top() >= sectorf && user->_f_Z() <= sectorc); } // Now get the information from the line. @@ -190,8 +190,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_UPPERTEXTURE)) continue; - if (user->Z() > rover->top.plane->ZatPoint(checkx, checky) || - user->Top() < rover->bottom.plane->ZatPoint(checkx, checky)) + if (user->_f_Z() > rover->top.plane->ZatPoint(checkx, checky) || + user->_f_Top() < rover->bottom.plane->ZatPoint(checkx, checky)) continue; // This 3D floor depicts a switch texture in front of the player's eyes @@ -199,7 +199,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo } } - return (user->Top() > open.top); + return (user->_f_Top() > open.top); } else if ((TexMan.FindSwitch(side->GetTexture(side_t::bottom))) != NULL) { @@ -212,8 +212,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo if (!(rover->flags & FF_EXISTS)) continue; if (!(rover->flags & FF_LOWERTEXTURE)) continue; - if (user->Z() > rover->top.plane->ZatPoint(checkx, checky) || - user->Top() < rover->bottom.plane->ZatPoint(checkx, checky)) + if (user->_f_Z() > rover->top.plane->ZatPoint(checkx, checky) || + user->_f_Top() < rover->bottom.plane->ZatPoint(checkx, checky)) continue; // This 3D floor depicts a switch texture in front of the player's eyes @@ -221,7 +221,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo } } - return (user->Z() < open.bottom); + return (user->_f_Z() < open.bottom); } else if ((flags & ML_3DMIDTEX) || (TexMan.FindSwitch(side->GetTexture(side_t::mid))) != NULL) { @@ -229,12 +229,12 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, fixedvec3 *optpo // to keep compatibility with Eternity's implementation. if (!P_GetMidTexturePosition(line, sideno, &checktop, &checkbot)) return false; - return user->Z() < checktop && user->Top() > checkbot; + return user->_f_Z() < checktop && user->_f_Top() > checkbot; } else { // no switch found. Check whether the player can touch either top or bottom texture - return (user->Top() > open.top) || (user->Z() < open.bottom); + return (user->_f_Top() > open.top) || (user->_f_Z() < open.bottom); } } diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index b6bdceda5..61eb73dc7 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -99,7 +99,7 @@ void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool befo // TELEPORTATION // -bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags) +bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, DAngle angle, int flags) { bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING)); @@ -109,10 +109,10 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, sector_t *destsect; bool resetpitch = false; fixed_t floorheight, ceilingheight; - fixed_t missilespeed = 0; + double missilespeed = 0; - old = thing->Pos(); - aboveFloor = thing->Z() - thing->floorz; + old = thing->_f_Pos(); + aboveFloor = thing->_f_Z() - thing->_f_floorz(); destsect = P_PointInSector (x, y); // killough 5/12/98: exclude voodoo dolls: player = thing->player; @@ -122,7 +122,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, ceilingheight = destsect->ceilingplane.ZatPoint (x, y); if (thing->flags & MF_MISSILE) { // We don't measure z velocity, because it doesn't change. - missilespeed = xs_CRoundToInt(DVector2(thing->vel.x, thing->vel.y).Length()); + missilespeed = thing->VelXYToSpeed(); } if (flags & TELF_KEEPHEIGHT) { @@ -135,9 +135,9 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, if (thing->flags & MF_NOGRAVITY && aboveFloor) { z = floorheight + aboveFloor; - if (z + thing->height > ceilingheight) + if (z + thing->_f_height() > ceilingheight) { - z = ceilingheight - thing->height; + z = ceilingheight - thing->_f_height(); } } else @@ -152,9 +152,9 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, else if (thing->flags & MF_MISSILE) { z = floorheight + aboveFloor; - if (z + thing->height > ceilingheight) + if (z + thing->_f_height() > ceilingheight) { - z = ceilingheight - thing->height; + z = ceilingheight - thing->_f_height(); } } else @@ -168,19 +168,19 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, } if (player) { - player->viewz = thing->Z() + player->viewheight; + player->viewz = thing->_f_Z() + player->viewheight; if (resetpitch) { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; } } if (!(flags & TELF_KEEPORIENTATION)) { - thing->angle = angle; + thing->Angles.Yaw = angle; } else { - angle = thing->angle; + angle = thing->Angles.Yaw; } // Spawn teleport fog at source and destination if ((flags & TELF_SOURCEFOG) && !predicting) @@ -194,7 +194,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; fixedvec2 vector = Vec2Angle(20 * FRACUNIT, angle); fixedvec2 fogpos = P_GetOffsetPosition(x, y, vector.x, vector.y); - P_SpawnTeleportFog(thing, fogpos.x, fogpos.y, thing->Z() + fogDelta, false, true); + P_SpawnTeleportFog(thing, fogpos.x, fogpos.y, thing->_f_Z() + fogDelta, false, true); } if (thing->player) @@ -214,17 +214,14 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, } if (thing->flags & MF_MISSILE) { - angle >>= ANGLETOFINESHIFT; - thing->vel.x = FixedMul (missilespeed, finecosine[angle]); - thing->vel.y = FixedMul (missilespeed, finesine[angle]); + thing->VelFromAngle(missilespeed); } // [BC] && bHaltVelocity. else if (!(flags & TELF_KEEPORIENTATION) && !(flags & TELF_KEEPVELOCITY)) { // no fog doesn't alter the player's momentum - thing->vel.x = thing->vel.y = thing->vel.z = 0; + thing->Vel.Zero(); // killough 10/98: kill all bobbing velocity too - if (player) - player->vel.x = player->vel.y = 0; + if (player) player->Vel.Zero(); } return true; } @@ -328,10 +325,10 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int f { AActor *searcher; fixed_t z; - angle_t angle = 0; - fixed_t s = 0, c = 0; - fixed_t vx = 0, vy = 0; - angle_t badangle = 0; + DAngle angle = 0.; + double s = 0, c = 0; + double vx = 0, vy = 0; + DAngle badangle = 0.; if (thing == NULL) { // Teleport function called with an invalid actor @@ -358,21 +355,21 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int f // Rotate 90 degrees, so that walking perpendicularly across // teleporter linedef causes thing to exit in the direction // indicated by the exit thing. - angle = R_PointToAngle2 (0, 0, line->dx, line->dy) - searcher->angle + ANG90; + angle = VecToAngle(line->dx, line->dy) - searcher->Angles.Yaw + 90; // Sine, cosine of angle adjustment - s = finesine[angle>>ANGLETOFINESHIFT]; - c = finecosine[angle>>ANGLETOFINESHIFT]; + s = angle.Sin(); + c = angle.Cos(); // Velocity of thing crossing teleporter linedef - vx = thing->vel.x; - vy = thing->vel.y; + vx = thing->Vel.X; + vy = thing->Vel.Y; - z = searcher->Z(); + z = searcher->_f_Z(); } else if (searcher->IsKindOf (PClass::FindClass(NAME_TeleportDest2))) { - z = searcher->Z(); + z = searcher->_f_Z(); } else { @@ -380,21 +377,21 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int f } if ((i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL)) { - badangle = 1 << ANGLETOFINESHIFT; + badangle = 0.01; } - if (P_Teleport (thing, searcher->X(), searcher->Y(), z, searcher->angle + badangle, flags)) + if (P_Teleport (thing, searcher->_f_X(), searcher->_f_Y(), z, searcher->Angles.Yaw + badangle, flags)) { // [RH] Lee Killough's changes for silent teleporters from BOOM if (!(flags & TELF_DESTFOG) && line && (flags & TELF_KEEPORIENTATION)) { // Rotate thing according to difference in angles - thing->angle += angle; + thing->Angles.Yaw += angle; // Rotate thing's velocity to come out of exit just like it entered - thing->vel.x = FixedMul(vx, c) - FixedMul(vy, s); - thing->vel.y = FixedMul(vy, c) + FixedMul(vx, s); + thing->Vel.X = vx*c - vy*s; + thing->Vel.Y = vy*c + vx*s; } - if ((vx | vy) == 0 && thing->player != NULL && thing->player->mo == thing && !predicting) + if (vx == 0 && vy == 0 && thing->player != NULL && thing->player->mo == thing && !predicting) { thing->player->mo->PlayIdle (); } @@ -429,65 +426,57 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO if ((l=lines+i) != line && l->backsector) { // Get the thing's position along the source linedef - SDWORD pos; // 30.2 fixed - fixed_t nposx, nposy; // offsets from line - { - SQWORD den; + double pos; + DVector2 npos; // offsets from line + double den; - den = (SQWORD)line->dx*line->dx + (SQWORD)line->dy*line->dy; - if (den == 0) + den = line->Delta().LengthSquared(); + if (den == 0) + { + pos = 0; + npos.Zero(); + } + else + { + double num = (thing->Pos().XY() - line->V1()) | line->Delta(); + if (num <= 0) { pos = 0; - nposx = 0; - nposy = 0; + } + else if (num >= den) + { + pos = 1; } else { - SQWORD num = (SQWORD)(thing->X()-line->v1->x)*line->dx + - (SQWORD)(thing->Y()-line->v1->y)*line->dy; - if (num <= 0) - { - pos = 0; - } - else if (num >= den) - { - pos = 1<<30; - } - else - { - pos = (SDWORD)(num / (den>>30)); - } - nposx = thing->X() - line->v1->x - MulScale30 (line->dx, pos); - nposy = thing->Y() - line->v1->y - MulScale30 (line->dy, pos); + pos = num / den; } + npos = thing->Pos().XY() - line->V1() - line->Delta() * pos; } // Get the angle between the two linedefs, for rotating // orientation and velocity. Rotate 180 degrees, and flip // the position across the exit linedef, if reversed. - angle_t angle = - R_PointToAngle2(0, 0, l->dx, l->dy) - - R_PointToAngle2(0, 0, line->dx, line->dy); + DAngle angle = VecToAngle(l->Delta()) - VecToAngle(line->Delta()); if (!reverse) { - angle += ANGLE_180; - pos = (1<<30) - pos; + angle += 180.; + pos = 1 - pos; } // Sine, cosine of angle adjustment - fixed_t s = finesine[angle>>ANGLETOFINESHIFT]; - fixed_t c = finecosine[angle>>ANGLETOFINESHIFT]; + double s = angle.Sin(); + double c = angle.Cos(); - fixed_t x, y; + DVector2 p; // Rotate position along normal to match exit linedef - x = DMulScale16 (nposx, c, -nposy, s); - y = DMulScale16 (nposy, c, nposx, s); + p.X = npos.X*c - npos.Y*s; + p.Y = npos.Y*c + npos.X*s; // Interpolate position across the exit linedef - x += l->v1->x + MulScale30 (pos, l->dx); - y += l->v1->y + MulScale30 (pos, l->dy); + p += l->V1() + pos*l->Delta(); // Whether this is a player, and if so, a pointer to its player_t. // Voodoo dolls are excluded by making sure thing->player->mo==thing. @@ -495,10 +484,12 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO thing->player : NULL; // Whether walking towards first side of exit linedef steps down + fixed_t x = FLOAT2FIXED(p.X); + fixed_t y = FLOAT2FIXED(p.Y); bool stepdown = l->frontsector->floorplane.ZatPoint(x, y) < l->backsector->floorplane.ZatPoint(x, y); // Height of thing above ground - fixed_t z = thing->Z() - thing->floorz; + fixed_t z = thing->_f_Z() - thing->_f_floorz(); // Side to exit the linedef on positionally. // @@ -551,24 +542,22 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO } // Rotate thing's orientation according to difference in linedef angles - thing->angle += angle; + thing->Angles.Yaw += angle; // Velocity of thing crossing teleporter linedef - x = thing->vel.x; - y = thing->vel.y; + p = thing->Vel.XY(); // Rotate thing's velocity to come out of exit just like it entered - thing->vel.x = DMulScale16 (x, c, -y, s); - thing->vel.y = DMulScale16 (y, c, x, s); + thing->Vel.X = p.X*c - p.Y*s; + thing->Vel.Y = p.Y*c + p.X*s; // Adjust a player's view, in case there has been a height change if (player && player->mo == thing) { // Adjust player's local copy of velocity - x = player->vel.x; - y = player->vel.y; - player->vel.x = DMulScale16 (x, c, -y, s); - player->vel.y = DMulScale16 (y, c, x, s); + p = player->Vel; + player->Vel.X = p.X*c - p.Y*s; + player->Vel.Y = p.Y*c + p.X*s; // Save the current deltaviewheight, used in stepping fixed_t deltaviewheight = player->deltaviewheight; @@ -611,20 +600,19 @@ bool EV_TeleportOther (int other_tid, int dest_tid, bool fog) static bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool floorz, bool fog) { - int an = (dest->angle - source->angle) >> ANGLETOFINESHIFT; - fixed_t offX = victim->X() - source->X(); - fixed_t offY = victim->Y() - source->Y(); - angle_t offAngle = victim->angle - source->angle; + int an = (dest->_f_angle() - source->_f_angle()) >> ANGLETOFINESHIFT; + fixed_t offX = victim->_f_X() - source->_f_X(); + fixed_t offY = victim->_f_Y() - source->_f_Y(); fixed_t newX = DMulScale16 (offX, finecosine[an], -offY, finesine[an]); fixed_t newY = DMulScale16 (offX, finesine[an], offY, finecosine[an]); bool res = - P_Teleport (victim, dest->X() + newX, - dest->Y() + newY, - floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(), - 0, fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION); + P_Teleport (victim, dest->_f_X() + newX, + dest->_f_Y() + newY, + floorz ? ONFLOORZ : dest->_f_Z() + victim->_f_Z() - source->_f_Z(), + 0., fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION); // P_Teleport only changes angle if fog is true - victim->angle = dest->angle + offAngle; + victim->Angles.Yaw = (dest->Angles.Yaw + victim->Angles.Yaw - source->Angles.Yaw).Normalized360(); return res; } @@ -632,7 +620,7 @@ static bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool fl #if 0 static void MoveTheDecal (DBaseDecal *decal, fixed_t z, AActor *source, AActor *dest) { - int an = (dest->angle - source->angle) >> ANGLETOFINESHIFT; + int an = (dest->_f_angle() - source->_f_angle()) >> ANGLETOFINESHIFT; fixed_t offX = decal->x - source->x; fixed_t offY = decal->y - source->y; fixed_t newX = DMulScale16 (offX, finecosine[an], -offY, finesine[an]); @@ -689,9 +677,9 @@ bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_t if (moveSource && didSomething) { didSomething |= - P_Teleport (sourceOrigin, destOrigin->X(), destOrigin->Y(), - floorz ? ONFLOORZ : destOrigin->Z(), 0, TELF_KEEPORIENTATION); - sourceOrigin->angle = destOrigin->angle; + P_Teleport (sourceOrigin, destOrigin->_f_X(), destOrigin->_f_Y(), + floorz ? ONFLOORZ : destOrigin->_f_Z(), 0., TELF_KEEPORIENTATION); + sourceOrigin->Angles.Yaw = destOrigin->Angles.Yaw; } return didSomething; diff --git a/src/p_terrain.cpp b/src/p_terrain.cpp index 3c6519393..a91d7fe92 100644 --- a/src/p_terrain.cpp +++ b/src/p_terrain.cpp @@ -95,6 +95,7 @@ enum EGenericType GEN_Class, GEN_Splash, GEN_Float, + GEN_Double, GEN_Time, GEN_Bool, GEN_Int, @@ -201,7 +202,7 @@ static FGenericParse SplashParser[] = { GEN_Byte, {myoffsetof(FSplashDef, ChunkXVelShift)} }, { GEN_Byte, {myoffsetof(FSplashDef, ChunkYVelShift)} }, { GEN_Byte, {myoffsetof(FSplashDef, ChunkZVelShift)} }, - { GEN_Fixed, {myoffsetof(FSplashDef, ChunkBaseZVel)} }, + { GEN_Double, {myoffsetof(FSplashDef, ChunkBaseZVel)} }, { GEN_Bool, {myoffsetof(FSplashDef, NoAlert)} } }; @@ -212,7 +213,7 @@ static FGenericParse TerrainParser[] = { GEN_Int, {myoffsetof(FTerrainDef, DamageAmount)} }, { GEN_Custom, {(size_t)ParseDamage} }, { GEN_Int, {myoffsetof(FTerrainDef, DamageTimeMask)} }, - { GEN_Fixed, {myoffsetof(FTerrainDef, FootClip)} }, + { GEN_Double, {myoffsetof(FTerrainDef, FootClip)} }, { GEN_Float, {myoffsetof(FTerrainDef, StepVolume)} }, { GEN_Time, {myoffsetof(FTerrainDef, WalkStepTics)} }, { GEN_Time, {myoffsetof(FTerrainDef, RunStepTics)} }, @@ -360,7 +361,7 @@ static void SetSplashDefaults (FSplashDef *splashdef) splashdef->ChunkXVelShift = splashdef->ChunkYVelShift = splashdef->ChunkZVelShift = 8; - splashdef->ChunkBaseZVel = FRACUNIT; + splashdef->ChunkBaseZVel = 1; splashdef->SmallSplashClip = 12*FRACUNIT; splashdef->NoAlert = false; } @@ -595,6 +596,11 @@ static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keyw SET_FIELD (float, float(sc.Float)); break; + case GEN_Double: + sc.MustGetFloat(); + SET_FIELD(double, sc.Float); + break; + case GEN_Time: sc.MustGetFloat (); SET_FIELD (int, (int)(sc.Float * TICRATE)); diff --git a/src/p_terrain.h b/src/p_terrain.h index 43d445c7e..b9217b45e 100644 --- a/src/p_terrain.h +++ b/src/p_terrain.h @@ -95,9 +95,9 @@ struct FSplashDef BYTE ChunkXVelShift; BYTE ChunkYVelShift; BYTE ChunkZVelShift; - fixed_t ChunkBaseZVel; - fixed_t SmallSplashClip; bool NoAlert; + double ChunkBaseZVel; + fixed_t SmallSplashClip; }; struct FTerrainDef @@ -107,7 +107,7 @@ struct FTerrainDef int DamageAmount; FName DamageMOD; int DamageTimeMask; - fixed_t FootClip; + double FootClip; float StepVolume; int WalkStepTics; int RunStepTics; diff --git a/src/p_things.cpp b/src/p_things.cpp index 5b0810d51..35560af6c 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -50,13 +50,14 @@ #include "d_player.h" #include "r_utility.h" #include "p_spec.h" +#include "math/cmath.h" // Set of spawnable things for the Thing_Spawn and Thing_Projectile specials. FClassMap SpawnableThings; static FRandom pr_leadtarget ("LeadTarget"); -bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid) +bool P_Thing_Spawn (int tid, AActor *source, int type, DAngle angle, bool fog, int newtid) { int rtn = 0; PClassActor *kind; @@ -85,7 +86,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, } while (spot != NULL) { - mobj = Spawn (kind, spot->Pos(), ALLOW_REPLACE); + mobj = Spawn (kind, spot->_f_Pos(), ALLOW_REPLACE); if (mobj != NULL) { @@ -94,10 +95,10 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, if (P_TestMobjLocation (mobj)) { rtn++; - mobj->angle = (angle != ANGLE_MAX ? angle : spot->angle); + mobj->Angles.Yaw = (angle != 1000000. ? angle : spot->Angles.Yaw); if (fog) { - P_SpawnTeleportFog(mobj, spot->X(), spot->Y(), spot->Z() + TELEFOGHEIGHT, false, true); + P_SpawnTeleportFog(mobj, spot->_f_X(), spot->_f_Y(), spot->_f_Z() + TELEFOGHEIGHT, false, true); } if (mobj->flags & MF_SPECIAL) mobj->flags |= MF_DROPPED; // Don't respawn @@ -126,9 +127,9 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) { fixed_t oldx, oldy, oldz; - oldx = source->X(); - oldy = source->Y(); - oldz = source->Z(); + oldx = source->_f_X(); + oldy = source->_f_Y(); + oldz = source->_f_Z(); source->SetOrigin (x, y, z, true); if (P_TestMobjLocation (source)) @@ -166,20 +167,21 @@ bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog) if (source != NULL && target != NULL) { - return P_MoveThing(source, target->X(), target->Y(), target->Z(), fog); + return P_MoveThing(source, target->_f_X(), target->_f_Y(), target->_f_Z(), fog); } return false; } -bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_name, angle_t angle, - fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid, +bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_name, DAngle angle, + fixed_t _speed, fixed_t _vspeed, int dest, AActor *forcedest, int gravity, int newtid, bool leadTarget) { int rtn = 0; PClassActor *kind; AActor *spot, *mobj, *targ = forcedest; FActorIterator iterator (tid); - double fspeed = speed; + double speed = FIXED2DBL(_speed); + double vspeed = FIXED2DBL(_vspeed); int defflags3; if (type_name == NULL) @@ -219,7 +221,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam { do { - fixed_t z = spot->Z(); + fixed_t z = spot->_f_Z(); if (defflags3 & MF3_FLOORHUGGER) { z = ONFLOORZ; @@ -230,9 +232,9 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam } else if (z != ONFLOORZ) { - z -= spot->floorclip; + z -= spot->_f_floorclip(); } - mobj = Spawn (kind, spot->X(), spot->Y(), z, ALLOW_REPLACE); + mobj = Spawn (kind, spot->_f_X(), spot->_f_Y(), z, ALLOW_REPLACE); if (mobj) { @@ -244,7 +246,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam mobj->flags &= ~MF_NOGRAVITY; if (!(mobj->flags3 & MF3_ISMONSTER) && gravity == 1) { - mobj->gravity = FRACUNIT/8; + mobj->Gravity = 1./8; } } else @@ -255,11 +257,10 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam if (targ != NULL) { - fixedvec3 vect = mobj->Vec3To(targ); - vect.z += targ->height / 2; - DVector3 aim(vect.x, vect.y, vect.z); + DVector3 aim = mobj->Vec3To(targ); + aim.Z += targ->Height / 2; - if (leadTarget && speed > 0 && (targ->vel.x | targ->vel.y | targ->vel.z)) + if (leadTarget && speed > 0 && !targ->Vel.isZero()) { // Aiming at the target's position some time in the future // is basically just an application of the law of sines: @@ -268,14 +269,14 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam // with the math. I don't think I would have thought of using // trig alone had I been left to solve it by myself. - DVector3 tvel(targ->vel.x, targ->vel.y, targ->vel.z); + DVector3 tvel = targ->Vel; if (!(targ->flags & MF_NOGRAVITY) && targ->waterlevel < 3) { // If the target is subject to gravity and not underwater, // assume that it isn't moving vertically. Thanks to gravity, // even if we did consider the vertical component of the target's // velocity, we would still miss more often than not. tvel.Z = 0.0; - if ((targ->vel.x | targ->vel.y) == 0) + if (targ->Vel.X == 0 && targ->Vel.Y == 0) { goto nolead; } @@ -283,9 +284,9 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam double dist = aim.Length(); double targspeed = tvel.Length(); double ydotx = -aim | tvel; - double a = acos (clamp (ydotx / targspeed / dist, -1.0, 1.0)); + double a = g_acos (clamp (ydotx / targspeed / dist, -1.0, 1.0)); double multiplier = double(pr_leadtarget.Random2())*0.1/255+1.1; - double sinb = -clamp (targspeed*multiplier * sin(a) / fspeed, -1.0, 1.0); + double sinb = -clamp (targspeed*multiplier * g_sin(a) / speed, -1.0, 1.0); // Use the cross product of two of the triangle's sides to get a // rotation vector. @@ -293,25 +294,19 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char *type_nam // The vector must be normalized. rv.MakeUnit(); // Now combine the rotation vector with angle b to get a rotation matrix. - DMatrix3x3 rm(rv, cos(asin(sinb)), sinb); + DMatrix3x3 rm(rv, g_cos(g_asin(sinb)), sinb); // And multiply the original aim vector with the matrix to get a // new aim vector that leads the target. DVector3 aimvec = rm * aim; // And make the projectile follow that vector at the desired speed. - double aimscale = fspeed / dist; - mobj->vel.x = fixed_t (aimvec[0] * aimscale); - mobj->vel.y = fixed_t (aimvec[1] * aimscale); - mobj->vel.z = fixed_t (aimvec[2] * aimscale); - mobj->angle = R_PointToAngle2 (0, 0, mobj->vel.x, mobj->vel.y); + mobj->Vel = aimvec * (speed / dist); + mobj->AngleFromVel(); } else { nolead: - mobj->angle = mobj->AngleTo(targ); - aim.Resize (fspeed); - mobj->vel.x = fixed_t(aim[0]); - mobj->vel.y = fixed_t(aim[1]); - mobj->vel.z = fixed_t(aim[2]); + mobj->Angles.Yaw = mobj->AngleTo(targ); + mobj->Vel = aim.Resized (speed); } if (mobj->flags2 & MF2_SEEKERMISSILE) { @@ -320,20 +315,19 @@ nolead: } else { - mobj->angle = angle; - mobj->vel.x = FixedMul (speed, finecosine[angle>>ANGLETOFINESHIFT]); - mobj->vel.y = FixedMul (speed, finesine[angle>>ANGLETOFINESHIFT]); - mobj->vel.z = vspeed; + mobj->Angles.Yaw = angle; + mobj->VelFromAngle(speed); + mobj->Vel.Z = vspeed; } // Set the missile's speed to reflect the speed it was spawned at. if (mobj->flags & MF_MISSILE) { - mobj->Speed = fixed_t (sqrt (double(mobj->vel.x)*mobj->vel.x + double(mobj->vel.y)*mobj->vel.y + double(mobj->vel.z)*mobj->vel.z)); + mobj->Speed = mobj->VelToSpeed(); } // Hugger missiles don't have any vertical velocity if (mobj->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)) { - mobj->vel.z = 0; + mobj->Vel.Z = 0; } if (mobj->flags & MF_SPECIAL) { @@ -427,21 +421,21 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser) AActor *info = thing->GetDefault (); - thing->vel.x = thing->vel.y = 0; + thing->Vel.X = thing->Vel.Y = 0; // [RH] Check against real height and radius - fixed_t oldheight = thing->height; - fixed_t oldradius = thing->radius; + double oldheight = thing->Height; + double oldradius = thing->radius; ActorFlags oldflags = thing->flags; thing->flags |= MF_SOLID; - thing->height = info->height; // [RH] Use real height + thing->Height = info->Height; // [RH] Use real height thing->radius = info->radius; // [RH] Use real radius - if (!P_CheckPosition (thing, thing->Pos())) + if (!P_CheckPosition (thing, thing->_f_Pos())) { thing->flags = oldflags; thing->radius = oldradius; - thing->height = oldheight; + thing->Height = oldheight; return false; } @@ -472,11 +466,11 @@ bool P_Thing_CanRaise(AActor *thing) // Check against real height and radius ActorFlags oldflags = thing->flags; - fixed_t oldheight = thing->height; - fixed_t oldradius = thing->radius; + double oldheight = thing->Height; + double oldradius = thing->radius; thing->flags |= MF_SOLID; - thing->height = info->height; + thing->Height = info->Height; thing->radius = info->radius; bool check = P_CheckPosition (thing, thing->Pos()); @@ -484,7 +478,7 @@ bool P_Thing_CanRaise(AActor *thing) // Restore checked properties thing->flags = oldflags; thing->radius = oldradius; - thing->height = oldheight; + thing->Height = oldheight; if (!check) { @@ -494,22 +488,19 @@ bool P_Thing_CanRaise(AActor *thing) return true; } -void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob) +void P_Thing_SetVelocity(AActor *actor, const DVector3 &vec, bool add, bool setbob) { if (actor != NULL) { if (!add) { - actor->vel.x = actor->vel.y = actor->vel.z = 0; - if (actor->player != NULL) actor->player->vel.x = actor->player->vel.y = 0; + actor->Vel.Zero(); + if (actor->player != NULL) actor->player->Vel.Zero(); } - actor->vel.x += vx; - actor->vel.y += vy; - actor->vel.z += vz; + actor->Vel += vec; if (setbob && actor->player != NULL) { - actor->player->vel.x += vx; - actor->player->vel.y += vy; + actor->player->Vel += vec.XY(); } } } @@ -692,18 +683,18 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, caller = temp; } - fixedvec3 old = caller->Pos(); + fixedvec3 old = caller->_f_Pos(); int oldpgroup = caller->Sector->PortalGroup; - zofs += FixedMul(reference->height, heightoffset); + zofs += FixedMul(reference->_f_height(), heightoffset); if (!(flags & WARPF_ABSOLUTEANGLE)) { - angle += (flags & WARPF_USECALLERANGLE) ? caller->angle : reference->angle; + angle += (flags & WARPF_USECALLERANGLE) ? caller->_f_angle() : reference->_f_angle(); } - const fixed_t rad = FixedMul(radiusoffset, reference->radius); + const fixed_t rad = FixedMul(radiusoffset, reference->_f_radius()); const angle_t fineangle = angle >> ANGLETOFINESHIFT; if (!(flags & WARPF_ABSOLUTEPOSITION)) @@ -730,7 +721,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), 0), true); - caller->SetZ(caller->floorz + zofs); + caller->_f_SetZ(caller->_f_floorz() + zofs); } else { @@ -745,7 +736,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, if (flags & WARPF_TOFLOOR) { caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs, true); - caller->SetZ(caller->floorz + zofs); + caller->_f_SetZ(caller->_f_floorz() + zofs); } else { @@ -761,25 +752,21 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, } else { - caller->angle = angle; + caller->Angles.Yaw = ANGLE2DBL(angle); if (flags & WARPF_COPYPITCH) - caller->SetPitch(reference->pitch, false); + caller->SetPitch(reference->Angles.Pitch, false); if (pitch) - caller->SetPitch(caller->pitch + pitch, false); + caller->SetPitch(caller->Angles.Pitch + ANGLE2DBL(pitch), false); if (flags & WARPF_COPYVELOCITY) { - caller->vel.x = reference->vel.x; - caller->vel.y = reference->vel.y; - caller->vel.z = reference->vel.z; + caller->Vel = reference->Vel; } if (flags & WARPF_STOP) { - caller->vel.x = 0; - caller->vel.y = 0; - caller->vel.z = 0; + caller->Vel.Zero(); } // this is no fun with line portals @@ -787,9 +774,9 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, { // This just translates the movement but doesn't change the vector fixedvec3 displacedold = old + Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup); - caller->PrevX += caller->X() - displacedold.x; - caller->PrevY += caller->Y() - displacedold.y; - caller->PrevZ += caller->Z() - displacedold.z; + caller->PrevX += caller->_f_X() - displacedold.x; + caller->PrevY += caller->_f_Y() - displacedold.y; + caller->PrevZ += caller->_f_Z() - displacedold.z; caller->PrevPortalGroup = caller->Sector->PortalGroup; } else if (flags & WARPF_COPYINTERPOLATION) @@ -797,9 +784,9 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, // Map both positions of the reference actor to the current portal group fixedvec3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup); fixedvec3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup); - caller->PrevX = caller->X() + displacedold.x - displacedref.x; - caller->PrevY = caller->Y() + displacedold.y - displacedref.y; - caller->PrevZ = caller->Z() + displacedold.z - displacedref.z; + caller->PrevX = caller->_f_X() + displacedold.x - displacedref.x; + caller->PrevY = caller->_f_Y() + displacedold.y - displacedref.y; + caller->PrevZ = caller->_f_Z() + displacedold.z - displacedref.z; caller->PrevPortalGroup = caller->Sector->PortalGroup; } else if (!(flags & WARPF_INTERPOLATE)) @@ -808,7 +795,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs, } if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB)) { - caller->AddZ(reference->GetBobOffset()); + caller->_f_AddZ(reference->GetBobOffset()); } } return true; diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 1de5e7059..bd011e5fc 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -195,16 +195,16 @@ void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *enterse if (aimdir != -1 && aimdir != position) return; AActor *portal = entersec->SkyBoxes[position]; - if (aimdir == sector_t::ceiling && portal->threshold < limitz) return; - else if (aimdir == sector_t::floor && portal->threshold > limitz) return; + if (aimdir == sector_t::ceiling && FLOAT2FIXED(portal->specialf1) < limitz) return; + else if (aimdir == sector_t::floor && FLOAT2FIXED(portal->specialf1) > limitz) return; FTraceInfo newtrace; FTraceResults results; memset(&results, 0, sizeof(results)); - newtrace.StartX = StartX + portal->scaleX; - newtrace.StartY = StartY + portal->scaleY; + newtrace.StartX = StartX + FLOAT2FIXED(portal->Scale.X); + newtrace.StartY = StartY + FLOAT2FIXED(portal->Scale.Y); newtrace.StartZ = StartZ; frac += FixedDiv(FRACUNIT, MaxDist); @@ -229,7 +229,7 @@ void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *enterse newtrace.inshootthrough = true; newtrace.startfrac = frac; newtrace.aimdir = position; - newtrace.limitz = portal->threshold; + newtrace.limitz = FLOAT2FIXED(portal->specialf1); newtrace.sectorsel = 0; if (newtrace.TraceTraverse(ActorMask ? PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE : PT_ADDLINES)) @@ -698,13 +698,13 @@ bool FTraceInfo::ThingCheck(intercept_t *in) fixed_t hity = StartY + FixedMul(Vy, dist); fixed_t hitz = StartZ + FixedMul(Vz, dist); - if (hitz > in->d.thing->Top()) + if (hitz > in->d.thing->_f_Top()) { // trace enters above actor if (Vz >= 0) return true; // Going up: can't hit // Does it hit the top of the actor? - dist = FixedDiv(in->d.thing->Top() - StartZ, Vz); + dist = FixedDiv(in->d.thing->_f_Top() - StartZ, Vz); if (dist > MaxDist) return true; in->frac = FixedDiv(dist, MaxDist); @@ -714,15 +714,15 @@ bool FTraceInfo::ThingCheck(intercept_t *in) hitz = StartZ + FixedMul(Vz, dist); // calculated coordinate is outside the actor's bounding box - if (abs(hitx - in->d.thing->X()) > in->d.thing->radius || - abs(hity - in->d.thing->Y()) > in->d.thing->radius) return true; + if (abs(hitx - in->d.thing->_f_X()) > in->d.thing->_f_radius() || + abs(hity - in->d.thing->_f_Y()) > in->d.thing->_f_radius()) return true; } - else if (hitz < in->d.thing->Z()) + else if (hitz < in->d.thing->_f_Z()) { // trace enters below actor if (Vz <= 0) return true; // Going down: can't hit // Does it hit the bottom of the actor? - dist = FixedDiv(in->d.thing->Z() - StartZ, Vz); + dist = FixedDiv(in->d.thing->_f_Z() - StartZ, Vz); if (dist > MaxDist) return true; in->frac = FixedDiv(dist, MaxDist); @@ -731,8 +731,8 @@ bool FTraceInfo::ThingCheck(intercept_t *in) hitz = StartZ + FixedMul(Vz, dist); // calculated coordinate is outside the actor's bounding box - if (abs(hitx - in->d.thing->X()) > in->d.thing->radius || - abs(hity - in->d.thing->Y()) > in->d.thing->radius) return true; + if (abs(hitx - in->d.thing->_f_X()) > in->d.thing->_f_radius() || + abs(hity - in->d.thing->_f_Y()) > in->d.thing->_f_radius()) return true; } if (CurSector->e->XFloor.ffloors.Size()) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 778e99adf..49b4779eb 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -471,7 +471,7 @@ public: FString arg0str, arg1str; memset(th, 0, sizeof(*th)); - th->gravity = FRACUNIT; + th->Gravity = 1; th->RenderStyle = STYLE_Count; th->alpha = -1; th->health = 1; @@ -519,7 +519,7 @@ public: case NAME_Gravity: CHECK_N(Zd | Zdt) - th->gravity = CheckFixed(key); + th->Gravity = CheckFloat(key); break; case NAME_Arg0: @@ -718,15 +718,15 @@ public: break; case NAME_ScaleX: - th->scaleX = CheckFixed(key); + th->Scale.X = CheckFloat(key); break; case NAME_ScaleY: - th->scaleY = CheckFixed(key); + th->Scale.Y = CheckFloat(key); break; case NAME_Scale: - th->scaleX = th->scaleY = CheckFixed(key); + th->Scale.X = th->Scale.Y = CheckFloat(key); break; default: @@ -1306,7 +1306,7 @@ public: if (floordrop) sec->Flags = SECF_FLOORDROP; // killough 3/7/98: end changes - sec->gravity = 1.f; // [RH] Default sector gravity of 1.0 + sec->gravity = 1.; // [RH] Default sector gravity of 1.0 sec->ZoneNumber = 0xFFFF; // killough 8/28/98: initialize all sectors to normal friction @@ -1444,7 +1444,7 @@ public: continue; case NAME_Gravity: - sec->gravity = float(CheckFloat(key)); + sec->gravity = CheckFloat(key); continue; case NAME_Lightcolor: diff --git a/src/p_user.cpp b/src/p_user.cpp index 5a26d46f3..840d10c94 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -238,7 +238,7 @@ CCMD (playerclasses) // // 16 pixels of bob -#define MAXBOB 0x100000 +#define MAXBOB 16. FArchive &operator<< (FArchive &arc, player_t *&p) { @@ -257,7 +257,7 @@ player_t::player_t() viewheight(0), deltaviewheight(0), bob(0), - vel({ 0,0 }), + Vel(0, 0), centering(0), turnticks(0), attackdown(0), @@ -313,7 +313,7 @@ player_t::player_t() crouchviewdelta(0), ConversationNPC(0), ConversationPC(0), - ConversationNPCAngle(0), + ConversationNPCAngle(0.), ConversationFaceTalker(0) { memset (&cmd, 0, sizeof(cmd)); @@ -336,8 +336,7 @@ player_t &player_t::operator=(const player_t &p) viewheight = p.viewheight; deltaviewheight = p.deltaviewheight; bob = p.bob; - vel.x = p.vel.x; - vel.y = p.vel.y; + Vel = p.Vel; centering = p.centering; turnticks = p.turnticks; attackdown = p.attackdown; @@ -745,11 +744,11 @@ void APlayerPawn::Tick() { if (player != NULL && player->mo == this && player->CanCrouch() && player->playerstate != PST_DEAD) { - height = FixedMul(GetDefault()->height, player->crouchfactor); + Height = GetDefault()->Height * player->crouchfactor; } else { - if (health > 0) height = GetDefault()->height; + if (health > 0) Height = GetDefault()->Height; } Super::Tick(); } @@ -1512,38 +1511,40 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags) // //=========================================================================== -void APlayerPawn::TweakSpeeds (int &forward, int &side) +void APlayerPawn::TweakSpeeds (double &forward, double &side) { - // Strife's player can't run when its healh is below 10 + // Strife's player can't run when its health is below 10 if (health <= RunHealth) { - forward = clamp(forward, -0x1900, 0x1900); - side = clamp(side, -0x1800, 0x1800); + forward = clamp(forward, -0x1900, 0x1900); + side = clamp(side, -0x1800, 0x1800); } // [GRB] - if ((unsigned int)(forward + 0x31ff) < 0x63ff) + if (fabs(forward) < 0x3200) { - forward = FixedMul (forward, ForwardMove1); + forward *= ForwardMove1; } else { - forward = FixedMul (forward, ForwardMove2); + forward *= ForwardMove2; } + + if (fabs(side) < 0x2800) if ((unsigned int)(side + 0x27ff) < 0x4fff) { - side = FixedMul (side, SideMove1); + side *= SideMove1; } else { - side = FixedMul (side, SideMove2); + side *= SideMove2; } if (!player->morphTics && Inventory != NULL) { - fixed_t factor = Inventory->GetSpeedFactor (); - forward = FixedMul(forward, factor); - side = FixedMul(side, factor); + double factor = Inventory->GetSpeedFactor (); + forward *= factor; + side *= factor; } } @@ -1579,7 +1580,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream) // Handle the different player death screams if ((((level.flags >> 15) | (dmflags)) & (DF_FORCE_FALLINGZD | DF_FORCE_FALLINGHX)) && - self->vel.z <= -39*FRACUNIT) + self->Vel.Z <= -39) { sound = S_FindSkinnedSound (self, "*splat"); chan = CHAN_BODY; @@ -1651,16 +1652,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullPop) self->flags &= ~MF_SOLID; mo = (APlayerPawn *)Spawn (spawntype, self->PosPlusZ(48*FRACUNIT), NO_REPLACE); //mo->target = self; - mo->vel.x = pr_skullpop.Random2() << 9; - mo->vel.y = pr_skullpop.Random2() << 9; - mo->vel.z = 2*FRACUNIT + (pr_skullpop() << 6); + mo->Vel.X = pr_skullpop.Random2() / 128.; + mo->Vel.Y = pr_skullpop.Random2() / 128.; + mo->Vel.Z = 2. + (pr_skullpop() / 1024.); // Attach player mobj to bloody skull player = self->player; self->player = NULL; mo->ObtainInventory (self); mo->player = player; mo->health = self->health; - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; if (player != NULL) { player->mo = mo; @@ -1702,7 +1703,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckPlayerDone) // //=========================================================================== -void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t &scaley) +void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale) { player_t *player = actor->player; int crouchspriteno; @@ -1710,14 +1711,13 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t if (player->userinfo.GetSkin() != 0 && !(actor->flags4 & MF4_NOSKIN)) { // Convert from default scale to skin scale. - fixed_t defscaleY = actor->GetDefault()->scaleY; - fixed_t defscaleX = actor->GetDefault()->scaleX; - scaley = Scale(scaley, skins[player->userinfo.GetSkin()].ScaleY, defscaleY); - scalex = Scale(scalex, skins[player->userinfo.GetSkin()].ScaleX, defscaleX); + DVector2 defscale = actor->GetDefault()->Scale; + scale.X *= skins[player->userinfo.GetSkin()].Scale.X / defscale.X; + scale.Y *= skins[player->userinfo.GetSkin()].Scale.Y / defscale.Y; } // Set the crouch sprite? - if (player->crouchfactor < FRACUNIT*3/4) + if (player->crouchfactor < 0.75) { if (spritenum == actor->SpawnState->sprite || spritenum == player->mo->crouchsprite) { @@ -1738,9 +1738,9 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t { spritenum = crouchspriteno; } - else if (player->playerstate != PST_DEAD && player->crouchfactor < FRACUNIT*3/4) + else if (player->playerstate != PST_DEAD && player->crouchfactor < 0.75) { - scaley /= 2; + scale.Y *= 0.5; } } } @@ -1755,30 +1755,23 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t ================== */ -void P_SideThrust (player_t *player, angle_t angle, fixed_t move) +void P_SideThrust (player_t *player, DAngle angle, double move) { - angle = (angle - ANGLE_90) >> ANGLETOFINESHIFT; - - player->mo->vel.x += FixedMul (move, finecosine[angle]); - player->mo->vel.y += FixedMul (move, finesine[angle]); + player->mo->Thrust(angle-90, move); } -void P_ForwardThrust (player_t *player, angle_t angle, fixed_t move) +void P_ForwardThrust (player_t *player, DAngle angle, double move) { - angle >>= ANGLETOFINESHIFT; - if ((player->mo->waterlevel || (player->mo->flags & MF_NOGRAVITY)) - && player->mo->pitch != 0) + && player->mo->Angles.Pitch != 0) { - angle_t pitch = (angle_t)player->mo->pitch >> ANGLETOFINESHIFT; - fixed_t zpush = FixedMul (move, finesine[pitch]); + double zpush = move * player->mo->Angles.Pitch.Sin(); if (player->mo->waterlevel && player->mo->waterlevel < 2 && zpush < 0) zpush = 0; - player->mo->vel.z -= zpush; - move = FixedMul (move, finecosine[pitch]); + player->mo->Vel.Z -= zpush; + move *= player->mo->Angles.Pitch.Cos(); } - player->mo->vel.x += FixedMul (move, finecosine[angle]); - player->mo->vel.y += FixedMul (move, finesine[angle]); + player->mo->Thrust(angle, move); } // @@ -1792,20 +1785,15 @@ void P_ForwardThrust (player_t *player, angle_t angle, fixed_t move) // reduced at a regular rate, even on ice (where the player coasts). // -void P_Bob (player_t *player, angle_t angle, fixed_t move, bool forward) +void P_Bob (player_t *player, DAngle angle, double move, bool forward) { if (forward && (player->mo->waterlevel || (player->mo->flags & MF_NOGRAVITY)) - && player->mo->pitch != 0) + && player->mo->Angles.Pitch != 0) { - angle_t pitch = (angle_t)player->mo->pitch >> ANGLETOFINESHIFT; - move = FixedMul (move, finecosine[pitch]); + move *= player->mo->Angles.Pitch.Cos(); } - - angle >>= ANGLETOFINESHIFT; - - player->vel.x += FixedMul(move, finecosine[angle]); - player->vel.y += FixedMul(move, finesine[angle]); + player->Vel += angle.ToVector(move); } /* @@ -1821,8 +1809,8 @@ Calculate the walking / running height adjustment void P_CalcHeight (player_t *player) { - int angle; - fixed_t bob; + DAngle angle; + double bob; bool still = false; // Regular movement bobbing @@ -1840,18 +1828,18 @@ void P_CalcHeight (player_t *player) } else if ((player->mo->flags & MF_NOGRAVITY) && !player->onground) { - player->bob = FRACUNIT / 2; + player->bob = 0.5; } else { - player->bob = DMulScale16 (player->vel.x, player->vel.x, player->vel.y, player->vel.y); + player->bob = player->Vel.LengthSquared(); if (player->bob == 0) { still = true; } else { - player->bob = FixedMul (player->bob, player->userinfo.GetMoveBob()); + player->bob *= player->userinfo.GetMoveBob(); if (player->bob > MAXBOB) player->bob = MAXBOB; @@ -1862,10 +1850,10 @@ void P_CalcHeight (player_t *player) if (player->cheats & CF_NOVELOCITY) { - player->viewz = player->mo->Z() + defaultviewheight; + player->viewz = player->mo->_f_Z() + defaultviewheight; - if (player->viewz > player->mo->ceilingz-4*FRACUNIT) - player->viewz = player->mo->ceilingz-4*FRACUNIT; + if (player->viewz > player->mo->_f_ceilingz()-4*FRACUNIT) + player->viewz = player->mo->_f_ceilingz()-4*FRACUNIT; return; } @@ -1874,8 +1862,8 @@ void P_CalcHeight (player_t *player) { if (player->health > 0) { - angle = DivScale13 (level.time, 120*TICRATE/35) & FINEMASK; - bob = FixedMul (player->userinfo.GetStillBob(), finesine[angle]); + angle = level.time / (120 * TICRATE / 35.) * 360.; + bob = player->userinfo.GetStillBob() * angle.Sin(); } else { @@ -1884,9 +1872,8 @@ void P_CalcHeight (player_t *player) } else { - // DivScale 13 because FINEANGLES == (1<<13) - angle = DivScale13 (level.time, 20*TICRATE/35) & FINEMASK; - bob = FixedMul (player->bob>>(player->mo->waterlevel > 1 ? 2 : 1), finesine[angle]); + angle = level.time / (20 * TICRATE / 35.) * 360.; + bob = player->bob * angle.Sin() * (player->mo->waterlevel > 1 ? 0.25f : 0.5f); } // move viewheight @@ -1918,19 +1905,19 @@ void P_CalcHeight (player_t *player) { bob = 0; } - player->viewz = player->mo->Z() + player->viewheight + bob; - if (player->mo->floorclip && player->playerstate != PST_DEAD + player->viewz = player->mo->_f_Z() + player->viewheight + FLOAT2FIXED(bob); + if (player->mo->Floorclip && player->playerstate != PST_DEAD && player->mo->Z() <= player->mo->floorz) { - player->viewz -= player->mo->floorclip; + player->viewz -= player->mo->_f_floorclip(); } - if (player->viewz > player->mo->ceilingz - 4*FRACUNIT) + if (player->viewz > player->mo->_f_ceilingz() - 4*FRACUNIT) { - player->viewz = player->mo->ceilingz - 4*FRACUNIT; + player->viewz = player->mo->_f_ceilingz() - 4*FRACUNIT; } - if (player->viewz < player->mo->floorz + 4*FRACUNIT) + if (player->viewz < player->mo->_f_floorz() + 4*FRACUNIT) { - player->viewz = player->mo->floorz + 4*FRACUNIT; + player->viewz = player->mo->_f_floorz() + 4*FRACUNIT; } } @@ -1943,7 +1930,7 @@ void P_CalcHeight (player_t *player) */ CUSTOM_CVAR (Float, sv_aircontrol, 0.00390625f, CVAR_SERVERINFO|CVAR_NOSAVE) { - level.aircontrol = (fixed_t)(self * 65536.f); + level.aircontrol = self; G_AirControlChanged (); } @@ -1956,11 +1943,11 @@ void P_MovePlayer (player_t *player) if (player->turnticks) { player->turnticks--; - mo->angle += (ANGLE_180 / TURN180_TICKS); + mo->Angles.Yaw += (180. / TURN180_TICKS); } else { - mo->angle += cmd->ucmd.yaw << 16; + mo->Angles.Yaw += cmd->ucmd.yaw * (360./65536.); } player->onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); @@ -1974,51 +1961,51 @@ void P_MovePlayer (player_t *player) if (cmd->ucmd.forwardmove | cmd->ucmd.sidemove) { - fixed_t forwardmove, sidemove; - int bobfactor; - int friction, movefactor; - int fm, sm; + double forwardmove, sidemove; + double bobfactor; + double friction, movefactor; + double fm, sm; movefactor = P_GetMoveFactor (mo, &friction); - bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; + bobfactor = friction < ORIG_FRICTION ? movefactor : fORIG_FRICTION_FACTOR; if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) { // [RH] allow very limited movement if not on ground. - movefactor = FixedMul (movefactor, level.aircontrol); - bobfactor = FixedMul (bobfactor, level.aircontrol); + movefactor *= level.aircontrol; + bobfactor*= level.aircontrol; } fm = cmd->ucmd.forwardmove; sm = cmd->ucmd.sidemove; mo->TweakSpeeds (fm, sm); - fm = FixedMul (fm, player->mo->Speed); - sm = FixedMul (sm, player->mo->Speed); + fm *= player->mo->Speed / 256; + sm *= player->mo->Speed / 256; // When crouching, speed and bobbing have to be reduced - if (player->CanCrouch() && player->crouchfactor != FRACUNIT) + if (player->CanCrouch() && player->crouchfactor != 1) { - fm = FixedMul(fm, player->crouchfactor); - sm = FixedMul(sm, player->crouchfactor); - bobfactor = FixedMul(bobfactor, player->crouchfactor); + fm *= player->crouchfactor; + sm *= player->crouchfactor; + bobfactor *= player->crouchfactor; } - forwardmove = Scale (fm, movefactor * 35, TICRATE << 8); - sidemove = Scale (sm, movefactor * 35, TICRATE << 8); + forwardmove = fm * movefactor * (35 / TICRATE); + sidemove = sm * movefactor * (35 / TICRATE); if (forwardmove) { - P_Bob (player, mo->angle, (cmd->ucmd.forwardmove * bobfactor) >> 8, true); - P_ForwardThrust (player, mo->angle, forwardmove); + P_Bob(player, mo->Angles.Yaw, cmd->ucmd.forwardmove * bobfactor / 256., true); + P_ForwardThrust(player, mo->Angles.Yaw, forwardmove); } if (sidemove) { - P_Bob (player, mo->angle-ANG90, (cmd->ucmd.sidemove * bobfactor) >> 8, false); - P_SideThrust (player, mo->angle, sidemove); + P_Bob(player, mo->Angles.Yaw - 90, cmd->ucmd.sidemove * bobfactor / 256., false); + P_SideThrust(player, mo->Angles.Yaw, sidemove); } if (debugfile) { - fprintf (debugfile, "move player for pl %d%c: (%d,%d,%d) (%d,%d) %d %d w%d [", int(player-players), + fprintf (debugfile, "move player for pl %d%c: (%f,%f,%f) (%f,%f) %f %f w%d [", int(player-players), player->cheats&CF_PREDICTING?'p':' ', player->mo->X(), player->mo->Y(), player->mo->Z(),forwardmove, sidemove, movefactor, friction, player->mo->waterlevel); msecnode_t *n = player->mo->touching_sectorlist; @@ -2030,7 +2017,7 @@ void P_MovePlayer (player_t *player) fprintf (debugfile, "]\n"); } - if (!(player->cheats & CF_PREDICTING) && (forwardmove|sidemove)) + if (!(player->cheats & CF_PREDICTING) && (forwardmove != 0 || sidemove != 0)) { player->mo->PlayRunning (); } @@ -2064,7 +2051,7 @@ void P_FallingDamage (AActor *actor) if (actor->floorsector->Flags & SECF_NOFALLINGDAMAGE) return; - vel = abs(actor->vel.z); + vel = abs(actor->_f_velz()); // Since Hexen falling damage is stronger than ZDoom's, it takes // precedence. ZDoom falling damage may not be as strong, but it @@ -2085,7 +2072,7 @@ void P_FallingDamage (AActor *actor) { vel = FixedMul (vel, 16*FRACUNIT/23); damage = ((FixedMul (vel, vel) / 10) >> FRACBITS) - 24; - if (actor->vel.z > -39*FRACUNIT && damage > actor->health + if (actor->_f_velz() > -39*FRACUNIT && damage > actor->health && actor->health != 1) { // No-death threshold damage = actor->health-1; @@ -2147,8 +2134,7 @@ void P_FallingDamage (AActor *actor) void P_DeathThink (player_t *player) { int dir; - angle_t delta; - int lookDelta; + DAngle delta; P_MovePsprites (player); @@ -2159,10 +2145,10 @@ void P_DeathThink (player_t *player) player->deltaviewheight = 0; if (player->onground) { - if (player->mo->pitch > -(int)ANGLE_1*19) + if (player->mo->Angles.Pitch > -19.) { - lookDelta = (-(int)ANGLE_1*19 - player->mo->pitch) / 8; - player->mo->pitch += lookDelta; + DAngle lookDelta = (-19. - player->mo->Angles.Pitch) / 8; + player->mo->Angles.Pitch += lookDelta; } } } @@ -2177,17 +2163,17 @@ void P_DeathThink (player_t *player) { player->viewheight = 6*FRACUNIT; } - if (player->mo->pitch < 0) + if (player->mo->Angles.Pitch < 0) { - player->mo->pitch += ANGLE_1*3; + player->mo->Angles.Pitch += 3; } - else if (player->mo->pitch > 0) + else if (player->mo->Angles.Pitch > 0) { - player->mo->pitch -= ANGLE_1*3; + player->mo->Angles.Pitch -= 3; } - if (abs(player->mo->pitch) < ANGLE_1*3) + if (fabs(player->mo->Angles.Pitch) < 3) { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; } } P_CalcHeight (player); @@ -2195,7 +2181,7 @@ void P_DeathThink (player_t *player) if (player->attacker && player->attacker != player->mo) { // Watch killer dir = P_FaceMobj (player->mo, player->attacker, &delta); - if (delta < ANGLE_1*10) + if (delta < 10) { // Looking at killer, so fade damage and poison counters if (player->damagecount) { @@ -2207,17 +2193,17 @@ void P_DeathThink (player_t *player) } } delta /= 8; - if (delta > ANGLE_1*5) + if (delta > 5.) { - delta = ANGLE_1*5; + delta = 5.; } if (dir) { // Turn clockwise - player->mo->angle += delta; + player->mo->Angles.Yaw += delta; } else { // Turn counter clockwise - player->mo->angle -= delta; + player->mo->Angles.Yaw -= delta; } } else @@ -2255,19 +2241,19 @@ void P_DeathThink (player_t *player) void P_CrouchMove(player_t * player, int direction) { - fixed_t defaultheight = player->mo->GetDefault()->height; - fixed_t savedheight = player->mo->height; - fixed_t crouchspeed = direction * CROUCHSPEED; + double defaultheight = player->mo->GetDefault()->Height; + double savedheight = player->mo->Height; + double crouchspeed = direction * CROUCHSPEED; fixed_t oldheight = player->viewheight; player->crouchdir = (signed char) direction; player->crouchfactor += crouchspeed; // check whether the move is ok - player->mo->height = FixedMul(defaultheight, player->crouchfactor); - if (!P_TryMove(player->mo, player->mo->X(), player->mo->Y(), false, NULL)) + player->mo->Height = defaultheight * player->crouchfactor; + if (!P_TryMove(player->mo, player->mo->_f_X(), player->mo->_f_Y(), false, NULL)) { - player->mo->height = savedheight; + player->mo->Height = savedheight; if (direction > 0) { // doesn't fit @@ -2275,14 +2261,14 @@ void P_CrouchMove(player_t * player, int direction) return; } } - player->mo->height = savedheight; + player->mo->Height = savedheight; - player->crouchfactor = clamp(player->crouchfactor, FRACUNIT/2, FRACUNIT); - player->viewheight = FixedMul(player->mo->ViewHeight, player->crouchfactor); + player->crouchfactor = clamp(player->crouchfactor, 0.5, 1.); + player->viewheight = fixed_t(player->mo->ViewHeight * player->crouchfactor); player->crouchviewdelta = player->viewheight - player->mo->ViewHeight; // Check for eyes going above/below fake floor due to crouching motion. - P_CheckFakeFloorTriggers(player->mo, player->mo->Z() + oldheight, true); + P_CheckFakeFloorTriggers(player->mo, player->mo->_f_Z() + oldheight, true); } //---------------------------------------------------------------------------- @@ -2303,8 +2289,8 @@ void P_PlayerThink (player_t *player) if (debugfile && !(player->cheats & CF_PREDICTING)) { fprintf (debugfile, "tic %d for pl %d: (%d, %d, %d, %u) b:%02x p:%d y:%d f:%d s:%d u:%d\n", - gametic, (int)(player-players), player->mo->X(), player->mo->Y(), player->mo->Z(), - player->mo->angle>>ANGLETOFINESHIFT, player->cmd.ucmd.buttons, + gametic, (int)(player-players), player->mo->_f_X(), player->mo->_f_Y(), player->mo->_f_Z(), + player->mo->_f_angle()>>ANGLETOFINESHIFT, player->cmd.ucmd.buttons, player->cmd.ucmd.pitch, player->cmd.ucmd.yaw, player->cmd.ucmd.forwardmove, player->cmd.ucmd.sidemove, player->cmd.ucmd.upmove); } @@ -2428,12 +2414,12 @@ void P_PlayerThink (player_t *player) { player->crouching = 0; } - if (crouchdir == 1 && player->crouchfactor < FRACUNIT && + if (crouchdir == 1 && player->crouchfactor < 1 && player->mo->Top() < player->mo->ceilingz) { P_CrouchMove(player, 1); } - else if (crouchdir == -1 && player->crouchfactor > FRACUNIT/2) + else if (crouchdir == -1 && player->crouchfactor > 0.5) { P_CrouchMove(player, -1); } @@ -2444,7 +2430,7 @@ void P_PlayerThink (player_t *player) player->Uncrouch(); } - player->crouchoffset = -FixedMul(player->mo->ViewHeight, (FRACUNIT - player->crouchfactor)); + player->crouchoffset = -fixed_t(player->mo->ViewHeight * (1 - player->crouchfactor)); // MUSINFO stuff if (player->MUSINFOtics >= 0 && player->MUSINFOactor != NULL) @@ -2493,54 +2479,38 @@ void P_PlayerThink (player_t *player) // [RH] Look up/down stuff if (!level.IsFreelookAllowed()) { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; } else { - int look = cmd->ucmd.pitch << 16; - // The player's view pitch is clamped between -32 and +56 degrees, // which translates to about half a screen height up and (more than) // one full screen height down from straight ahead when view panning // is used. - if (look) + int clook = cmd->ucmd.pitch; + if (clook != 0) { - if (look == -32768 << 16) + if (clook == -32768) { // center view player->centering = true; } else if (!player->centering) { - fixed_t oldpitch = player->mo->pitch; - player->mo->pitch -= look; - if (look > 0) - { // look up - player->mo->pitch = MAX(player->mo->pitch, player->MinPitch); - if (player->mo->pitch > oldpitch) - { - player->mo->pitch = player->MinPitch; - } - } - else - { // look down - player->mo->pitch = MIN(player->mo->pitch, player->MaxPitch); - if (player->mo->pitch < oldpitch) - { - player->mo->pitch = player->MaxPitch; - } - } + // no more overflows with floating point. Yay! :) + player->mo->Angles.Pitch = clamp(player->mo->Angles.Pitch - clook * (360. / 65536.), player->MinPitch, player->MaxPitch); } } } if (player->centering) { - if (abs(player->mo->pitch) > 2*ANGLE_1) + player->mo->Angles.Pitch.Normalize180(); // make sure we are in the proper range here for the following code. + if (fabs(player->mo->Angles.Pitch) > 2.) { - player->mo->pitch = FixedMul(player->mo->pitch, FRACUNIT*2/3); + player->mo->Angles.Pitch *= (2. / 3.); } else { - player->mo->pitch = 0; + player->mo->Angles.Pitch = 0.; player->centering = false; if (player - players == consoleplayer) { @@ -2574,20 +2544,20 @@ void P_PlayerThink (player_t *player) } else if (player->mo->waterlevel >= 2) { - player->mo->vel.z = FixedMul(4*FRACUNIT, player->mo->Speed); + player->mo->Vel.Z = 4 * player->mo->Speed; } else if (player->mo->flags & MF_NOGRAVITY) { - player->mo->vel.z = 3*FRACUNIT; + player->mo->Vel.Z = 3.; } else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0) { - fixed_t jumpvelz = player->mo->JumpZ * 35 / TICRATE; + double jumpvelz = player->mo->JumpZ * 35 / TICRATE; // [BC] If the player has the high jump power, double his jump velocity. if ( player->cheats & CF_HIGHJUMP ) jumpvelz *= 2; - player->mo->vel.z += jumpvelz; + player->mo->Vel.Z += jumpvelz; player->mo->flags2 &= ~MF2_ONMOBJ; player->jumpTics = -1; if (!(player->cheats & CF_PREDICTING)) @@ -2613,12 +2583,12 @@ void P_PlayerThink (player_t *player) } if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2)) { - player->mo->vel.z = FixedMul(player->mo->Speed, cmd->ucmd.upmove << 9); + player->mo->Vel.Z = player->mo->Speed * cmd->ucmd.upmove / 128.; if (player->mo->waterlevel < 2 && !(player->mo->flags & MF_NOGRAVITY)) { player->mo->flags2 |= MF2_FLY; player->mo->flags |= MF_NOGRAVITY; - if ((player->mo->vel.z <= -39 * FRACUNIT) && !(player->cheats & CF_PREDICTING)) + if ((player->mo->Vel.Z <= -39) && !(player->cheats & CF_PREDICTING)) { // Stop falling scream S_StopSound (player->mo, CHAN_VOICE); } @@ -2642,14 +2612,14 @@ void P_PlayerThink (player_t *player) P_PlayerOnSpecial3DFloor (player); P_PlayerInSpecialSector (player); - if (player->mo->Z() <= player->mo->Sector->floorplane.ZatPoint(player->mo) || + if (player->mo->_f_Z() <= player->mo->Sector->floorplane.ZatPoint(player->mo) || player->mo->waterlevel) { // Player must be touching the floor P_PlayerOnSpecialFlat(player, P_GetThingFloorType(player->mo)); } - if (player->mo->vel.z <= -player->mo->FallingScreamMinSpeed && - player->mo->vel.z >= -player->mo->FallingScreamMaxSpeed && !player->morphTics && + if (player->mo->_f_velz() <= -player->mo->FallingScreamMinSpeed && + player->mo->_f_velz() >= -player->mo->FallingScreamMaxSpeed && !player->morphTics && player->mo->waterlevel == 0) { int id = S_FindSkinnedSound (player->mo, "*falling"); @@ -2868,16 +2838,16 @@ void P_PredictPlayer (player_t *player) { // Z is not compared as lifts will alter this with no apparent change // Make lerping less picky by only testing whole units - DoLerp = ((PredictionLast.x >> 16) != (player->mo->X() >> 16) || - (PredictionLast.y >> 16) != (player->mo->Y() >> 16)); + DoLerp = ((PredictionLast.x >> 16) != (player->mo->_f_X() >> 16) || + (PredictionLast.y >> 16) != (player->mo->_f_Y() >> 16)); // Aditional Debug information if (developer && DoLerp) { DPrintf("Lerp! Ltic (%d) && Ptic (%d) | Lx (%d) && Px (%d) | Ly (%d) && Py (%d)\n", PredictionLast.gametic, i, - (PredictionLast.x >> 16), (player->mo->X() >> 16), - (PredictionLast.y >> 16), (player->mo->Y() >> 16)); + (PredictionLast.x >> 16), (player->mo->_f_X() >> 16), + (PredictionLast.y >> 16), (player->mo->_f_Y() >> 16)); } } } @@ -2895,9 +2865,9 @@ void P_PredictPlayer (player_t *player) } PredictionLast.gametic = maxtic - 1; - PredictionLast.x = player->mo->X(); - PredictionLast.y = player->mo->Y(); - PredictionLast.z = player->mo->Z(); + PredictionLast.x = player->mo->_f_X(); + PredictionLast.y = player->mo->_f_Y(); + PredictionLast.z = player->mo->_f_Z(); if (PredictionLerptics > 0) { @@ -3071,8 +3041,7 @@ void player_t::Serialize (FArchive &arc) << viewheight << deltaviewheight << bob - << vel.x - << vel.y + << Vel << centering << health << inventorytics; @@ -3158,7 +3127,7 @@ void player_t::Serialize (FArchive &arc) arc << LogText << ConversationNPC << ConversationPC - << ConversationNPCAngle + << ConversationNPCAngle.Degrees << ConversationFaceTalker; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 309e12921..a9ae49f12 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -100,9 +100,9 @@ static int WriteTHINGS (FILE *file) mapthinghexen_t mt = { 0, 0, 0, 0, 0, 0, 0, 0, {0} }; AActor *mo = players[consoleplayer].mo; - mt.x = LittleShort(short(mo->X() >> FRACBITS)); - mt.y = LittleShort(short(mo->Y() >> FRACBITS)); - mt.angle = LittleShort(short(MulScale32 (mo->angle >> ANGLETOFINESHIFT, 360))); + mt.x = LittleShort(short(mo->X())); + mt.y = LittleShort(short(mo->Y())); + mt.angle = LittleShort(short(MulScale32 (mo->_f_angle() >> ANGLETOFINESHIFT, 360))); mt.type = LittleShort((short)1); mt.flags = LittleShort((short)(7|224|MTF_SINGLE)); fwrite (&mt, sizeof(mt), 1, file); diff --git a/src/po_man.cpp b/src/po_man.cpp index ab6de8756..fa94c198a 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -174,8 +174,6 @@ void PO_Init (void); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, - fixed_t startSpotY); static void UnLinkPolyobj (FPolyObj *po); static void LinkPolyobj (FPolyObj *po); static bool CheckMobjBlocking (side_t *seg, FPolyObj *po); @@ -858,9 +856,7 @@ int FPolyObj::GetMirror() void FPolyObj::ThrustMobj (AActor *actor, side_t *side) { - int thrustAngle; - int thrustX; - int thrustY; + DAngle thrustAngle; DPolyAction *pe; int force; @@ -871,7 +867,7 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side) } vertex_t *v1 = side->V1(); vertex_t *v2 = side->V2(); - thrustAngle = (R_PointToAngle2 (v1->x, v1->y, v2->x, v2->y) - ANGLE_90) >> ANGLETOFINESHIFT; + thrustAngle = VecToAngle(v2->x - v1->x, v2->y - v1->y) - 90.; pe = static_cast(specialdata); if (pe) @@ -898,13 +894,12 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side) force = FRACUNIT; } - thrustX = FixedMul (force, finecosine[thrustAngle]); - thrustY = FixedMul (force, finesine[thrustAngle]); - actor->vel.x += thrustX; - actor->vel.y += thrustY; + DVector2 thrust = thrustAngle.ToVector(FIXED2FLOAT(force)); + actor->Vel += thrust; + if (crush) { - fixedvec2 pos = actor->Vec2Offset(thrustX, thrustY); + fixedvec2 pos = actor->Vec2Offset(FLOAT2FIXED(thrust.X), FLOAT2FIXED(thrust.Y)); if (bHurtOnTouch || !P_CheckMove (actor, pos.x, pos.y)) { int newdam = P_DamageMobj (actor, NULL, NULL, crush, NAME_Crush); @@ -1036,13 +1031,16 @@ void FPolyObj::DoMovePolyobj (int x, int y) // //========================================================================== -static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_t startSpotY) +static void RotatePt (DAngle an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_t startSpotY) { fixed_t tr_x = *x; fixed_t tr_y = *y; - *x = (DMulScale16 (tr_x, finecosine[an], -tr_y, finesine[an]) & 0xFFFFFE00) + startSpotX; - *y = (DMulScale16 (tr_x, finesine[an], tr_y, finecosine[an]) & 0xFFFFFE00) + startSpotY; + double s = an.Sin(); + double c = an.Cos(); + + *x = (xs_CRoundToInt(tr_x * c - tr_y*s) & 0xfffffe00) + startSpotX; + *y = (xs_CRoundToInt(tr_x * s + tr_y*c) & 0xfffffe00) + startSpotY; } //========================================================================== @@ -1053,11 +1051,11 @@ static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_ bool FPolyObj::RotatePolyobj (angle_t angle, bool fromsave) { - int an; + DAngle an; bool blocked; FBoundingBox oldbounds = Bounds; - an = (this->angle+angle)>>ANGLETOFINESHIFT; + an = ANGLE2DBL(this->angle + angle); UnLinkPolyobj(); @@ -1203,7 +1201,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) && !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS)) && (!(ld->flags & ML_3DMIDTEX) || (!P_LineOpening_3dMidtex(mobj, ld, open) && - (mobj->Top() < open.top) + (mobj->_f_Top() < open.top) ) || (open.abovemidtex && mobj->Z() > mobj->floorz)) ) { @@ -1217,7 +1215,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) performBlockingThrust = true; } - FBoundingBox box(mobj->X(), mobj->Y(), mobj->radius); + FBoundingBox box(mobj->_f_X(), mobj->_f_Y(), mobj->_f_radius()); if (box.Right() <= ld->bbox[BOXLEFT] || box.Left() >= ld->bbox[BOXRIGHT] @@ -1235,15 +1233,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) // Best use the one facing the player and ignore the back side. if (ld->sidedef[1] != NULL) { - int side = P_PointOnLineSidePrecise(mobj->X(), mobj->Y(), ld); + int side = P_PointOnLineSidePrecise(mobj->_f_X(), mobj->_f_Y(), ld); if (ld->sidedef[side] != sd) { continue; } // [BL] See if we hit below the floor/ceiling of the poly. else if(!performBlockingThrust && ( - mobj->Z() < ld->sidedef[!side]->sector->GetSecPlane(sector_t::floor).ZatPoint(mobj) || - mobj->Top() > ld->sidedef[!side]->sector->GetSecPlane(sector_t::ceiling).ZatPoint(mobj) + mobj->_f_Z() < ld->sidedef[!side]->sector->GetSecPlane(sector_t::floor).ZatPoint(mobj) || + mobj->_f_Top() > ld->sidedef[!side]->sector->GetSecPlane(sector_t::ceiling).ZatPoint(mobj) )) { performBlockingThrust = true; @@ -1778,7 +1776,7 @@ void PO_Init (void) node_t *no = &nodes[i]; double fdx = (double)no->dx; double fdy = (double)no->dy; - no->len = (float)sqrt(fdx * fdx + fdy * fdy); + no->len = (float)g_sqrt(fdx * fdx + fdy * fdy); } // mark all subsectors which have a seg belonging to a polyobj diff --git a/src/portal.cpp b/src/portal.cpp index de2d1d14b..ef6013f51 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -53,6 +53,7 @@ #include "p_maputl.h" #include "p_spec.h" #include "p_checkposition.h" +#include "math/cmath.h" // simulation recurions maximum CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) @@ -247,12 +248,12 @@ static void SetRotation(FLinePortal *port) { if (port != NULL && port->mDestination != NULL) { - line_t *dst = port->mDestination; - line_t *line = port->mOrigin; - double angle = atan2(dst->dy, dst->dx) - atan2(line->dy, line->dx) + M_PI; - port->mSinRot = FLOAT2FIXED(sin(angle)); - port->mCosRot = FLOAT2FIXED(cos(angle)); - port->mAngleDiff = RAD2ANGLE(angle); + line_t *dst = port->mDestination; + line_t *line = port->mOrigin; + double angle = g_atan2(dst->dy, dst->dx) - g_atan2(line->dy, line->dx) + M_PI; + port->mSinRot = FLOAT2FIXED(g_sin(angle)); + port->mCosRot = FLOAT2FIXED(g_cos(angle)); + port->mAngleDiff = ToDegrees(angle); } } @@ -605,12 +606,12 @@ void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy) // //============================================================================ -void P_TranslatePortalAngle(line_t* src, angle_t& angle) +void P_TranslatePortalAngle(line_t* src, DAngle& angle) { if (!src) return; FLinePortal *port = src->getPortal(); if (!port) return; - angle += port->mAngleDiff; + angle = (angle + port->mAngleDiff).Normalized360(); } //============================================================================ @@ -668,7 +669,7 @@ void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy) { double _vx = FIXED2DBL(vx); double _vy = FIXED2DBL(vy); - double len = sqrt(_vx*_vx+_vy*_vy); + double len = g_sqrt(_vx*_vx+_vy*_vy); vx = FLOAT2FIXED(_vx/len); vy = FLOAT2FIXED(_vy/len); } @@ -812,13 +813,13 @@ static void AddDisplacementForPortal(AStackPoint *portal) FDisplacement & disp = Displacements(thisgroup, othergroup); if (!disp.isSet) { - disp.pos.x = portal->scaleX; - disp.pos.y = portal->scaleY; + disp.pos.x = FLOAT2FIXED(portal->Scale.X); + disp.pos.y = FLOAT2FIXED(portal->Scale.Y); disp.isSet = true; } else { - if (disp.pos.x != portal->scaleX || disp.pos.y != portal->scaleY) + if (disp.pos.x != FLOAT2FIXED(portal->Scale.X) || disp.pos.y != FLOAT2FIXED(portal->Scale.Y)) { Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum); portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL; @@ -958,30 +959,30 @@ void P_CreateLinkedPortals() id = 1; if (orgs.Size() != 0) { - for (int i = 0; i < numsectors; i++) + for (int i = 0; i < numsectors; i++) + { + for (int j = 0; j < 2; j++) { - for (int j = 0; j < 2; j++) + AActor *box = sectors[i].SkyBoxes[j]; + if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL) { - AActor *box = sectors[i].SkyBoxes[j]; - if (box != NULL && box->special1 == SKYBOX_LINKEDPORTAL) + secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane; + if (plane.a || plane.b) { - secplane_t &plane = j == 0 ? sectors[i].floorplane : sectors[i].ceilingplane; - if (plane.a || plane.b) - { - // The engine cannot deal with portals on a sloped plane. - sectors[i].SkyBoxes[j] = NULL; + // The engine cannot deal with portals on a sloped plane. + sectors[i].SkyBoxes[j] = NULL; Printf("Portal on %s of sector %d is sloped and will be disabled\n", j == 0 ? "floor" : "ceiling", i); - } } } } + } - // Group all sectors, starting at each portal origin. - for (unsigned i = 0; i < orgs.Size(); i++) - { - if (CollectSectors(id, orgs[i]->Sector)) id++; - if (CollectSectors(id, orgs[i]->Mate->Sector)) id++; - } + // Group all sectors, starting at each portal origin. + for (unsigned i = 0; i < orgs.Size(); i++) + { + if (CollectSectors(id, orgs[i]->Sector)) id++; + if (CollectSectors(id, orgs[i]->Mate->Sector)) id++; + } } for (unsigned i = 0; i < linePortals.Size(); i++) { @@ -1088,8 +1089,8 @@ void P_CreateLinkedPortals() } if (sectors[i].PortalIsLinked(sector_t::ceiling) && sectors[i].PortalIsLinked(sector_t::floor)) { - fixed_t cz = sectors[i].SkyBoxes[sector_t::ceiling]->threshold; - fixed_t fz = sectors[i].SkyBoxes[sector_t::floor]->threshold; + double cz = sectors[i].SkyBoxes[sector_t::ceiling]->specialf1; + double fz = sectors[i].SkyBoxes[sector_t::floor]->specialf1; if (cz < fz) { // This is a fatal condition. We have to remove one of the two portals. Choose the one that doesn't match the current plane @@ -1117,7 +1118,7 @@ void P_CreateLinkedPortals() if (!(actor->flags & MF_NOBLOCKMAP)) { FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); - P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check); + P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->_f_Pos(), actor->_f_Top(), actor->_f_radius(), check); if (check.Size() > 0) { actor->UnlinkFromWorld(); @@ -1203,7 +1204,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t { sector_t *sec = P_PointInSector(position.x, position.y); sector_t *wsec = sec; - while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->SkyBoxes[sector_t::ceiling]->threshold) + while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > FLOAT2FIXED(wsec->SkyBoxes[sector_t::ceiling]->specialf1)) { sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector; fixedvec2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup); @@ -1215,7 +1216,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t retval = true; } wsec = sec; - while (!wsec->PortalBlocksMovement(sector_t::floor) && position.z < wsec->SkyBoxes[sector_t::floor]->threshold) + while (!wsec->PortalBlocksMovement(sector_t::floor) && position.z < FLOAT2FIXED(wsec->SkyBoxes[sector_t::floor]->specialf1)) { sector_t *othersec = wsec->SkyBoxes[sector_t::floor]->Sector; fixedvec2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup); @@ -1255,7 +1256,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t sector_t *sec = s ? ld->backsector : ld->frontsector; if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling))) { - if (sec->SkyBoxes[sector_t::ceiling]->threshold < upperz) + if (FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->specialf1) < upperz) { int grp = sec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup; if (!(processMask.getBit(grp))) @@ -1274,7 +1275,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t sector_t *sec = s ? ld->backsector : ld->frontsector; if (sec && !(sec->PortalBlocksMovement(sector_t::floor))) { - if (sec->SkyBoxes[sector_t::floor]->threshold > position.z) + if (FLOAT2FIXED(sec->SkyBoxes[sector_t::floor]->specialf1) > position.z) { int grp = sec->SkyBoxes[sector_t::floor]->Sector->PortalGroup; if (!(processMask.getBit(grp))) diff --git a/src/portal.h b/src/portal.h index d5a781f2d..4fe89a3c6 100644 --- a/src/portal.h +++ b/src/portal.h @@ -179,7 +179,7 @@ struct FLinePortal BYTE mFlags; BYTE mDefFlags; BYTE mAlign; - angle_t mAngleDiff; + DAngle mAngleDiff; fixed_t mSinRot; fixed_t mCosRot; }; @@ -203,7 +203,15 @@ inline int P_NumPortalGroups() bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true); void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y); void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy); -void P_TranslatePortalAngle(line_t* src, angle_t& angle); +inline void P_TranslatePortalVXVY(line_t* src, double& vx, double& vy) +{ + fixed_t x = FLOAT2FIXED(vx); + fixed_t y = FLOAT2FIXED(vy); + P_TranslatePortalVXVY(src, x, y); + vx = FIXED2DBL(x); + vx = FIXED2DBL(y); +} +void P_TranslatePortalAngle(line_t* src, DAngle& angle); void P_TranslatePortalZ(line_t* src, fixed_t& z); void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy); fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y); diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index 04c3a3f2e..90bc42663 100644 --- a/src/posix/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -491,7 +491,7 @@ void SDLFB::Update () return; pixels = Surface->pixels; - pitch = Surface->pitch; + pitch = Surface->_f_pitch(); } if (NotPaletted) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 03b3c2830..39ab1bf91 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -596,8 +596,8 @@ void R_InitSkins (void) } else if (0 == stricmp (key, "scale")) { - skins[i].ScaleX = clamp (FLOAT2FIXED(atof (sc.String)), 1, 256*FRACUNIT); - skins[i].ScaleY = skins[i].ScaleX; + skins[i].Scale.X = clamp(atof (sc.String), 1./65536, 256.); + skins[i].Scale.Y = skins[i].Scale.X; } else if (0 == stricmp (key, "game")) { @@ -937,8 +937,7 @@ void R_InitSprites () PClassPlayerPawn *type = PlayerClasses[0].Type; skins[i].range0start = type->ColorRangeStart; skins[i].range0end = type->ColorRangeEnd; - skins[i].ScaleX = GetDefaultByType (type)->scaleX; - skins[i].ScaleY = GetDefaultByType (type)->scaleY; + skins[i].Scale = GetDefaultByType (type)->Scale; } R_InitSpriteDefs (); @@ -967,8 +966,7 @@ void R_InitSprites () } skins[i].range0start = basetype->ColorRangeStart; skins[i].range0end = basetype->ColorRangeEnd; - skins[i].ScaleX = GetDefaultByType (basetype)->scaleX; - skins[i].ScaleY = GetDefaultByType (basetype)->scaleY; + skins[i].Scale = GetDefaultByType (basetype)->Scale; skins[i].sprite = GetDefaultByType (basetype)->SpawnState->sprite; skins[i].namespc = ns_global; diff --git a/src/r_data/sprites.h b/src/r_data/sprites.h index 28feb433e..d882ee981 100644 --- a/src/r_data/sprites.h +++ b/src/r_data/sprites.h @@ -1,6 +1,8 @@ #ifndef __RES_SPRITES_H #define __RES_SPRITES_H +#include "vectors.h" + #define MAX_SPRITE_FRAMES 29 // [RH] Macro-ized as in BOOM. // @@ -51,8 +53,7 @@ public: BYTE range0start; BYTE range0end; bool othergame; // [GRB] - fixed_t ScaleX; - fixed_t ScaleY; + DVector2 Scale; int sprite; int crouchsprite; int namespc; // namespace for this skin diff --git a/src/r_defs.h b/src/r_defs.h index ae6409edd..7819a0cdd 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -26,6 +26,7 @@ #include "doomdef.h" #include "templates.h" #include "memarena.h" +#include "m_bbox.h" // Some more or less basic data types // we depend on. @@ -261,6 +262,11 @@ struct secplane_t fixed_t a, b, c, d, ic; + DVector3 Normal() const + { + return{ FIXED2FLOAT(a), FIXED2FLOAT(b), FIXED2FLOAT(c) }; + } + // Returns < 0 : behind; == 0 : on; > 0 : in front int PointOnSide (fixed_t x, fixed_t y, fixed_t z) const { @@ -303,7 +309,12 @@ struct secplane_t fixed_t ZatPoint (const AActor *ac) const { - return FixedMul (ic, -d - DMulScale16 (a, ac->X(), b, ac->Y())); + return FixedMul (ic, -d - DMulScale16 (a, ac->_f_X(), b, ac->_f_Y())); + } + + double ZatPointF(const AActor *ac) const + { + return FIXED2DBL(ZatPoint(ac)); } // Returns the value of z at (x,y) if d is equal to dist @@ -583,6 +594,7 @@ struct sector_t int GetFloorLight () const; int GetCeilingLight () const; sector_t *GetHeightSec() const; + fixed_t GetFriction(int plane = sector_t::floor, fixed_t *movefac = NULL) const; DInterpolation *SetInterpolation(int position, bool attach); @@ -860,17 +872,27 @@ struct sector_t bool PlaneMoving(int pos); // Portal-aware height calculation - fixed_t HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec = NULL); - fixed_t LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec = NULL); + fixed_t _f_HighestCeilingAt(fixed_t x, fixed_t y, sector_t **resultsec = NULL); + fixed_t _f_LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec = NULL); - fixed_t HighestCeilingAt(AActor *a, sector_t **resultsec = NULL) + fixed_t _f_HighestCeilingAt(AActor *a, sector_t **resultsec = NULL) { - return HighestCeilingAt(a->X(), a->Y(), resultsec); + return _f_HighestCeilingAt(a->_f_X(), a->_f_Y(), resultsec); } - fixed_t LowestFloorAt(AActor *a, sector_t **resultsec = NULL) + double HighestCeilingAt(AActor *a, sector_t **resultsec = NULL) { - return LowestFloorAt(a->X(), a->Y(), resultsec); + return FIXED2DBL(_f_HighestCeilingAt(a->_f_X(), a->_f_Y(), resultsec)); + } + + fixed_t _f_LowestFloorAt(AActor *a, sector_t **resultsec = NULL) + { + return _f_LowestFloorAt(a->_f_X(), a->_f_Y(), resultsec); + } + + double LowestFloorAt(AActor *a, sector_t **resultsec = NULL) + { + return FIXED2DBL(_f_LowestFloorAt(a->_f_X(), a->_f_Y(), resultsec)); } fixed_t NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t bottomz, fixed_t topz, int flags = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); @@ -941,7 +963,7 @@ struct sector_t // thinglist is a subset of touching_thinglist struct msecnode_t *touching_thinglist; // phares 3/14/98 - float gravity; // [RH] Sector gravity (1.0 is normal) + double gravity; // [RH] Sector gravity (1.0 is normal) FNameNoInit damagetype; // [RH] Means-of-death for applied damage int damageamount; // [RH] Damage to do while standing on floor short damageinterval; // Interval for damage application @@ -1177,6 +1199,21 @@ struct line_t unsigned portalindex; TObjPtr skybox; + DVector2 V1() const + { + return{ FIXED2DBL(v1->x), FIXED2DBL(v1->y) }; + } + + DVector2 V2() const + { + return{ FIXED2DBL(v2->x), FIXED2DBL(v2->y) }; + } + + DVector2 Delta() const + { + return{ FIXED2DBL(dx), FIXED2DBL(dy) }; + } + FLinePortal *getPortal() const { return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex]; @@ -1396,13 +1433,22 @@ inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refse inline void AActor::ClearInterpolation() { - PrevX = X(); - PrevY = Y(); - PrevZ = Z(); - PrevAngle = angle; + PrevX = _f_X(); + PrevY = _f_Y(); + PrevZ = _f_Z(); + PrevAngles = Angles; if (Sector) PrevPortalGroup = Sector->PortalGroup; else PrevPortalGroup = 0; } +inline bool FBoundingBox::inRange(const line_t *ld) const +{ + return (!(Left() > ld->bbox[BOXRIGHT] || + Right() < ld->bbox[BOXLEFT] || + Top() < ld->bbox[BOXBOTTOM] || + Bottom() > ld->bbox[BOXTOP])); +} + + #endif diff --git a/src/r_draw.cpp b/src/r_draw.cpp index c16817691..7a7fe5a96 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -1072,7 +1072,7 @@ void R_DrawSpanP_C (void) #ifdef RANGECHECK if (ds_x2 < ds_x1 || ds_x1 < 0 - || ds_x2 >= screen->width || ds_y > screen->height) + || ds_x2 >= screen->width || ds_y > screen->_f_height()) { I_Error ("R_DrawSpan: %i to %i at %i", ds_x1, ds_x2, ds_y); } diff --git a/src/r_main.cpp b/src/r_main.cpp index 44ed781bb..8add28594 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -735,7 +735,9 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) { P_TranslatePortalXY(pds->src, viewx, viewy); P_TranslatePortalZ(pds->src, viewz); - P_TranslatePortalAngle(pds->src, viewangle); + DAngle va = ANGLE2DBL(viewangle); + P_TranslatePortalAngle(pds->src, va); + viewangle = va.BAMs(); } viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 15653a1e8..bbf63333e 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1106,7 +1106,7 @@ void R_DrawHeightPlanes(fixed_t height) void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked) { -// pl->angle = pa<_f_angle() = pa<left >= pl->right) return; @@ -1243,7 +1243,7 @@ void R_DrawSkyBoxes () viewx = viewpos.x; viewy = viewpos.y; viewz = viewpos.z; - viewangle = savedangle + sky->PrevAngle + FixedMul(r_TicFrac, sky->angle - sky->PrevAngle); + viewangle = savedangle + FLOAT2ANGLE(sky->PrevAngles.Yaw.Degrees) + FixedMul(r_TicFrac, sky->_f_angle() - FLOAT2ANGLE(sky->PrevAngles.Yaw.Degrees)); R_CopyStackedViewParameters(); } @@ -1251,8 +1251,8 @@ void R_DrawSkyBoxes () { extralight = pl->extralight; R_SetVisibility (pl->visibility); - viewx = pl->viewx - sky->Mate->X() + sky->X(); - viewy = pl->viewy - sky->Mate->Y() + sky->Y(); + viewx = pl->viewx - sky->Mate->_f_X() + sky->_f_X(); + viewy = pl->viewy - sky->Mate->_f_Y() + sky->_f_Y(); viewz = pl->viewz; viewangle = pl->viewangle; } diff --git a/src/r_things.cpp b/src/r_things.cpp index 644ca7899..5aa00e44c 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -763,7 +763,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor // [ZZ] Or less definitely not visible (hue) // [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal. - if (!CurrentPortalInSkybox && CurrentPortal && !!P_PointOnLineSidePrecise(thing->X(), thing->Y(), CurrentPortal->dst)) + if (!CurrentPortalInSkybox && CurrentPortal && !!P_PointOnLineSidePrecise(thing->_f_X(), thing->_f_Y(), CurrentPortal->dst)) return; // [RH] Interpolate the sprite's position to make it look smooth @@ -776,17 +776,16 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor voxel = NULL; int spritenum = thing->sprite; - fixed_t spritescaleX = thing->scaleX; - fixed_t spritescaleY = thing->scaleY; + DVector2 spriteScale = thing->Scale; int renderflags = thing->renderflags; - if (spritescaleY < 0) + if (spriteScale.Y < 0) { - spritescaleY = -spritescaleY; + spriteScale.Y = -spriteScale.Y; renderflags ^= RF_YFLIP; } if (thing->player != NULL) { - P_CheckPlayerSprite(thing, spritenum, spritescaleX, spritescaleY); + P_CheckPlayerSprite(thing, spritenum, spriteScale); } if (thing->picnum.isValid()) @@ -807,11 +806,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28; + rot = (ang - thing->_f_angle() + (angle_t)(ANGLE_45/2)*9) >> 28; } else { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; + rot = (ang - thing->_f_angle() + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; } picnum = sprframe->Texture[rot]; if (sprframe->Flip & (1 << rot)) @@ -846,11 +845,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9) >> 28; + rot = (ang - thing->_f_angle() + (angle_t)(ANGLE_45/2)*9) >> 28; } else { - rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; + rot = (ang - thing->_f_angle() + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; } picnum = sprframe->Texture[rot]; if (sprframe->Flip & (1 << rot)) @@ -864,9 +863,9 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } } } - if (spritescaleX < 0) + if (spriteScale.X < 0) { - spritescaleX = -spritescaleX; + spriteScale.X = -spriteScale.X; renderflags ^= RF_XFLIP; } if (voxel == NULL && (tex == NULL || tex->UseType == FTexture::TEX_Null)) @@ -874,6 +873,8 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor return; } + fixed_t spritescaleX = FLOAT2FIXED(spriteScale.X); + fixed_t spritescaleY = FLOAT2FIXED(spriteScale.Y); if ((renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) { R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, renderflags); @@ -919,7 +920,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { xscale = FixedMul(spritescaleX, voxel->Scale); yscale = FixedMul(spritescaleY, voxel->Scale); - gzt = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ) - thing->floorclip; + gzt = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ) - FLOAT2FIXED(thing->Floorclip); gzb = fz + MulScale8(yscale, voxel->Voxel->Mips[0].PivotZ - (voxel->Voxel->Mips[0].SizeZ << 8)); if (gzt <= gzb) return; @@ -995,11 +996,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->xscale = xscale; vis->yscale = Scale(InvZtoScale, yscale, tz << 4); vis->idepth = (unsigned)DivScale32(1, tz) >> 1; // tz is 20.12, so idepth ought to be 12.20, but signed math makes it 13.19 - vis->floorclip = FixedDiv (thing->floorclip, yscale); - vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv (viewz - fz + thing->floorclip, yscale); + vis->floorclip = FixedDiv (FLOAT2FIXED(thing->Floorclip), yscale); + vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv (viewz - fz + FLOAT2FIXED(thing->Floorclip), yscale); vis->x1 = x1 < WindowLeft ? WindowLeft : x1; vis->x2 = x2 > WindowRight ? WindowRight : x2; - vis->angle = thing->angle; + vis->angle = thing->_f_angle(); if (renderflags & RF_XFLIP) { @@ -1025,11 +1026,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->x1 = WindowLeft; vis->x2 = WindowRight; vis->idepth = (unsigned)DivScale32(1, MAX(tz, MINZ)) >> 1; - vis->floorclip = thing->floorclip; + vis->floorclip = FLOAT2FIXED(thing->Floorclip); - fz -= thing->floorclip; + fz -= FLOAT2FIXED(thing->Floorclip); - vis->angle = thing->angle + voxel->AngleOffset; + vis->angle = thing->_f_angle() + voxel->AngleOffset; int voxelspin = (thing->flags & MF_DROPPED) ? voxel->DroppedSpin : voxel->PlacedSpin; if (voxelspin != 0) @@ -1149,7 +1150,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f fixed_t lx1, lx2, ly1, ly2; fixed_t gzb, gzt, tz; FTexture *pic = TexMan(picnum, true); - angle_t ang = (thing->angle + ANGLE_90) >> ANGLETOFINESHIFT; + angle_t ang = (thing->_f_angle() + ANGLE_90) >> ANGLETOFINESHIFT; vissprite_t *vis; // Determine left and right edges of sprite. The sprite's angle is its normal, @@ -1254,12 +1255,12 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside) { if(!(rover->top.plane->a) && !(rover->top.plane->b)) { - if(rover->top.plane->Zat0() <= thing->Z()) fakefloor = rover; + if(rover->top.plane->Zat0() <= thing->_f_Z()) fakefloor = rover; } } if(!(rover->bottom.plane->a) && !(rover->bottom.plane->b)) { - if(rover->bottom.plane->Zat0() >= thing->Top()) fakeceiling = rover; + if(rover->bottom.plane->Zat0() >= thing->_f_Top()) fakeceiling = rover; } } R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling); @@ -1589,7 +1590,7 @@ void R_DrawPlayerSprites () // [RH] Don't draw the targeter's crosshair if the player already has a crosshair set. if (psp->state && (i != ps_targetcenter || CrosshairImage == NULL)) { - R_DrawPSprite (psp, i, camera, psp->sx + ofsx, psp->sy + ofsy); + R_DrawPSprite (psp, i, camera, FLOAT2FIXED(psp->sx) + ofsx, FLOAT2FIXED(psp->sy) + ofsy); } // [RH] Don't bob the targeter. if (i == ps_flash) @@ -2114,8 +2115,8 @@ void R_DrawSprite (vissprite_t *spr) if (spr->fakeceiling != NULL) { - fixed_t ceilingz = spr->fakeceiling->bottom.plane->Zat0(); - if (viewz < ceilingz && ceilingz == sclipTop) + fixed_t ceilingZ = spr->fakeceiling->bottom.plane->Zat0(); + if (viewz < ceilingZ && ceilingZ == sclipTop) { h = spr->fakeceiling->top.plane->Zat0(); } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 666c23e69..d36c77765 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -57,6 +57,7 @@ #include "r_utility.h" #include "d_player.h" #include "p_local.h" +#include "math/cmath.h" // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -254,7 +255,7 @@ angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x, fixed_t y) else { // we have to use the slower but more precise floating point atan2 function here. - return xs_RoundToUInt(atan2(double(y), double(x)) * (ANGLE_180/M_PI)); + return xs_RoundToUInt(g_atan2(double(y), double(x)) * (ANGLE_180/M_PI)); } } @@ -273,7 +274,7 @@ void R_InitPointToAngle (void) // for (i = 0; i <= SLOPERANGE; i++) { - f = atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); + f = g_atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); tantoangle[i] = (angle_t)(0xffffffff*f); } } @@ -322,16 +323,16 @@ void R_InitTables (void) const double pimul = PI*2/FINEANGLES; // viewangle tangent table - finetangent[0] = (fixed_t)(FRACUNIT*tan ((0.5-FINEANGLES/4)*pimul)+0.5); + finetangent[0] = (fixed_t)(FRACUNIT*g_tan ((0.5-FINEANGLES/4)*pimul)+0.5); for (i = 1; i < FINEANGLES/2; i++) { - finetangent[i] = (fixed_t)(FRACUNIT*tan ((i-FINEANGLES/4)*pimul)+0.5); + finetangent[i] = (fixed_t)(FRACUNIT*g_tan ((i-FINEANGLES/4)*pimul)+0.5); } // finesine table for (i = 0; i < FINEANGLES/4; i++) { - finesine[i] = (fixed_t)(FRACUNIT * sin (i*pimul)); + finesine[i] = (fixed_t)(FRACUNIT * g_sin (i*pimul)); } for (i = 0; i < FINEANGLES/4; i++) { @@ -607,8 +608,8 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi angle_t totaladiff = 0; fixed_t oviewz = iview->oviewz; fixed_t nviewz = iview->nviewz; - fixedvec3a oldpos = { iview->oviewx, iview->oviewy, 0, 0 }; - fixedvec3a newpos = { iview->nviewx, iview->nviewy, 0, 0 }; + fixedvec3a oldpos = { iview->oviewx, iview->oviewy, 0, 0. }; + fixedvec3a newpos = { iview->nviewx, iview->nviewy, 0, 0. }; InterpolationPath.Push(newpos); // add this to the array to simplify the loops below for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) @@ -617,7 +618,7 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi fixedvec3a &end = InterpolationPath[i]; pathlen += xs_CRoundToInt(DVector2(end.x - start.x, end.y - start.y).Length()); totalzdiff += start.z; - totaladiff += start.angle; + totaladiff += FLOAT2ANGLE(start.angle.Degrees); } fixed_t interpolatedlen = FixedMul(frac, pathlen); @@ -627,7 +628,7 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi fixedvec3a &end = InterpolationPath[i]; fixed_t fraglen = xs_CRoundToInt(DVector2(end.x - start.x, end.y - start.y).Length()); zdiff += start.z; - adiff += start.angle; + adiff += FLOAT2ANGLE(start.angle.Degrees); if (fraglen <= interpolatedlen) { interpolatedlen -= fraglen; @@ -660,8 +661,8 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi player - players == consoleplayer && camera == player->mo && !demoplayback && - iview->nviewx == camera->X() && - iview->nviewy == camera->Y() && + iview->nviewx == camera->_f_X() && + iview->nviewy == camera->_f_Y() && !(player->cheats & (CF_TOTALLYFROZEN|CF_FROZEN)) && player->playerstate == PST_LIVE && player->mo->reactiontime == 0 && @@ -680,11 +681,11 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi // Avoid overflowing viewpitch (can happen when a netgame is stalled) if (viewpitch > INT_MAX - delta) { - viewpitch = player->MaxPitch; + viewpitch = FLOAT2ANGLE(player->MaxPitch.Degrees); } else { - viewpitch = MIN(viewpitch + delta, player->MaxPitch); + viewpitch = MIN(viewpitch + delta, FLOAT2ANGLE(player->MaxPitch.Degrees)); } } else if (delta < 0) @@ -692,11 +693,11 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi // Avoid overflowing viewpitch (can happen when a netgame is stalled) if (viewpitch < INT_MIN - delta) { - viewpitch = player->MinPitch; + viewpitch = FLOAT2ANGLE(player->MinPitch.Degrees); } else { - viewpitch = MAX(viewpitch + delta, player->MinPitch); + viewpitch = MAX(viewpitch + delta, FLOAT2ANGLE(player->MinPitch.Degrees)); } } } @@ -712,10 +713,10 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi while (!viewsector->PortalBlocksMovement(sector_t::ceiling)) { AActor *point = viewsector->SkyBoxes[sector_t::ceiling]; - if (viewz > point->threshold) + if (viewz > FLOAT2FIXED(point->specialf1)) { - viewx += point->scaleX; - viewy += point->scaleY; + viewx += FLOAT2FIXED(point->Scale.X); + viewy += FLOAT2FIXED(point->Scale.Y); viewsector = R_PointInSubsector(viewx, viewy)->sector; moved = true; } @@ -726,10 +727,10 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi while (!viewsector->PortalBlocksMovement(sector_t::floor)) { AActor *point = viewsector->SkyBoxes[sector_t::floor]; - if (viewz < point->threshold) + if (viewz < FLOAT2FIXED(point->specialf1)) { - viewx += point->scaleX; - viewy += point->scaleY; + viewx += FLOAT2FIXED(point->Scale.X); + viewy += FLOAT2FIXED(point->Scale.Y); viewsector = R_PointInSubsector(viewx, viewy)->sector; moved = true; } @@ -982,19 +983,19 @@ void R_SetupFrame (AActor *actor) } else { - iview->nviewx = camera->X(); - iview->nviewy = camera->Y(); - iview->nviewz = camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight(); + iview->nviewx = camera->_f_X(); + iview->nviewy = camera->_f_Y(); + iview->nviewz = camera->player ? camera->player->viewz : FLOAT2FIXED(camera->Z() + camera->GetCameraHeight()); viewsector = camera->Sector; r_showviewer = false; } - iview->nviewpitch = camera->pitch; + iview->nviewpitch = camera->_f_pitch(); if (camera->player != 0) { player = camera->player; } - iview->nviewangle = camera->angle; + iview->nviewangle = camera->_f_angle(); if (iview->otic == -1 || r_NoInterpolate) { R_ResetViewInterpolation (); @@ -1049,14 +1050,14 @@ void R_SetupFrame (AActor *actor) if ((jiggers.RelIntensityX | jiggers.RelOffsetX) != 0) { - int ang = (camera->angle) >> ANGLETOFINESHIFT; + int ang = (camera->_f_angle()) >> ANGLETOFINESHIFT; fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityX, jiggers.RelOffsetX); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } if ((jiggers.RelIntensityY | jiggers.RelOffsetY) != 0) { - int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; + int ang = (camera->_f_angle() + ANG90) >> ANGLETOFINESHIFT; fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityY, jiggers.RelOffsetY); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); diff --git a/src/r_utility.h b/src/r_utility.h index 5c953c7ab..0d4b4d023 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -60,14 +60,14 @@ angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); inline angle_t R_PointToAngle (fixed_t x, fixed_t y) { return R_PointToAngle2 (viewx, viewy, x, y); } inline angle_t R_PointToAnglePrecise (fixed_t viewx, fixed_t viewy, fixed_t x, fixed_t y) { - return xs_RoundToUInt(atan2(double(y-viewy), double(x-viewx)) * (ANGLE_180/M_PI)); + return xs_RoundToUInt(g_atan2(double(y-viewy), double(x-viewx)) * (ANGLE_180/M_PI)); } // Used for interpolation waypoints. struct fixedvec3a { fixed_t x, y, z; - angle_t angle; + DAngle angle; }; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 2b1ff7c8b..63d4026d3 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -2281,7 +2281,7 @@ void AAmbientSound::Activate (AActor *activator) Destroy (); return; } - amb->periodmin = Scale(S_GetMSLength(sndnum), TICRATE, 1000); + amb->periodmin = ::Scale(S_GetMSLength(sndnum), TICRATE, 1000); } NextCheck = level.maptime; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 38a43a430..100773e06 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -736,9 +736,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, // Only actors maintain velocity information. if (type == SOURCE_Actor && actor != NULL) { - vel->X = FIXED2FLOAT(actor->vel.x) * TICRATE; - vel->Y = FIXED2FLOAT(actor->vel.z) * TICRATE; - vel->Z = FIXED2FLOAT(actor->vel.y) * TICRATE; + vel->X = float(actor->Vel.X * TICRATE); + vel->Y = float(actor->Vel.Y * TICRATE); + vel->Z = float(actor->Vel.Z * TICRATE); } else { @@ -1950,7 +1950,7 @@ static void S_SetListener(SoundListener &listener, AActor *listenactor) { if (listenactor != NULL) { - listener.angle = ANGLE2RADF(listenactor->angle); + listener.angle = ANGLE2RADF(listenactor->_f_angle()); /* listener.velocity.X = listenactor->vel.x * (TICRATE/65536.f); listener.velocity.Y = listenactor->vel.z * (TICRATE/65536.f); diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 548dd7201..9b7de9e43 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -1357,7 +1357,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f))) { float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale); - dir.Resize((gain > 0.00001f) ? 1.f/gain : 100000.f); + dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f); } if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS) { @@ -1596,7 +1596,7 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f))) { float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr) * chan->DistanceScale); - dir.Resize((gain > 0.00001f) ? 1.f/gain : 100000.f); + dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f); } if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS) { diff --git a/src/tables.h b/src/tables.h index 6fe767a4f..790deed5f 100644 --- a/src/tables.h +++ b/src/tables.h @@ -53,6 +53,7 @@ #define ANGLETOFINESHIFT 19 #define BOBTOFINESHIFT (FINEANGLEBITS - 6) +#define BOBTORAD(v) ((v) * (M_PI/32)) // from FloatBobTable to radians. // Effective size is 10240. extern fixed_t finesine[5*FINEANGLES/4]; diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index c1610a521..0a0e93f6f 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -63,7 +63,7 @@ struct FExtraInfo bool bSolidOnDeath, bSolidOnBurn; bool bBurnAway, bDiesAway, bGenericIceDeath; bool bExplosive; - fixed_t DeathHeight, BurnHeight; + double DeathHeight, BurnHeight; }; class AFakeInventory : public AInventory @@ -256,7 +256,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) if (extra.DeathHeight == 0) { - extra.DeathHeight = ((AActor*)(type->Defaults))->height; + extra.DeathHeight = ((AActor*)(type->Defaults))->Height; } type->DeathHeight = extra.DeathHeight; } @@ -296,7 +296,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) type->OwnedStates[extra.FireDeathStart].SetAction("A_ActiveAndUnblock"); } - if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->height; + if (extra.BurnHeight == 0) extra.BurnHeight = ((AActor*)(type->Defaults))->Height; type->BurnHeight = extra.BurnHeight; bag.statedef.SetStateLabel("Burn", &type->OwnedStates[extra.FireDeathStart]); @@ -445,7 +445,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (sc.Compare ("Scale")) { sc.MustGetFloat (); - defaults->scaleX = defaults->scaleY = FLOAT2FIXED(sc.Float); + defaults->Scale.X = defaults->Scale.Y = sc.Float; } else if (sc.Compare ("RenderStyle")) { @@ -455,22 +455,22 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (sc.Compare ("Radius")) { sc.MustGetFloat (); - defaults->radius = int(sc.Float * FRACUNIT); + defaults->radius = sc.Float; } else if (sc.Compare ("Height")) { sc.MustGetFloat (); - defaults->height = int(sc.Float * FRACUNIT); + defaults->Height = sc.Float; } else if (def == DEF_BreakableDecoration && sc.Compare ("DeathHeight")) { sc.MustGetFloat (); - extra.DeathHeight = int(sc.Float * FRACUNIT); + extra.DeathHeight = sc.Float; } else if (def == DEF_BreakableDecoration && sc.Compare ("BurnHeight")) { sc.MustGetFloat (); - extra.BurnHeight = int(sc.Float * FRACUNIT); + extra.BurnHeight = sc.Float; } else if (def == DEF_BreakableDecoration && sc.Compare ("Health")) { @@ -514,7 +514,7 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, else if (def == DEF_Projectile && sc.Compare ("Speed")) { sc.MustGetFloat (); - defaults->Speed = fixed_t(sc.Float * 65536.f); + defaults->Speed = sc.Float; } else if (sc.Compare ("Mass")) { diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c5081f57a..5ca8bbdb9 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -76,6 +76,7 @@ #include "d_player.h" #include "p_maputl.h" #include "p_spec.h" +#include "math/cmath.h" AActor *SingleActorFromTID(int tid, AActor *defactor); @@ -312,9 +313,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetDistance) } else { - fixedvec3 diff = self->Vec3To(target); + fixedvec3 diff = self->_f_Vec3To(target); if (checkz) - diff.z += (target->height - self->height) / 2; + diff.z += (target->_f_height() - self->_f_height()) / 2; const double length = DVector3(FIXED2DBL(diff.x), FIXED2DBL(diff.y), (checkz) ? FIXED2DBL(diff.z) : 0).Length(); ret->SetFloat(length); @@ -598,7 +599,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_UnsetFloat) // //========================================================================== static void DoAttack (AActor *self, bool domelee, bool domissile, - int MeleeDamage, FSoundID MeleeSound, PClassActor *MissileType,fixed_t MissileHeight) + int MeleeDamage, FSoundID MeleeSound, PClassActor *MissileType,double MissileHeight) { if (self->target == NULL) return; @@ -613,9 +614,10 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, else if (domissile && MissileType != NULL) { // This seemingly senseless code is needed for proper aiming. - self->AddZ(MissileHeight + self->GetBobOffset() - 32*FRACUNIT); + double add = MissileHeight + FIXED2FLOAT(self->GetBobOffset()) - 32; + self->AddZ(add); AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), self, self->target, MissileType, false); - self->AddZ(-(MissileHeight + self->GetBobOffset() - 32*FRACUNIT)); + self->AddZ(-add); if (missile) { @@ -642,8 +644,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MissileAttack) { PARAM_ACTION_PROLOGUE; PClassActor *MissileType = PClass::FindActor(self->GetClass()->MissileName); - fixed_t MissileHeight = self->GetClass()->MissileHeight; - DoAttack(self, false, true, 0, 0, MissileType, MissileHeight); + DoAttack(self, false, true, 0, 0, MissileType, self->GetClass()->MissileHeight); return 0; } @@ -653,8 +654,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ComboAttack) int MeleeDamage = self->GetClass()->MeleeDamage; FSoundID MeleeSound = self->GetClass()->MeleeSound; PClassActor *MissileType = PClass::FindActor(self->GetClass()->MissileName); - fixed_t MissileHeight = self->GetClass()->MissileHeight; - DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, MissileHeight); + DoAttack(self, true, true, MeleeDamage, MeleeSound, MissileType, self->GetClass()->MissileHeight); return 0; } @@ -823,20 +823,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_BulletAttack) PARAM_ACTION_PROLOGUE; int i; - int bangle; - int slope; if (!self->target) return 0; A_FaceTarget (self); - bangle = self->angle; - slope = P_AimLineAttack (self, bangle, MISSILERANGE); + DAngle slope = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); for (i = self->GetMissileDamage (0, 1); i > 0; --i) { - int angle = bangle + (pr_cabullet.Random2() << 20); + DAngle angle = self->Angles.Yaw + pr_cabullet.Random2() * (5.625 / 256.); int damage = ((pr_cabullet()%5)+1)*3; P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_Hitscan, NAME_BulletPuff); @@ -1094,19 +1091,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) if (nails) { - angle_t ang; + DAngle ang; for (int i = 0; i < nails; i++) { - ang = i*(ANGLE_MAX/nails); + ang = i*360./nails; // Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim - P_LineAttack (self, ang, MISSILERANGE, 0, + P_LineAttack (self, ang, MISSILERANGE, 0., //P_AimLineAttack (self, ang, MISSILERANGE), naildamage, NAME_Hitscan, pufftype); } } P_RadiusAttack (self, self->target, damage, distance, self->DamageType, flags, fulldmgdistance); - P_CheckSplash(self, distance<target != NULL && self->target->player != NULL) { validcount++; @@ -1149,7 +1146,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust) } P_RadiusAttack (self, self->target, force, distance, self->DamageType, flags | RADF_NODAMAGE, fullthrustdistance); - P_CheckSplash(self, distance << FRACBITS); + P_CheckSplash(self, distance); if (sourcenothrust) { @@ -1202,9 +1199,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) PARAM_CLASS (ti, AActor); PARAM_FIXED_OPT (spawnheight) { spawnheight = 32*FRACUNIT; } PARAM_INT_OPT (spawnofs_xy) { spawnofs_xy = 0; } - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_DANGLE_OPT(Angle) { Angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_ANGLE_OPT (pitch) { pitch = 0; } + PARAM_DANGLE_OPT(Pitch) { Pitch = 0.; } PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; } AActor *ref = COPY_AAPTR(self, ptr); @@ -1218,12 +1215,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) { if (ti) { - angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; + angle_t ang = (self->_f_angle() - ANGLE_90) >> ANGLETOFINESHIFT; fixed_t x = spawnofs_xy * finecosine[ang]; fixed_t y = spawnofs_xy * finesine[ang]; fixed_t z = spawnheight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0); - fixedvec3 pos = self->Pos(); + fixedvec3 pos = self->_f_Pos(); switch (aimmode) { case 0: @@ -1240,7 +1237,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) case 2: self->SetXYZ(self->Vec3Offset(x, y, 0)); - missile = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false); + missile = P_SpawnMissileAngleZSpeed(self, self->_f_Z() + self->GetBobOffset() + spawnheight, ti, self->_f_angle(), 0, GetDefaultByType(ti)->_f_speed(), self, false); self->SetXYZ(pos); flags |= CMF_ABSOLUTEPITCH; @@ -1254,38 +1251,32 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) // so that this can handle missiles with a high vertical velocity // component properly. - fixed_t missilespeed; + double missilespeed; if ( (CMF_ABSOLUTEPITCH|CMF_OFFSETPITCH) & flags) { if (CMF_OFFSETPITCH & flags) { - DVector2 velocity (missile->vel.x, missile->vel.y); - pitch += R_PointToAngle2(0,0, xs_CRoundToInt(velocity.Length()), missile->vel.z); + Pitch += missile->Vel.Pitch(); } - ang = pitch >> ANGLETOFINESHIFT; - missilespeed = abs(FixedMul(finecosine[ang], missile->Speed)); - missile->vel.z = FixedMul(finesine[ang], missile->Speed); + missilespeed = fabs(Pitch.Cos() * missile->Speed); + missile->Vel.Z = Pitch.Sin() * missile->Speed; } else { - DVector2 velocity (missile->vel.x, missile->vel.y); - missilespeed = xs_CRoundToInt(velocity.Length()); + missilespeed = missile->VelXYToSpeed(); } if (CMF_SAVEPITCH & flags) { - missile->pitch = pitch; + missile->Angles.Pitch = Pitch; // In aimmode 0 and 1 without absolutepitch or offsetpitch, the pitch parameter // contains the unapplied parameter. In that case, it is set as pitch without // otherwise affecting the spawned actor. } - missile->angle = (CMF_ABSOLUTEANGLE & flags) ? angle : missile->angle + angle ; - - ang = missile->angle >> ANGLETOFINESHIFT; - missile->vel.x = FixedMul(missilespeed, finecosine[ang]); - missile->vel.y = FixedMul(missilespeed, finesine[ang]); + missile->Angles.Yaw = (CMF_ABSOLUTEANGLE & flags) ? Angle : missile->Angles.Yaw + Angle; + missile->VelFromAngle(missilespeed); // handle projectile shooting projectiles - track the // links back to a real owner @@ -1349,12 +1340,12 @@ enum CBA_Flags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE (spread_xy); - PARAM_ANGLE (spread_z); + PARAM_DANGLE (spread_xy); + PARAM_DANGLE (spread_z); PARAM_INT (numbullets); PARAM_INT (damageperbullet); PARAM_CLASS_OPT (pufftype, AActor) { pufftype = PClass::FindActor(NAME_BulletPuff); } - PARAM_FIXED_OPT (range) { range = MISSILERANGE; } + PARAM_FLOAT_OPT (range) { range = 0; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_TARGET; } @@ -1364,8 +1355,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) range = MISSILERANGE; int i; - int bangle; - int bslope = 0; + DAngle bangle; + DAngle bslope = 0.; int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; if (ref != NULL || (flags & CBAF_AIMFACING)) @@ -1374,15 +1365,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) { A_Face(self, ref); } - bangle = self->angle; + bangle = self->Angles.Yaw; if (!(flags & CBAF_NOPITCH)) bslope = P_AimLineAttack (self, bangle, MISSILERANGE); S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM); for (i = 0; i < numbullets; i++) { - int angle = bangle; - int slope = bslope; + DAngle angle = bangle; + DAngle slope = bslope; if (flags & CBAF_EXPLICITANGLE) { @@ -1391,8 +1382,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) } else { - angle += pr_cwbullet.Random2() * (spread_xy / 255); - slope += pr_cwbullet.Random2() * (spread_z / 255); + angle += spread_xy * (pr_cwbullet.Random2() / 255.); + slope += spread_z * (pr_cwbullet.Random2() / 255.); } int damage = damageperbullet; @@ -1475,9 +1466,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) else if (ti) { // This seemingly senseless code is needed for proper aiming. - self->AddZ(spawnheight + self->GetBobOffset() - 32*FRACUNIT); + self->_f_AddZ(spawnheight + self->GetBobOffset() - 32*FRACUNIT); AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), self, self->target, ti, false); - self->AddZ(-(spawnheight + self->GetBobOffset() - 32*FRACUNIT)); + self->_f_AddZ(-(spawnheight + self->GetBobOffset() - 32*FRACUNIT)); if (missile) { @@ -1533,13 +1524,13 @@ enum FB_Flags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE (spread_xy); - PARAM_ANGLE (spread_z); + PARAM_DANGLE (spread_xy); + PARAM_DANGLE (spread_z); PARAM_INT (numbullets); PARAM_INT (damageperbullet); PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } PARAM_INT_OPT (flags) { flags = FBF_USEAMMO; } - PARAM_FIXED_OPT (range) { range = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } if (!self->player) return 0; @@ -1547,8 +1538,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) AWeapon *weapon = player->ReadyWeapon; int i; - int bangle; - int bslope = 0; + DAngle bangle; + DAngle bslope = 0.; int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; if ((flags & FBF_USEAMMO) && weapon && ACTION_CALL_FROM_WEAPON()) @@ -1563,7 +1554,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) if (!(flags & FBF_NOFLASH)) static_cast(self)->PlayAttacking2 (); if (!(flags & FBF_NOPITCH)) bslope = P_BulletSlope(self); - bangle = self->angle; + bangle = self->Angles.Yaw; if (pufftype == NULL) pufftype = PClass::FindActor(NAME_BulletPuff); @@ -1588,8 +1579,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) numbullets = 1; for (i = 0; i < numbullets; i++) { - int angle = bangle; - int slope = bslope; + DAngle angle = bangle; + DAngle slope = bslope; if (flags & FBF_EXPLICITANGLE) { @@ -1598,8 +1589,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets) } else { - angle += pr_cwbullet.Random2() * (spread_xy / 255); - slope += pr_cwbullet.Random2() * (spread_z / 255); + angle += spread_xy * (pr_cwbullet.Random2() / 255.); + slope += spread_z * (pr_cwbullet.Random2() / 255.); } int damage = damageperbullet; @@ -1629,12 +1620,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (ti, AActor); - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } PARAM_BOOL_OPT (useammo) { useammo = true; } PARAM_INT_OPT (spawnofs_xy) { spawnofs_xy = 0; } PARAM_FIXED_OPT (spawnheight) { spawnheight = 0; } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_ANGLE_OPT (pitch) { pitch = 0; } + PARAM_DANGLE_OPT(pitch) { pitch = 0.; } if (!self->player) return 0; @@ -1652,19 +1643,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) if (ti) { - angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; + angle_t ang = (self->_f_angle() - ANGLE_90) >> ANGLETOFINESHIFT; fixed_t x = spawnofs_xy * finecosine[ang]; fixed_t y = spawnofs_xy * finesine[ang]; fixed_t z = spawnheight; - fixed_t shootangle = self->angle; + DAngle shootangle = self->Angles.Yaw; if (flags & FPF_AIMATANGLE) shootangle += angle; // Temporarily adjusts the pitch - fixed_t saved_player_pitch = self->pitch; - self->pitch -= pitch; + DAngle saved_player_pitch = self->Angles.Pitch; + self->Angles.Pitch -= pitch; AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &t, NULL, false, (flags & FPF_NOAUTOAIM) != 0); - self->pitch = saved_player_pitch; + self->Angles.Pitch = saved_player_pitch; // automatic handling of seeker missiles if (misl) @@ -1677,12 +1668,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile) { // This original implementation is to aim straight ahead and then offset // the angle from the resulting direction. - DVector3 velocity(misl->vel.x, misl->vel.y, 0); - fixed_t missilespeed = xs_CRoundToInt(velocity.Length()); - misl->angle += angle; - angle_t an = misl->angle >> ANGLETOFINESHIFT; - misl->vel.x = FixedMul (missilespeed, finecosine[an]); - misl->vel.y = FixedMul (missilespeed, finesine[an]); + misl->Angles.Yaw += angle; + misl->VelFromAngle(misl->VelXYToSpeed()); } } } @@ -1715,7 +1702,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) PARAM_BOOL_OPT (norandom) { norandom = false; } PARAM_INT_OPT (flags) { flags = CPF_USEAMMO; } PARAM_CLASS_OPT (pufftype, AActor) { pufftype = NULL; } - PARAM_FIXED_OPT (range) { range = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; } PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } @@ -1729,17 +1716,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) AWeapon *weapon = player->ReadyWeapon; - angle_t angle; - int pitch; + DAngle angle; + DAngle pitch; FTranslatedLineTarget t; int actualdamage; if (!norandom) damage *= pr_cwpunch() % 8 + 1; - angle = self->angle + (pr_cwpunch.Random2() << 18); - if (range == 0) - range = MELEERANGE; + angle = self->Angles.Yaw + pr_cwpunch.Random2() * (5.625 / 256); + if (range == 0) range = MELEERANGE; pitch = P_AimLineAttack (self, angle, range, &t); // only use ammo when actually hitting something! @@ -1798,7 +1784,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch) if (!(flags & CPF_NOTURN)) { // turn to face target - self->angle = t.angleFromSource; + self->Angles.Yaw = t.angleFromSource; } if (flags & CPF_PULLIN) self->flags |= MF_JUSTATTACKED; @@ -1906,9 +1892,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) FTranslatedLineTarget t; - fixedvec3 savedpos = self->Pos(); - angle_t saved_angle = self->angle; - fixed_t saved_pitch = self->pitch; + DVector3 savedpos = self->Pos(); + DAngle saved_angle = self->Angles.Yaw; + DAngle saved_pitch = self->Angles.Pitch; if (aim && self->target == NULL) { @@ -1925,43 +1911,40 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) if (aim) { - self->angle = self->AngleTo(self->target); + self->Angles.Yaw = self->AngleTo(self->target); } - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &t, ANGLE_1*60, 0, aim ? self->target : NULL); + self->Angles.Pitch = P_AimLineAttack (self, self->Angles.Yaw, MISSILERANGE, &t, 60., 0, aim ? self->target : NULL); if (t.linetarget == NULL && aim) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. - fixedvec2 pos = self->Vec2To(self->target); - DVector2 xydiff(pos.x, pos.y); - double zdiff = (self->target->Z() + (self->target->height>>1)) - - (self->Z() + (self->height>>1) - self->floorclip); - self->pitch = int(atan2(zdiff, xydiff.Length()) * ANGLE_180 / -M_PI); + DVector2 xydiff = self->Vec2To(self->target); + double zdiff = self->target->Center() - self->Center() - self->Floorclip; + self->Angles.Pitch = VecToAngle(xydiff.Length(), zdiff); } // Let the aim trail behind the player if (aim) { - saved_angle = self->angle = self->AngleTo(self->target, -self->target->vel.x * 3, -self->target->vel.y * 3); + saved_angle = self->Angles.Yaw = self->AngleTo(self->target, -self->target->Vel.X * 3, -self->target->Vel.Y * 3); if (aim == CRF_AIMDIRECT) { // Tricky: We must offset to the angle of the current position // but then change the angle again to ensure proper aim. self->SetXY(self->Vec2Offset( - spawnofs_xy * finecosine[self->angle], - spawnofs_xy * finesine[self->angle])); + FLOAT2FIXED(spawnofs_xy * self->Angles.Yaw.Cos()), + FLOAT2FIXED(spawnofs_xy * self->Angles.Yaw.Sin()))); spawnofs_xy = 0; - self->angle = self->AngleTo(self->target,- self->target->vel.x * 3, -self->target->vel.y * 3); + self->Angles.Yaw = self->AngleTo(self->target,- self->target->Vel.X * 3, -self->target->Vel.Y * 3); } if (self->target->flags & MF_SHADOW) { - angle_t rnd = pr_crailgun.Random2() << 21; - self->angle += rnd; - saved_angle = rnd; + DAngle rnd = pr_crailgun.Random2() * (45. / 256.); + self->Angles.Yaw += rnd; } } - angle_t angle = (self->angle - ANG90) >> ANGLETOFINESHIFT; + angle_t angle = (self->_f_angle() - ANG90) >> ANGLETOFINESHIFT; angle_t angleoffset; angle_t slopeoffset; @@ -1980,8 +1963,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) P_RailAttack (self, damage, spawnofs_xy, spawnofs_z, color1, color2, maxdiff, flags, pufftype, angleoffset, slopeoffset, range, duration, sparsity, driftspeed, spawnclass,SpiralOffset); self->SetXYZ(savedpos); - self->angle = saved_angle; - self->pitch = saved_pitch; + self->Angles.Yaw = saved_angle; + self->Angles.Pitch = saved_pitch; return 0; } @@ -2243,10 +2226,10 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) mo->tracer = self->tracer; } - mo->angle = self->angle; + mo->Angles.Yaw = self->Angles.Yaw; if (flags & SIXF_TRANSFERPITCH) { - mo->pitch = self->pitch; + mo->Angles.Pitch = self->Angles.Pitch; } if (!(flags & SIXF_ORIGINATOR)) { @@ -2257,7 +2240,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) } if (flags & SIXF_TELEFRAG) { - P_TeleportMove(mo, mo->Pos(), true); + P_TeleportMove(mo, mo->_f_Pos(), true); // This is needed to ensure consistent behavior. // Otherwise it will only spawn if nothing gets telefragged flags |= SIXF_NOCHECKPOSITION; @@ -2324,8 +2307,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) } if (flags & SIXF_TRANSFERSCALE) { - mo->scaleX = self->scaleX; - mo->scaleY = self->scaleY; + mo->Scale = self->Scale; } if (flags & SIXF_TRANSFERAMBUSHFLAG) { @@ -2367,7 +2349,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) if (flags & SIXF_TRANSFERROLL) { - mo->roll = self->roll; + mo->Angles.Roll = self->Angles.Roll; } if (flags & SIXF_ISTARGET) @@ -2416,7 +2398,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) if (distance == 0) { // use the minimum distance that does not result in an overlap - distance = (self->radius + GetDefaultByType(missile)->radius) >> FRACBITS; + distance = (self->_f_radius() + GetDefaultByType(missile)->_f_radius()) >> FRACBITS; } if (ACTION_CALL_FROM_WEAPON()) @@ -2434,7 +2416,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) } } - AActor *mo = Spawn( missile, self->Vec3Angle(distance, self->angle, -self->floorclip + self->GetBobOffset() + zheight), ALLOW_REPLACE); + AActor *mo = Spawn( missile, self->_f_Vec3Angle(distance, self->_f_angle(), -self->_f_floorclip() + self->GetBobOffset() + zheight), ALLOW_REPLACE); int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0); ACTION_RETURN_BOOL(InitSpawnedItem(self, mo, flags)); // for an inventory item's use state @@ -2454,10 +2436,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) PARAM_FIXED_OPT (xofs) { xofs = 0; } PARAM_FIXED_OPT (yofs) { yofs = 0; } PARAM_FIXED_OPT (zofs) { zofs = 0; } - PARAM_FIXED_OPT (xvel) { xvel = 0; } - PARAM_FIXED_OPT (yvel) { yvel = 0; } - PARAM_FIXED_OPT (zvel) { zvel = 0; } - PARAM_ANGLE_OPT (angle) { angle = 0; } + PARAM_FLOAT_OPT (xvel) { xvel = 0; } + PARAM_FLOAT_OPT (yvel) { yvel = 0; } + PARAM_FLOAT_OPT (zvel) { zvel = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (chance) { chance = 0; } PARAM_INT_OPT (tid) { tid = 0; } @@ -2480,10 +2462,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) if (!(flags & SIXF_ABSOLUTEANGLE)) { - angle += self->angle; + angle += self->Angles.Yaw; } - - angle_t ang = angle >> ANGLETOFINESHIFT; + double s = angle.Sin(); + double c = angle.Cos(); if (flags & SIXF_ABSOLUTEPOSITION) { @@ -2493,20 +2475,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) { // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - pos = self->Vec2Offset( - FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]), - FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang])); + pos = self->Vec2Offset(fixed_t(xofs * c + yofs * s), fixed_t(xofs * s - yofs*c)); } if (!(flags & SIXF_ABSOLUTEVELOCITY)) { // Same orientation issue here! - fixed_t newxvel = FixedMul(xvel, finecosine[ang]) + FixedMul(yvel, finesine[ang]); - yvel = FixedMul(xvel, finesine[ang]) - FixedMul(yvel, finecosine[ang]); + double newxvel = xvel * c + yvel * s; + yvel = xvel * s - yvel * c; xvel = newxvel; } - AActor *mo = Spawn(missile, pos.x, pos.y, self->Z() - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE); + AActor *mo = Spawn(missile, pos.x, pos.y, self->_f_Z() - self->_f_floorclip() + self->GetBobOffset() + zofs, ALLOW_REPLACE); bool res = InitSpawnedItem(self, mo, flags); if (res) { @@ -2516,19 +2496,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) mo->tid = tid; mo->AddToHash(); } + mo->Vel = {xvel, yvel, zvel}; if (flags & SIXF_MULTIPLYSPEED) { - mo->vel.x = FixedMul(xvel, mo->Speed); - mo->vel.y = FixedMul(yvel, mo->Speed); - mo->vel.z = FixedMul(zvel, mo->Speed); + mo->Vel *= mo->Speed; } - else - { - mo->vel.x = xvel; - mo->vel.y = yvel; - mo->vel.z = zvel; - } - mo->angle = angle; + mo->Angles.Yaw = angle; } ACTION_RETURN_BOOL(res); // for an inventory item's use state } @@ -2545,7 +2518,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) PARAM_ACTION_PROLOGUE; PARAM_CLASS (missile, AActor); PARAM_FIXED_OPT (zheight) { zheight = 0; } - PARAM_FIXED_OPT (xyvel) { xyvel = 0; } + PARAM_FLOAT_OPT (xyvel) { xyvel = 0; } PARAM_FIXED_OPT (zvel) { zvel = 0; } PARAM_BOOL_OPT (useammo) { useammo = true; } @@ -2571,36 +2544,36 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) AActor *bo; bo = Spawn(missile, - self->PosPlusZ(-self->floorclip + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0)), + self->PosPlusZ(-self->_f_floorclip() + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0)), ALLOW_REPLACE); if (bo) { P_PlaySpawnSound(bo, self); if (xyvel != 0) bo->Speed = xyvel; - bo->angle = self->angle + (((pr_grenade()&7) - 4) << 24); + bo->Angles.Yaw = self->Angles.Yaw + (((pr_grenade()&7) - 4) * (360./256.)); - angle_t pitch = angle_t(-self->pitch) >> ANGLETOFINESHIFT; - angle_t angle = bo->angle >> ANGLETOFINESHIFT; + DAngle pitch = -self->Angles.Pitch; + DAngle angle = bo->Angles.Yaw; // There are two vectors we are concerned about here: xy and z. We rotate // them separately according to the shooter's pitch and then sum them to // get the final velocity vector to shoot with. - fixed_t xy_xyscale = FixedMul(bo->Speed, finecosine[pitch]); - fixed_t xy_velz = FixedMul(bo->Speed, finesine[pitch]); - fixed_t xy_velx = FixedMul(xy_xyscale, finecosine[angle]); - fixed_t xy_vely = FixedMul(xy_xyscale, finesine[angle]); + double xy_xyscale = bo->Speed * pitch.Cos(); + double xy_velz = bo->Speed * pitch.Sin(); + double xy_velx = xy_xyscale * angle.Cos(); + double xy_vely = xy_xyscale * angle.Sin(); - pitch = angle_t(self->pitch) >> ANGLETOFINESHIFT; - fixed_t z_xyscale = FixedMul(zvel, finesine[pitch]); - fixed_t z_velz = FixedMul(zvel, finecosine[pitch]); - fixed_t z_velx = FixedMul(z_xyscale, finecosine[angle]); - fixed_t z_vely = FixedMul(z_xyscale, finesine[angle]); + pitch = self->Angles.Pitch; + double z_xyscale = zvel * pitch.Sin(); + double z_velz = zvel * pitch.Cos(); + double z_velx = z_xyscale * angle.Cos(); + double z_vely = z_xyscale * angle.Sin(); - bo->vel.x = xy_velx + z_velx + (self->vel.x >> 1); - bo->vel.y = xy_vely + z_vely + (self->vel.y >> 1); - bo->vel.z = xy_velz + z_velz; + bo->Vel.X = xy_velx + z_velx + self->Vel.X / 2; + bo->Vel.Y = xy_vely + z_vely + self->Vel.Y / 2; + bo->Vel.Z = xy_velz + z_velz; bo->target = self; P_CheckMissileSpawn (bo, self->radius); @@ -2621,12 +2594,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Recoil) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(xyvel); + PARAM_FLOAT(xyvel); - angle_t angle = self->angle + ANG180; - angle >>= ANGLETOFINESHIFT; - self->vel.x += FixedMul(xyvel, finecosine[angle]); - self->vel.y += FixedMul(xyvel, finesine[angle]); + self->Thrust(self->Angles.Yaw + 180., xyvel); return 0; } @@ -2910,8 +2880,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeTo) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetScale) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED (scalex); - PARAM_FIXED_OPT (scaley) { scaley = scalex; } + PARAM_FLOAT (scalex); + PARAM_FLOAT_OPT (scaley) { scaley = scalex; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } PARAM_BOOL_OPT (usezero) { usezero = false; } @@ -2923,8 +2893,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetScale) { scaley = scalex; } - ref->scaleX = scalex; - ref->scaleY = scaley; + ref->Scale = { scalex, scaley }; } return 0; } @@ -2955,8 +2924,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) PARAM_ACTION_PROLOGUE; PARAM_CLASS (debris, AActor); PARAM_BOOL_OPT (transfer_translation) { transfer_translation = false; } - PARAM_FIXED_OPT (mult_h) { mult_h = FRACUNIT; } - PARAM_FIXED_OPT (mult_v) { mult_v = FRACUNIT; } + PARAM_FLOAT_OPT (mult_h) { mult_h = 1; } + PARAM_FLOAT_OPT (mult_v) { mult_v = 1; } int i; AActor *mo; @@ -2964,16 +2933,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) return 0; // only positive values make sense here - if (mult_v <= 0) - mult_v = FRACUNIT; - if (mult_h <= 0) - mult_h = FRACUNIT; + if (mult_v <= 0) mult_v = 1; + if (mult_h <= 0) mult_h = 1; for (i = 0; i < GetDefaultByType(debris)->health; i++) { fixed_t xo = ((pr_spawndebris() - 128) << 12); fixed_t yo = ((pr_spawndebris() - 128) << 12); - fixed_t zo = (pr_spawndebris()*self->height / 256 + self->GetBobOffset()); + fixed_t zo = (pr_spawndebris()*self->_f_height() / 256 + self->GetBobOffset()); mo = Spawn(debris, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { @@ -2985,9 +2952,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) { mo->SetState (mo->GetClass()->OwnedStates + i); } - mo->vel.z = FixedMul(mult_v, ((pr_spawndebris()&7)+5)*FRACUNIT); - mo->vel.x = FixedMul(mult_h, pr_spawndebris.Random2()<<(FRACBITS-6)); - mo->vel.y = FixedMul(mult_h, pr_spawndebris.Random2()<<(FRACBITS-6)); + mo->Vel.X = mult_h * pr_spawndebris.Random2() / 64.; + mo->Vel.Y = mult_h * pr_spawndebris.Random2() / 64.; + mo->Vel.Z = mult_v * ((pr_spawndebris() & 7) + 5); } } return 0; @@ -3034,7 +3001,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle) if (lifetime != 0) { - const angle_t ang = (angle + ((flags & SPF_RELANG) ? self->angle : 0)) >> ANGLETOFINESHIFT; + const angle_t ang = (angle + ((flags & SPF_RELANG) ? self->_f_angle() : 0)) >> ANGLETOFINESHIFT; fixedvec3 pos; //[MC] Code ripped right out of A_SpawnItemEx. if (flags & SPF_RELPOS) @@ -3108,16 +3075,16 @@ static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool return false; } // Check distance first, since it's cheaper than checking sight. - fixedvec2 pos = camera->Vec2To(self); + fixedvec2 pos = camera->_f_Vec2To(self); fixed_t dz; - fixed_t eyez = (camera->Top() - (camera->height>>2)); // same eye height as P_CheckSight - if (eyez > self->Top()) + fixed_t eyez = (camera->_f_Top() - (camera->_f_height()>>2)); // same eye height as P_CheckSight + if (eyez > self->_f_Top()) { - dz = self->Top() - eyez; + dz = self->_f_Top() - eyez; } - else if (eyez < self->Z()) + else if (eyez < self->_f_Z()) { - dz = self->Z() - eyez; + dz = self->_f_Z() - eyez; } else { @@ -3178,16 +3145,16 @@ static bool DoCheckRange(AActor *self, AActor *camera, double range, bool twodi) return false; } // Check distance first, since it's cheaper than checking sight. - fixedvec2 pos = camera->Vec2To(self); + fixedvec2 pos = camera->_f_Vec2To(self); fixed_t dz; - fixed_t eyez = (camera->Top() - (camera->height>>2)); // same eye height as P_CheckSight - if (eyez > self->Top()) + fixed_t eyez = (camera->_f_Top() - (camera->_f_height()>>2)); // same eye height as P_CheckSight + if (eyez > self->_f_Top()) { - dz = self->Top() - eyez; + dz = self->_f_Top() - eyez; } - else if (eyez < self->Z()) + else if (eyez < self->_f_Z()) { - dz = self->Z() - eyez; + dz = self->_f_Z() - eyez; } else { @@ -3344,28 +3311,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst) return 0; } - self->vel.x = self->vel.y = self->vel.z = 0; - self->height = self->GetDefault()->height; + self->Vel.Zero(); + self->Height = self->GetDefault()->Height; // [RH] In Hexen, this creates a random number of shards (range [24,56]) // with no relation to the size of the self shattering. I think it should // base the number of shards on the size of the dead thing, so bigger // things break up into more shards than smaller things. - // An self with radius 20 and height 64 creates ~40 chunks. - numChunks = MAX (4, (self->radius>>FRACBITS)*(self->height>>FRACBITS)/32); + // An self with _f_radius() 20 and height 64 creates ~40 chunks. + numChunks = MAX (4, int(self->radius * self->Height)); i = (pr_burst.Random2()) % (numChunks/4); for (i = MAX (24, numChunks + i); i >= 0; i--) { - fixed_t xo = (((pr_burst() - 128)*self->radius) >> 7); - fixed_t yo = (((pr_burst() - 128)*self->radius) >> 7); - fixed_t zo = (pr_burst()*self->height / 255 + self->GetBobOffset()); + fixed_t xo = (((pr_burst() - 128)*self->_f_radius()) >> 7); + fixed_t yo = (((pr_burst() - 128)*self->_f_radius()) >> 7); + fixed_t zo = (pr_burst()*self->_f_height() / 255 + self->GetBobOffset()); mo = Spawn(chunk, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE); if (mo) { - mo->vel.z = FixedDiv(mo->Z() - self->Z(), self->height)<<2; - mo->vel.x = pr_burst.Random2 () << (FRACBITS-7); - mo->vel.y = pr_burst.Random2 () << (FRACBITS-7); + mo->Vel.Z = 4 * (mo->Z() - self->Z()) * self->Height; + mo->Vel.X = pr_burst.Random2() / 128.; + mo->Vel.Y = pr_burst.Random2() / 128.; mo->RenderStyle = self->RenderStyle; mo->alpha = self->alpha; mo->CopyFriendliness(self, true); @@ -3429,11 +3396,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckCeiling) DEFINE_ACTION_FUNCTION(AActor, A_Stop) { PARAM_ACTION_PROLOGUE; - self->vel.x = self->vel.y = self->vel.z = 0; + self->Vel.Zero(); if (self->player && self->player->mo == self && !(self->player->cheats & CF_PREDICTING)) { self->player->mo->PlayIdle(); - self->player->vel.x = self->player->vel.y = 0; + self->player->Vel.Zero(); } return 0; } @@ -3442,11 +3409,10 @@ static void CheckStopped(AActor *self) { if (self->player != NULL && self->player->mo == self && - !(self->player->cheats & CF_PREDICTING) && - !(self->vel.x | self->vel.y | self->vel.z)) + !(self->player->cheats & CF_PREDICTING) && !self->Vel.isZero()) { self->player->mo->PlayIdle(); - self->player->vel.x = self->player->vel.y = 0; + self->player->Vel.Zero(); } } @@ -3471,21 +3437,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) PARAM_INT_OPT(flags) { flags = RSF_FOG; } bool oktorespawn = false; - fixedvec3 pos = self->Pos(); + fixedvec3 pos = self->_f_Pos(); self->flags |= MF_SOLID; - self->height = self->GetDefault()->height; + self->Height = self->GetDefault()->Height; self->radius = self->GetDefault()->radius; CALL_ACTION(A_RestoreSpecialPosition, self); if (flags & RSF_TELEFRAG) { // [KS] DIE DIE DIE DIE erm *ahem* =) - oktorespawn = P_TeleportMove(self, self->Pos(), true, false); + oktorespawn = P_TeleportMove(self, self->_f_Pos(), true, false); } else { - oktorespawn = P_CheckPosition(self, self->X(), self->Y(), true); + oktorespawn = P_CheckPosition(self, self->_f_X(), self->_f_Y(), true); } if (oktorespawn) @@ -3523,7 +3489,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) if (flags & RSF_FOG) { P_SpawnTeleportFog(self, pos, true, true); - P_SpawnTeleportFog(self, self->Pos(), false, true); + P_SpawnTeleportFog(self, self->_f_Pos(), false, true); } if (self->CountsAsKill()) { @@ -3565,9 +3531,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlayerSkinCheck) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetGravity) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(gravity); + PARAM_FLOAT(gravity); - self->gravity = clamp(gravity, 0, FRACUNIT*10); + self->Gravity = clamp(gravity, 0., 10.); return 0; } @@ -3732,11 +3698,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) PARAM_ACTION_PROLOGUE; PARAM_STATE (jump); PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (range) { range = 0; } - PARAM_FIXED_OPT (minrange) { minrange = 0; } + PARAM_FLOAT_OPT (range) { range = 0; } + PARAM_FLOAT_OPT (minrange) { minrange = 0; } { - PARAM_ANGLE_OPT (angle) { angle = 0; } - PARAM_ANGLE_OPT (pitch) { pitch = 0; } + PARAM_DANGLE_OPT(angle) { angle = 0.; } + PARAM_DANGLE_OPT(pitch) { pitch = 0.; } PARAM_FIXED_OPT (offsetheight) { offsetheight = 0; } PARAM_FIXED_OPT (offsetwidth) { offsetwidth = 0; } PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } @@ -3748,30 +3714,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) { if (self->player != NULL) { - // Synced with hitscan: self->player->mo->height is strangely conscientious about getting the right actor for player - offsetheight = FixedMul(offsetheight, FixedMul (self->player->mo->height, self->player->crouchfactor)); + // Synced with hitscan: self->player->mo->_f_height() is strangely conscientious about getting the right actor for player + offsetheight = FixedMul(offsetheight, fixed_t(self->player->mo->_f_height() * self->player->crouchfactor)); } else { - offsetheight = FixedMul(offsetheight, self->height); + offsetheight = FixedMul(offsetheight, self->_f_height()); } } if (flags & CLOFF_MUL_WIDTH) { - offsetforward = FixedMul(self->radius, offsetforward); - offsetwidth = FixedMul(self->radius, offsetwidth); + offsetforward = FixedMul(self->_f_radius(), offsetforward); + offsetwidth = FixedMul(self->_f_radius(), offsetwidth); } - pos = self->PosPlusZ(offsetheight - self->floorclip); + pos = self->PosPlusZ(offsetheight - self->_f_floorclip()); if (!(flags & CLOFF_FROMBASE)) { // default to hitscan origin - // Synced with hitscan: self->height is strangely NON-conscientious about getting the right actor for player - pos.z += (self->height >> 1); + // Synced with hitscan: self->_f_height() is strangely NON-conscientious about getting the right actor for player + pos.z += (self->_f_height() >> 1); if (self->player != NULL) { - pos.z += FixedMul (self->player->mo->AttackZOffset, self->player->crouchfactor); + pos.z += fixed_t (self->player->mo->AttackZOffset * self->player->crouchfactor); } else { @@ -3781,11 +3747,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) if (target) { - fixed_t xydist = self->Distance2D(target); - fixed_t distance = P_AproxDistance(xydist, target->Z() - pos.z); - - if (range && !(flags & CLOFF_CHECKPARTIAL)) + if (range > 0 && !(flags & CLOFF_CHECKPARTIAL)) { + double distance = self->Distance3D(target); if (distance > range) { ACTION_RETURN_STATE(NULL); @@ -3793,49 +3757,48 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) } { - angle_t ang; + DAngle ang; if (flags & CLOFF_NOAIM_HORZ) { - ang = self->angle; + ang = self->Angles.Yaw; } else ang = self->AngleTo (target); angle += ang; - - ang >>= ANGLETOFINESHIFT; - fixedvec2 xy = self->Vec2Offset( - FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), - FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); + double s = ang.Sin(); + double c = ang.Cos(); + + fixedvec2 xy = self->Vec2Offset(fixed_t(offsetforward * c + offsetwidth * s), fixed_t(offsetforward * s - offsetwidth * c)); pos.x = xy.x; pos.y = xy.y; } + double xydist = self->Distance2D(target); if (flags & CLOFF_NOAIM_VERT) { - pitch += self->pitch; + pitch += self->Angles.Pitch; } else if (flags & CLOFF_AIM_VERT_NOOFFSET) { - pitch -= R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + offsetheight + target->height / 2); + pitch -= VecToAngle(xydist, FIXED2FLOAT(target->_f_Z() - pos.z + offsetheight + target->_f_height() / 2)); } else { - pitch -= R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + target->height / 2); + pitch -= VecToAngle(xydist, FIXED2FLOAT(target->_f_Z() - pos.z + target->_f_height() / 2)); } } else if (flags & CLOFF_ALLOWNULL) { - angle += self->angle; - pitch += self->pitch; + angle += self->Angles.Yaw; + pitch += self->Angles.Pitch; - angle_t ang = self->angle >> ANGLETOFINESHIFT; + double s = angle.Sin(); + double c = angle.Cos(); - fixedvec2 xy = self->Vec2Offset( - FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), - FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); + fixedvec2 xy = self->Vec2Offset(fixed_t(offsetforward * c + offsetwidth * s), fixed_t(offsetforward * s - offsetwidth * c)); pos.x = xy.x; pos.y = xy.y; @@ -3845,12 +3808,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) ACTION_RETURN_STATE(NULL); } - angle >>= ANGLETOFINESHIFT; - pitch >>= ANGLETOFINESHIFT; + double cp = pitch.Cos(); - vx = FixedMul (finecosine[pitch], finecosine[angle]); - vy = FixedMul (finecosine[pitch], finesine[angle]); - vz = -finesine[pitch]; + vx = FLOAT2FIXED(cp * angle.Cos()); + vy = FLOAT2FIXED(cp * angle.Sin()); + vz = FLOAT2FIXED(-pitch.Sin()); } /* Variable set: @@ -3876,13 +3838,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) lof_data.Flags = flags; lof_data.BadActor = false; - Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, + Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, FLOAT2FIXED(range), ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, CheckLOFTraceFunc, &lof_data); if (trace.HitType == TRACE_HitActor || ((flags & CLOFF_JUMP_ON_MISS) && !lof_data.BadActor && trace.HitType != TRACE_HitNone)) { - if (minrange > 0 && trace.Distance < minrange) + if (minrange > 0 && trace.Distance < FLOAT2FIXED(minrange)) { ACTION_RETURN_STATE(NULL); } @@ -3976,7 +3938,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) else { // Does the player aim at something that can be shot? - P_AimLineAttack(self, self->angle, MISSILERANGE, &t, (flags & JLOSF_NOAUTOAIM) ? ANGLE_1/2 : 0, ALF_PORTALRESTRICT); + P_AimLineAttack(self, self->Angles.Yaw, MISSILERANGE, &t, (flags & JLOSF_NOAUTOAIM) ? 0.5 : 0., ALF_PORTALRESTRICT); if (!t.linetarget) { @@ -4048,7 +4010,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS) if (fov && (fov < ANGLE_MAX)) { - an = viewport->AngleTo(target) - viewport->angle; + an = viewport->__f_AngleTo(target) - viewport->_f_angle(); if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) { @@ -4128,7 +4090,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS) if (fov && (fov < ANGLE_MAX)) { - an = target->AngleTo(self) - target->angle; + an = target->__f_AngleTo(self) - target->_f_angle(); if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2))) { @@ -4463,7 +4425,7 @@ enum DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(angle) { angle = 0; } + PARAM_FLOAT_OPT(angle) { angle = 0; } PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -4486,7 +4448,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE(pitch); + PARAM_FLOAT(pitch); PARAM_INT_OPT(flags) { flags = 0; } PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } @@ -4497,23 +4459,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) return 0; } - if (ref->player != NULL || (flags & SPF_FORCECLAMP)) - { // clamp the pitch we set - int min, max; - - if (ref->player != NULL) - { - min = ref->player->MinPitch; - max = ref->player->MaxPitch; - } - else - { - min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); - max = ANGLE_90 - (1 << ANGLETOFINESHIFT); - } - pitch = clamp(pitch, min, max); - } - ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE), !!(flags & SPF_FORCECLAMP)); return 0; } @@ -4529,7 +4474,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE (roll); + PARAM_FLOAT (roll); PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -4552,7 +4497,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(scale); + PARAM_FLOAT(scale); PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -4562,11 +4507,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) return 0; } - INTBOOL was_moving = ref->vel.x | ref->vel.y | ref->vel.z; + bool was_moving = !ref->Vel.isZero(); - ref->vel.x = FixedMul(ref->vel.x, scale); - ref->vel.y = FixedMul(ref->vel.y, scale); - ref->vel.z = FixedMul(ref->vel.z, scale); + ref->Vel *= scale; // If the actor was previously moving but now is not, and is a player, // update its player variables. (See A_Stop.) @@ -4586,9 +4529,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ScaleVelocity) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED_OPT (x) { x = 0; } - PARAM_FIXED_OPT (y) { y = 0; } - PARAM_FIXED_OPT (z) { z = 0; } + PARAM_FLOAT_OPT (x) { x = 0; } + PARAM_FLOAT_OPT (y) { y = 0; } + PARAM_FLOAT_OPT (z) { z = 0; } PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } @@ -4599,28 +4542,24 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeVelocity) return 0; } - INTBOOL was_moving = ref->vel.x | ref->vel.y | ref->vel.z; + INTBOOL was_moving = !ref->Vel.isZero(); - fixed_t vx = x, vy = y, vz = z; - fixed_t sina = finesine[ref->angle >> ANGLETOFINESHIFT]; - fixed_t cosa = finecosine[ref->angle >> ANGLETOFINESHIFT]; + DVector3 vel(x, y, z); + double sina = ref->Angles.Yaw.Sin(); + double cosa = ref->Angles.Yaw.Cos(); if (flags & 1) // relative axes - make x, y relative to actor's current angle { - vx = DMulScale16(x, cosa, -y, sina); - vy = DMulScale16(x, sina, y, cosa); + vel.X = x*cosa - y*sina; + vel.Y = x*sina + y*cosa; } if (flags & 2) // discard old velocity - replace old velocity with new velocity { - ref->vel.x = vx; - ref->vel.y = vy; - ref->vel.z = vz; + ref->Vel = vel; } else // add new velocity to old velocity { - ref->vel.x += vx; - ref->vel.y += vy; - ref->vel.z += vz; + ref->Vel += vel; } if (was_moving) @@ -4769,8 +4708,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) PARAM_CLASS_OPT (target_type, ASpecialSpot) { target_type = PClass::FindActor("BossSpot"); } PARAM_CLASS_OPT (fog_type, AActor) { fog_type = PClass::FindActor("TeleportFog"); } PARAM_INT_OPT (flags) { flags = 0; } - PARAM_FIXED_OPT (mindist) { mindist = 128 << FRACBITS; } - PARAM_FIXED_OPT (maxdist) { maxdist = 128 << FRACBITS; } + PARAM_FLOAT_OPT (mindist) { mindist = 128; } + PARAM_FLOAT_OPT (maxdist) { maxdist = 0; } PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -4841,28 +4780,30 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) // of the spot. if (flags & TF_SENSITIVEZ) { - fixed_t posz = (flags & TF_USESPOTZ) ? spot->Z() : spot->floorz; - if ((posz + ref->height > spot->ceilingz) || (posz < spot->floorz)) + double posz = (flags & TF_USESPOTZ) ? spot->Z() : spot->floorz; + if ((posz + ref->Height > spot->ceilingz) || (posz < spot->floorz)) { return numret; } } - fixedvec3 prev = ref->Pos(); - fixed_t aboveFloor = spot->Z() - spot->floorz; - fixed_t finalz = spot->floorz + aboveFloor; + DVector3 prev = ref->Pos(); + double aboveFloor = spot->Z() - spot->floorz; + double finalz = spot->floorz + aboveFloor; - if (spot->Z() + ref->height > spot->ceilingz) - finalz = spot->ceilingz - ref->height; + if (spot->Top() > spot->ceilingz) + finalz = spot->ceilingz - ref->Height; else if (spot->Z() < spot->floorz) finalz = spot->floorz; + DVector3 tpos = spot->PosAtZ(finalz); + //Take precedence and cooperate with telefragging first. - bool tele_result = P_TeleportMove(ref, spot->X(), spot->Y(), finalz, !!(flags & TF_TELEFRAG)); + bool tele_result = P_TeleportMove(ref, tpos, !!(flags & TF_TELEFRAG)); if (!tele_result && (flags & TF_FORCED)) { //If for some reason the original move didn't work, regardless of telefrag, force it to move. - ref->SetOrigin(spot->X(), spot->Y(), finalz, false); + ref->SetOrigin(tpos, false); tele_result = true; } @@ -4900,10 +4841,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) ref->SetZ((flags & TF_USESPOTZ) ? spot->Z() : ref->floorz, false); if (!(flags & TF_KEEPANGLE)) - ref->angle = spot->angle; + ref->Angles.Yaw = spot->Angles.Yaw; - if (!(flags & TF_KEEPVELOCITY)) - ref->vel.x = ref->vel.y = ref->vel.z = 0; + if (!(flags & TF_KEEPVELOCITY)) ref->Vel.Zero(); if (!(flags & TF_NOJUMP)) //The state jump should only happen with the calling actor. { @@ -4940,8 +4880,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Turn) { PARAM_ACTION_PROLOGUE; - PARAM_ANGLE_OPT(angle) { angle = 0; } - self->angle += angle; + PARAM_FLOAT_OPT(angle) { angle = 0; } + self->Angles.Yaw += angle; return 0; } @@ -5005,13 +4945,13 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis weaveXY = self->WeaveIndexXY & 63; weaveZ = self->WeaveIndexZ & 63; - angle = (self->angle + ANG90) >> ANGLETOFINESHIFT; + angle = (self->_f_angle() + ANG90) >> ANGLETOFINESHIFT; if (xydist != 0 && xyspeed != 0) { dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist); - newX = self->X() - FixedMul (finecosine[angle], dist); - newY = self->Y() - FixedMul (finesine[angle], dist); + newX = self->_f_X() - FixedMul (finecosine[angle], dist); + newY = self->_f_Y() - FixedMul (finesine[angle], dist); weaveXY = (weaveXY + xyspeed) & 63; dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist); newX += FixedMul (finecosine[angle], dist); @@ -5025,8 +4965,8 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis self->UnlinkFromWorld (); self->flags |= MF_NOBLOCKMAP; // We need to do portal offsetting here explicitly, because SetXY cannot do that. - newX -= self->X(); - newY -= self->Y(); + newX -= self->_f_X(); + newY -= self->_f_Y(); self->SetXY(self->Vec2Offset(newX, newY)); self->LinkToWorld (); } @@ -5034,9 +4974,9 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis } if (zdist != 0 && zspeed != 0) { - self->AddZ(-MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist)); + self->_f_AddZ(-MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist)); weaveZ = (weaveZ + zspeed) & 63; - self->AddZ(MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist)); + self->_f_AddZ(MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist)); self->WeaveIndexZ = weaveZ; } } @@ -5121,12 +5061,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) A_FaceTarget (self); // Target can dodge if it can see enemy - angle_t angle = self->target->AngleTo(self) - self->target->angle; + angle_t angle = self->target->__f_AngleTo(self) - self->target->_f_angle(); angle >>= 24; bool dodge = (P_CheckSight(self->target, self) && (angle>226 || angle<30)); // Distance check is simplistic - fixedvec2 vec = self->Vec2To(self->target); + fixedvec2 vec = self->_f_Vec2To(self->target); fixed_t dx = abs (vec.x); fixed_t dy = abs (vec.y); fixed_t dist = dx > dy ? dx : dy; @@ -5139,9 +5079,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) dist /= blocksize; // Now for the speed accuracy thingie - fixed_t speed = FixedMul(self->target->vel.x, self->target->vel.x) - + FixedMul(self->target->vel.y, self->target->vel.y) - + FixedMul(self->target->vel.z, self->target->vel.z); + fixed_t speed = FixedMul(self->target->_f_velx(), self->target->_f_velx()) + + FixedMul(self->target->_f_vely(), self->target->_f_vely()) + + FixedMul(self->target->_f_velz(), self->target->_f_velz()); int hitchance = speed < runspeed ? 256 : 160; // Distance accuracy (factoring dodge) @@ -5157,9 +5097,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if (pr_cabullet() < hitchance) { // Compute position for spawning blood/puff - angle = self->target->AngleTo(self); + angle = self->target->__f_AngleTo(self); - fixedvec3 bloodpos = self->target->Vec3Angle(self->target->radius, angle, self->target->height >> 1); + fixedvec3 bloodpos = self->target->_f_Vec3Angle(self->target->_f_radius(), angle, self->target->_f_height() >> 1); int damage = flags & WAF_NORANDOM ? maxdamage : (1 + (pr_cabullet() % maxdamage)); @@ -5496,8 +5436,8 @@ static bool DoRadiusGive(AActor *self, AActor *thing, PClassActor *item, int amo if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass) { - fixedvec3 diff = self->Vec3To(thing); - diff.z += (thing->height - self->height) / 2; + fixedvec3 diff = self->_f_Vec3To(thing); + diff.z += (thing->_f_height() - self->_f_height()) / 2; if (flags & RGF_CUBE) { // check if inside a cube double dx = fabs((double)(diff.x)); @@ -5582,8 +5522,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) else { FPortalGroupArray check(FPortalGroupArray::PGA_Full3d); - fixed_t mid = self->Z() + self->height / 2; - FMultiBlockThingsIterator it(check, self->X(), self->Y(), mid-distance, mid+distance, distance, false, self->Sector); + fixed_t mid = self->_f_Z() + self->_f_height() / 2; + FMultiBlockThingsIterator it(check, self->_f_X(), self->_f_Y(), mid-distance, mid+distance, distance, false, self->Sector); FMultiBlockThingsIterator::CheckResult cres; while ((it.Next(&cres))) @@ -5682,7 +5622,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropItem) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(speed); + PARAM_FLOAT(speed); PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -5702,7 +5642,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetFloatSpeed) { PARAM_ACTION_PROLOGUE; - PARAM_FIXED(speed); + PARAM_FLOAT(speed); PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; } AActor *ref = COPY_AAPTR(self, ptr); @@ -6414,11 +6354,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) if (mobj != NULL && mobj != self) //AAPTR_DEFAULT is completely useless in this regard. { - if ((high) && (mobj->Z() > ((includeHeight ? self->height : 0) + self->Z() + offsethigh))) + if ((high) && (mobj->_f_Z() > ((includeHeight ? self->_f_height() : 0) + self->_f_Z() + offsethigh))) { ACTION_RETURN_STATE(high); } - else if ((low) && (mobj->Z() + (includeHeight ? mobj->height : 0)) < (self->Z() + offsetlow)) + else if ((low) && (mobj->_f_Z() + (includeHeight ? mobj->_f_height() : 0)) < (self->_f_Z() + offsetlow)) { ACTION_RETURN_STATE(low); } @@ -6599,8 +6539,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) //Ripped from sphere checking in A_RadiusGive (along with a number of things). if ((ref->AproxDistance(mo) < distance && ((flags & CPXF_NOZ) || - ((ref->Z() > mo->Z() && ref->Z() - mo->Top() < distance) || - (ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance))))) + ((ref->_f_Z() > mo->_f_Z() && ref->_f_Z() - mo->_f_Top() < distance) || + (ref->_f_Z() <= mo->_f_Z() && mo->_f_Z() - ref->_f_Top() < distance))))) { if ((flags & CPXF_CHECKSIGHT) && !(P_CheckSight(mo, ref, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY))) continue; @@ -6712,7 +6652,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) } //Nothing to block it so skip the rest. - bool checker = (flags & CBF_DROPOFF) ? P_CheckMove(mobj, mobj->X(), mobj->Y()) : P_TestMobjLocation(mobj); + bool checker = (flags & CBF_DROPOFF) ? P_CheckMove(mobj, mobj->_f_X(), mobj->_f_Y()) : P_TestMobjLocation(mobj); if (checker) { ACTION_RETURN_STATE(NULL); @@ -6776,10 +6716,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) } //Don't bother calculating this if we don't have any horizontal movement. - if (!(flags & FMDF_NOANGLE) && (mobj->vel.x != 0 || mobj->vel.y != 0)) + if (!(flags & FMDF_NOANGLE) && (mobj->Vel.X != 0 || mobj->Vel.Y != 0)) { - angle_t current = mobj->angle; - const angle_t angle = R_PointToAngle2(0, 0, mobj->vel.x, mobj->vel.y); + angle_t current = mobj->_f_angle(); + const angle_t angle = R_PointToAngle2(0, 0, mobj->_f_velx(), mobj->_f_vely()); //Done because using anglelimit directly causes a signed/unsigned mismatch. const angle_t limit = anglelimit; @@ -6794,7 +6734,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) current += limit + offset; else current -= limit + offset; - mobj->SetAngle(current, !!(flags & FMDF_INTERPOLATE)); + mobj->SetAngle(ANGLE2DBL(current), !!(flags & FMDF_INTERPOLATE)); } else if (current > angle) { @@ -6802,20 +6742,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) current -= limit + offset; else current += limit + offset; - mobj->SetAngle(current, !!(flags & FMDF_INTERPOLATE)); + mobj->SetAngle(ANGLE2DBL(current), !!(flags & FMDF_INTERPOLATE)); } else - mobj->SetAngle(angle + ANGLE_180 + offset, !!(flags & FMDF_INTERPOLATE)); + mobj->SetAngle(ANGLE2DBL(angle + ANGLE_180 + offset), !!(flags & FMDF_INTERPOLATE)); } else - mobj->SetAngle(angle + offset, !!(flags & FMDF_INTERPOLATE)); + mobj->SetAngle(ANGLE2DBL(angle + offset), !!(flags & FMDF_INTERPOLATE)); } if (!(flags & FMDF_NOPITCH)) { - fixed_t current = mobj->pitch; - const DVector2 velocity(mobj->vel.x, mobj->vel.y); - const fixed_t pitch = R_PointToAngle2(0, 0, xs_CRoundToInt(velocity.Length()), -mobj->vel.z); + fixed_t current = mobj->_f_pitch(); + const DVector2 velocity(mobj->_f_velx(), mobj->_f_vely()); + const fixed_t pitch = R_PointToAngle2(0, 0, xs_CRoundToInt(velocity.Length()), -mobj->_f_velz()); if (pitchlimit > 0) { // [MC] angle_t for pitchlimit was required because otherwise @@ -6839,17 +6779,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection) max = MIN(plimit, (pitch - current)); current += max; } - mobj->SetPitch(current, !!(flags & FMDF_INTERPOLATE)); + mobj->SetPitch(ANGLE2DBL(current), !!(flags & FMDF_INTERPOLATE)); } else { - mobj->SetPitch(pitch, !!(flags & FMDF_INTERPOLATE)); + mobj->SetPitch(ANGLE2DBL(pitch), !!(flags & FMDF_INTERPOLATE)); } } else { - mobj->SetPitch(pitch, !!(flags & FMDF_INTERPOLATE)); + mobj->SetPitch(ANGLE2DBL(pitch), !!(flags & FMDF_INTERPOLATE)); } } ACTION_RETURN_BOOL(true); diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 132440a73..da23b61e3 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -620,37 +620,37 @@ void InitThingdef() PSymbolTable &symt = RUNTIME_CLASS(AActor)->Symbols; PType *array5 = NewArray(TypeSInt32, 5); symt.AddSymbol(new PField(NAME_Alpha, TypeFixed, VARF_Native, myoffsetof(AActor,alpha))); - symt.AddSymbol(new PField(NAME_Angle, TypeAngle, VARF_Native, myoffsetof(AActor,angle))); - symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor,args))); - symt.AddSymbol(new PField(NAME_CeilingZ, TypeFixed, VARF_Native, myoffsetof(AActor,ceilingz))); - symt.AddSymbol(new PField(NAME_FloorZ, TypeFixed, VARF_Native, myoffsetof(AActor,floorz))); - symt.AddSymbol(new PField(NAME_Health, TypeSInt32, VARF_Native, myoffsetof(AActor,health))); - symt.AddSymbol(new PField(NAME_Mass, TypeSInt32, VARF_Native, myoffsetof(AActor,Mass))); - symt.AddSymbol(new PField(NAME_Pitch, TypeAngle, VARF_Native, myoffsetof(AActor,pitch))); - symt.AddSymbol(new PField(NAME_Roll, TypeAngle, VARF_Native, myoffsetof(AActor,roll))); - symt.AddSymbol(new PField(NAME_Special, TypeSInt32, VARF_Native, myoffsetof(AActor,special))); - symt.AddSymbol(new PField(NAME_TID, TypeSInt32, VARF_Native, myoffsetof(AActor,tid))); - symt.AddSymbol(new PField(NAME_TIDtoHate, TypeSInt32, VARF_Native, myoffsetof(AActor,TIDtoHate))); - symt.AddSymbol(new PField(NAME_WaterLevel, TypeSInt32, VARF_Native, myoffsetof(AActor,waterlevel))); + symt.AddSymbol(new PField(NAME_Angle, TypeFloat64, VARF_Native, myoffsetof(AActor,Angles.Yaw))); + symt.AddSymbol(new PField(NAME_Args, array5, VARF_Native, myoffsetof(AActor,args))); + symt.AddSymbol(new PField(NAME_CeilingZ, TypeFloat64, VARF_Native, myoffsetof(AActor,ceilingz))); + symt.AddSymbol(new PField(NAME_FloorZ, TypeFloat64, VARF_Native, myoffsetof(AActor,floorz))); + symt.AddSymbol(new PField(NAME_Health, TypeSInt32, VARF_Native, myoffsetof(AActor,health))); + symt.AddSymbol(new PField(NAME_Mass, TypeSInt32, VARF_Native, myoffsetof(AActor,Mass))); + symt.AddSymbol(new PField(NAME_Pitch, TypeFloat64, VARF_Native, myoffsetof(AActor,Angles.Pitch))); + symt.AddSymbol(new PField(NAME_Roll, TypeFloat64, VARF_Native, myoffsetof(AActor,Angles.Roll))); + symt.AddSymbol(new PField(NAME_Special, TypeSInt32, VARF_Native, myoffsetof(AActor,special))); + symt.AddSymbol(new PField(NAME_TID, TypeSInt32, VARF_Native, myoffsetof(AActor,tid))); + symt.AddSymbol(new PField(NAME_TIDtoHate, TypeSInt32, VARF_Native, myoffsetof(AActor,TIDtoHate))); + symt.AddSymbol(new PField(NAME_WaterLevel, TypeSInt32, VARF_Native, myoffsetof(AActor,waterlevel))); symt.AddSymbol(new PField(NAME_X, TypeFixed, VARF_Native, myoffsetof(AActor,__pos.x))); // must remain read-only! symt.AddSymbol(new PField(NAME_Y, TypeFixed, VARF_Native, myoffsetof(AActor,__pos.y))); // must remain read-only! symt.AddSymbol(new PField(NAME_Z, TypeFixed, VARF_Native, myoffsetof(AActor,__pos.z))); // must remain read-only! - symt.AddSymbol(new PField(NAME_VelX, TypeFixed, VARF_Native, myoffsetof(AActor,vel.x))); - symt.AddSymbol(new PField(NAME_VelY, TypeFixed, VARF_Native, myoffsetof(AActor,vel.y))); - symt.AddSymbol(new PField(NAME_VelZ, TypeFixed, VARF_Native, myoffsetof(AActor,vel.z))); - symt.AddSymbol(new PField(NAME_MomX, TypeFixed, VARF_Native, myoffsetof(AActor,vel.x))); - symt.AddSymbol(new PField(NAME_MomY, TypeFixed, VARF_Native, myoffsetof(AActor,vel.y))); - symt.AddSymbol(new PField(NAME_MomZ, TypeFixed, VARF_Native, myoffsetof(AActor,vel.z))); - symt.AddSymbol(new PField(NAME_ScaleX, TypeFixed, VARF_Native, myoffsetof(AActor,scaleX))); - symt.AddSymbol(new PField(NAME_ScaleY, TypeFixed, VARF_Native, myoffsetof(AActor,scaleY))); - symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor,Score))); - symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor,accuracy))); - symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor,stamina))); - symt.AddSymbol(new PField(NAME_Height, TypeFixed, VARF_Native, myoffsetof(AActor,height))); - symt.AddSymbol(new PField(NAME_Radius, TypeFixed, VARF_Native, myoffsetof(AActor,radius))); - symt.AddSymbol(new PField(NAME_ReactionTime,TypeSInt32, VARF_Native, myoffsetof(AActor,reactiontime))); + symt.AddSymbol(new PField(NAME_VelX, TypeFloat64, VARF_Native, myoffsetof(AActor,Vel.X))); + symt.AddSymbol(new PField(NAME_VelY, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Y))); + symt.AddSymbol(new PField(NAME_VelZ, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Z))); + symt.AddSymbol(new PField(NAME_MomX, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.X))); + symt.AddSymbol(new PField(NAME_MomY, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Y))); + symt.AddSymbol(new PField(NAME_MomZ, TypeFloat64, VARF_Native, myoffsetof(AActor, Vel.Z))); + symt.AddSymbol(new PField(NAME_ScaleX, TypeFloat64, VARF_Native, myoffsetof(AActor, Scale.X))); + symt.AddSymbol(new PField(NAME_ScaleY, TypeFloat64, VARF_Native, myoffsetof(AActor, Scale.Y))); + symt.AddSymbol(new PField(NAME_Score, TypeSInt32, VARF_Native, myoffsetof(AActor,Score))); + symt.AddSymbol(new PField(NAME_Accuracy, TypeSInt32, VARF_Native, myoffsetof(AActor,accuracy))); + symt.AddSymbol(new PField(NAME_Stamina, TypeSInt32, VARF_Native, myoffsetof(AActor,stamina))); + symt.AddSymbol(new PField(NAME_Height, TypeFloat64, VARF_Native, myoffsetof(AActor,Height))); + symt.AddSymbol(new PField(NAME_Radius, TypeFloat64, VARF_Native, myoffsetof(AActor,radius))); + symt.AddSymbol(new PField(NAME_ReactionTime,TypeSInt32, VARF_Native, myoffsetof(AActor,reactiontime))); symt.AddSymbol(new PField(NAME_MeleeRange, TypeFixed, VARF_Native, myoffsetof(AActor,meleerange))); - symt.AddSymbol(new PField(NAME_Speed, TypeFixed, VARF_Native, myoffsetof(AActor,Speed))); - symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native, myoffsetof(AActor,threshold))); - symt.AddSymbol(new PField(NAME_DefThreshold,TypeSInt32, VARF_Native, myoffsetof(AActor,DefThreshold))); + symt.AddSymbol(new PField(NAME_Speed, TypeFloat64, VARF_Native, myoffsetof(AActor,Speed))); + symt.AddSymbol(new PField(NAME_Threshold, TypeSInt32, VARF_Native, myoffsetof(AActor,threshold))); + symt.AddSymbol(new PField(NAME_DefThreshold,TypeSInt32, VARF_Native, myoffsetof(AActor,DefThreshold))); } diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 7ecc3c3c4..441e53371 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -53,6 +53,7 @@ #include "m_fixed.h" #include "vmbuilder.h" #include "v_text.h" +#include "math/cmath.h" struct FLOP { @@ -65,23 +66,23 @@ struct FLOP // degrees to radians for those that work with angles. static const FLOP FxFlops[] = { - { NAME_Exp, FLOP_EXP, [](double v) { return exp(v); } }, - { NAME_Log, FLOP_LOG, [](double v) { return log(v); } }, - { NAME_Log10, FLOP_LOG10, [](double v) { return log10(v); } }, - { NAME_Sqrt, FLOP_SQRT, [](double v) { return sqrt(v); } }, + { NAME_Exp, FLOP_EXP, [](double v) { return g_exp(v); } }, + { NAME_Log, FLOP_LOG, [](double v) { return g_log(v); } }, + { NAME_Log10, FLOP_LOG10, [](double v) { return g_log10(v); } }, + { NAME_Sqrt, FLOP_SQRT, [](double v) { return g_sqrt(v); } }, { NAME_Ceil, FLOP_CEIL, [](double v) { return ceil(v); } }, { NAME_Floor, FLOP_FLOOR, [](double v) { return floor(v); } }, - { NAME_ACos, FLOP_ACOS_DEG, [](double v) { return acos(v) * (180.0 / M_PI); } }, - { NAME_ASin, FLOP_ASIN_DEG, [](double v) { return asin(v) * (180.0 / M_PI); } }, - { NAME_ATan, FLOP_ATAN_DEG, [](double v) { return atan(v) * (180.0 / M_PI); } }, - { NAME_Cos, FLOP_COS_DEG, [](double v) { return cos(v * (M_PI / 180.0)); } }, - { NAME_Sin, FLOP_SIN_DEG, [](double v) { return sin(v * (M_PI / 180.0)); } }, - { NAME_Tan, FLOP_TAN_DEG, [](double v) { return tan(v * (M_PI / 180.0)); } }, + { NAME_ACos, FLOP_ACOS_DEG, [](double v) { return g_acos(v) * (180.0 / M_PI); } }, + { NAME_ASin, FLOP_ASIN_DEG, [](double v) { return g_asin(v) * (180.0 / M_PI); } }, + { NAME_ATan, FLOP_ATAN_DEG, [](double v) { return g_atan(v) * (180.0 / M_PI); } }, + { NAME_Cos, FLOP_COS_DEG, [](double v) { return g_cosdeg(v); } }, + { NAME_Sin, FLOP_SIN_DEG, [](double v) { return g_sindeg(v); } }, + { NAME_Tan, FLOP_TAN_DEG, [](double v) { return g_tan(v * (M_PI / 180.0)); } }, - { NAME_CosH, FLOP_COSH, [](double v) { return cosh(v); } }, - { NAME_SinH, FLOP_SINH, [](double v) { return sinh(v); } }, - { NAME_TanH, FLOP_TANH, [](double v) { return tanh(v); } }, + { NAME_CosH, FLOP_COSH, [](double v) { return g_cosh(v); } }, + { NAME_SinH, FLOP_SINH, [](double v) { return g_sinh(v); } }, + { NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } }, }; ExpEmit::ExpEmit(VMFunctionBuilder *build, int type) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index d84e10493..e8c83fe40 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -242,7 +242,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in defaults->DamageType = set? NAME_Ice : NAME_None; break; case DEPF_LOWGRAVITY: - defaults->gravity = set? FRACUNIT/8 : FRACUNIT; + defaults->Gravity = set ? 1. / 8 : 1.; break; case DEPF_SHORTMISSILERANGE: defaults->maxtargetrange = set? 896*FRACUNIT : 0; @@ -251,7 +251,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in defaults->meleethreshold = set? 196*FRACUNIT : 0; break; case DEPF_QUARTERGRAVITY: - defaults->gravity = set? FRACUNIT/4 : FRACUNIT; + defaults->Gravity = set ? 1. / 4 : 1.; break; case DEPF_FIRERESIST: info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT); @@ -312,13 +312,13 @@ bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index) case DEPF_ICEDAMAGE: return actor->DamageType == NAME_Ice; case DEPF_LOWGRAVITY: - return actor->gravity == FRACUNIT/8; + return actor->Gravity == 1./8; case DEPF_SHORTMISSILERANGE: return actor->maxtargetrange == 896*FRACUNIT; case DEPF_LONGMELEERANGE: return actor->meleethreshold == 196*FRACUNIT; case DEPF_QUARTERGRAVITY: - return actor->gravity == FRACUNIT/4; + return actor->Gravity == 1./4; case DEPF_FIRERESIST: if (info->DamageFactors) { @@ -606,7 +606,7 @@ DEFINE_PROPERTY(projectilekickback, I, Actor) //========================================================================== DEFINE_PROPERTY(speed, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->Speed = id; } @@ -615,8 +615,8 @@ DEFINE_PROPERTY(speed, F, Actor) //========================================================================== DEFINE_PROPERTY(floatspeed, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->FloatSpeed=id; + PROP_DOUBLE_PARM(id, 0); + defaults->FloatSpeed = id; } //========================================================================== @@ -624,8 +624,8 @@ DEFINE_PROPERTY(floatspeed, F, Actor) //========================================================================== DEFINE_PROPERTY(radius, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->radius=id; + PROP_DOUBLE_PARM(id, 0); + defaults->radius = id; } //========================================================================== @@ -633,8 +633,8 @@ DEFINE_PROPERTY(radius, F, Actor) //========================================================================== DEFINE_PROPERTY(height, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->height=id; + PROP_DOUBLE_PARM(id, 0); + defaults->Height=id; } //========================================================================== @@ -642,7 +642,7 @@ DEFINE_PROPERTY(height, F, Actor) //========================================================================== DEFINE_PROPERTY(projectilepassheight, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); defaults->projectilepassheight=id; } @@ -660,8 +660,8 @@ DEFINE_PROPERTY(mass, I, Actor) //========================================================================== DEFINE_PROPERTY(xscale, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->scaleX = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Scale.X = id; } //========================================================================== @@ -669,8 +669,8 @@ DEFINE_PROPERTY(xscale, F, Actor) //========================================================================== DEFINE_PROPERTY(yscale, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->scaleY = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Scale.Y = id; } //========================================================================== @@ -678,8 +678,8 @@ DEFINE_PROPERTY(yscale, F, Actor) //========================================================================== DEFINE_PROPERTY(scale, F, Actor) { - PROP_FIXED_PARM(id, 0); - defaults->scaleX = defaults->scaleY = id; + PROP_DOUBLE_PARM(id, 0); + defaults->Scale.X = defaults->Scale.Y = id; } //========================================================================== @@ -916,9 +916,9 @@ DEFINE_PROPERTY(explosiondamage, I, Actor) //========================================================================== DEFINE_PROPERTY(deathheight, F, Actor) { - PROP_FIXED_PARM(h, 0); + PROP_DOUBLE_PARM(h, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); - static_cast(info)->DeathHeight = MAX(0, h); + static_cast(info)->DeathHeight = MAX(0., h); } //========================================================================== @@ -926,9 +926,9 @@ DEFINE_PROPERTY(deathheight, F, Actor) //========================================================================== DEFINE_PROPERTY(burnheight, F, Actor) { - PROP_FIXED_PARM(h, 0); + PROP_DOUBLE_PARM(h, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); - static_cast(info)->BurnHeight = MAX(0, h); + static_cast(info)->BurnHeight = MAX(0., h); } //========================================================================== @@ -993,7 +993,7 @@ DEFINE_PROPERTY(missiletype, S, Actor) //========================================================================== DEFINE_PROPERTY(missileheight, F, Actor) { - PROP_FIXED_PARM(id, 0); + PROP_DOUBLE_PARM(id, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->MissileHeight = id; } @@ -1300,7 +1300,7 @@ DEFINE_PROPERTY(poisondamagetype, S, Actor) //========================================================================== DEFINE_PROPERTY(fastspeed, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->FastSpeed = i; } @@ -1320,7 +1320,7 @@ DEFINE_PROPERTY(radiusdamagefactor, F, Actor) //========================================================================== DEFINE_PROPERTY(cameraheight, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); static_cast(info)->CameraHeight = i; } @@ -1330,8 +1330,8 @@ DEFINE_PROPERTY(cameraheight, F, Actor) //========================================================================== DEFINE_PROPERTY(vspeed, F, Actor) { - PROP_FIXED_PARM(i, 0); - defaults->vel.z = i; + PROP_DOUBLE_PARM(i, 0); + defaults->Vel.Z = i; } //========================================================================== @@ -1339,10 +1339,10 @@ DEFINE_PROPERTY(vspeed, F, Actor) //========================================================================== DEFINE_PROPERTY(gravity, F, Actor) { - PROP_FIXED_PARM(i, 0); + PROP_DOUBLE_PARM(i, 0); if (i < 0) I_Error ("Gravity must not be negative."); - defaults->gravity = i; + defaults->Gravity = i; } //========================================================================== @@ -2513,7 +2513,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, attackzoffset, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, jumpz, F, PlayerPawn) { - PROP_FIXED_PARM(z, 0); + PROP_DOUBLE_PARM(z, 0); defaults->JumpZ = z; } @@ -2600,11 +2600,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, aircapacity, F, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, forwardmove, F_f, PlayerPawn) { - PROP_FIXED_PARM(m, 0); + PROP_DOUBLE_PARM(m, 0); defaults->ForwardMove1 = defaults->ForwardMove2 = m; if (PROP_PARM_COUNT > 1) { - PROP_FIXED_PARM(m2, 1); + PROP_DOUBLE_PARM(m2, 1); defaults->ForwardMove2 = m2; } } @@ -2614,11 +2614,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, forwardmove, F_f, PlayerPawn) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(player, sidemove, F_f, PlayerPawn) { - PROP_FIXED_PARM(m, 0); + PROP_DOUBLE_PARM(m, 0); defaults->SideMove1 = defaults->SideMove2 = m; if (PROP_PARM_COUNT > 1) { - PROP_FIXED_PARM(m2, 1); + PROP_DOUBLE_PARM(m2, 1); defaults->SideMove2 = m2; } } diff --git a/src/v_video.h b/src/v_video.h index 7e0b09258..c94e6ec76 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -35,6 +35,7 @@ #define __V_VIDEO_H__ #include "doomtype.h" +#include "vectors.h" #include "doomdef.h" #include "dobject.h" diff --git a/src/vectors.h b/src/vectors.h index 87db3461e..9eaa375cf 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -42,16 +42,15 @@ #include #include +#include "m_fixed.h" +#include "math/cmath.h" -#ifndef PI -#define PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif #define EQUAL_EPSILON (1/65536.f) -#define DEG2RAD(d) ((d)*PI/180.f) -#define RAD2DEG(r) ((r)*180.f/PI) +//#define DEG2RAD(d) ((d)*M_PI/180.) +//#define RAD2DEG(r) ((r)*180./M_PI) template struct TVector3; template struct TRotator; @@ -66,8 +65,8 @@ struct TVector2 { } - TVector2 (double a, double b) - : X(vec_t(a)), Y(vec_t(b)) + TVector2 (vec_t a, vec_t b) + : X(a), Y(b) { } @@ -102,12 +101,12 @@ struct TVector2 // Access X and Y as an array vec_t &operator[] (int index) { - return *(&X + index); + return index == 0 ? X : Y; } const vec_t &operator[] (int index) const { - return *(&X + index); + return index == 0 ? X : Y; } // Test for equality @@ -147,53 +146,53 @@ struct TVector2 return *this; } - friend TVector2 operator+ (const TVector2 &v, double scalar) + friend TVector2 operator+ (const TVector2 &v, vec_t scalar) { return TVector2(v.X + scalar, v.Y + scalar); } - friend TVector2 operator+ (double scalar, const TVector2 &v) + friend TVector2 operator+ (vec_t scalar, const TVector2 &v) { return TVector2(v.X + scalar, v.Y + scalar); } // Scalar subtraction - TVector2 &operator-= (double scalar) + TVector2 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar; return *this; } - TVector2 operator- (double scalar) const + TVector2 operator- (vec_t scalar) const { return TVector2(X - scalar, Y - scalar); } // Scalar multiplication - TVector2 &operator*= (double scalar) + TVector2 &operator*= (vec_t scalar) { X *= scalar, Y *= scalar; return *this; } - friend TVector2 operator* (const TVector2 &v, double scalar) + friend TVector2 operator* (const TVector2 &v, vec_t scalar) { return TVector2(v.X * scalar, v.Y * scalar); } - friend TVector2 operator* (double scalar, const TVector2 &v) + friend TVector2 operator* (vec_t scalar, const TVector2 &v) { return TVector2(v.X * scalar, v.Y * scalar); } // Scalar division - TVector2 &operator/= (double scalar) + TVector2 &operator/= (vec_t scalar) { scalar = 1 / scalar, X *= scalar, Y *= scalar; return *this; } - TVector2 operator/ (double scalar) const + TVector2 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector2(X * scalar, Y * scalar); @@ -224,12 +223,12 @@ struct TVector2 } // Vector length - double Length() const + vec_t Length() const { - return sqrt (X*X + Y*Y); + return (vec_t)g_sqrt (X*X + Y*Y); } - double LengthSquared() const + vec_t LengthSquared() const { return X*X + Y*Y; } @@ -237,15 +236,15 @@ struct TVector2 // Return a unit vector facing the same direction as this one TVector2 Unit() const { - double len = Length(); + vec_t len = Length(); if (len != 0) len = 1 / len; return *this * len; } // Scales this vector into a unit vector. Returns the old length - double MakeUnit() + vec_t MakeUnit() { - double len, ilen; + vec_t len, ilen; len = ilen = Length(); if (ilen != 0) ilen = 1 / ilen; *this *= ilen; @@ -258,17 +257,23 @@ struct TVector2 return X*other.X + Y*other.Y; } - // Returns the angle (in radians) that the ray (0,0)-(X,Y) faces - double Angle() const - { - return atan2 (X, Y); - } + // Returns the angle that the ray (0,0)-(X,Y) faces + TAngle Angle() const; - // Returns a rotated vector. TAngle is in radians. + // Returns a rotated vector. angle is in degrees. TVector2 Rotated (double angle) { - double cosval = cos (angle); - double sinval = sin (angle); + double cosval = g_cosdeg (angle); + double sinval = g_sindeg (angle); + return TVector2(X*cosval - Y*sinval, Y*cosval + X*sinval); + } + + // Returns a rotated vector. angle is in degrees. + template + TVector2 Rotated(TAngle angle) + { + double cosval = angle.Cos(); + double sinval = angle.Sin(); return TVector2(X*cosval - Y*sinval, Y*cosval + X*sinval); } @@ -296,8 +301,8 @@ struct TVector3 { } - TVector3 (double a, double b, double c) - : X(vec_t(a)), Y(vec_t(b)), Z(vec_t(c)) + TVector3 (vec_t a, vec_t b, vec_t c) + : X(a), Y(b), Z(c) { } @@ -306,7 +311,7 @@ struct TVector3 { } - TVector3 (const Vector2 &xy, double z) + TVector3 (const Vector2 &xy, vec_t z) : X(xy.X), Y(xy.Y), Z(z) { } @@ -318,6 +323,11 @@ struct TVector3 Z = Y = X = 0; } + bool isZero() const + { + return X == 0 && Y == 0 && Z == 0; + } + TVector3 &operator= (const TVector3 &other) { Z = other.Z, Y = other.Y, X = other.X; @@ -327,12 +337,12 @@ struct TVector3 // Access X and Y and Z as an array vec_t &operator[] (int index) { - return *(&X + index); + return index == 0 ? X : index == 1 ? Y : Z; } const vec_t &operator[] (int index) const { - return *(&X + index); + return index == 0 ? X : index == 1 ? Y : Z; } // Test for equality @@ -366,59 +376,59 @@ struct TVector3 } // Scalar addition - TVector3 &operator+= (double scalar) + TVector3 &operator+= (vec_t scalar) { X += scalar, Y += scalar, Z += scalar; return *this; } - friend TVector3 operator+ (const TVector3 &v, double scalar) + friend TVector3 operator+ (const TVector3 &v, vec_t scalar) { return TVector3(v.X + scalar, v.Y + scalar, v.Z + scalar); } - friend TVector3 operator+ (double scalar, const TVector3 &v) + friend TVector3 operator+ (vec_t scalar, const TVector3 &v) { return TVector3(v.X + scalar, v.Y + scalar, v.Z + scalar); } // Scalar subtraction - TVector3 &operator-= (double scalar) + TVector3 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar, Z -= scalar; return *this; } - TVector3 operator- (double scalar) const + TVector3 operator- (vec_t scalar) const { return TVector3(X - scalar, Y - scalar, Z - scalar); } // Scalar multiplication - TVector3 &operator*= (double scalar) + TVector3 &operator*= (vec_t scalar) { X = vec_t(X *scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar); return *this; } - friend TVector3 operator* (const TVector3 &v, double scalar) + friend TVector3 operator* (const TVector3 &v, vec_t scalar) { return TVector3(v.X * scalar, v.Y * scalar, v.Z * scalar); } - friend TVector3 operator* (double scalar, const TVector3 &v) + friend TVector3 operator* (vec_t scalar, const TVector3 &v) { return TVector3(v.X * scalar, v.Y * scalar, v.Z * scalar); } // Scalar division - TVector3 &operator/= (double scalar) + TVector3 &operator/= (vec_t scalar) { scalar = 1 / scalar, X = vec_t(X * scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar); return *this; } - TVector3 operator/ (double scalar) const + TVector3 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector3(X * scalar, Y * scalar, Z * scalar); @@ -462,11 +472,16 @@ struct TVector3 return *this; } - // Add a 3D vector and a 2D vector. - // Discards the Z component of the 3D vector and returns a 2D vector. - friend Vector2 operator+ (const TVector3 &v3, const Vector2 &v2) + // returns the XY fields as a 2D-vector. + Vector2 XY() const { - return Vector2(v3.X + v2.X, v3.Y + v2.Y); + return{ X, Y }; + } + + // Add a 3D vector and a 2D vector. + friend TVector3 operator+ (const TVector3 &v3, const Vector2 &v2) + { + return TVector3(v3.X + v2.X, v3.Y + v2.Y, v3.Z); } friend Vector2 operator+ (const Vector2 &v2, const TVector3 &v3) @@ -486,10 +501,16 @@ struct TVector3 return Vector2(v2.X - v3.X, v2.Y - v3.Y); } + + + // Returns the angle (in radians) that the ray (0,0)-(X,Y) faces + TAngle Angle() const; + TAngle Pitch() const; + // Vector length double Length() const { - return sqrt (X*X + Y*Y + Z*Z); + return g_sqrt (X*X + Y*Y + Z*Z); } double LengthSquared() const @@ -514,15 +535,21 @@ struct TVector3 } // Resizes this vector to be the specified length (if it is not 0) - TVector3 &Resize(double len) + TVector3 &MakeResize(double len) { - double nowlen = Length(); - X = vec_t(X * (len /= nowlen)); - Y = vec_t(Y * len); - Z = vec_t(Z * len); + double scale = len / Length(); + X = vec_t(X * scale); + Y = vec_t(Y * scale); + Z = vec_t(Z * scale); return *this; } + TVector3 Resized(double len) + { + double scale = len / Length(); + return{ vec_t(X * scale), vec_t(Y * scale), vec_t(Z * scale) }; + } + // Dot product double operator | (const TVector3 &other) const { @@ -572,7 +599,7 @@ struct TMatrix3x3 // (The axis vector must be normalized.) TMatrix3x3(const Vector3 &axis, double radians) { - double c = cos(radians), s = sin(radians), t = 1 - c; + double c = g_cos(radians), s = g_sin(radians), t = 1 - c; /* In comments: A more readable version of the matrix setup. This was found in Diana Gruber's article "The Mathematics of the 3D Rotation Matrix" at and is @@ -750,24 +777,32 @@ struct TAngle { vec_t Degrees; + + // This is to catch any accidental attempt to assign an angle_t to this type. Any explicit exception will require a type cast. + TAngle(int) = delete; + TAngle(unsigned int) = delete; + TAngle(long) = delete; + TAngle(unsigned long) = delete; + TAngle &operator= (int other) = delete; + TAngle &operator= (unsigned other) = delete; + TAngle &operator= (long other) = delete; + TAngle &operator= (unsigned long other) = delete; + TAngle () { } - TAngle (float amt) + TAngle (vec_t amt) : Degrees(amt) { } - TAngle (double amt) - : Degrees(vec_t(amt)) - { - } - + /* TAngle (int amt) : Degrees(vec_t(amt)) { } + */ TAngle (const TAngle &other) : Degrees(other.Degrees) @@ -786,8 +821,8 @@ struct TAngle return *this; } - operator float() const { return Degrees; } - operator double() const { return Degrees; } + // intentionally disabled so that common math functions cannot be accidentally called with a TAngle. + //operator vec_t() const { return Degrees; } TAngle operator- () const { @@ -838,53 +873,53 @@ struct TAngle return Degrees / other.Degrees; } - TAngle &operator+= (double other) + TAngle &operator+= (vec_t other) { - Degrees = vec_t(Degrees + other); + Degrees = Degrees + other; return *this; } - TAngle &operator-= (double other) + TAngle &operator-= (vec_t other) { - Degrees = vec_t(Degrees - other); + Degrees = Degrees - other; return *this; } - TAngle &operator*= (double other) + TAngle &operator*= (vec_t other) { - Degrees = vec_t(Degrees * other); + Degrees = Degrees * other; return *this; } - TAngle &operator/= (double other) + TAngle &operator/= (vec_t other) { - Degrees = vec_t(Degrees / other); + Degrees = Degrees / other; return *this; } - TAngle operator+ (double other) const + TAngle operator+ (vec_t other) const { return Degrees + other; } - TAngle operator- (double other) const + TAngle operator- (vec_t other) const { return Degrees - other; } - friend TAngle operator- (double o1, TAngle o2) + friend TAngle operator- (vec_t o1, TAngle o2) { return TAngle(o1 - o2.Degrees); } - TAngle operator* (double other) const + TAngle operator* (vec_t other) const { - return Degrees * vec_t(other); + return Degrees * other; } - TAngle operator/ (double other) const + TAngle operator/ (vec_t other) const { - return Degrees / vec_t(other); + return Degrees / other; } // Should the comparisons consider an epsilon value? @@ -918,32 +953,32 @@ struct TAngle return Degrees != other.Degrees; } - bool operator< (double other) const + bool operator< (vec_t other) const { return Degrees < other; } - bool operator> (double other) const + bool operator> (vec_t other) const { return Degrees > other; } - bool operator<= (double other) const + bool operator<= (vec_t other) const { return Degrees <= other; } - bool operator>= (double other) const + bool operator>= (vec_t other) const { return Degrees >= other; } - bool operator== (double other) const + bool operator== (vec_t other) const { return Degrees == other; } - bool operator!= (double other) const + bool operator!= (vec_t other) const { return Degrees != other; } @@ -951,67 +986,94 @@ struct TAngle // Ensure the angle is between [0.0,360.0) degrees TAngle &Normalize360() { - // Normalizing the angle converts it to a BAM, masks it, and converts it back to a float. - - // This could have been kept entirely in floating point using fmod(), but the MSVCRT has lots - // of overhead for that function, despite the x87 offering the FPREM instruction which does - // exactly what fmod() is supposed to do. So fmod ends up being an order of magnitude slower - // than casting to and from an int. - - // Casting Degrees to a volatile ensures that the compiler will not try to evaluate an expression - // such as "TAngle a(360*100+24); a.Normalize360();" at compile time. Normally, it would see that - // this expression is constant and attempt to remove the Normalize360() call entirely and store - // the result of the function in the TAngle directly. Unfortunately, it does not do the casting - // properly and will overflow, producing an incorrect result. So we need to make sure it always - // evaluates Normalize360 at run time and never at compile time. (This applies to VC++. I don't - // know if other compilers suffer similarly). - Degrees = vec_t((int(*(volatile vec_t *)&Degrees * ((1<<30)/360.0)) & ((1<<30)-1)) * (360.f/(1<<30))); + // Normalizing the angle converts it to a BAM, which masks it, and converts it back to a float. + // Note: We MUST use xs_Float here because it is the only method that guarantees reliable wraparound. + Degrees = (vec_t)ANGLE2DBL((unsigned int)FLOAT2ANGLE(Degrees)); return *this; } // Ensures the angle is between (-180.0,180.0] degrees TAngle &Normalize180() { - Degrees = vec_t((((int(*(volatile vec_t *)&Degrees * ((1<<30)/360.0))+(1<<29)-1) & ((1<<30)-1)) - (1<<29)+1) * (360.f/(1<<30))); + Degrees = (vec_t)ANGLE2DBL((signed int)FLOAT2ANGLE(Degrees)); return *this; } + // Same as above but doesn't alter the calling object itself + + // Ensure the angle is between [0.0,360.0) degrees + TAngle Normalized360() const + { + + return (vec_t)ANGLE2DBL((unsigned int)FLOAT2ANGLE(Degrees)); + } + + // Ensures the angle is between (-180.0,180.0] degrees + TAngle Normalized180() const + { + return (vec_t)ANGLE2DBL((signed int)FLOAT2ANGLE(Degrees)); + } + // Like Normalize360(), except the integer value is not converted back to a float. // The steps parameter must be a power of 2. - int Quantize(int steps) + int Quantize(int steps) const { - return int(*(volatile vec_t *)&Degrees * (steps/360.0)) & (steps-1); + return xs_CRoundToInt((Degrees * (steps/360.0)) & (steps-1)); } + + vec_t Radians() const + { + return Degrees * (M_PI / 180.0); + } + + unsigned BAMs() const + { + return FLOAT2ANGLE(Degrees); + } + + TVector2 ToVector(vec_t length) const + { + return TVector2(length * Cos(), length * Sin()); + } + + int FixedAngle() // for ACS. This must be normalized so it just converts to BAM first and then shifts 16 bits right. + { + return FLOAT2ANGLE(Degrees) >> 16; + } + + double Cos() const + { + return g_cosdeg(Degrees); + } + + double Sin() const + { + return g_sindeg(Degrees); + } + + double Tan() const + { + return g_tan(Degrees * (M_PI / 180.)); + } + + // This is for calculating vertical velocity. For high pitches the tangent will become too large to be useful. + double TanClamped(double max = 5.) const + { + return clamp(Tan(), -max, max); + } + }; template inline double ToRadians (const TAngle °) { - return double(deg.Degrees * (PI / 180.0)); + return double(deg.Degrees * (M_PI / 180.0)); } -template -inline TAngle ToDegrees (double rad) +// If this gets templated there will be countless instantiation errors. +inline TAngle ToDegrees (double rad) { - return TAngle (double(rad * (180.0 / PI))); -} - -template -inline double cos (const TAngle °) -{ - return cos(ToRadians(deg)); -} - -template -inline double sin (const TAngle °) -{ - return sin(ToRadians(deg)); -} - -template -inline double tan (const TAngle °) -{ - return tan(ToRadians(deg)); + return TAngle (double(rad * (180.0 / M_PI))); } template @@ -1021,15 +1083,68 @@ inline TAngle fabs (const TAngle °) } template -inline TAngle vectoyaw (const TVector2 &vec) +inline TAngle deltaangle(const TAngle &a1, const TAngle &a2) { - return atan2(vec.Y, vec.X) * (180.0 / PI); + return (a2 - a1).Normalize180(); } template -inline TAngle vectoyaw (const TVector3 &vec) +inline TAngle deltaangle(const TAngle &a1, double a2) { - return atan2(vec.Y, vec.X) * (180.0 / PI); + return (a2 - a1).Normalize180(); +} + +template +inline TAngle deltaangle(double a1, const TAngle &a2) +{ + return (a2 - a1).Normalize180(); +} + +template +inline TAngle diffangle(const TAngle &a1, const TAngle &a2) +{ + return fabs((a1 - a2).Normalize180()); +} + +template +inline TAngle diffangle(const TAngle &a1, double a2) +{ + return fabs((a1 - a2).Normalize180()); +} + +inline TAngle VecToAngle(double x, double y) +{ + return g_atan2(y, x) * (180.0 / M_PI); +} + +template +inline TAngle VecToAngle (const TVector2 &vec) +{ + return (T)g_atan2(vec.Y, vec.X) * (180.0 / M_PI); +} + +template +inline TAngle VecToAngle (const TVector3 &vec) +{ + return (T)g_atan2(vec.Y, vec.X) * (180.0 / M_PI); +} + +template +TAngle TVector2::Angle() const +{ + return VecToAngle(X, Y); +} + +template +TAngle TVector3::Angle() const +{ + return VecToAngle(X, Y); +} + +template +TAngle TVector3::Pitch() const +{ + return VecToAngle(TVector2(X, Y).Length(), Z); } // Much of this is copied from TVector3. Is all that functionality really appropriate? @@ -1199,14 +1314,17 @@ struct TRotator template inline TVector3::TVector3 (const TRotator &rot) -: X(cos(rot.Pitch)*cos(rot.Yaw)), Y(cos(rot.Pitch)*sin(rot.Yaw)), Z(-sin(rot.Pitch)) { + double pcos = rot.Pitch.Cos(); + X = pcos * rot.Yaw.Cos(); + Y = pcos * rot.Yaw.Sin(); + Z = rot.Pitch.Sin(); } template inline TMatrix3x3::TMatrix3x3(const TVector3 &axis, TAngle degrees) { - double c = cos(degrees), s = sin(degrees), t = 1 - c; + double c = degrees.Cos(), s = degrees.Sin(), t = 1 - c; double sx = s*axis.X, sy = s*axis.Y, sz = s*axis.Z; double tx, ty, txx, tyy, u, v; @@ -1236,5 +1354,6 @@ typedef TVector2 DVector2; typedef TVector3 DVector3; typedef TRotator DRotator; typedef TMatrix3x3 DMatrix3x3; +typedef TAngle DAngle; #endif diff --git a/src/version.h b/src/version.h index 02a602f99..6edab985e 100644 --- a/src/version.h +++ b/src/version.h @@ -72,11 +72,11 @@ const char *GetVersionString(); // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 3100 +#define MINSAVEVER 4535 // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4533 +#define SAVEVER 4535 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 0a3a1b4f4..3dd99b62b 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -727,7 +727,7 @@ void CalculateCPUSpeed() PerfToMillisec = PerfToSec * 1000.0; } - if (!batchrun) Printf ("CPU Speed: %.0f MHz\n", 0.001 / PerfToMillisec); + if (!batchrun) Printf ("CPU _f_speed(): %.0f MHz\n", 0.001 / PerfToMillisec); } //========================================================================== diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index 9bafb9fb8..e6afc1307 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -30,18 +30,18 @@ external_declaration ::= NOP. %left MULTIPLY DIVIDE MODULUS. %left NEG. -%type exp {int} -exp(A) ::= NUM(B). { A = B.val; } -exp(A) ::= exp(B) PLUS exp(C). { A = B + C; } -exp(A) ::= exp(B) MINUS exp(C). { A = B - C; } -exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; } -exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } -exp(A) ::= exp(B) MODULUS exp(C). { if (C != 0) A = B % C; else context->PrintError("Division by zero"); } -exp(A) ::= exp(B) OR exp(C). { A = B | C; } -exp(A) ::= exp(B) AND exp(C). { A = B & C; } -exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; } -exp(A) ::= MINUS exp(B). [NEG] { A = -B; } -exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } +%type expr {int} +expr(A) ::= NUM(B). { A = B.val; } +expr(A) ::= expr(B) PLUS expr(C). { A = B + C; } +expr(A) ::= expr(B) MINUS expr(C). { A = B - C; } +expr(A) ::= expr(B) MULTIPLY expr(C). { A = B * C; } +expr(A) ::= expr(B) DIVIDE expr(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } +expr(A) ::= expr(B) MODULUS expr(C). { if (C != 0) A = B % C; else context->PrintError("Division by zero"); } +expr(A) ::= expr(B) OR expr(C). { A = B | C; } +expr(A) ::= expr(B) AND expr(C). { A = B & C; } +expr(A) ::= expr(B) XOR expr(C). { A = B ^ C; } +expr(A) ::= MINUS expr(B). [NEG] { A = -B; } +expr(A) ::= LPAREN expr(B) RPAREN. { A = B; } //========================================================================== @@ -50,7 +50,7 @@ exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } // //========================================================================== -define_statement ::= DEFINE SYM(A) LPAREN exp(B) RPAREN. +define_statement ::= DEFINE SYM(A) LPAREN expr(B) RPAREN. { context->AddSym (A.sym, B); } @@ -77,7 +77,7 @@ single_enum ::= SYM(A). context->AddSym (A.sym, context->EnumVal++); } -single_enum ::= SYM(A) EQUALS exp(B). +single_enum ::= SYM(A) EQUALS expr(B). { context->AddSym (A.sym, B); context->EnumVal = B+1; @@ -90,19 +90,19 @@ single_enum ::= SYM(A) EQUALS exp(B). //========================================================================== %type linetype_exp {int} -linetype_exp(Z) ::= exp(A). +linetype_exp(Z) ::= expr(A). { Z = static_cast(context)->DefiningLineType = A; } -linetype_declaration ::= linetype_exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN. +linetype_declaration ::= linetype_exp(linetype) EQUALS expr(flags) COMMA expr(special) LPAREN special_args(arg) RPAREN. { SimpleLineTranslations.SetVal(linetype, FLineTrans(special&0xffff, flags+arg.addflags, arg.args[0], arg.args[1], arg.args[2], arg.args[3], arg.args[4])); static_cast(context)->DefiningLineType = -1; } -linetype_declaration ::= linetype_exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. +linetype_declaration ::= linetype_exp EQUALS expr COMMA SYM(S) LPAREN special_args RPAREN. { Printf ("%s, line %d: %s is undefined\n", context->SourceFile, context->SourceLine, S.sym); static_cast(context)->DefiningLineType = -1; @@ -219,7 +219,7 @@ special_args(Z) ::= multi_special_arg(Z). %type boom_body {MoreLines *} -boom_declaration ::= LBRACKET exp(special) RBRACKET LPAREN exp(firsttype) COMMA exp(lasttype) RPAREN LBRACE boom_body(stores) RBRACE. +boom_declaration ::= LBRACKET expr(special) RBRACKET LPAREN expr(firsttype) COMMA expr(lasttype) RPAREN LBRACE boom_body(stores) RBRACE. { int i; MoreLines *probe; @@ -305,12 +305,12 @@ boom_selector(A) ::= ARG5. { A = 3; } boom_op(A) ::= EQUALS. { A = '='; } boom_op(A) ::= OR_EQUAL. { A = OR_EQUAL; } -boom_args(A) ::= exp(B). +boom_args(A) ::= expr(B). { A.constant = B; A.filters = NULL; } -boom_args(A) ::= exp(B) LBRACKET arg_list(C) RBRACKET. +boom_args(A) ::= expr(B) LBRACKET arg_list(C) RBRACKET. { A.mask = B; A.filters = C; @@ -329,7 +329,7 @@ arg_list(A) ::= list_val(B) COMMA arg_list(C). A->filter = B; } -list_val(A) ::= exp(B) COLON exp(C). +list_val(A) ::= expr(B) COLON expr(C). { A.filter = B; A.value = C; @@ -341,7 +341,7 @@ list_val(A) ::= exp(B) COLON exp(C). // //========================================================================== -maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON. +maxlinespecial_def ::= MAXLINESPECIAL EQUALS expr(mx) SEMICOLON. { // Just kill all specials higher than the max. // If the translator wants to redefine some later, just let it. @@ -356,36 +356,36 @@ maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON. %type sector_op {int} -sector_declaration ::= SECTOR exp(from) EQUALS exp(to) SEMICOLON. +sector_declaration ::= SECTOR expr(from) EQUALS expr(to) SEMICOLON. { FSectorTrans tr(to, true); SectorTranslations.SetVal(from, tr); } -sector_declaration ::= SECTOR exp EQUALS SYM(sy) SEMICOLON. +sector_declaration ::= SECTOR expr EQUALS SYM(sy) SEMICOLON. { Printf("Unknown constant '%s'\n", sy.sym); } -sector_declaration ::= SECTOR exp(from) EQUALS exp(to) NOBITMASK SEMICOLON. +sector_declaration ::= SECTOR expr(from) EQUALS expr(to) NOBITMASK SEMICOLON. { FSectorTrans tr(to, false); SectorTranslations.SetVal(from, tr); } -sector_bitmask ::= SECTOR BITMASK exp(mask) sector_op(op) exp(shift) SEMICOLON. +sector_bitmask ::= SECTOR BITMASK expr(mask) sector_op(op) expr(shift) SEMICOLON. { FSectorMask sm = { mask, op, shift}; SectorMasks.Push(sm); } -sector_bitmask ::= SECTOR BITMASK exp(mask) SEMICOLON. +sector_bitmask ::= SECTOR BITMASK expr(mask) SEMICOLON. { FSectorMask sm = { mask, 0, 0}; SectorMasks.Push(sm); } -sector_bitmask ::= SECTOR BITMASK exp(mask) CLEAR SEMICOLON. +sector_bitmask ::= SECTOR BITMASK expr(mask) CLEAR SEMICOLON. { FSectorMask sm = { mask, 0, 1}; SectorMasks.Push(sm); @@ -396,7 +396,7 @@ sector_op(A) ::= RSHASSIGN. { A = -1; } %type lineflag_op {int} -lineflag_declaration ::= LINEFLAG exp(from) EQUALS exp(to) SEMICOLON. +lineflag_declaration ::= LINEFLAG expr(from) EQUALS expr(to) SEMICOLON. { if (from >= 0 && from < 16) { @@ -405,7 +405,7 @@ lineflag_declaration ::= LINEFLAG exp(from) EQUALS exp(to) SEMICOLON. } } -lineflag_declaration ::= LINEFLAG exp(from) AND exp(mask) SEMICOLON. +lineflag_declaration ::= LINEFLAG expr(from) AND expr(mask) SEMICOLON. { if (from >= 0 && from < 16) { diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 8fb740274..1f5c8d95b 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -896,6 +896,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_FLOAT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); double x = param[p].f; #define PARAM_FIXED_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); fixed_t x = FLOAT2FIXED(param[p].f); #define PARAM_ANGLE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); angle_t x = FLOAT2ANGLE(param[p].f); +#define PARAM_DANGLE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_FLOAT); DAngle x = param[p].f; #define PARAM_STRING_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_STRING); FString x = param[p].s(); #define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); FState *x = (FState *)param[p].a; #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a; @@ -914,6 +915,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_FLOAT_OPT_AT(p,x) double x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_FIXED_OPT_AT(p,x) fixed_t x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = FLOAT2FIXED(param[p].f); } else #define PARAM_ANGLE_OPT_AT(p,x) angle_t x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = FLOAT2ANGLE(param[p].f); } else +#define PARAM_DANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else #define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else #define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); x = (FState *)param[p].a; } else #define PARAM_POINTER_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER); x = (type *)param[p].a; } else @@ -931,6 +933,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_FLOAT(x) ++paramnum; PARAM_FLOAT_AT(paramnum,x) #define PARAM_FIXED(x) ++paramnum; PARAM_FIXED_AT(paramnum,x) #define PARAM_ANGLE(x) ++paramnum; PARAM_ANGLE_AT(paramnum,x) +#define PARAM_DANGLE(x) ++paramnum; PARAM_DANGLE_AT(paramnum,x) #define PARAM_STRING(x) ++paramnum; PARAM_STRING_AT(paramnum,x) #define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x) #define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type) @@ -945,6 +948,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction #define PARAM_FLOAT_OPT(x) ++paramnum; PARAM_FLOAT_OPT_AT(paramnum,x) #define PARAM_FIXED_OPT(x) ++paramnum; PARAM_FIXED_OPT_AT(paramnum,x) #define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x) +#define PARAM_DANGLE_OPT(x) ++paramnum; PARAM_DANGLE_OPT_AT(paramnum,x) #define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x) #define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x) #define PARAM_POINTER_OPT(x,type) ++paramnum; PARAM_POINTER_OPT_AT(paramnum,x,type) diff --git a/src/zscript/vmexec.cpp b/src/zscript/vmexec.cpp index ebce8c5f2..070aeb30a 100644 --- a/src/zscript/vmexec.cpp +++ b/src/zscript/vmexec.cpp @@ -1,6 +1,7 @@ #include #include "vm.h" #include "xs_Float.h" +#include "math/cmath.h" #define IMPLEMENT_VMEXEC diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index eb54e7b76..954a8cde8 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -1269,7 +1269,7 @@ begin: OP(LENV): ASSERTF(a); ASSERTF(B+2); - reg.f[a] = sqrt(reg.f[B] * reg.f[B] + reg.f[B+1] * reg.f[B+1] + reg.f[B+2] * reg.f[B+2]); + reg.f[a] = g_sqrt(reg.f[B] * reg.f[B] + reg.f[B+1] * reg.f[B+1] + reg.f[B+2] * reg.f[B+2]); NEXTOP; OP(EQV_R): @@ -1392,30 +1392,30 @@ static double DoFLOP(int flop, double v) { case FLOP_ABS: return fabs(v); case FLOP_NEG: return -v; - case FLOP_EXP: return exp(v); - case FLOP_LOG: return log(v); - case FLOP_LOG10: return log10(v); - case FLOP_SQRT: return sqrt(v); + case FLOP_EXP: return g_exp(v); + case FLOP_LOG: return g_log(v); + case FLOP_LOG10: return g_log10(v); + case FLOP_SQRT: return g_sqrt(v); case FLOP_CEIL: return ceil(v); case FLOP_FLOOR: return floor(v); - case FLOP_ACOS: return acos(v); - case FLOP_ASIN: return asin(v); - case FLOP_ATAN: return atan(v); - case FLOP_COS: return cos(v); - case FLOP_SIN: return sin(v); - case FLOP_TAN: return tan(v); + case FLOP_ACOS: return g_acos(v); + case FLOP_ASIN: return g_asin(v); + case FLOP_ATAN: return g_atan(v); + case FLOP_COS: return g_cos(v); + case FLOP_SIN: return g_sin(v); + case FLOP_TAN: return g_tan(v); - case FLOP_ACOS_DEG: return acos(v) * (180 / M_PI); - case FLOP_ASIN_DEG: return asin(v) * (180 / M_PI); - case FLOP_ATAN_DEG: return atan(v) * (180 / M_PI); - case FLOP_COS_DEG: return cos(v * (M_PI / 180)); - case FLOP_SIN_DEG: return sin(v * (M_PI / 180)); - case FLOP_TAN_DEG: return tan(v * (M_PI / 180)); + case FLOP_ACOS_DEG: return g_acos(v) * (180 / M_PI); + case FLOP_ASIN_DEG: return g_asin(v) * (180 / M_PI); + case FLOP_ATAN_DEG: return g_atan(v) * (180 / M_PI); + case FLOP_COS_DEG: return g_cosdeg(v); + case FLOP_SIN_DEG: return g_sindeg(v); + case FLOP_TAN_DEG: return g_tan(v * (M_PI / 180)); - case FLOP_COSH: return cosh(v); - case FLOP_SINH: return sinh(v); - case FLOP_TANH: return tanh(v); + case FLOP_COSH: return g_cosh(v); + case FLOP_SINH: return g_sinh(v); + case FLOP_TANH: return g_tanh(v); } assert(0); return 0; diff --git a/src/zscript/zcc_expr.cpp b/src/zscript/zcc_expr.cpp index 644a122a5..0cd399d64 100644 --- a/src/zscript/zcc_expr.cpp +++ b/src/zscript/zcc_expr.cpp @@ -1,3 +1,4 @@ +#include #include "dobject.h" #include "sc_man.h" #include "c_console.h" diff --git a/wadsrc/static/actors/strife/strifeweapons.txt b/wadsrc/static/actors/strife/strifeweapons.txt index 4e4990e98..b807f110a 100644 --- a/wadsrc/static/actors/strife/strifeweapons.txt +++ b/wadsrc/static/actors/strife/strifeweapons.txt @@ -740,7 +740,7 @@ ACTOR StrifeGrenadeLauncher : StrifeWeapon Tag "$TAG_GLAUNCHER1" Inventory.PickupMessage "$TXT_GLAUNCHER" - action native A_FireGrenade (class grenadetype, int angleofs, state flash); + action native A_FireGrenade (class grenadetype, float angleofs, state flash); States {