- finished conversion of most of g_doom.

Only things left here are accesses to AActor::ceilingz and radius in A_PainShootSkull, plus scaleX and scaleY in the ScriptedMarine sprite setting code.
Most is still using wrapper functions around the fixed point versions.
This commit is contained in:
Christoph Oelckers 2016-03-20 10:52:10 +01:00
parent a4f5846c7c
commit 5875e91f39
17 changed files with 214 additions and 81 deletions

View file

@ -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<class T>
inline T *Spawn(const DVector3 &pos, replace_t allowreplacement)
{
return static_cast<T *>(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<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y), zz, allowreplacement));
}
inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)

View file

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

View file

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

View file

@ -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<ABasicArmorBonus *>(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);
}
}

View file

@ -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<<FRACBITS);
P_CheckSplash(self, 128.);
// Now launch mushroom cloud
AActor *target = Spawn("Mapspot", self->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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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