diff --git a/src/actor.h b/src/actor.h index 15599aff3..c72a5586f 100644 --- a/src/actor.h +++ b/src/actor.h @@ -534,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; @@ -922,6 +926,31 @@ public: 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) { @@ -949,6 +978,19 @@ public: } } + DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false) + { + if (absolute) + { + 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) @@ -1332,6 +1374,14 @@ public: fixedvec3 ret = { _f_X(), _f_Y(), _f_Z() + zadd }; return ret; } + DVector3 PosPlusZ(double zadd) const + { + return { X(), Y(), Z() + zadd }; + } + DVector3 PosAtZ(double zadd) const + { + return{ X(), Y(), zadd }; + } fixed_t _f_Top() const { return _f_Z() + height; @@ -1389,6 +1439,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; @@ -1400,6 +1456,12 @@ 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 { @@ -1554,7 +1616,10 @@ inline AActor *Spawn (PClassActor *type, const fixedvec3 &pos, replace_t allowre inline AActor *Spawn(PClassActor *type, const DVector3 &pos, replace_t allowreplacement) { - return Spawn(type, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), 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); @@ -1567,7 +1632,10 @@ inline AActor *Spawn (const char *type, const fixedvec3 &pos, replace_t allowrep inline AActor *Spawn(const char *type, const DVector3 &pos, replace_t allowreplacement) { - return Spawn(type, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), 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) @@ -1577,7 +1645,10 @@ inline AActor *Spawn (FName classname, const fixedvec3 &pos, replace_t allowrepl inline AActor *Spawn(FName type, const DVector3 &pos, replace_t allowreplacement) { - return Spawn(type, FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), 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); } @@ -1596,7 +1667,10 @@ inline T *Spawn (const fixedvec3 &pos, replace_t allowreplacement) template inline T *Spawn(const DVector3 &pos, replace_t allowreplacement) { - return static_cast(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), FLOAT2FIXED(pos.Z), 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) diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp index 9f72e9f64..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; @@ -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; } @@ -154,7 +154,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) } if (!(target->flags7 & MF7_DONTTHRUST)) { - target->Vel.Z = FIXED2FLOAT(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 46ef7e782..51ee77ff8 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -31,9 +31,9 @@ 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"; @@ -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->_f_X() - 196*FRACUNIT; x < self->_f_X() + 320*FRACUNIT; x += 8*FRACUNIT) + + for (double x = -196; x < +320; x += 8) { - BrainishExplosion (x, self->_f_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->_f_X() + pr_brainexplode.Random2()*2048; - fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT; - BrainishExplosion (x, self->_f_Y(), z); + double x = pr_brainexplode.Random2() / 32.; + DVector3 pos = self->Vec2OffsetZ(x, 0, 1 / 512. + pr_brainexplode() * 2); + BrainishExplosion(pos); return 0; } @@ -286,7 +285,7 @@ static void SpawnFly(AActor *self, PClassActor *spawntype, FSoundID sound) if (!(newmobj->ObjectFlags & OF_EuthanizeMe)) { // telefrag anything in this spot - P_TeleportMove (newmobj, newmobj->_f_Pos(), true); + P_TeleportMove (newmobj, newmobj->Pos(), true); } newmobj->flags4 |= MF4_BOSSSPAWNED; } diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index b75fd30ff..0b14d61e7 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -124,7 +124,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) PARAM_FLOAT_OPT (range) { range = 0; } PARAM_DANGLE_OPT(spread_xy) { spread_xy = 2.8125; } PARAM_DANGLE_OPT(spread_z) { spread_z = 0.; } - PARAM_FIXED_OPT (lifesteal) { lifesteal = 0; } + PARAM_FLOAT_OPT (lifesteal) { lifesteal = 0; } PARAM_INT_OPT (lifestealmax) { lifestealmax = 0; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } @@ -207,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(); @@ -221,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); } } diff --git a/src/g_doom/a_fatso.cpp b/src/g_doom/a_fatso.cpp index ffc313c35..7cfda4ded 100644 --- a/src/g_doom/a_fatso.cpp +++ b/src/g_doom/a_fatso.cpp @@ -126,7 +126,7 @@ 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_FLOAT_OPT (vrange) { vrange = 4; } PARAM_FLOAT_OPT (hrange) { hrange = 0.5; } int i, j; @@ -141,7 +141,7 @@ 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. @@ -153,9 +153,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) { AActor *mo; target->SetXYZ( - self->_f_X() + (i << FRACBITS), // Aim in many directions from source - self->_f_Y() + (j << FRACBITS), - self->_f_Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high + 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))) { // Use old function for MBF compatibility 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_painelemental.cpp b/src/g_doom/a_painelemental.cpp index 5575a2ec1..765409fe6 100644 --- a/src/g_doom/a_painelemental.cpp +++ b/src/g_doom/a_painelemental.cpp @@ -21,17 +21,17 @@ 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->_f_Top() + 8*FRACUNIT > self->ceilingz) + if (self->Top() + 8 > FIXED2FLOAT(self->ceilingz)) { if (self->flags & MF_FLOAT) { @@ -62,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 + FIXED2FLOAT(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->_f_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++) { @@ -77,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; @@ -86,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; @@ -96,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 // ^ } } @@ -109,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->_f_Top() > - (other->Sector->HighestCeilingAt(other))) || - (other->_f_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);// ^ @@ -131,7 +126,7 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int // Check for movements. - if (!P_CheckPosition (other, other->_f_Pos())) + if (!P_CheckPosition (other, other->Pos())) { // kill it immediately P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None); @@ -158,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->_f_angle()+angle, spawntype, flags, limit); + A_PainShootSkull (self, self->Angles.Yaw + angle, spawntype, flags, limit); return 0; } @@ -177,8 +172,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack) return 0; A_FaceTarget (self); - A_PainShootSkull (self, self->_f_angle() + ANG45, spawntype); - A_PainShootSkull (self, self->_f_angle() - ANG45, spawntype); + A_PainShootSkull (self, self->Angles.Yaw + 45., spawntype); + A_PainShootSkull (self, self->Angles.Yaw - 45., spawntype); return 0; } @@ -192,8 +187,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie) self->flags &= ~MF_FRIENDLY; } A_Unblock(self, true); - A_PainShootSkull (self, self->_f_angle() + ANG90, spawntype); - A_PainShootSkull (self, self->_f_angle() + ANG180, spawntype); - A_PainShootSkull (self, self->_f_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_revenant.cpp b/src/g_doom/a_revenant.cpp index 293fb56f8..221f6dad3 100644 --- a/src/g_doom/a_revenant.cpp +++ b/src/g_doom/a_revenant.cpp @@ -28,12 +28,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile) return 0; A_FaceTarget (self); - missile = P_SpawnMissileZ (self, self->_f_Z() + 48*FRACUNIT, - self->target, PClass::FindActor("RevenantTracer")); + self->AddZ(16.); + missile = P_SpawnMissile(self, self->target, PClass::FindActor("RevenantTracer")); + self->AddZ(-16.); if (missile != NULL) { - missile->SetOrigin(missile->Vec3Offset(missile->_f_velx(), missile->_f_vely(), 0), false); + missile->SetOrigin(missile->Vec3Offset(missile->Vel.X, missile->Vel.Y, 0.), false); missile->tracer = self->target; } return 0; @@ -63,9 +64,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // spawn a puff of smoke behind the rocket - P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->_f_Pos(), self->_f_angle(), self->_f_angle(), 3); + P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->Angles.Yaw, self->Angles.Yaw, 3); - smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->_f_velx(), -self->_f_vely(), 0), ALLOW_REPLACE); + smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->Vel.X, -self->Vel.Y, 0.), ALLOW_REPLACE); smoke->Vel.Z = 1.; smoke->tics -= pr_tracer()&3; diff --git a/src/m_bbox.h b/src/m_bbox.h index a48b6fecb..e8f8d65a5 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,6 +44,14 @@ 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); @@ -72,6 +81,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/p_local.h b/src/p_local.h index 5f8d8244d..a3842d1ca 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -118,10 +118,6 @@ 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 @@ -144,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) { @@ -258,6 +258,10 @@ 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); @@ -269,6 +273,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); @@ -346,6 +354,10 @@ 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); +inline void P_CheckSplash(AActor *self, double distance) +{ + return P_CheckSplash(self, FLOAT2FIXED(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 diff --git a/src/p_map.cpp b/src/p_map.cpp index dcbc1b637..3a0c99adb 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1624,8 +1624,8 @@ 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.floorz = tm.dropoffz = newsec->_f_LowestFloorAt(x, y, &tm.floorsector); + tm.ceilingz = 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); 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 b38765067..bf1d08f93 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5743,7 +5743,7 @@ bool P_HitFloor (AActor *thing) void P_CheckSplash(AActor *self, fixed_t distance) { sector_t *floorsec; - self->Sector->LowestFloorAt(self, &floorsec); + self->Sector->_f_LowestFloorAt(self, &floorsec); if (self->_f_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 diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 43560b516..905678d5f 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -889,7 +889,7 @@ 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; @@ -913,7 +913,7 @@ 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; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index baa8034ad..f0ef2561e 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -436,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->_f_Z() != sector->LowestFloorAt(player->mo) + if (player->mo->_f_Z() != sector->_f_LowestFloorAt(player->mo) && !player->mo->waterlevel) { return; diff --git a/src/p_spec.h b/src/p_spec.h index 0c0624b87..979765d91 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -568,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) diff --git a/src/r_defs.h b/src/r_defs.h index ff5ce96e3..a66575bb2 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. @@ -813,17 +814,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->_f_X(), a->_f_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->_f_X(), a->_f_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); @@ -1313,6 +1324,14 @@ inline void AActor::ClearInterpolation() 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