diff --git a/src/p_map.cpp b/src/p_map.cpp index 7f559fff4..55e90dcf6 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3423,38 +3423,36 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p // //========================================================================== -static bool CheckForGhost (FTraceResults &res) +static ETraceStatus CheckForGhost (FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { - return false; + return TRACE_Stop; } // check for physical attacks on a ghost if (res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL) { - res.HitType = TRACE_HitNone; - return true; + return TRACE_Skip; } - return false; + return TRACE_Stop; } -static bool CheckForSpectral (FTraceResults &res) +static ETraceStatus CheckForSpectral (FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { - return false; + return TRACE_Stop; } // check for physical attacks on spectrals if (res.Actor->flags4 & MF4_SPECTRAL) { - res.HitType = TRACE_HitNone; - return true; + return TRACE_Skip; } - return false; + return TRACE_Stop; } //========================================================================== @@ -3886,17 +3884,17 @@ struct SRailHit }; static TArray RailHits (16); -static bool ProcessRailHit (FTraceResults &res) +static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { - return false; + return TRACE_Stop; } // Invulnerable things completely block the shot if (res.Actor->flags2 & MF2_INVULNERABLE) { - return false; + return TRACE_Stop; } // Save this thing for damaging later, and continue the trace @@ -3905,7 +3903,7 @@ static bool ProcessRailHit (FTraceResults &res) newhit.Distance = res.Distance - 10*FRACUNIT; // put blood in front RailHits.Push (newhit); - return true; + return TRACE_Continue; } //========================================================================== @@ -3914,17 +3912,17 @@ static bool ProcessRailHit (FTraceResults &res) // //========================================================================== -static bool ProcessNoPierceRailHit (FTraceResults &res) +static ETraceStatus ProcessNoPierceRailHit (FTraceResults &res, void *userdata) { if (res.HitType != TRACE_HitActor) { - return false; + return TRACE_Stop; } // Invulnerable things completely block the shot if (res.Actor->flags2 & MF2_INVULNERABLE) { - return false; + return TRACE_Stop; } // Only process the first hit @@ -3933,7 +3931,7 @@ static bool ProcessNoPierceRailHit (FTraceResults &res) newhit.Distance = res.Distance - 10*FRACUNIT; // put blood in front RailHits.Push (newhit); - return false; + return TRACE_Stop; } //========================================================================== diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 93c347d9f..d1b9f63ac 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -48,7 +48,8 @@ struct FTraceInfo sector_t *CurSector; fixed_t MaxDist; fixed_t EnterDist; - bool (*TraceCallback)(FTraceResults &res); + ETraceStatus (*TraceCallback)(FTraceResults &res, void *data); + void *TraceCallbackData; DWORD TraceFlags; int inshootthrough; @@ -71,7 +72,7 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, fixed_t vx, fixed_t vy, fixed_t vz, fixed_t maxDist, DWORD actorMask, DWORD wallMask, AActor *ignore, FTraceResults &res, - DWORD flags, bool (*callback)(FTraceResults &res)) + DWORD flags, ETraceStatus (*callback)(FTraceResults &res, void *), void *callbackdata) { int ptflags; FTraceInfo inf; @@ -91,6 +92,7 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, inf.MaxDist = maxDist; inf.EnterDist = 0; inf.TraceCallback = callback; + inf.TraceCallbackData = callbackdata; inf.TraceFlags = flags; inf.Results = &res; inf.inshootthrough = true; @@ -506,7 +508,13 @@ cont: if (TraceCallback != NULL) { - if (!TraceCallback (*Results)) return false; + 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; + } } else { @@ -515,8 +523,7 @@ cont: } // Encountered an actor - if (!(in->d.thing->flags & ActorMask) || - in->d.thing == IgnoreThis) + if (!(in->d.thing->flags & ActorMask) || in->d.thing == IgnoreThis) { continue; } @@ -583,13 +590,19 @@ cont: // the trace hit a 3D-floor before the thing. // Calculate an intersection and abort. Results->Sector = §ors[CurSector->sectornum]; - if (!CheckSectorPlane(CurSector, Results->HitType==TRACE_HitFloor)) + if (!CheckSectorPlane(CurSector, Results->HitType == TRACE_HitFloor)) { - Results->HitType=TRACE_HitNone; + Results->HitType = TRACE_HitNone; } if (TraceCallback != NULL) { - return TraceCallback (*Results); + switch (TraceCallback(*Results, TraceCallbackData)) + { + case TRACE_Continue: return true; + case TRACE_Stop: return false; + case TRACE_Abort: Results->HitType = TRACE_HitNone; return false; + case TRACE_Skip: Results->HitType = TRACE_HitNone; return true; + } } else { @@ -608,7 +621,13 @@ cont1: if (TraceCallback != NULL) { - if (!TraceCallback (*Results)) return false; + 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; + } } else { diff --git a/src/p_trace.h b/src/p_trace.h index 8ce905da3..403b1f9cf 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -85,10 +85,20 @@ enum TRACE_Impact = 4, // Trigger SPAC_IMPACT lines }; +// return values from callback +enum ETraceStatus +{ + TRACE_Stop, // stop the trace, returning this hit + TRACE_Continue, // continue the trace, returning this hit if there are none further along + TRACE_Skip, // continue the trace; do not return this hit + TRACE_Abort, // stop the trace, returning no hits +}; + bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, fixed_t vx, fixed_t vy, fixed_t vz, fixed_t maxDist, DWORD ActorMask, DWORD WallMask, AActor *ignore, FTraceResults &res, - DWORD traceFlags=0, bool (*callback)(FTraceResults &res)=NULL); + DWORD traceFlags=0, + ETraceStatus (*callback)(FTraceResults &res, void *)=NULL, void *callbackdata=NULL); #endif //__P_TRACE_H__