mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
Implemented workaround for ZScript LineTrace with 3D floors
This commit is contained in:
parent
85300993af
commit
3eef3d7845
2 changed files with 40 additions and 23 deletions
|
@ -74,7 +74,7 @@ struct FTraceInfo
|
||||||
int sectorsel;
|
int sectorsel;
|
||||||
|
|
||||||
void Setup3DFloors();
|
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 ThingCheck(intercept_t *in, double dist, DVector3 hit);
|
||||||
bool TraceTraverse (int ptflags);
|
bool TraceTraverse (int ptflags);
|
||||||
bool CheckPlane(const secplane_t &plane);
|
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;
|
int lineside;
|
||||||
sector_t *entersector;
|
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.
|
// 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.
|
// 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.
|
// We must check special activation here because the code below is never reached.
|
||||||
if (TraceFlags & TRACE_PCross)
|
if (TraceFlags & TRACE_PCross)
|
||||||
|
@ -472,7 +472,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
||||||
}
|
}
|
||||||
else if (entersector == NULL ||
|
else if (entersector == NULL ||
|
||||||
hit.Z < bf || hit.Z > bc ||
|
hit.Z < bf || hit.Z > bc ||
|
||||||
in->d.line->flags & WallMask)
|
((in->d.line->flags & WallMask) && !special3dpass))
|
||||||
{
|
{
|
||||||
// hit the wall
|
// hit the wall
|
||||||
Results->HitType = TRACE_HitWall;
|
Results->HitType = TRACE_HitWall;
|
||||||
|
@ -480,7 +480,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
||||||
entersector == NULL ? TIER_Middle :
|
entersector == NULL ? TIER_Middle :
|
||||||
hit.Z <= bf ? TIER_Lower :
|
hit.Z <= bf ? TIER_Lower :
|
||||||
hit.Z >= bc ? TIER_Upper : TIER_Middle;
|
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);
|
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;
|
Results->HitType = TRACE_HitNone;
|
||||||
if (TraceFlags & TRACE_PCross)
|
if (!special3dpass)
|
||||||
{
|
{
|
||||||
P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_PCross);
|
if (TraceFlags & TRACE_PCross)
|
||||||
}
|
{
|
||||||
if (TraceFlags & TRACE_Impact)
|
P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_PCross);
|
||||||
{ // This is incorrect for "impact", but Hexen did this, so
|
}
|
||||||
// we need to as well, for compatibility
|
if (TraceFlags & TRACE_Impact)
|
||||||
P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_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:
|
cont:
|
||||||
|
@ -604,7 +607,7 @@ cont:
|
||||||
Results->HitType = TRACE_HitNone;
|
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);
|
P_ActivateLine(in->d.line, IgnoreThis, lineside, SPAC_Impact);
|
||||||
}
|
}
|
||||||
|
@ -625,10 +628,21 @@ cont:
|
||||||
{
|
{
|
||||||
switch (TraceCallback(*Results, TraceCallbackData))
|
switch (TraceCallback(*Results, TraceCallbackData))
|
||||||
{
|
{
|
||||||
case TRACE_Stop: return false;
|
case TRACE_Stop:
|
||||||
case TRACE_Abort: Results->HitType = TRACE_HitNone; return false;
|
return false;
|
||||||
case TRACE_Skip: Results->HitType = TRACE_HitNone; break;
|
|
||||||
default: break;
|
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)
|
else if ((in->d.thing->flags & ActorMask) && in->d.thing != IgnoreThis)
|
||||||
{
|
{
|
||||||
|
@ -996,6 +1010,8 @@ DEFINE_ACTION_FUNCTION(DLineTracer, Trace)
|
||||||
|
|
||||||
// these are internal hacks.
|
// these are internal hacks.
|
||||||
traceFlags &= ~(TRACE_PCross | TRACE_Impact);
|
traceFlags &= ~(TRACE_PCross | TRACE_Impact);
|
||||||
|
// this too
|
||||||
|
traceFlags |= TRACE_3DCallback;
|
||||||
|
|
||||||
// Trace(vector3 start, Sector sector, vector3 direction, double maxDist, ETraceFlags traceFlags)
|
// 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,
|
bool res = Trace(DVector3(start_x, start_y, start_z), sector, DVector3(direction_x, direction_y, direction_z), maxDist,
|
||||||
|
|
|
@ -92,11 +92,12 @@ struct FTraceResults
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TRACE_NoSky = 1, // Hitting the sky returns TRACE_HitNone
|
TRACE_NoSky = 0x0001, // Hitting the sky returns TRACE_HitNone
|
||||||
TRACE_PCross = 2, // Trigger SPAC_PCROSS lines
|
TRACE_PCross = 0x0002, // Trigger SPAC_PCROSS lines
|
||||||
TRACE_Impact = 4, // Trigger SPAC_IMPACT lines
|
TRACE_Impact = 0x0004, // Trigger SPAC_IMPACT lines
|
||||||
TRACE_PortalRestrict= 8, // Cannot go through portals without a static link offset.
|
TRACE_PortalRestrict= 0x0008, // Cannot go through portals without a static link offset.
|
||||||
TRACE_ReportPortals = 16, // Report any portal crossing to the TraceCallback
|
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
|
// return values from callback
|
||||||
|
|
Loading…
Reference in a new issue