From a0b2915b8fd4c253f156eb2d376ca56637ef4752 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 6 Mar 2016 02:07:04 +0100 Subject: [PATCH] - 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. --- src/p_trace.cpp | 28 ++++++++++++++++++++-------- src/p_trace.h | 25 +++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index d8c5aa781e..ad2bb269c2 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -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 = §ors[CurSector->sectornum]; + Results->CrossedWaterPos = { Results->X, Results->Y, Results->Z }; + } + Results = res; + } + + Results->CopyIfCloser(TempResults); return true; } else if (Results->HitType == TRACE_HitNone) diff --git a/src/p_trace.h b/src/p_trace.h index d02498133d..641a8c0077 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -36,6 +36,7 @@ #include #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 {