From 3eef3d7845635b0ee929f33ead146adf62ce5e35 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Wed, 25 Apr 2018 19:24:37 +0300 Subject: [PATCH] Implemented workaround for ZScript LineTrace with 3D floors --- src/p_trace.cpp | 52 ++++++++++++++++++++++++++++++++----------------- src/p_trace.h | 11 ++++++----- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index b60abc477a..5041294bb8 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -74,7 +74,7 @@ struct FTraceInfo int sectorsel; void Setup3DFloors(); - bool LineCheck(intercept_t *in, double dist, DVector3 hit); + bool LineCheck(intercept_t *in, double dist, DVector3 hit, bool special3dpass); bool ThingCheck(intercept_t *in, double dist, DVector3 hit); bool TraceTraverse (int ptflags); bool CheckPlane(const secplane_t &plane); @@ -380,7 +380,7 @@ void FTraceInfo::Setup3DFloors() // //========================================================================== -bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit) +bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit, bool special3dpass) { int lineside; sector_t *entersector; @@ -419,7 +419,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit) // For backwards compatibility: Ignore lines with the same sector on both sides. // This is the way Doom.exe did it and some WADs (e.g. Alien Vendetta MAP15) need it. - if (i_compatflags & COMPATF_TRACE && in->d.line->backsector == in->d.line->frontsector) + if (i_compatflags & COMPATF_TRACE && in->d.line->backsector == in->d.line->frontsector && !special3dpass) { // We must check special activation here because the code below is never reached. if (TraceFlags & TRACE_PCross) @@ -472,7 +472,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit) } else if (entersector == NULL || hit.Z < bf || hit.Z > bc || - in->d.line->flags & WallMask) + ((in->d.line->flags & WallMask) && !special3dpass)) { // hit the wall Results->HitType = TRACE_HitWall; @@ -480,7 +480,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit) entersector == NULL ? TIER_Middle : hit.Z <= bf ? TIER_Lower : hit.Z >= bc ? TIER_Upper : TIER_Middle; - if (TraceFlags & TRACE_Impact) + if ((TraceFlags & TRACE_Impact) && !special3dpass) { P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_Impact); } @@ -565,14 +565,17 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit) } Results->HitType = TRACE_HitNone; - if (TraceFlags & TRACE_PCross) + if (!special3dpass) { - P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_PCross); - } - if (TraceFlags & TRACE_Impact) - { // This is incorrect for "impact", but Hexen did this, so - // we need to as well, for compatibility - P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_Impact); + if (TraceFlags & TRACE_PCross) + { + P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_PCross); + } + if (TraceFlags & TRACE_Impact) + { // This is incorrect for "impact", but Hexen did this, so + // we need to as well, for compatibility + P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_Impact); + } } } cont: @@ -604,7 +607,7 @@ cont: Results->HitType = TRACE_HitNone; } } - if (Results->HitType == TRACE_HitWall && TraceFlags & TRACE_Impact) + if (Results->HitType == TRACE_HitWall && TraceFlags & TRACE_Impact && (!special3dpass || Results->Tier != TIER_FFloor)) { P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_Impact); } @@ -625,10 +628,21 @@ cont: { switch (TraceCallback(*Results, TraceCallbackData)) { - case TRACE_Stop: return false; - case TRACE_Abort: Results->HitType = TRACE_HitNone; return false; - case TRACE_Skip: Results->HitType = TRACE_HitNone; break; - default: break; + case TRACE_Stop: + return false; + + case TRACE_Abort: + Results->HitType = TRACE_HitNone; + return false; + + case TRACE_Skip: + Results->HitType = TRACE_HitNone; + if (!special3dpass && (TraceFlags & TRACE_3DCallback)) + return LineCheck(in, dist, hit, true); + break; + + default: + break; } } @@ -835,7 +849,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) } } } - if (!LineCheck(in, dist, hit)) break; + if (!LineCheck(in, dist, hit, false)) break; } else if ((in->d.thing->flags & ActorMask) && in->d.thing != IgnoreThis) { @@ -996,6 +1010,8 @@ DEFINE_ACTION_FUNCTION(DLineTracer, Trace) // these are internal hacks. traceFlags &= ~(TRACE_PCross | TRACE_Impact); + // this too + traceFlags |= TRACE_3DCallback; // Trace(vector3 start, Sector sector, vector3 direction, double maxDist, ETraceFlags traceFlags) bool res = Trace(DVector3(start_x, start_y, start_z), sector, DVector3(direction_x, direction_y, direction_z), maxDist, diff --git a/src/p_trace.h b/src/p_trace.h index 0a61cc7258..92a0f30a53 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -92,11 +92,12 @@ struct FTraceResults enum { - TRACE_NoSky = 1, // Hitting the sky returns TRACE_HitNone - TRACE_PCross = 2, // Trigger SPAC_PCROSS lines - TRACE_Impact = 4, // Trigger SPAC_IMPACT lines - TRACE_PortalRestrict= 8, // Cannot go through portals without a static link offset. - TRACE_ReportPortals = 16, // Report any portal crossing to the TraceCallback + TRACE_NoSky = 0x0001, // Hitting the sky returns TRACE_HitNone + TRACE_PCross = 0x0002, // Trigger SPAC_PCROSS lines + TRACE_Impact = 0x0004, // Trigger SPAC_IMPACT lines + TRACE_PortalRestrict= 0x0008, // Cannot go through portals without a static link offset. + TRACE_ReportPortals = 0x0010, // Report any portal crossing to the TraceCallback + TRACE_3DCallback = 0x0020, // [ZZ] use TraceCallback to determine whether we need to go through a line to do 3D floor check, or not. without this, only line flag mask is used }; // return values from callback