- added a heightsec change when aborting the main trace due to having found a target in a subtrace.

- be a bit smarter about what to copy from a subtrace. There's 3 distinct pieces of information here: The hit itself, the CrossedWater setting for Boom-transfers and the CrossedWater setting for 3D floors.

Note: Ideally this should return all water hits it can detect, not just the first one.
This commit is contained in:
Christoph Oelckers 2016-03-06 02:07:04 +01:00
parent 74592334e4
commit a0b2915b8f
2 changed files with 43 additions and 10 deletions

View file

@ -227,13 +227,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.Results->HitType != TRACE_HitNone)
{
if (newtrace.Results->Fraction < TempResults->Fraction)
{
*TempResults = *newtrace.Results;
}
}
Results->CopyIfCloser(TempResults);
}
}
@ -855,7 +849,25 @@ bool FTraceInfo::TraceTraverse (int ptflags)
if (TempResults->HitType != TRACE_HitNone &&
(Results->HitType == TRACE_HitNone || Results->Fraction > TempResults->Fraction))
{
*Results = *TempResults;
// 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)
{
// Save the result so that the water check doesn't destroy it.
FTraceResults *res = Results;
FTraceResults hsecResult;
Results = &hsecResult;
if (CheckSectorPlane(CurSector->heightsec, true))
{
Results->CrossedWater = &sectors[CurSector->sectornum];
Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z };
}
Results = res;
}
Results->CopyIfCloser(TempResults);
return true;
}
else if (Results->HitType == TRACE_HitNone)

View file

@ -36,6 +36,7 @@
#include <stddef.h>
#include "actor.h"
#include "cmdlib.h"
#include "textures/textures.h"
struct sector_t;
@ -70,7 +71,7 @@ struct FTraceResults
fixed_t Distance;
fixed_t Fraction;
AActor *Actor; // valid if hit an actor
line_t *Line; // valid if hit a line
@ -78,12 +79,32 @@ struct FTraceResults
BYTE Tier;
bool unlinked; // passed through a portal without static offset.
ETraceResult HitType;
F3DFloor *ffloor;
sector_t *CrossedWater; // For Boom-style, Transfer_Heights-based deep water
fixedvec3 CrossedWaterPos; // remember the position so that we can use it for spawning the splash
F3DFloor *Crossed3DWater; // For 3D floor-based deep water
fixedvec3 Crossed3DWaterPos;
F3DFloor *ffloor;
void CopyIfCloser(FTraceResults *other)
{
if (other->Distance < Distance || HitType == TRACE_HitNone)
{
memcpy(this, other, myoffsetof(FTraceResults, CrossedWater));
}
if (CrossedWater == NULL && other->CrossedWater != NULL)
{
CrossedWater = other->CrossedWater;
CrossedWaterPos = other->CrossedWaterPos;
}
if (Crossed3DWater == NULL && other->Crossed3DWater != NULL)
{
Crossed3DWater = other->Crossed3DWater;
Crossed3DWaterPos = other->Crossed3DWaterPos;
}
}
};
enum
{