- Added an enum for the values a Trace callback function can return.

- Added a userdata parameter to pass to the Trace callback function.

SVN r4200 (trunk)
This commit is contained in:
Randy Heit 2013-03-23 02:54:13 +00:00
parent c54ea7f6b7
commit dcf50ab6cb
3 changed files with 55 additions and 28 deletions

View file

@ -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) if (res.HitType != TRACE_HitActor)
{ {
return false; return TRACE_Stop;
} }
// check for physical attacks on a ghost // check for physical attacks on a ghost
if (res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL) if (res.Actor->flags3 & MF3_GHOST || res.Actor->flags4 & MF4_SPECTRAL)
{ {
res.HitType = TRACE_HitNone; return TRACE_Skip;
return true;
} }
return false; return TRACE_Stop;
} }
static bool CheckForSpectral (FTraceResults &res) static ETraceStatus CheckForSpectral (FTraceResults &res, void *userdata)
{ {
if (res.HitType != TRACE_HitActor) if (res.HitType != TRACE_HitActor)
{ {
return false; return TRACE_Stop;
} }
// check for physical attacks on spectrals // check for physical attacks on spectrals
if (res.Actor->flags4 & MF4_SPECTRAL) if (res.Actor->flags4 & MF4_SPECTRAL)
{ {
res.HitType = TRACE_HitNone; return TRACE_Skip;
return true;
} }
return false; return TRACE_Stop;
} }
//========================================================================== //==========================================================================
@ -3886,17 +3884,17 @@ struct SRailHit
}; };
static TArray<SRailHit> RailHits (16); static TArray<SRailHit> RailHits (16);
static bool ProcessRailHit (FTraceResults &res) static ETraceStatus ProcessRailHit (FTraceResults &res, void *userdata)
{ {
if (res.HitType != TRACE_HitActor) if (res.HitType != TRACE_HitActor)
{ {
return false; return TRACE_Stop;
} }
// Invulnerable things completely block the shot // Invulnerable things completely block the shot
if (res.Actor->flags2 & MF2_INVULNERABLE) if (res.Actor->flags2 & MF2_INVULNERABLE)
{ {
return false; return TRACE_Stop;
} }
// Save this thing for damaging later, and continue the trace // 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 newhit.Distance = res.Distance - 10*FRACUNIT; // put blood in front
RailHits.Push (newhit); 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) if (res.HitType != TRACE_HitActor)
{ {
return false; return TRACE_Stop;
} }
// Invulnerable things completely block the shot // Invulnerable things completely block the shot
if (res.Actor->flags2 & MF2_INVULNERABLE) if (res.Actor->flags2 & MF2_INVULNERABLE)
{ {
return false; return TRACE_Stop;
} }
// Only process the first hit // Only process the first hit
@ -3933,7 +3931,7 @@ static bool ProcessNoPierceRailHit (FTraceResults &res)
newhit.Distance = res.Distance - 10*FRACUNIT; // put blood in front newhit.Distance = res.Distance - 10*FRACUNIT; // put blood in front
RailHits.Push (newhit); RailHits.Push (newhit);
return false; return TRACE_Stop;
} }
//========================================================================== //==========================================================================

View file

@ -48,7 +48,8 @@ struct FTraceInfo
sector_t *CurSector; sector_t *CurSector;
fixed_t MaxDist; fixed_t MaxDist;
fixed_t EnterDist; fixed_t EnterDist;
bool (*TraceCallback)(FTraceResults &res); ETraceStatus (*TraceCallback)(FTraceResults &res, void *data);
void *TraceCallbackData;
DWORD TraceFlags; DWORD TraceFlags;
int inshootthrough; 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, fixed_t vx, fixed_t vy, fixed_t vz, fixed_t maxDist,
DWORD actorMask, DWORD wallMask, AActor *ignore, DWORD actorMask, DWORD wallMask, AActor *ignore,
FTraceResults &res, FTraceResults &res,
DWORD flags, bool (*callback)(FTraceResults &res)) DWORD flags, ETraceStatus (*callback)(FTraceResults &res, void *), void *callbackdata)
{ {
int ptflags; int ptflags;
FTraceInfo inf; FTraceInfo inf;
@ -91,6 +92,7 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector,
inf.MaxDist = maxDist; inf.MaxDist = maxDist;
inf.EnterDist = 0; inf.EnterDist = 0;
inf.TraceCallback = callback; inf.TraceCallback = callback;
inf.TraceCallbackData = callbackdata;
inf.TraceFlags = flags; inf.TraceFlags = flags;
inf.Results = &res; inf.Results = &res;
inf.inshootthrough = true; inf.inshootthrough = true;
@ -506,7 +508,13 @@ cont:
if (TraceCallback != NULL) 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 else
{ {
@ -515,8 +523,7 @@ cont:
} }
// Encountered an actor // Encountered an actor
if (!(in->d.thing->flags & ActorMask) || if (!(in->d.thing->flags & ActorMask) || in->d.thing == IgnoreThis)
in->d.thing == IgnoreThis)
{ {
continue; continue;
} }
@ -583,13 +590,19 @@ cont:
// the trace hit a 3D-floor before the thing. // the trace hit a 3D-floor before the thing.
// Calculate an intersection and abort. // Calculate an intersection and abort.
Results->Sector = &sectors[CurSector->sectornum]; Results->Sector = &sectors[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) 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 else
{ {
@ -608,7 +621,13 @@ cont1:
if (TraceCallback != NULL) 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 else
{ {

View file

@ -85,10 +85,20 @@ enum
TRACE_Impact = 4, // Trigger SPAC_IMPACT lines 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, 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, fixed_t vx, fixed_t vy, fixed_t vz, fixed_t maxDist,
DWORD ActorMask, DWORD WallMask, AActor *ignore, DWORD ActorMask, DWORD WallMask, AActor *ignore,
FTraceResults &res, 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__ #endif //__P_TRACE_H__