From 5175d56129422622bd9ca8505288b7d2dd2211df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 6 Mar 2016 21:58:36 +0100 Subject: [PATCH] - 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. --- src/actor.h | 5 + src/basictypes.h | 42 ++++++-- src/d_net.cpp | 4 +- src/g_doom/a_revenant.cpp | 2 +- src/g_shared/a_decals.cpp | 24 ++--- src/g_shared/a_sharedglobal.h | 4 +- src/p_local.h | 18 +++- src/p_map.cpp | 164 +++++++++++++----------------- src/p_mobj.cpp | 31 +++--- src/p_trace.cpp | 51 ++++++---- src/p_trace.h | 3 +- src/portal.cpp | 5 - src/thingdef/thingdef_codeptr.cpp | 2 +- 13 files changed, 187 insertions(+), 168 deletions(-) diff --git a/src/actor.h b/src/actor.h index 51ce9752c..b5b32611c 100644 --- a/src/actor.h +++ b/src/actor.h @@ -829,6 +829,11 @@ public: 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 // to distinguish between portal-aware and portal-unaware distance calculation. fixed_t AproxDistance(AActor *other, bool absolute = false) diff --git a/src/basictypes.h b/src/basictypes.h index 356e197dd..6c71fce9b 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -112,30 +112,56 @@ struct fixedvec3 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() { - fixedvec2 ret = { x, y }; - return ret; + return { x, y }; } }; inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2) { - fixedvec2 v = { v1.x + v2.x, v1.y + v2.y }; - return v; + return { v1.x + v2.x, v1.y + v2.y }; +} + +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) { - fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; - return v; + return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z }; } inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2) { - fixedvec3 v = { v1.x + v2.x, v1.y + v2.y, v1.z }; - return v; + return { v1.x + v2.x, v1.y + v2.y, v1.z }; +} + +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) diff --git a/src/d_net.cpp b/src/d_net.cpp index faba5ef41..4d8e33d3d 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2382,9 +2382,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) { if (trace.HitType == TRACE_HitWall) { - DImpactDecal::StaticCreate (s, - trace.X, trace.Y, trace.Z, - trace.Line->sidedef[trace.Side], NULL); + DImpactDecal::StaticCreate (s, trace.HitPos, trace.Line->sidedef[trace.Side], NULL); } } } diff --git a/src/g_doom/a_revenant.cpp b/src/g_doom/a_revenant.cpp index 1c034b372..5b8ca293c 100644 --- a/src/g_doom/a_revenant.cpp +++ b/src/g_doom/a_revenant.cpp @@ -64,7 +64,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer) return 0; // 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); diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index ef7b3eb8c..d37250887 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -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) { @@ -646,13 +646,13 @@ DImpactDecal *DImpactDecal::StaticCreate (const char *name, fixed_t x, fixed_t y 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; } -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; 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. if (tpl->ShadeColor != tpl_low->ShadeColor) lowercolor=0; else lowercolor = color; - StaticCreate (tpl_low, x, y, z, wall, ffloor, lowercolor); + StaticCreate (tpl_low, pos, wall, ffloor, lowercolor); } DImpactDecal::CheckMax(); - decal = new DImpactDecal (z); + decal = new DImpactDecal (pos.z); if (decal == NULL) { return NULL; } - if (!decal->StickToWall (wall, x, y, ffloor).isValid()) + if (!decal->StickToWall (wall, pos.x, pos.y, ffloor).isValid()) { 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 - decal->Spread (tpl, wall, x, y, z, ffloor); + decal->Spread (tpl, wall, pos.x, pos.y, pos.z, ffloor); } return decal; } @@ -779,22 +779,20 @@ DBaseDecal *ShootDecal(const FDecalTemplate *tpl, AActor *basisactor, sector_t * { if (permanent) { - decal = new DBaseDecal(trace.Z); + decal = new DBaseDecal(trace.HitPos.z); 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); // Spread decal to nearby walls if it does not all fit on this one 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; } else { - return DImpactDecal::StaticCreate(tpl, - trace.X, trace.Y, trace.Z, - trace.Line->sidedef[trace.Side], NULL); + return DImpactDecal::StaticCreate(tpl, trace.HitPos, trace.Line->sidedef[trace.Side], NULL); } } return NULL; diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index cfbe4526b..1e59bf740 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -63,8 +63,8 @@ public: DImpactDecal (fixed_t z); 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 FDecalTemplate *tpl, 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, const fixedvec3 &pos, side_t *wall, F3DFloor * ffloor, PalEntry color=0); void BeginPlay (); void Destroy (); diff --git a/src/p_local.h b/src/p_local.h index e1c12e652..47911f5f1 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -141,18 +141,18 @@ enum EPuffFlags 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); -inline AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const fixedvec3 &pos, 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 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); 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); } -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_BloodSplatter (fixedvec3 pos, AActor *originator); +void P_BloodSplatter2 (fixedvec3 pos, AActor *originator); void P_RipperBlood (AActor *mo, AActor *bleeder); int P_GetThingFloorType (AActor *thing); 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, FName pufftype, int flags = 0, FTranslatedLineTarget *victim = NULL, int *actualdamage = NULL); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); +inline void P_TraceBleed(int damage, const fixedvec3 &pos, AActor *target, angle_t angle, int pitch) +{ + P_TraceBleed(damage, pos.x, pos.y, pos.z, target, angle, pitch); +} void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch); void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version void P_TraceBleed(int damage, FTranslatedLineTarget *t, AActor *puff); // hitscan version void P_TraceBleed (int damage, AActor *target); // random direction version 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); +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_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 diff --git a/src/p_map.cpp b/src/p_map.cpp index a0ecc58f7..15718ec4c 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -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 SpawnShootDecal(AActor *t1, const FTraceResults &trace); -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 void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff); static FRandom pr_tracebleed("TraceBleed"); static FRandom pr_checkthing("CheckThing"); @@ -245,7 +244,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines if (open.top < tmf.ceilingz) { 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)); mit.StopUp(); } @@ -1527,7 +1526,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch !(tm.thing->flags3 & MF3_BLOODLESSIMPACT) && (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)) { @@ -3667,7 +3666,7 @@ struct aim_t void EnterSectorPortal(int position, fixed_t frac, sector_t *entersec, fixed_t newtoppitch, fixed_t newbottompitch) { AActor *portal = entersec->SkyBoxes[position]; - if (portal == NULL) + if (position == sector_t::ceiling && portal->threshold < limitz) return; else if (position == sector_t::floor && portal->threshold > limitz) return; aim_t newtrace = Clone(); @@ -3779,7 +3778,7 @@ struct aim_t if (aimdebug) 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.); 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) { // 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 { @@ -4240,21 +4239,19 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, } else { - fixed_t hitx = 0, hity = 0, hitz = 0; - if (trace.HitType != TRACE_HitActor) { // position a bit closer for puffs if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon) { - fixed_t closer = trace.Distance - 4 * FRACUNIT; - fixedvec2 pos = t1->Vec2Offset(FixedMul(vx, closer), FixedMul(vy, closer)); - puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, - shootz + FixedMul(vz, closer), angle - ANG90, 0, puffFlags); + fixedvec2 pos = P_GetOffsetPosition(trace.HitPos.x, trace.HitPos.y, -trace.HitVector.x * 4, -trace.HitVector.y * 4); + puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y, trace.HitPos.z - trace.HitVector.z * 4, trace.SrcAngleToTarget, + trace.SrcAngleToTarget - ANGLE_90, 0, puffFlags); + puff->radius = 1; } // [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. if (t1->DecalGenerator != NULL || @@ -4283,7 +4280,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, trace.Sector->heightsec == NULL && trace.HitType == TRACE_HitFloor) { - P_HitWater(puff, trace.Sector, trace.X, trace.Y, trace.Z); + P_HitWater(puff, trace.Sector, trace.HitPos); } } else @@ -4297,14 +4294,13 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, (t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD)); // 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. - if (i_compatflags & COMPATF_HITSCAN) dist -= 10 * FRACUNIT; - hitx = t1->X() + FixedMul(vx, dist); - hity = t1->Y() + FixedMul(vy, dist); - hitz = shootz + FixedMul(vz, dist); - - + if (i_compatflags & COMPATF_HITSCAN) + { + fixedvec2 ofs = P_GetOffsetPosition(bleedpos.x, bleedpos.y, -10 * trace.HitVector.x, -10 * trace.HitVector.y); + bleedpos -= { ofs.x, ofs.y, -10 * trace.HitVector.z}; + } // Spawn bullet puffs or blood spots, depending on target type. 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; // 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. @@ -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 // 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; } -#pragma message("damage angle") - newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags); + newdam = P_DamageMobj(trace.Actor, puff ? puff : t1, t1, damage, damageType, dmgflags|DMG_USEANGLE, trace.SrcAngleToTarget); if (actualdamage != NULL) { *actualdamage = newdam; @@ -4357,7 +4352,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, !(trace.Actor->flags & MF_NOBLOOD) && !(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) @@ -4369,35 +4364,34 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, { if (axeBlood) { - P_BloodSplatter2(hitx, hity, hitz, trace.Actor); + P_BloodSplatter2(bleedpos, trace.Actor); } if (pr_lineattack() < 192) { - P_BloodSplatter(hitx, hity, hitz, trace.Actor); + P_BloodSplatter(bleedpos, trace.Actor); } } } // [RH] Stick blood to walls - P_TraceBleed(newdam > 0 ? newdam : damage, trace.X, trace.Y, trace.Z, - trace.Actor, srcangle, srcpitch); + P_TraceBleed(newdam > 0 ? newdam : damage, trace.HitPos, + trace.Actor, trace.SrcAngleToTarget, srcpitch); } } if (victim != NULL) { victim->linetarget = trace.Actor; - victim->angleFromSource = R_PointToAngle2(t1->X(), t1->Y(), trace.Actor->X(), trace.Actor->Y()); - victim->unlinked = false; + victim->angleFromSource = trace.SrcAngleToTarget; + victim->unlinked = trace.unlinked; } } if (trace.Crossed3DWater || trace.CrossedWater) { - if (puff == NULL) { // 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; } - SpawnDeepSplash(t1, trace, puff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); + SpawnDeepSplash(t1, trace, puff); } } 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; } - DImpactDecal::StaticCreate(bloodType, - bleedtrace.X, bleedtrace.Y, bleedtrace.Z, - bleedtrace.Line->sidedef[bleedtrace.Side], - bleedtrace.ffloor, - bloodcolor); + DImpactDecal::StaticCreate(bloodType, bleedtrace.HitPos, + bleedtrace.Line->sidedef[bleedtrace.Side], bleedtrace.ffloor, bloodcolor); } } } @@ -4645,7 +4636,8 @@ void P_TraceBleed(int damage, AActor *target) struct SRailHit { AActor *HitActor; - fixed_t Distance; + fixedvec3 HitPos; + angle_t HitAngle; }; struct RailData { @@ -4679,7 +4671,13 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata) // Save this thing for damaging later, and continue the trace SRailHit newhit; 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); 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 bleed = false; int puffflags = PF_HITTHING; AActor *hitactor = rail_data.RailHits[i].HitActor; - fixed_t hitdist = rail_data.RailHits[i].Distance; - - x = xy.x + FixedMul(hitdist, vx); - y = xy.y + FixedMul(hitdist, vy); - z = shootz + FixedMul(hitdist, vz); + fixedvec3 &hitpos = rail_data.RailHits[i].HitPos; + angle_t hitangle = rail_data.RailHits[i].HitAngle; if ((hitactor->flags & MF_NOBLOOD) || (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) { - 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; @@ -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->flags7 & MF7_FOILBUDDHA) dmgFlagPass |= DMG_FOILBUDDHA; } -#pragma message("damage angle") - int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass); + int newdam = P_DamageMobj(hitactor, thepuff ? thepuff : source, source, damage, damagetype, dmgFlagPass|DMG_USEANGLE, hitangle); if (bleed) { - P_SpawnBlood(x, y, z, (source->angle + angleoffset) - ANG180, newdam > 0 ? newdam : damage, hitactor); - P_TraceBleed(newdam > 0 ? newdam : damage, x, y, z, hitactor, source->angle, pitch); + P_SpawnBlood(hitpos, hitangle, newdam > 0 ? newdam : damage, hitactor); + 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) { - 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)) puff->Destroy(); } @@ -4834,7 +4827,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i AActor* puff = NULL; 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) && (((trace.HitType == TRACE_HitFloor) && (puff->floorpic == 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 (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) { - 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(); } // Draw the slug's trail. - end.X = FIXED2DBL(trace.X); - end.Y = FIXED2DBL(trace.Y); - end.Z = FIXED2DBL(trace.Z); + end.X = FIXED2DBL(trace.HitPos.x); + end.Y = FIXED2DBL(trace.HitPos.y); + end.Z = FIXED2DBL(trace.HitPos.z); P_DrawRailTrail(source, start, end, color1, color2, maxdiff, railflags, spawnclass, source->angle + angleoffset, duration, sparsity, drift, SpiralOffset); } @@ -4900,9 +4891,9 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera } else { - CameraX = trace.X; - CameraY = trace.Y; - CameraZ = trace.Z; + CameraX = trace.HitPos.x; + CameraY = trace.HitPos.y; + CameraZ = trace.HitPos.z; } CameraSector = trace.Sector; unlinked = trace.unlinked; @@ -6426,7 +6417,7 @@ void SpawnShootDecal(AActor *t1, const FTraceResults &trace) if (decalbase != NULL) { 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, - fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor) +static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff) { - const secplane_t *plane; - if (ffloor && trace.Crossed3DWater) - plane = trace.Crossed3DWater->top.plane; + const fixedvec3 *hitpos; + if (trace.Crossed3DWater) + { + hitpos = &trace.Crossed3DWaterPos; + } else if (trace.CrossedWater && trace.CrossedWater->heightsec) - plane = &trace.CrossedWater->heightsec->floorplane; + { + hitpos = &trace.CrossedWaterPos; + } else return; - fixed_t num, den, hitdist; - 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); - } - } + P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos->x, hitpos->y), *hitpos); } //============================================================================= diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 70ea6a0b9..aa3691afa 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1444,8 +1444,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) } } - DImpactDecal::StaticCreate (base->GetDecal (), - x, y, z, line->sidedef[side], ffloor); + DImpactDecal::StaticCreate(base->GetDecal(), { x, y, z }, line->sidedef[side], ffloor); } } } @@ -5228,7 +5227,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) // 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; @@ -5256,8 +5255,8 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, fixed_t x, fixed_t y if ( puff && (puff->flags5 & MF5_PUFFGETSOWNER)) puff->target = source; - - if (source != NULL) puff->angle = puff->AngleTo(source); + // Angle is the opposite of the hit direction (i.e. the puff faces the source.) + puff->angle = hitdir + ANGLE_180; // If a puff has a crash state and an actor was not hit, // it will enter the crash state. This is used by the StrifeSpark @@ -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)) { - P_DrawSplash2 (32, x, y, z, dir, updown, 1); + P_DrawSplash2 (32, x, y, z, particledir, updown, 1); 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(); 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; - 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->velx = 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) { - 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(); 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; - x += ((pr_splat()-128)<<11); - y += ((pr_splat()-128)<<11); + pos.x += ((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; // colorize the blood! @@ -5472,7 +5471,7 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) } 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()) { - 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 P_HitWater (thing, m->m_sector, pos.x, pos.y, pos.z); + return P_HitWater (thing, m->m_sector, pos); } //--------------------------------------------------------------------------- diff --git a/src/p_trace.cpp b/src/p_trace.cpp index ad2bb269c..2e96db7c9 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -87,11 +87,18 @@ struct FTraceInfo 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)); } + 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)) { - Results->CopyIfCloser(TempResults); + TempResults->CopyIfCloser(newtrace.Results); } } @@ -319,7 +326,7 @@ void FTraceInfo::Setup3DFloors() if (Check3DFloorPlane(rover, false)) { 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)) { Results->CrossedWater = §ors[CurSector->sectornum]; - Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; + Results->CrossedWaterPos = Results->HitPos; } } @@ -645,9 +652,8 @@ cont: if (Results->HitType == TRACE_HitWall) { - Results->X = hitx; - Results->Y = hity; - Results->Z = hitz; + Results->HitPos = { hitx, hity, hitz }; + SetSourcePosition(); Results->Distance = dist; Results->Fraction = in->frac; Results->Line = in->d.line; @@ -773,9 +779,8 @@ cont1: Results->HitType = TRACE_HitActor; - Results->X = hitx; - Results->Y = hity; - Results->Z = hitz; + Results->HitPos = { hitx, hity, hitz }; + SetSourcePosition(); Results->Distance = dist; Results->Fraction = in->frac; Results->Actor = in->d.thing; @@ -823,7 +828,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) if (Check3DFloorPlane(rover, false)) { 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 if (Results->CrossedWater == 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. FTraceResults *res = Results; @@ -862,7 +867,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) if (CheckSectorPlane(CurSector->heightsec, true)) { Results->CrossedWater = §ors[CurSector->sectornum]; - Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; + Results->CrossedWaterPos = Results->HitPos; } Results = res; } @@ -889,7 +894,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) if (Results->CrossedWater == 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. FTraceResults *res = Results; @@ -899,15 +904,17 @@ bool FTraceInfo::TraceTraverse (int ptflags) if (CheckSectorPlane(CurSector->heightsec, true)) { Results->CrossedWater = §ors[CurSector->sectornum]; - Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; + Results->CrossedWaterPos = Results->HitPos; } Results = res; } if (Results->HitType == TRACE_HitNone && Results->Distance == 0) { - Results->X = StartX + FixedMul(Vx, MaxDist); - Results->Y = StartY + FixedMul(Vy, MaxDist); - Results->Z = StartZ + FixedMul(Vz, MaxDist); + Results->HitPos = { + StartX + FixedMul(Vx, MaxDist), + StartY + FixedMul(Vy, MaxDist), + StartZ + FixedMul(Vz, MaxDist) }; + SetSourcePosition(); Results->Distance = MaxDist; Results->Fraction = FRACUNIT; } @@ -934,9 +941,11 @@ bool FTraceInfo::CheckPlane (const secplane_t &plane) if (hitdist > EnterDist && hitdist < MaxDist) { - Results->X = StartX + FixedMul (Vx, hitdist); - Results->Y = StartY + FixedMul (Vy, hitdist); - Results->Z = StartZ + FixedMul (Vz, hitdist); + Results->HitPos = { + StartX + FixedMul(Vx, hitdist), + StartY + FixedMul(Vy, hitdist), + StartZ + FixedMul(Vz, hitdist) }; + SetSourcePosition(); Results->Distance = hitdist; Results->Fraction = FixedDiv (hitdist, MaxDist); return true; diff --git a/src/p_trace.h b/src/p_trace.h index 641a8c007..43203f035 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -65,7 +65,8 @@ struct FTraceResults { sector_t *Sector; FTextureID HitTexture; - fixed_t X, Y, Z; + fixedvec3 HitPos; + fixedvec3 HitVector; fixedvec3 SrcFromTarget; angle_t SrcAngleToTarget; diff --git a/src/portal.cpp b/src/portal.cpp index 6f0baeaea..e37697944 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -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) { // Keep this temporary work stuff static. This function can never be called recursively diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index db1f722f1..42863b3aa 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5178,7 +5178,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood) { spawnblood = false; - P_SpawnPuff(self, pufftype, bloodpos, angle, 0); + P_SpawnPuff(self, pufftype, bloodpos, angle, angle, 0); } } else if (self->target->flags3 & MF3_GHOST)