- made adjustments to P_LineAttack and P_RailAttack to deal with altered angles by passing through a non-parallel portal.

- fixed: P_FindFloorCeiling set the floorsector for a new ceilingheight.

Note: P_DrawRailTrail still needs to be changed, at the moment rail trails through portals will not work correctly.
This commit is contained in:
Christoph Oelckers 2016-03-06 21:58:36 +01:00
parent 90553bb61c
commit 5175d56129
13 changed files with 187 additions and 168 deletions

View file

@ -829,6 +829,11 @@ public:
return R_PointToAngle2(X(), Y(), otherx, othery); return R_PointToAngle2(X(), Y(), otherx, othery);
} }
fixed_t AngleTo(fixedvec2 other)
{
return R_PointToAngle2(X(), Y(), other.x, other.y);
}
// 'absolute' is reserved for a linked portal implementation which needs // 'absolute' is reserved for a linked portal implementation which needs
// to distinguish between portal-aware and portal-unaware distance calculation. // to distinguish between portal-aware and portal-unaware distance calculation.
fixed_t AproxDistance(AActor *other, bool absolute = false) fixed_t AproxDistance(AActor *other, bool absolute = false)

View file

@ -112,30 +112,56 @@ struct fixedvec3
return *this; return *this;
} }
fixedvec3 &operator -=(const fixedvec2 &other)
{
x -= other.x;
y -= other.y;
return *this;
}
fixedvec3 &operator -=(const fixedvec3 &other)
{
x -= other.x;
y -= other.y;
z -= other.z;
return *this;
}
operator fixedvec2() operator fixedvec2()
{ {
fixedvec2 ret = { x, y }; return { x, y };
return ret;
} }
}; };
inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2) inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2)
{ {
fixedvec2 v = { v1.x + v2.x, v1.y + v2.y }; return { v1.x + v2.x, v1.y + v2.y };
return v; }
inline fixedvec2 operator -(const fixedvec2 &v1, const fixedvec2 &v2)
{
return { v1.x - v2.x, v1.y - v2.y };
} }
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2) inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2)
{ {
fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
return v;
} }
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2) inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2)
{ {
fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z }; return { v1.x + v2.x, v1.y + v2.y, v1.z };
return v; }
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec2 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec3 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
} }
#define FIXED_MAX (signed)(0x7fffffff) #define FIXED_MAX (signed)(0x7fffffff)

View file

@ -2382,9 +2382,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
{ {
if (trace.HitType == TRACE_HitWall) if (trace.HitType == TRACE_HitWall)
{ {
DImpactDecal::StaticCreate (s, DImpactDecal::StaticCreate (s, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
trace.X, trace.Y, trace.Z,
trace.Line->sidedef[trace.Side], NULL);
} }
} }
} }

View file

@ -64,7 +64,7 @@ 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->X(), self->Y(), self->Z(), 0, 3); P_SpawnPuff (self, PClass::FindActor(NAME_BulletPuff), self->Pos(), self->angle, self->angle, 3);
smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE); smoke = Spawn ("RevenantTracerSmoke", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE);

View file

@ -638,7 +638,7 @@ void DImpactDecal::CheckMax ()
} }
} }
DImpactDecal *DImpactDecal::StaticCreate (const char *name, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color) DImpactDecal *DImpactDecal::StaticCreate (const char *name, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
{ {
if (cl_maxdecals > 0) if (cl_maxdecals > 0)
{ {
@ -646,13 +646,13 @@ DImpactDecal *DImpactDecal::StaticCreate (const char *name, fixed_t x, fixed_t y
if (tpl != NULL && (tpl = tpl->GetDecal()) != NULL) if (tpl != NULL && (tpl = tpl->GetDecal()) != NULL)
{ {
return StaticCreate (tpl, x, y, z, wall, ffloor, color); return StaticCreate (tpl, pos, wall, ffloor, color);
} }
} }
return NULL; return NULL;
} }
DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color) DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color)
{ {
DImpactDecal *decal = NULL; DImpactDecal *decal = NULL;
if (tpl != NULL && cl_maxdecals > 0 && !(wall->Flags & WALLF_NOAUTODECALS)) if (tpl != NULL && cl_maxdecals > 0 && !(wall->Flags & WALLF_NOAUTODECALS))
@ -666,16 +666,16 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
// apply the custom color as well. // apply the custom color as well.
if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0; if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0;
else lowercolor = color; else lowercolor = color;
StaticCreate (tpl_low, x, y, z, wall, ffloor, lowercolor); StaticCreate (tpl_low, pos, wall, ffloor, lowercolor);
} }
DImpactDecal::CheckMax(); DImpactDecal::CheckMax();
decal = new DImpactDecal (z); decal = new DImpactDecal (pos.z);
if (decal == NULL) if (decal == NULL)
{ {
return NULL; return NULL;
} }
if (!decal->StickToWall (wall, x, y, ffloor).isValid()) if (!decal->StickToWall (wall, pos.x, pos.y, ffloor).isValid())
{ {
return NULL; return NULL;
} }
@ -692,7 +692,7 @@ DImpactDecal *DImpactDecal::StaticCreate (const FDecalTemplate *tpl, fixed_t x,
} }
// Spread decal to nearby walls if it does not all fit on this one // Spread decal to nearby walls if it does not all fit on this one
decal->Spread (tpl, wall, x, y, z, ffloor); decal->Spread (tpl, wall, pos.x, pos.y, pos.z, ffloor);
} }
return decal; return decal;
} }
@ -779,22 +779,20 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t *
{ {
if (permanent) if (permanent)
{ {
decal = new DBaseDecal(trace.Z); decal = new DBaseDecal(trace.HitPos.z);
wall = trace.Line->sidedef[trace.Side]; wall = trace.Line->sidedef[trace.Side];
decal->StickToWall(wall, trace.X, trace.Y, trace.ffloor); decal->StickToWall(wall, trace.HitPos.x, trace.HitPos.y, trace.ffloor);
tpl->ApplyToDecal(decal, wall); tpl->ApplyToDecal(decal, wall);
// Spread decal to nearby walls if it does not all fit on this one // Spread decal to nearby walls if it does not all fit on this one
if (cl_spreaddecals) if (cl_spreaddecals)
{ {
decal->Spread(tpl, wall, trace.X, trace.Y, trace.Z, trace.ffloor); decal->Spread(tpl, wall, trace.HitPos.x, trace.HitPos.y, trace.HitPos.z, trace.ffloor);
} }
return decal; return decal;
} }
else else
{ {
return DImpactDecal::StaticCreate(tpl, return DImpactDecal::StaticCreate(tpl, trace.HitPos, trace.Line->sidedef[trace.Side], NULL);
trace.X, trace.Y, trace.Z,
trace.Line->sidedef[trace.Side], NULL);
} }
} }
return NULL; return NULL;

View file

@ -63,8 +63,8 @@ public:
DImpactDecal (fixed_t z); DImpactDecal (fixed_t z);
DImpactDecal (side_t *wall, const FDecalTemplate *templ); DImpactDecal (side_t *wall, const FDecalTemplate *templ);
static DImpactDecal *StaticCreate (const char *name, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color=0); static DImpactDecal *StaticCreate (const char *name, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0);
static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, F3DFloor * ffloor, PalEntry color=0); static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0);
void BeginPlay (); void BeginPlay ();
void Destroy (); void Destroy ();

View file

@ -141,18 +141,18 @@ enum EPuffFlags
PF_NORANDOMZ = 16 PF_NORANDOMZ = 16
}; };
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags = 0, AActor *vict = NULL); AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t hitdir, angle_t particledir, int updown, int flags = 0, AActor *vict = NULL);
inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec3 &pos, angle_t dir, int updown, int flags = 0, AActor *vict = NULL) inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec3 &pos, angle_t hitdir, angle_t particledir, int updown, int flags = 0, AActor *vict = NULL)
{ {
return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, dir, updown, flags, vict); return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, hitdir, particledir, 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)
{ {
P_SpawnBlood(pos.x, pos.y, pos.z, dir, damage, originator); P_SpawnBlood(pos.x, pos.y, pos.z, dir, damage, originator);
} }
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator); void P_BloodSplatter (fixedvec3 pos, AActor *originator);
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator); void P_BloodSplatter2 (fixedvec3 pos, AActor *originator);
void P_RipperBlood (AActor *mo, AActor *bleeder); void P_RipperBlood (AActor *mo, AActor *bleeder);
int P_GetThingFloorType (AActor *thing); int P_GetThingFloorType (AActor *thing);
void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target); void P_ExplodeMissile (AActor *missile, line_t *explodeline, AActor *target);
@ -328,12 +328,20 @@ enum // P_LineAttack flags
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, 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, angle_t angle, fixed_t distance, int 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); 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); void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version 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, FTranslatedLineTarget *t, AActor *puff); // hitscan version
void P_TraceBleed (int damage, AActor *target); // random direction version void P_TraceBleed (int damage, AActor *target); // random direction version
bool P_HitFloor (AActor *thing); bool P_HitFloor (AActor *thing);
bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false); bool P_HitWater (AActor *thing, sector_t *sec, fixed_t splashx = FIXED_MIN, fixed_t splashy = FIXED_MIN, fixed_t splashz=FIXED_MIN, bool checkabove = false, bool alert = true, bool force = false);
inline bool P_HitWater(AActor *thing, sector_t *sec, const fixedvec3 &pos, bool checkabove = false, bool alert = true, bool force = false)
{
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);
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

View file

@ -65,8 +65,7 @@ CVAR(Bool, cl_doautoaim, false, CVAR_ARCHIVE)
static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 * posforwindowcheck = NULL); static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, fixedvec2 * posforwindowcheck = NULL);
static void SpawnShootDecal(AActor *t1, const FTraceResults &trace); static void SpawnShootDecal(AActor *t1, const FTraceResults &trace);
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff, static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff);
fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor = false);
static FRandom pr_tracebleed("TraceBleed"); static FRandom pr_tracebleed("TraceBleed");
static FRandom pr_checkthing("CheckThing"); static FRandom pr_checkthing("CheckThing");
@ -245,7 +244,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines
if (open.top < tmf.ceilingz) if (open.top < tmf.ceilingz)
{ {
tmf.ceilingz = open.top; tmf.ceilingz = open.top;
if (open.topsec != NULL) tmf.floorsector = open.topsec; if (open.topsec != NULL) tmf.ceilingsector = open.topsec;
if (ffcf_verbose) Printf(" Adjust ceilingz to %f\n", FIXED2FLOAT(open.top)); if (ffcf_verbose) Printf(" Adjust ceilingz to %f\n", FIXED2FLOAT(open.top));
mit.StopUp(); mit.StopUp();
} }
@ -1527,7 +1526,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
!(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) &&
(pr_checkthing() < 192)) (pr_checkthing() < 192))
{ {
P_BloodSplatter(tm.thing->X(), tm.thing->Y(), tm.thing->Z(), thing); P_BloodSplatter(tm.thing->Pos(), thing);
} }
if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT)) if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT))
{ {
@ -3667,7 +3666,7 @@ struct aim_t
void EnterSectorPortal(int position, fixed_t frac, sector_t *entersec, fixed_t newtoppitch, fixed_t newbottompitch) void EnterSectorPortal(int position, fixed_t frac, sector_t *entersec, fixed_t newtoppitch, fixed_t newbottompitch)
{ {
AActor *portal = entersec->SkyBoxes[position]; AActor *portal = entersec->SkyBoxes[position];
if (portal == NULL)
if (position == sector_t::ceiling && portal->threshold < limitz) return; if (position == sector_t::ceiling && portal->threshold < limitz) return;
else if (position == sector_t::floor && portal->threshold > limitz) return; else if (position == sector_t::floor && portal->threshold > limitz) return;
aim_t newtrace = Clone(); aim_t newtrace = Clone();
@ -3779,7 +3778,7 @@ struct aim_t
if (aimdebug) if (aimdebug)
Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f,%f\n", Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f,%f\n",
startpos.x / 65536., startpos.y / 65536., startpos.y / 65536., startpos.x / 65536., startpos.y / 65536., startpos.z / 65536.,
aimtrace.x / 65536., aimtrace.y / 65536.); aimtrace.x / 65536., aimtrace.y / 65536.);
while ((in = it.Next())) while ((in = it.Next()))
@ -4102,7 +4101,7 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, FTranslated
//========================================================================== //==========================================================================
// //
// // Helper stuff for P_LineAttack
// //
//========================================================================== //==========================================================================
@ -4231,7 +4230,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
} }
if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) if (puffDefaults != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{ // Spawn the puff anyway { // Spawn the puff anyway
puff = P_SpawnPuff(t1, pufftype, trace.X, trace.Y, trace.Z, angle - ANG180, 2, puffFlags); puff = P_SpawnPuff(t1, pufftype, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget, 2, puffFlags);
} }
else else
{ {
@ -4240,21 +4239,19 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
} }
else else
{ {
fixed_t hitx = 0, hity = 0, hitz = 0;
if (trace.HitType != TRACE_HitActor) if (trace.HitType != TRACE_HitActor)
{ {
// position a bit closer for puffs // position a bit closer for puffs
if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon) if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon)
{ {
fixed_t closer = trace.Distance - 4 * FRACUNIT; fixedvec2 pos = P_GetOffsetPosition(trace.HitPos.x, trace.HitPos.y, -trace.HitVector.x * 4, -trace.HitVector.y * 4);
fixedvec2 pos = t1->Vec2Offset(FixedMul(vx, closer), FixedMul(vy, closer)); puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, trace.HitPos.z - trace.HitVector.z * 4, trace.SrcAngleToTarget,
puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, trace.SrcAngleToTarget - ANGLE_90, 0, puffFlags);
shootz + FixedMul(vz, closer), angle - ANG90, 0, puffFlags); puff->radius = 1;
} }
// [RH] Spawn a decal // [RH] Spawn a decal
if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon && !(flags & LAF_NOIMPACTDECAL) && !(puffDefaults->flags7 & MF7_NODECAL)) if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon && !trace.Line->isVisualPortal() && !(flags & LAF_NOIMPACTDECAL) && !(puffDefaults->flags7 & MF7_NODECAL))
{ {
// [TN] If the actor or weapon has a decal defined, use that one. // [TN] If the actor or weapon has a decal defined, use that one.
if (t1->DecalGenerator != NULL || if (t1->DecalGenerator != NULL ||
@ -4283,7 +4280,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
trace.Sector->heightsec == NULL && trace.Sector->heightsec == NULL &&
trace.HitType == TRACE_HitFloor) trace.HitType == TRACE_HitFloor)
{ {
P_HitWater(puff, trace.Sector, trace.X, trace.Y, trace.Z); P_HitWater(puff, trace.Sector, trace.HitPos);
} }
} }
else else
@ -4297,14 +4294,13 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
// Hit a thing, so it could be either a puff or blood // Hit a thing, so it could be either a puff or blood
fixed_t dist = trace.Distance; fixedvec3 bleedpos = trace.HitPos;
// position a bit closer for puffs/blood if using compatibility mode. // position a bit closer for puffs/blood if using compatibility mode.
if (i_compatflags & COMPATF_HITSCAN) dist -= 10 * FRACUNIT; if (i_compatflags & COMPATF_HITSCAN)
hitx = t1->X() + FixedMul(vx, dist); {
hity = t1->Y() + FixedMul(vy, dist); fixedvec2 ofs = P_GetOffsetPosition(bleedpos.x, bleedpos.y, -10 * trace.HitVector.x, -10 * trace.HitVector.y);
hitz = shootz + FixedMul(vz, dist); bleedpos -= { ofs.x, ofs.y, -10 * trace.HitVector.z};
}
// Spawn bullet puffs or blood spots, depending on target type. // Spawn bullet puffs or blood spots, depending on target type.
if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) || if ((puffDefaults != NULL && puffDefaults->flags3 & MF3_PUFFONACTORS) ||
@ -4315,7 +4311,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
puffFlags |= PF_HITTHINGBLEED; puffFlags |= PF_HITTHINGBLEED;
// We must pass the unreplaced puff type here // We must pass the unreplaced puff type here
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING, trace.Actor); puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 2, puffFlags | PF_HITTHING, trace.Actor);
} }
// Allow puffs to inflict poison damage, so that hitscans can poison, too. // Allow puffs to inflict poison damage, so that hitscans can poison, too.
@ -4341,11 +4337,10 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
{ {
// Since the puff is the damage inflictor we need it here // Since the puff is the damage inflictor we need it here
// regardless of whether it is displayed or not. // regardless of whether it is displayed or not.
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); puff = P_SpawnPuff(t1, pufftype, bleedpos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
killPuff = true; killPuff = true;
} }
#pragma message("damage angle") 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);
if (actualdamage != NULL) if (actualdamage != NULL)
{ {
*actualdamage = newdam; *actualdamage = newdam;
@ -4357,7 +4352,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
!(trace.Actor->flags & MF_NOBLOOD) && !(trace.Actor->flags & MF_NOBLOOD) &&
!(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT))) !(trace.Actor->flags2 & (MF2_INVULNERABLE | MF2_DORMANT)))
{ {
P_SpawnBlood(hitx, hity, hitz, angle - ANG180, newdam > 0 ? newdam : damage, trace.Actor); P_SpawnBlood(bleedpos, trace.SrcAngleToTarget, newdam > 0 ? newdam : damage, trace.Actor);
} }
if (damage) if (damage)
@ -4369,35 +4364,34 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
{ {
if (axeBlood) if (axeBlood)
{ {
P_BloodSplatter2(hitx, hity, hitz, trace.Actor); P_BloodSplatter2(bleedpos, trace.Actor);
} }
if (pr_lineattack() < 192) if (pr_lineattack() < 192)
{ {
P_BloodSplatter(hitx, hity, hitz, trace.Actor); P_BloodSplatter(bleedpos, trace.Actor);
} }
} }
} }
// [RH] Stick blood to walls // [RH] Stick blood to walls
P_TraceBleed(newdam > 0 ? newdam : damage, trace.X, trace.Y, trace.Z, P_TraceBleed(newdam > 0 ? newdam : damage, trace.HitPos,
trace.Actor, srcangle, srcpitch); trace.Actor, trace.SrcAngleToTarget, srcpitch);
} }
} }
if (victim != NULL) if (victim != NULL)
{ {
victim->linetarget = trace.Actor; victim->linetarget = trace.Actor;
victim->angleFromSource = R_PointToAngle2(t1->X(), t1->Y(), trace.Actor->X(), trace.Actor->Y()); victim->angleFromSource = trace.SrcAngleToTarget;
victim->unlinked = false; victim->unlinked = trace.unlinked;
} }
} }
if (trace.Crossed3DWater || trace.CrossedWater) if (trace.Crossed3DWater || trace.CrossedWater)
{ {
if (puff == NULL) if (puff == NULL)
{ // Spawn puff just to get a mass for the splash { // Spawn puff just to get a mass for the splash
puff = P_SpawnPuff(t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, puffFlags | PF_HITTHING | PF_TEMPORARY); puff = P_SpawnPuff(t1, pufftype, trace.HitPos, 0, 0, 2, puffFlags | PF_HITTHING | PF_TEMPORARY);
killPuff = true; killPuff = true;
} }
SpawnDeepSplash(t1, trace, puff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); SpawnDeepSplash(t1, trace, puff);
} }
} }
if (killPuff && puff != NULL) if (killPuff && puff != NULL)
@ -4553,11 +4547,8 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an
bloodcolor.a = 1; bloodcolor.a = 1;
} }
DImpactDecal::StaticCreate(bloodType, DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos,
bleedtrace.X, bleedtrace.Y, bleedtrace.Z, bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor);
bleedtrace.Line->sidedef[bleedtrace.Side],
bleedtrace.ffloor,
bloodcolor);
} }
} }
} }
@ -4645,7 +4636,8 @@ void P_TraceBleed(int damage, AActor *target)
struct SRailHit struct SRailHit
{ {
AActor *HitActor; AActor *HitActor;
fixed_t Distance; fixedvec3 HitPos;
angle_t HitAngle;
}; };
struct RailData struct RailData
{ {
@ -4679,7 +4671,13 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
// Save this thing for damaging later, and continue the trace // Save this thing for damaging later, and continue the trace
SRailHit newhit; SRailHit newhit;
newhit.HitActor = res.Actor; newhit.HitActor = res.Actor;
newhit.Distance = res.Distance - 10 * FRACUNIT; // put blood in front newhit.HitPos = res.HitPos;
newhit.HitAngle = res.SrcAngleToTarget;
if (i_compatflags & COMPATF_HITSCAN)
{
fixedvec2 ofs = P_GetOffsetPosition(newhit.HitPos.x, newhit.HitPos.y, -10 * res.HitVector.x, -10 * res.HitVector.y);
newhit.HitPos = { ofs.x, ofs.y, -10 * res.HitVector.z};
}
data->RailHits.Push(newhit); data->RailHits.Push(newhit);
return data->StopAtOne ? TRACE_Stop : TRACE_Continue; return data->StopAtOne ? TRACE_Stop : TRACE_Continue;
@ -4761,17 +4759,13 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
{ {
fixed_t x, y, z;
bool spawnpuff; bool spawnpuff;
bool bleed = false; bool bleed = false;
int puffflags = PF_HITTHING; int puffflags = PF_HITTHING;
AActor *hitactor = rail_data.RailHits[i].HitActor; AActor *hitactor = rail_data.RailHits[i].HitActor;
fixed_t hitdist = rail_data.RailHits[i].Distance; fixedvec3 &hitpos = rail_data.RailHits[i].HitPos;
angle_t hitangle = rail_data.RailHits[i].HitAngle;
x = xy.x + FixedMul(hitdist, vx);
y = xy.y + FixedMul(hitdist, vy);
z = shootz + FixedMul(hitdist, vz);
if ((hitactor->flags & MF_NOBLOOD) || if ((hitactor->flags & MF_NOBLOOD) ||
(hitactor->flags2 & MF2_DORMANT || ((hitactor->flags2 & MF2_INVULNERABLE) && !(puffDefaults->flags3 & MF3_FOILINVUL)))) (hitactor->flags2 & MF2_DORMANT || ((hitactor->flags2 & MF2_INVULNERABLE) && !(puffDefaults->flags3 & MF3_FOILINVUL))))
@ -4789,7 +4783,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
} }
if (spawnpuff) if (spawnpuff)
{ {
P_SpawnPuff(source, puffclass, x, y, z, (source->angle + angleoffset) - ANG90, 1, puffflags, hitactor); P_SpawnPuff(source, puffclass, hitpos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, puffflags, hitactor);
} }
int dmgFlagPass = DMG_INFLICTOR_IS_PUFF; int dmgFlagPass = DMG_INFLICTOR_IS_PUFF;
@ -4802,13 +4796,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->flags3 & MF3_FOILINVUL) dmgFlagPass |= DMG_FOILINVUL;
if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA; if (puffDefaults->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA;
} }
#pragma message("damage angle") 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);
if (bleed) if (bleed)
{ {
P_SpawnBlood(x, y, z, (source->angle + angleoffset) - ANG180, newdam > 0 ? newdam : damage, hitactor); P_SpawnBlood(hitpos, hitangle, newdam > 0 ? newdam : damage, hitactor);
P_TraceBleed(newdam > 0 ? newdam : damage, x, y, z, hitactor, source->angle, pitch); P_TraceBleed(newdam > 0 ? newdam : damage, hitpos, hitactor, source->angle, pitch);
} }
} }
@ -4819,7 +4812,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{ {
puff = P_SpawnPuff(source, puffclass, trace.X, trace.Y, trace.Z, (source->angle + angleoffset) - ANG90, 1, 0); puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, 0);
if (puff && (trace.Line != NULL) && (trace.Line->special == Line_Horizon) && !(puff->flags3 & MF3_SKYEXPLODE)) if (puff && (trace.Line != NULL) && (trace.Line->special == Line_Horizon) && !(puff->flags3 & MF3_SKYEXPLODE))
puff->Destroy(); puff->Destroy();
} }
@ -4834,7 +4827,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
AActor* puff = NULL; AActor* puff = NULL;
if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF) if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{ {
puff = P_SpawnPuff(source, puffclass, trace.X, trace.Y, trace.Z, (source->angle + angleoffset) - ANG90, 1, 0); puff = P_SpawnPuff(source, puffclass, trace.HitPos, trace.SrcAngleToTarget, trace.SrcAngleToTarget - ANGLE_90, 1, 0);
if (puff && !(puff->flags3 & MF3_SKYEXPLODE) && if (puff && !(puff->flags3 & MF3_SKYEXPLODE) &&
(((trace.HitType == TRACE_HitFloor) && (puff->floorpic == skyflatnum)) || (((trace.HitType == TRACE_HitFloor) && (puff->floorpic == skyflatnum)) ||
((trace.HitType == TRACE_HitCeiling) && (puff->ceilingpic == skyflatnum)))) ((trace.HitType == TRACE_HitCeiling) && (puff->ceilingpic == skyflatnum))))
@ -4845,23 +4838,21 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
} }
if (thepuff != NULL) if (thepuff != NULL)
{ {
if (trace.HitType == TRACE_HitFloor &&
trace.CrossedWater == NULL &&
trace.Sector->heightsec == NULL)
{
P_HitWater(thepuff, trace.Sector, trace.X, trace.Y, trace.Z);
}
if (trace.Crossed3DWater || trace.CrossedWater) if (trace.Crossed3DWater || trace.CrossedWater)
{ {
SpawnDeepSplash(source, trace, thepuff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); SpawnDeepSplash(source, trace, thepuff);
}
else if (trace.HitType == TRACE_HitFloor && trace.Sector->heightsec == NULL)
{
P_HitWater(thepuff, trace.Sector, trace.HitPos);
} }
thepuff->Destroy(); thepuff->Destroy();
} }
// Draw the slug's trail. // Draw the slug's trail.
end.X = FIXED2DBL(trace.X); end.X = FIXED2DBL(trace.HitPos.x);
end.Y = FIXED2DBL(trace.Y); end.Y = FIXED2DBL(trace.HitPos.y);
end.Z = FIXED2DBL(trace.Z); 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->angle + angleoffset, duration, sparsity, drift, SpiralOffset);
} }
@ -4900,9 +4891,9 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera
} }
else else
{ {
CameraX = trace.X; CameraX = trace.HitPos.x;
CameraY = trace.Y; CameraY = trace.HitPos.y;
CameraZ = trace.Z; CameraZ = trace.HitPos.z;
} }
CameraSector = trace.Sector; CameraSector = trace.Sector;
unlinked = trace.unlinked; unlinked = trace.unlinked;
@ -6426,7 +6417,7 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
if (decalbase != NULL) if (decalbase != NULL)
{ {
DImpactDecal::StaticCreate(decalbase->GetDecal(), DImpactDecal::StaticCreate(decalbase->GetDecal(),
trace.X, trace.Y, trace.Z, trace.Line->sidedef[trace.Side], trace.ffloor); trace.HitPos, trace.Line->sidedef[trace.Side], trace.ffloor);
} }
} }
@ -6436,31 +6427,20 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace)
// //
//========================================================================== //==========================================================================
static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff, static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff)
fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor)
{ {
const secplane_t *plane; const fixedvec3 *hitpos;
if (ffloor && trace.Crossed3DWater) if (trace.Crossed3DWater)
plane = trace.Crossed3DWater->top.plane; {
hitpos = &trace.Crossed3DWaterPos;
}
else if (trace.CrossedWater && trace.CrossedWater->heightsec) else if (trace.CrossedWater && trace.CrossedWater->heightsec)
plane = &trace.CrossedWater->heightsec->floorplane; {
hitpos = &trace.CrossedWaterPos;
}
else return; else return;
fixed_t num, den, hitdist; P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos->x, hitpos->y), *hitpos);
den = TMulScale16(plane->a, vx, plane->b, vy, plane->c, vz);
if (den != 0)
{
num = TMulScale16(plane->a, t1->X(), plane->b, t1->Y(), plane->c, shootz) + plane->d;
hitdist = FixedDiv(-num, den);
if (hitdist >= 0 && hitdist <= trace.Distance)
{
fixedvec2 hitpos = t1->Vec2Offset(FixedMul(vx, hitdist), FixedMul(vy, hitdist));
fixed_t hitz = shootz + FixedMul(vz, hitdist);
P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos.x, hitpos.y), hitpos.x, hitpos.y, hitz);
}
}
} }
//============================================================================= //=============================================================================

View file

@ -1444,8 +1444,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
} }
} }
DImpactDecal::StaticCreate (base->GetDecal (), DImpactDecal::StaticCreate(base->GetDecal(), { x, y, z }, line->sidedef[side], ffloor);
x, y, z, line->sidedef[side], ffloor);
} }
} }
} }
@ -5228,7 +5227,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
// P_SpawnPuff // P_SpawnPuff
// //
AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t dir, int updown, int flags, AActor *vict) AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y, fixed_t z, angle_t hitdir, angle_t particledir, int updown, int flags, AActor *vict)
{ {
AActor *puff; AActor *puff;
@ -5256,8 +5255,8 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y
if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER)) if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER))
puff->target = source; puff->target = source;
// Angle is the opposite of the hit direction (i.e. the puff faces the source.)
if (source != NULL) puff->angle = puff->AngleTo(source); puff->angle = hitdir + ANGLE_180;
// If a puff has a crash state and an actor was not hit, // 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 // it will enter the crash state. This is used by the StrifeSpark
@ -5282,7 +5281,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y
{ {
if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES)) if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES))
{ {
P_DrawSplash2 (32, x, y, z, dir, updown, 1); P_DrawSplash2 (32, x, y, z, particledir, updown, 1);
puff->renderflags |= RF_INVISIBLE; puff->renderflags |= RF_INVISIBLE;
} }
@ -5402,7 +5401,7 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) void P_BloodSplatter (fixedvec3 pos, AActor *originator)
{ {
PalEntry bloodcolor = originator->GetBloodColor(); PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(1); PClassActor *bloodcls = originator->GetBloodType(1);
@ -5416,7 +5415,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{ {
AActor *mo; AActor *mo;
mo = Spawn(bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement mo = Spawn(bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement
mo->target = originator; mo->target = originator;
mo->velx = pr_splatter.Random2 () << 10; mo->velx = pr_splatter.Random2 () << 10;
mo->vely = pr_splatter.Random2 () << 10; mo->vely = pr_splatter.Random2 () << 10;
@ -5432,7 +5431,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
} }
if (bloodtype >= 1) if (bloodtype >= 1)
{ {
P_DrawSplash2 (40, x, y, z, 0u - originator->AngleTo(x, y), 2, bloodcolor); P_DrawSplash2 (40, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor);
} }
} }
@ -5442,7 +5441,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
// //
//=========================================================================== //===========================================================================
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) void P_BloodSplatter2 (fixedvec3 pos, AActor *originator)
{ {
PalEntry bloodcolor = originator->GetBloodColor(); PalEntry bloodcolor = originator->GetBloodColor();
PClassActor *bloodcls = originator->GetBloodType(2); PClassActor *bloodcls = originator->GetBloodType(2);
@ -5456,10 +5455,10 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{ {
AActor *mo; AActor *mo;
x += ((pr_splat()-128)<<11); pos.x += ((pr_splat()-128)<<11);
y += ((pr_splat()-128)<<11); pos.y += ((pr_splat()-128)<<11);
mo = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement mo = Spawn (bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement
mo->target = originator; mo->target = originator;
// colorize the blood! // colorize the blood!
@ -5472,7 +5471,7 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
} }
if (bloodtype >= 1) if (bloodtype >= 1)
{ {
P_DrawSplash2 (100, x, y, z, 0u - originator->AngleTo(x, y), 2, bloodcolor); P_DrawSplash2 (100, pos.x, pos.y, pos.z, 0u - originator->AngleTo(pos), 2, bloodcolor);
} }
} }
@ -5733,7 +5732,7 @@ bool P_HitFloor (AActor *thing)
{ {
if (rover->top.plane->ZatPoint(pos.x, pos.y) == thing->Z()) if (rover->top.plane->ZatPoint(pos.x, pos.y) == thing->Z())
{ {
return P_HitWater (thing, m->m_sector, pos.x, pos.y, pos.z); return P_HitWater (thing, m->m_sector, pos);
} }
} }
} }
@ -5743,7 +5742,7 @@ bool P_HitFloor (AActor *thing)
return false; return false;
} }
return P_HitWater (thing, m->m_sector, pos.x, pos.y, pos.z); return P_HitWater (thing, m->m_sector, pos);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View file

@ -87,11 +87,18 @@ struct FTraceInfo
return CheckPlane(checkFloor ? sector->floorplane : sector->ceilingplane); return CheckPlane(checkFloor ? sector->floorplane : sector->ceilingplane);
} }
bool FTraceInfo::Check3DFloorPlane(const F3DFloor *ffloor, bool checkBottom) bool Check3DFloorPlane(const F3DFloor *ffloor, bool checkBottom)
{ {
return CheckPlane(checkBottom? *(ffloor->bottom.plane) : *(ffloor->top.plane)); return CheckPlane(checkBottom? *(ffloor->bottom.plane) : *(ffloor->top.plane));
} }
void SetSourcePosition()
{
Results->SrcFromTarget = { StartX, StartY, StartZ };
Results->HitVector = { Vx, Vy, Vz };
Results->SrcAngleToTarget = R_PointToAngle2(0, 0, Results->HitPos.x - StartX, Results->HitPos.y - StartY);
}
}; };
@ -227,7 +234,7 @@ void FTraceInfo::EnterSectorPortal(int position, fixed_t frac, sector_t *enterse
if (newtrace.TraceTraverse(ActorMask ? PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE : PT_ADDLINES)) if (newtrace.TraceTraverse(ActorMask ? PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE : PT_ADDLINES))
{ {
Results->CopyIfCloser(TempResults); TempResults->CopyIfCloser(newtrace.Results);
} }
} }
@ -319,7 +326,7 @@ void FTraceInfo::Setup3DFloors()
if (Check3DFloorPlane(rover, false)) if (Check3DFloorPlane(rover, false))
{ {
Results->Crossed3DWater = rover; Results->Crossed3DWater = rover;
Results->Crossed3DWaterPos = { Results->X, Results->Y, Results->Z }; Results->Crossed3DWaterPos = Results->HitPos;
} }
} }
@ -468,7 +475,7 @@ bool FTraceInfo::LineCheck(intercept_t *in)
if (CheckSectorPlane(hsec, true)) if (CheckSectorPlane(hsec, true))
{ {
Results->CrossedWater = &sectors[CurSector->sectornum]; Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; Results->CrossedWaterPos = Results->HitPos;
} }
} }
@ -645,9 +652,8 @@ cont:
if (Results->HitType == TRACE_HitWall) if (Results->HitType == TRACE_HitWall)
{ {
Results->X = hitx; Results->HitPos = { hitx, hity, hitz };
Results->Y = hity; SetSourcePosition();
Results->Z = hitz;
Results->Distance = dist; Results->Distance = dist;
Results->Fraction = in->frac; Results->Fraction = in->frac;
Results->Line = in->d.line; Results->Line = in->d.line;
@ -773,9 +779,8 @@ cont1:
Results->HitType = TRACE_HitActor; Results->HitType = TRACE_HitActor;
Results->X = hitx; Results->HitPos = { hitx, hity, hitz };
Results->Y = hity; SetSourcePosition();
Results->Z = hitz;
Results->Distance = dist; Results->Distance = dist;
Results->Fraction = in->frac; Results->Fraction = in->frac;
Results->Actor = in->d.thing; Results->Actor = in->d.thing;
@ -823,7 +828,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (Check3DFloorPlane(rover, false)) if (Check3DFloorPlane(rover, false))
{ {
Results->Crossed3DWater = rover; Results->Crossed3DWater = rover;
Results->Crossed3DWaterPos = { Results->X, Results->Y, Results->Z }; Results->Crossed3DWaterPos = Results->HitPos;
} }
} }
} }
@ -852,7 +857,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
// We still need to do a water check here or this may get missed on occasion // We still need to do a water check here or this may get missed on occasion
if (Results->CrossedWater == NULL && if (Results->CrossedWater == NULL &&
CurSector->heightsec != NULL && CurSector->heightsec != NULL &&
CurSector->heightsec->floorplane.ZatPoint(Results->X, Results->Y) >= Results->Z) CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.z)
{ {
// Save the result so that the water check doesn't destroy it. // Save the result so that the water check doesn't destroy it.
FTraceResults *res = Results; FTraceResults *res = Results;
@ -862,7 +867,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (CheckSectorPlane(CurSector->heightsec, true)) if (CheckSectorPlane(CurSector->heightsec, true))
{ {
Results->CrossedWater = &sectors[CurSector->sectornum]; Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; Results->CrossedWaterPos = Results->HitPos;
} }
Results = res; Results = res;
} }
@ -889,7 +894,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (Results->CrossedWater == NULL && if (Results->CrossedWater == NULL &&
CurSector->heightsec != NULL && CurSector->heightsec != NULL &&
CurSector->heightsec->floorplane.ZatPoint(Results->X, Results->Y) >= Results->Z) CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.z)
{ {
// Save the result so that the water check doesn't destroy it. // Save the result so that the water check doesn't destroy it.
FTraceResults *res = Results; FTraceResults *res = Results;
@ -899,15 +904,17 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (CheckSectorPlane(CurSector->heightsec, true)) if (CheckSectorPlane(CurSector->heightsec, true))
{ {
Results->CrossedWater = &sectors[CurSector->sectornum]; Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; Results->CrossedWaterPos = Results->HitPos;
} }
Results = res; Results = res;
} }
if (Results->HitType == TRACE_HitNone && Results->Distance == 0) if (Results->HitType == TRACE_HitNone && Results->Distance == 0)
{ {
Results->X = StartX + FixedMul(Vx, MaxDist); Results->HitPos = {
Results->Y = StartY + FixedMul(Vy, MaxDist); StartX + FixedMul(Vx, MaxDist),
Results->Z = StartZ + FixedMul(Vz, MaxDist); StartY + FixedMul(Vy, MaxDist),
StartZ + FixedMul(Vz, MaxDist) };
SetSourcePosition();
Results->Distance = MaxDist; Results->Distance = MaxDist;
Results->Fraction = FRACUNIT; Results->Fraction = FRACUNIT;
} }
@ -934,9 +941,11 @@ bool FTraceInfo::CheckPlane (const secplane_t &plane)
if (hitdist > EnterDist && hitdist < MaxDist) if (hitdist > EnterDist && hitdist < MaxDist)
{ {
Results->X = StartX + FixedMul (Vx, hitdist); Results->HitPos = {
Results->Y = StartY + FixedMul (Vy, hitdist); StartX + FixedMul(Vx, hitdist),
Results->Z = StartZ + FixedMul (Vz, hitdist); StartY + FixedMul(Vy, hitdist),
StartZ + FixedMul(Vz, hitdist) };
SetSourcePosition();
Results->Distance = hitdist; Results->Distance = hitdist;
Results->Fraction = FixedDiv (hitdist, MaxDist); Results->Fraction = FixedDiv (hitdist, MaxDist);
return true; return true;

View file

@ -65,7 +65,8 @@ struct FTraceResults
{ {
sector_t *Sector; sector_t *Sector;
FTextureID HitTexture; FTextureID HitTexture;
fixed_t X, Y, Z; fixedvec3 HitPos;
fixedvec3 HitVector;
fixedvec3 SrcFromTarget; fixedvec3 SrcFromTarget;
angle_t SrcAngleToTarget; angle_t SrcAngleToTarget;

View file

@ -1078,11 +1078,6 @@ void P_CreateLinkedPortals()
// //
//============================================================================ //============================================================================
static bool ProcessLayer()
{
}
bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out) bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out)
{ {
// Keep this temporary work stuff static. This function can never be called recursively // Keep this temporary work stuff static. This function can never be called recursively

View file

@ -5178,7 +5178,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood) if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood)
{ {
spawnblood = false; spawnblood = false;
P_SpawnPuff(self, pufftype, bloodpos, angle, 0); P_SpawnPuff(self, pufftype, bloodpos, angle, angle, 0);
} }
} }
else if (self->target->flags3 & MF3_GHOST) else if (self->target->flags3 & MF3_GHOST)