Implemented workaround for ZScript LineTrace with 3D floors

This commit is contained in:
ZZYZX 2018-04-25 19:24:37 +03:00 committed by Christoph Oelckers
parent 85300993af
commit 3eef3d7845
2 changed files with 40 additions and 23 deletions

View file

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

View file

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