- 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 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 FDecalBase;
class AInventory; class AInventory;
@ -922,6 +926,31 @@ public:
else return P_GetOffsetPosition(_f_X(), _f_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) 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) fixedvec3 _f_Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false)
{ {
if (absolute) if (absolute)
@ -1332,6 +1374,14 @@ public:
fixedvec3 ret = { _f_X(), _f_Y(), _f_Z() + zadd }; fixedvec3 ret = { _f_X(), _f_Y(), _f_Z() + zadd };
return ret; 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 fixed_t _f_Top() const
{ {
return _f_Z() + height; return _f_Z() + height;
@ -1389,6 +1439,12 @@ public:
__pos.y = yy; __pos.y = yy;
__pos.z = zz; __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) void SetXY(const fixedvec2 &npos)
{ {
__pos.x = npos.x; __pos.x = npos.x;
@ -1400,6 +1456,12 @@ public:
__pos.y = npos.y; __pos.y = npos.y;
__pos.z = npos.z; __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 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) 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); 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) 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) 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) 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> template<class T>
inline T *Spawn(const DVector3 &pos, replace_t allowreplacement) 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) inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)

View file

@ -13,7 +13,7 @@
// PIT_VileCheck // PIT_VileCheck
// Detect a corpse that could be raised. // 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) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
PARAM_FIXED_OPT(height) { height = 0; } PARAM_FLOAT_OPT(height) { height = 0; }
A_Fire(self, height); A_Fire(self, height);
return 0; return 0;
} }
void A_Fire(AActor *self, int height) void A_Fire(AActor *self, double height)
{ {
AActor *dest; AActor *dest;
@ -116,7 +116,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
PARAM_INT_OPT (dmg) { dmg = 20; } PARAM_INT_OPT (dmg) { dmg = 20; }
PARAM_INT_OPT (blastdmg) { blastdmg = 70; } PARAM_INT_OPT (blastdmg) { blastdmg = 70; }
PARAM_INT_OPT (blastrad) { blastrad = 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_NAME_OPT (dmgtype) { dmgtype = NAME_Fire; }
PARAM_INT_OPT (flags) { flags = 0; } PARAM_INT_OPT (flags) { flags = 0; }
@ -154,7 +154,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
} }
if (!(target->flags7 & MF7_DONTTHRUST)) 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; return 0;
} }

View file

@ -31,9 +31,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainPain)
return 0; 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) if (boom != NULL)
{ {
boom->DeathSound = "misc/brainexplode"; 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) DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
fixed_t x;
for (double x = -196; x < +320; x += 8)
for (x = self->_f_X() - 196*FRACUNIT; x < self->_f_X() + 320*FRACUNIT; x += 8*FRACUNIT)
{ {
BrainishExplosion (x, self->_f_Y() - 320*FRACUNIT, // (1 / 512.) is actually what the original value of 128 did, even though it probably meant 128 map units.
128 + (pr_brainscream() << (FRACBITS + 1))); BrainishExplosion(self->Vec2OffsetZ(x, -320, (1 / 512.) + pr_brainexplode() * 2));
} }
S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE); S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE);
return 0; return 0;
@ -71,9 +70,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BrainScream)
DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode) DEFINE_ACTION_FUNCTION(AActor, A_BrainExplode)
{ {
PARAM_ACTION_PROLOGUE; PARAM_ACTION_PROLOGUE;
fixed_t x = self->_f_X() + pr_brainexplode.Random2()*2048; double x = pr_brainexplode.Random2() / 32.;
fixed_t z = 128 + pr_brainexplode()*2*FRACUNIT; DVector3 pos = self->Vec2OffsetZ(x, 0, 1 / 512. + pr_brainexplode() * 2);
BrainishExplosion (x, self->_f_Y(), z); BrainishExplosion(pos);
return 0; return 0;
} }
@ -286,7 +285,7 @@ static void SpawnFly(AActor *self, PClassActor *spawntype, FSoundID sound)
if (!(newmobj->ObjectFlags & OF_EuthanizeMe)) if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
{ {
// telefrag anything in this spot // telefrag anything in this spot
P_TeleportMove (newmobj, newmobj->_f_Pos(), true); P_TeleportMove (newmobj, newmobj->Pos(), true);
} }
newmobj->flags4 |= MF4_BOSSSPAWNED; newmobj->flags4 |= MF4_BOSSSPAWNED;
} }

View file

@ -124,7 +124,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
PARAM_FLOAT_OPT (range) { range = 0; } PARAM_FLOAT_OPT (range) { range = 0; }
PARAM_DANGLE_OPT(spread_xy) { spread_xy = 2.8125; } PARAM_DANGLE_OPT(spread_xy) { spread_xy = 2.8125; }
PARAM_DANGLE_OPT(spread_z) { spread_z = 0.; } 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_INT_OPT (lifestealmax) { lifestealmax = 0; }
PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; } PARAM_CLASS_OPT (armorbonustype, ABasicArmorBonus) { armorbonustype = NULL; }
@ -207,7 +207,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
{ {
assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))); assert(armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)));
ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype, 0,0,0, NO_REPLACE)); 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->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
armorbonus->flags |= MF_DROPPED; armorbonus->flags |= MF_DROPPED;
armorbonus->ClearCounters(); armorbonus->ClearCounters();
@ -221,7 +221,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
else 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_CLASS_OPT (spawntype, AActor) { spawntype = NULL; }
PARAM_INT_OPT (n) { n = 0; } PARAM_INT_OPT (n) { n = 0; }
PARAM_INT_OPT (flags) { flags = 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; } PARAM_FLOAT_OPT (hrange) { hrange = 0.5; }
int i, j; 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_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 // Now launch mushroom cloud
AActor *target = Spawn("Mapspot", self->Pos(), NO_REPLACE); // We need something to aim at. 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; AActor *mo;
target->SetXYZ( target->SetXYZ(
self->_f_X() + (i << FRACBITS), // Aim in many directions from source self->X() + i, // Aim in many directions from source
self->_f_Y() + (j << FRACBITS), self->Y() + j,
self->_f_Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high self->Z() + (P_AproxDistance(i,j) * vrange)); // Aim up fairly high
if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options if ((flags & MSF_Classic) || // Flag explicitely set, or no flags and compat options
(flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM))) (flags == 0 && (self->state->DefineFlags & SDF_DEHACKED) && (i_compatflags & COMPATF_MUSHROOM)))
{ // Use old function for MBF compatibility { // 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; return 0;
} }

View file

@ -21,17 +21,17 @@ enum PA_Flags
// A_PainShootSkull // A_PainShootSkull
// Spawn a lost soul and launch it at the target // 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; AActor *other;
int prestep; double prestep;
if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul"); if (spawntype == NULL) spawntype = PClass::FindActor("LostSoul");
assert(spawntype != NULL); assert(spawntype != NULL);
if (self->DamageType == NAME_Massacre) return; if (self->DamageType == NAME_Massacre) return;
// [RH] check to make sure it's not too close to the ceiling // [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) 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 // okay, there's room for another one
prestep = 4*FRACUNIT + prestep = 4 + FIXED2FLOAT(self->radius + GetDefaultByType(spawntype)->radius) * 1.5;
3*(self->radius + GetDefaultByType(spawntype)->radius)/2;
// NOTE: The following code contains some advance work for line-to-line portals which is currenty inactive. // NOTE: The following code contains some advance work for line-to-line portals which is currenty inactive.
fixedvec2 dist = Vec2Angle(prestep, angle); DVector2 dist = Angle.ToVector(prestep);
fixedvec3 pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT, true); DVector3 pos = self->Vec3Offset(dist.X, dist.Y, 8., true);
fixedvec3 src = self->_f_Pos(); DVector3 src = self->Pos();
for (int i = 0; i < 2; i++) 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.// | // wall or an impassible line, or a "monsters can't cross" line.// |
// If it is, then we don't allow the spawn. // V // 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); FBlockLinesIterator it(box);
line_t *ld; line_t *ld;
bool inportal = false; bool inportal = false;
@ -86,8 +85,8 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
{ {
if (ld->isLinePortal() && i == 0) if (ld->isLinePortal() && i == 0)
{ {
if (P_PointOnLineSidePrecise(src.x, src.y, ld) == 0 && if (P_PointOnLineSidePrecise(src, ld) == 0 &&
P_PointOnLineSidePrecise(pos.x, pos.y, ld) == 1) 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. // crossed a portal line from front to back, we need to repeat the check on the other side as well.
inportal = true; inportal = true;
@ -96,12 +95,9 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
else if (!(ld->flags & ML_TWOSIDED) || else if (!(ld->flags & ML_TWOSIDED) ||
(ld->flags & (ML_BLOCKING | ML_BLOCKMONSTERS | ML_BLOCKEVERYTHING))) (ld->flags & (ML_BLOCKING | ML_BLOCKMONSTERS | ML_BLOCKEVERYTHING)))
{ {
if (!(box.Left() > ld->bbox[BOXRIGHT] || if (box.inRange(ld))
box.Right() < ld->bbox[BOXLEFT] ||
box.Top() < ld->bbox[BOXBOTTOM] ||
box.Bottom() > ld->bbox[BOXTOP]))
{ {
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 // ^ return; // line blocks trajectory // ^
} }
} }
@ -109,20 +105,19 @@ void A_PainShootSkull (AActor *self, angle_t angle, PClassActor *spawntype, int
if (!inportal) break; if (!inportal) break;
// recalculate position and redo the check on the other side of the portal // recalculate position and redo the check on the other side of the portal
pos = self->Vec3Offset(dist.x, dist.y, 8 * FRACUNIT); pos = self->Vec3Offset(dist.X, dist.Y, 8.);
src.x = pos.x - dist.x; src.X = pos.X - dist.X;
src.y = pos.y - dist.y; 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 // 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. // ceiling of its new sector, or below the floor. If so, kill it.
if ((other->_f_Top() > if (other->Top() > other->Sector->HighestCeilingAt(other) ||
(other->Sector->HighestCeilingAt(other))) || other->Z() < other->Sector->LowestFloorAt(other))
(other->_f_Z() < other->Sector->LowestFloorAt(other)))
{ {
// kill it immediately // kill it immediately
P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);// ^ 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. // Check for movements.
if (!P_CheckPosition (other, other->_f_Pos())) if (!P_CheckPosition (other, other->Pos()))
{ {
// kill it immediately // kill it immediately
P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None); P_DamageMobj (other, self, self, TELEFRAG_DAMAGE, NAME_None);
@ -158,13 +153,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack)
return 0; return 0;
PARAM_CLASS_OPT (spawntype, AActor) { spawntype = NULL; } 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 (flags) { flags = 0; }
PARAM_INT_OPT (limit) { limit = -1; } PARAM_INT_OPT (limit) { limit = -1; }
if (!(flags & PAF_AIMFACING)) if (!(flags & PAF_AIMFACING))
A_FaceTarget (self); 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; return 0;
} }
@ -177,8 +172,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DualPainAttack)
return 0; return 0;
A_FaceTarget (self); A_FaceTarget (self);
A_PainShootSkull (self, self->_f_angle() + ANG45, spawntype); A_PainShootSkull (self, self->Angles.Yaw + 45., spawntype);
A_PainShootSkull (self, self->_f_angle() - ANG45, spawntype); A_PainShootSkull (self, self->Angles.Yaw - 45., spawntype);
return 0; return 0;
} }
@ -192,8 +187,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainDie)
self->flags &= ~MF_FRIENDLY; self->flags &= ~MF_FRIENDLY;
} }
A_Unblock(self, true); A_Unblock(self, true);
A_PainShootSkull (self, self->_f_angle() + ANG90, spawntype); A_PainShootSkull (self, self->Angles.Yaw + 90, spawntype);
A_PainShootSkull (self, self->_f_angle() + ANG180, spawntype); A_PainShootSkull (self, self->Angles.Yaw + 180, spawntype);
A_PainShootSkull (self, self->_f_angle() + ANG270, spawntype); A_PainShootSkull (self, self->Angles.Yaw + 270, spawntype);
return 0; return 0;
} }

View file

@ -28,12 +28,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkelMissile)
return 0; return 0;
A_FaceTarget (self); A_FaceTarget (self);
missile = P_SpawnMissileZ (self, self->_f_Z() + 48*FRACUNIT, self->AddZ(16.);
self->target, PClass::FindActor("RevenantTracer")); missile = P_SpawnMissile(self, self->target, PClass::FindActor("RevenantTracer"));
self->AddZ(-16.);
if (missile != NULL) 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; missile->tracer = self->target;
} }
return 0; return 0;
@ -63,9 +64,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
return 0; return 0;
// spawn a puff of smoke behind the rocket // 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->Vel.Z = 1.;
smoke->tics -= pr_tracer()&3; smoke->tics -= pr_tracer()&3;

View file

@ -23,6 +23,7 @@
#define __M_BBOX_H__ #define __M_BBOX_H__
#include "doomtype.h" #include "doomtype.h"
#include "m_fixed.h"
struct line_t; struct line_t;
struct node_t; struct node_t;
@ -43,6 +44,14 @@ public:
m_Box[BOXBOTTOM] = bottom; 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) FBoundingBox(fixed_t x, fixed_t y, fixed_t radius)
{ {
setBox(x, y, radius); setBox(x, y, radius);
@ -72,6 +81,8 @@ public:
inline fixed_t Left () const { return m_Box[BOXLEFT]; } inline fixed_t Left () const { return m_Box[BOXLEFT]; }
inline fixed_t Right () const { return m_Box[BOXRIGHT]; } inline fixed_t Right () const { return m_Box[BOXRIGHT]; }
bool inRange(const line_t *ld) const;
int BoxOnLineSide (const line_t *ld) const; int BoxOnLineSide (const line_t *ld) const;
void Set(int index, fixed_t value) {m_Box[index] = value;} void Set(int index, fixed_t value) {m_Box[index] = value;}

View file

@ -118,10 +118,6 @@ void P_PredictionLerpReset();
// P_MOBJ // 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_TEMPPLAYER 1 // spawning a short-lived dummy player
#define SPF_WEAPONFULLYUP 2 // spawn with weapon already raised #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); 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); 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) 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); 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); AActor *P_CheckOnmobj (AActor *thing);
void P_FakeZMovement (AActor *mo); 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, 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); 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_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); void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps);
bool P_BounceWall (AActor *mo); 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); 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, 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 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 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 else
{ {
// With noclip2, we must ignore 3D floors and go right to the uppermost ceiling and lowermost floor. // 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.floorz = tm.dropoffz = newsec->_f_LowestFloorAt(x, y, &tm.floorsector);
tm.ceilingz = newsec->HighestCeilingAt(x, y, &tm.ceilingsector); tm.ceilingz = newsec->_f_HighestCeilingAt(x, y, &tm.ceilingsector);
tm.floorpic = tm.floorsector->GetTexture(sector_t::floor); tm.floorpic = tm.floorsector->GetTexture(sector_t::floor);
tm.floorterrain = tm.floorsector->GetTerrain(sector_t::floor); tm.floorterrain = tm.floorsector->GetTerrain(sector_t::floor);
tm.ceilingpic = tm.ceilingsector->GetTexture(sector_t::ceiling); 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; 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) void P_CheckSplash(AActor *self, fixed_t distance)
{ {
sector_t *floorsec; 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) 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 // 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; sector_t *check = this;
fixed_t planeheight = FIXED_MIN; 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; sector_t *check = this;
fixed_t planeheight = FIXED_MAX; 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? // Falling, not all the way down yet?
sector = player->mo->Sector; 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) && !player->mo->waterlevel)
{ {
return; 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 tag, int speed, int delay, int lock,
int lightTag, bool boomgen = false, int topcountdown = 0); 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 class DAnimatedDoor : public DMovingCeiling
{ {
DECLARE_CLASS (DAnimatedDoor, DMovingCeiling) DECLARE_CLASS (DAnimatedDoor, DMovingCeiling)

View file

@ -26,6 +26,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "templates.h" #include "templates.h"
#include "memarena.h" #include "memarena.h"
#include "m_bbox.h"
// Some more or less basic data types // Some more or less basic data types
// we depend on. // we depend on.
@ -813,17 +814,27 @@ struct sector_t
bool PlaneMoving(int pos); bool PlaneMoving(int pos);
// Portal-aware height calculation // Portal-aware height calculation
fixed_t HighestCeilingAt(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 LowestFloorAt(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); 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; 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 #endif