mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-26 05:01:36 +00:00
- Removed PT_EARLYOUT from P_PathTraverse because it wasn't used anywhere.
- Rewrote BlockThingsIterator code not to use callbacks anymore. SVN r888 (trunk)
This commit is contained in:
parent
ebd17de30a
commit
0b26377624
7 changed files with 730 additions and 989 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
April 7, 2008 (Changes by Graf Zahl)
|
||||||
|
- Removed PT_EARLYOUT from P_PathTraverse because it wasn't used anywhere.
|
||||||
|
- Rewrote BlockThingsIterator code not to use callbacks anymore.
|
||||||
|
|
||||||
April 6, 2008 (Changes by Graf Zahl)
|
April 6, 2008 (Changes by Graf Zahl)
|
||||||
- Fixed: PIT_FindFloorCeiling required tmx and tmy to be set but
|
- Fixed: PIT_FindFloorCeiling required tmx and tmy to be set but
|
||||||
P_FindFloorCeiling never did that.
|
P_FindFloorCeiling never did that.
|
||||||
|
|
|
@ -35,58 +35,6 @@ void A_ThrustLower (AActor *);
|
||||||
void A_ThrustBlock (AActor *);
|
void A_ThrustBlock (AActor *);
|
||||||
void A_ThrustImpale (AActor *);
|
void A_ThrustImpale (AActor *);
|
||||||
|
|
||||||
AActor *tsthing;
|
|
||||||
|
|
||||||
bool PIT_ThrustStompThing (AActor *thing)
|
|
||||||
{
|
|
||||||
fixed_t blockdist;
|
|
||||||
|
|
||||||
if (!(thing->flags & MF_SHOOTABLE) )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
blockdist = thing->radius + tsthing->radius;
|
|
||||||
if ( abs(thing->x - tsthing->x) >= blockdist ||
|
|
||||||
abs(thing->y - tsthing->y) >= blockdist ||
|
|
||||||
(thing->z > tsthing->z+tsthing->height) )
|
|
||||||
return true; // didn't hit it
|
|
||||||
|
|
||||||
if (thing == tsthing)
|
|
||||||
return true; // don't clip against self
|
|
||||||
|
|
||||||
P_DamageMobj (thing, tsthing, tsthing, 10001, NAME_Crush);
|
|
||||||
P_TraceBleed (10001, thing);
|
|
||||||
tsthing->args[1] = 1; // Mark thrust thing as bloody
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void P_ThrustSpike (AActor *actor)
|
|
||||||
{
|
|
||||||
static TArray<AActor *> spikebt;
|
|
||||||
|
|
||||||
int xl,xh,yl,yh,bx,by;
|
|
||||||
int x0,x2,y0,y2;
|
|
||||||
|
|
||||||
tsthing = actor;
|
|
||||||
|
|
||||||
x0 = actor->x - actor->radius;
|
|
||||||
x2 = actor->x + actor->radius;
|
|
||||||
y0 = actor->y - actor->radius;
|
|
||||||
y2 = actor->y + actor->radius;
|
|
||||||
|
|
||||||
xl = (x0 - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
xh = (x2 - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yl = (y0 - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yh = (y2 - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
|
|
||||||
spikebt.Clear();
|
|
||||||
|
|
||||||
// stomp on any things contacted
|
|
||||||
for (bx = xl; bx <= xh; bx++)
|
|
||||||
for (by = yl; by <= yh; by++)
|
|
||||||
P_BlockThingsIterator (bx, by, PIT_ThrustStompThing, spikebt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// AThrustFloor is just a container for all the spike states.
|
// AThrustFloor is just a container for all the spike states.
|
||||||
// All the real spikes subclass it.
|
// All the real spikes subclass it.
|
||||||
|
|
||||||
|
@ -313,7 +261,19 @@ void A_ThrustBlock (AActor *actor)
|
||||||
|
|
||||||
void A_ThrustImpale (AActor *actor)
|
void A_ThrustImpale (AActor *actor)
|
||||||
{
|
{
|
||||||
// Impale all shootables in radius
|
AActor *thing;
|
||||||
P_ThrustSpike (actor);
|
FRadiusThingsIterator it(actor->x, actor->y, actor->radius);
|
||||||
|
while ((thing = it.Next()))
|
||||||
|
{
|
||||||
|
if (!(thing->flags & MF_SHOOTABLE) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (thing == actor)
|
||||||
|
continue; // don't clip against self
|
||||||
|
|
||||||
|
P_DamageMobj (thing, actor, actor, 10001, NAME_Crush);
|
||||||
|
P_TraceBleed (10001, thing);
|
||||||
|
actor->args[1] = 1; // Mark thrust thing as bloody
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
108
src/p_enemy.cpp
108
src/p_enemy.cpp
|
@ -2078,43 +2078,46 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// PIT_VileCheck
|
// P_CheckForResurrection (formerly part of A_VileChase)
|
||||||
|
// Check for ressurecting a body
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static AActor *corpsehit;
|
static bool P_CheckForResurrection(AActor *self, bool usevilestates)
|
||||||
static AActor *vileobj;
|
|
||||||
static fixed_t viletryx;
|
|
||||||
static fixed_t viletryy;
|
|
||||||
static FState *raisestate;
|
|
||||||
|
|
||||||
static bool PIT_VileCheck (AActor *thing)
|
|
||||||
{
|
{
|
||||||
int maxdist;
|
const AActor *info;
|
||||||
bool check;
|
AActor *temp;
|
||||||
|
|
||||||
if (!(thing->flags & MF_CORPSE) )
|
if (self->movedir != DI_NODIR)
|
||||||
return true; // not a monster
|
{
|
||||||
|
const fixed_t absSpeed = abs (self->Speed);
|
||||||
|
fixed_t viletryx = self->x + FixedMul (absSpeed, xspeed[self->movedir]);
|
||||||
|
fixed_t viletryy = self->y + FixedMul (absSpeed, yspeed[self->movedir]);
|
||||||
|
AActor *corpsehit;
|
||||||
|
FState *raisestate;
|
||||||
|
|
||||||
if (thing->tics != -1)
|
FBlockThingsIterator it(FBoundingBox(viletryx, viletryy, 32*FRACUNIT));
|
||||||
return true; // not lying still yet
|
while ((corpsehit = it.Next()))
|
||||||
|
{
|
||||||
|
if (!(corpsehit->flags & MF_CORPSE) )
|
||||||
|
continue; // not a monster
|
||||||
|
|
||||||
raisestate = thing->FindState(NAME_Raise);
|
if (corpsehit->tics != -1)
|
||||||
|
continue; // not lying still yet
|
||||||
|
|
||||||
|
raisestate = corpsehit->FindState(NAME_Raise);
|
||||||
if (raisestate == NULL)
|
if (raisestate == NULL)
|
||||||
return true; // monster doesn't have a raise state
|
continue; // monster doesn't have a raise state
|
||||||
|
|
||||||
// This may be a potential problem if this is used by something other
|
|
||||||
// than an Arch Vile.
|
|
||||||
//maxdist = thing->GetDefault()->radius + GetDefault<AArchvile>()->radius;
|
|
||||||
|
|
||||||
// use the current actor's radius instead of the Arch Vile's default.
|
// use the current actor's radius instead of the Arch Vile's default.
|
||||||
maxdist = thing->GetDefault()->radius + vileobj->radius;
|
fixed_t maxdist = corpsehit->GetDefault()->radius + self->radius;
|
||||||
|
|
||||||
if ( abs(thing->x - viletryx) > maxdist
|
maxdist = corpsehit-> GetDefault()->radius + self->radius;
|
||||||
|| abs(thing->y - viletryy) > maxdist )
|
|
||||||
return true; // not actually touching
|
if ( abs(corpsehit-> x - viletryx) > maxdist ||
|
||||||
|
abs(corpsehit-> y - viletryy) > maxdist )
|
||||||
|
continue; // not actually touching
|
||||||
|
|
||||||
corpsehit = thing;
|
|
||||||
corpsehit->momx = corpsehit->momy = 0;
|
corpsehit->momx = corpsehit->momy = 0;
|
||||||
// [RH] Check against real height and radius
|
// [RH] Check against real height and radius
|
||||||
|
|
||||||
|
@ -2124,58 +2127,12 @@ static bool PIT_VileCheck (AActor *thing)
|
||||||
|
|
||||||
corpsehit->flags |= MF_SOLID;
|
corpsehit->flags |= MF_SOLID;
|
||||||
corpsehit->height = corpsehit->GetDefault()->height;
|
corpsehit->height = corpsehit->GetDefault()->height;
|
||||||
check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y);
|
bool check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y);
|
||||||
corpsehit->flags = oldflags;
|
corpsehit->flags = oldflags;
|
||||||
corpsehit->radius = oldradius;
|
corpsehit->radius = oldradius;
|
||||||
corpsehit->height = oldheight;
|
corpsehit->height = oldheight;
|
||||||
|
if (!check) continue;
|
||||||
|
|
||||||
return !check;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// P_CheckForResurrection (formerly part of A_VileChase)
|
|
||||||
// Check for ressurecting a body
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static bool P_CheckForResurrection(AActor *self, bool usevilestates)
|
|
||||||
{
|
|
||||||
static TArray<AActor *> vilebt;
|
|
||||||
int xl, xh, yl, yh;
|
|
||||||
int bx, by;
|
|
||||||
|
|
||||||
const AActor *info;
|
|
||||||
AActor *temp;
|
|
||||||
|
|
||||||
if (self->movedir != DI_NODIR)
|
|
||||||
{
|
|
||||||
const fixed_t absSpeed = abs (self->Speed);
|
|
||||||
|
|
||||||
// check for corpses to raise
|
|
||||||
viletryx = self->x + FixedMul (absSpeed, xspeed[self->movedir]);
|
|
||||||
viletryy = self->y + FixedMul (absSpeed, yspeed[self->movedir]);
|
|
||||||
|
|
||||||
xl = (viletryx - bmaporgx - MAXRADIUS*2)>>MAPBLOCKSHIFT;
|
|
||||||
xh = (viletryx - bmaporgx + MAXRADIUS*2)>>MAPBLOCKSHIFT;
|
|
||||||
yl = (viletryy - bmaporgy - MAXRADIUS*2)>>MAPBLOCKSHIFT;
|
|
||||||
yh = (viletryy - bmaporgy + MAXRADIUS*2)>>MAPBLOCKSHIFT;
|
|
||||||
|
|
||||||
vileobj = self;
|
|
||||||
validcount++;
|
|
||||||
vilebt.Clear();
|
|
||||||
|
|
||||||
for (bx = xl; bx <= xh; bx++)
|
|
||||||
{
|
|
||||||
for (by = yl; by <= yh; by++)
|
|
||||||
{
|
|
||||||
// Call PIT_VileCheck to check
|
|
||||||
// whether object is a corpse
|
|
||||||
// that can be raised.
|
|
||||||
if (!P_BlockThingsIterator (bx, by, PIT_VileCheck, vilebt))
|
|
||||||
{
|
|
||||||
// got one!
|
// got one!
|
||||||
temp = self->target;
|
temp = self->target;
|
||||||
self->target = corpsehit;
|
self->target = corpsehit;
|
||||||
|
@ -2185,8 +2142,8 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
|
||||||
// If this is a friendly Arch-Vile (which is turning the resurrected monster into its friend)
|
// If this is a friendly Arch-Vile (which is turning the resurrected monster into its friend)
|
||||||
// and the Arch-Vile is currently targetting the resurrected monster the target must be cleared.
|
// and the Arch-Vile is currently targetting the resurrected monster the target must be cleared.
|
||||||
if (self->lastenemy == temp) self->lastenemy = NULL;
|
if (self->lastenemy == temp) self->lastenemy = NULL;
|
||||||
|
if (self->lastenemy == corpsehit) self->lastenemy = NULL;
|
||||||
if (temp == self->target) temp = NULL;
|
if (temp == self->target) temp = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
self->target = temp;
|
self->target = temp;
|
||||||
|
|
||||||
|
@ -2234,12 +2191,9 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
|
||||||
// You are the Archvile's minion now, so hate what it hates
|
// You are the Archvile's minion now, so hate what it hates
|
||||||
corpsehit->CopyFriendliness (self, false);
|
corpsehit->CopyFriendliness (self, false);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,12 +255,48 @@ public:
|
||||||
void Reset() { StartBlock(minx, miny); }
|
void Reset() { StartBlock(minx, miny); }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool P_BlockThingsIterator (int x, int y, bool(*func)(AActor*), TArray<AActor *> &checkarray, AActor *start=NULL);
|
class FBlockThingsIterator
|
||||||
|
{
|
||||||
|
typedef TArray<AActor *> BTChecked;
|
||||||
|
|
||||||
|
static TDeletingArray< BTChecked* > FreeBTChecked;
|
||||||
|
|
||||||
|
|
||||||
|
int minx, maxx;
|
||||||
|
int miny, maxy;
|
||||||
|
|
||||||
|
int curx, cury;
|
||||||
|
|
||||||
|
bool dontfreecheck;
|
||||||
|
BTChecked *checkarray;
|
||||||
|
|
||||||
|
FBlockNode *block;
|
||||||
|
|
||||||
|
static BTChecked *GetCheckArray();
|
||||||
|
void FreeCheckArray();
|
||||||
|
void StartBlock(int x, int y);
|
||||||
|
|
||||||
|
public:
|
||||||
|
FBlockThingsIterator(int minx, int miny, int maxx, int maxy, TArray<AActor *> *check = NULL);
|
||||||
|
FBlockThingsIterator(const FBoundingBox &box);
|
||||||
|
~FBlockThingsIterator()
|
||||||
|
{
|
||||||
|
if (!dontfreecheck) FreeCheckArray();
|
||||||
|
}
|
||||||
|
AActor *Next();
|
||||||
|
void Reset() { StartBlock(minx, miny); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FRadiusThingsIterator : public FBlockThingsIterator
|
||||||
|
{
|
||||||
|
fixed_t X, Y, Radius;
|
||||||
|
public:
|
||||||
|
FRadiusThingsIterator(fixed_t x, fixed_t y, fixed_t radius);
|
||||||
|
AActor *Next();
|
||||||
|
};
|
||||||
|
|
||||||
#define PT_ADDLINES 1
|
#define PT_ADDLINES 1
|
||||||
#define PT_ADDTHINGS 2
|
#define PT_ADDTHINGS 2
|
||||||
#define PT_EARLYOUT 4
|
|
||||||
|
|
||||||
extern divline_t trace;
|
extern divline_t trace;
|
||||||
|
|
||||||
|
|
602
src/p_map.cpp
602
src/p_map.cpp
|
@ -71,16 +71,11 @@ static void SpawnShootDecal (AActor *t1, const FTraceResults &trace);
|
||||||
static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puff,
|
static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puff,
|
||||||
fixed_t vx, fixed_t vy, fixed_t vz);
|
fixed_t vx, fixed_t vy, fixed_t vz);
|
||||||
|
|
||||||
fixed_t tmbbox[4];
|
|
||||||
AActor *tmthing;
|
AActor *tmthing;
|
||||||
static int tmflags;
|
static int tmflags;
|
||||||
static fixed_t tmx;
|
static fixed_t tmx;
|
||||||
static fixed_t tmy;
|
static fixed_t tmy;
|
||||||
static fixed_t tmz; // [RH] Needed for third dimension of teleporters
|
static fixed_t tmz; // [RH] Needed for third dimension of teleporters
|
||||||
static fixed_t pe_x; // Pain Elemental position for Lost Soul checks // phares
|
|
||||||
static fixed_t pe_y; // Pain Elemental position for Lost Soul checks // phares
|
|
||||||
static fixed_t ls_x; // Lost Soul position for Lost Soul checks // phares
|
|
||||||
static fixed_t ls_y; // Lost Soul position for Lost Soul checks // phares
|
|
||||||
|
|
||||||
static FRandom pr_tracebleed ("TraceBleed");
|
static FRandom pr_tracebleed ("TraceBleed");
|
||||||
static FRandom pr_checkthing ("CheckThing");
|
static FRandom pr_checkthing ("CheckThing");
|
||||||
|
@ -140,7 +135,7 @@ AActor *LastRipped;
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static bool PIT_FindFloorCeiling (line_t *ld, AActor *tmfthing, const FBoundingBox &box, fixed_t tmx, fixed_t tmy)
|
static bool PIT_FindFloorCeiling (line_t *ld, AActor *tmfthing, const FBoundingBox &box, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
if (box.Right() <= ld->bbox[BOXLEFT]
|
if (box.Right() <= ld->bbox[BOXLEFT]
|
||||||
|| box.Left() >= ld->bbox[BOXRIGHT]
|
|| box.Left() >= ld->bbox[BOXRIGHT]
|
||||||
|
@ -167,19 +162,19 @@ static bool PIT_FindFloorCeiling (line_t *ld, AActor *tmfthing, const FBoundingB
|
||||||
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
|
(ld->frontsector->ceilingplane.a | ld->frontsector->ceilingplane.b) |
|
||||||
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
|
(ld->backsector->ceilingplane.a | ld->backsector->ceilingplane.b)) == 0)
|
||||||
{
|
{
|
||||||
P_LineOpening (open, tmfthing, ld, sx=tmx, sy=tmy, tmx, tmy);
|
P_LineOpening (open, tmfthing, ld, sx=x, sy=y, x, y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Find the point on the line closest to the actor's center, and use
|
{ // Find the point on the line closest to the actor's center, and use
|
||||||
// that to calculate openings
|
// that to calculate openings
|
||||||
float dx = (float)ld->dx;
|
float dx = (float)ld->dx;
|
||||||
float dy = (float)ld->dy;
|
float dy = (float)ld->dy;
|
||||||
fixed_t r = (fixed_t)(((float)(tmx - ld->v1->x) * dx +
|
fixed_t r = (fixed_t)(((float)(x - ld->v1->x) * dx +
|
||||||
(float)(tmy - ld->v1->y) * dy) /
|
(float)(y - ld->v1->y) * dy) /
|
||||||
(dx*dx + dy*dy) * 16777216.f);
|
(dx*dx + dy*dy) * 16777216.f);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
{
|
{
|
||||||
P_LineOpening (open, tmfthing, ld, sx=ld->v1->x, sy=ld->v1->y, tmx, tmy);
|
P_LineOpening (open, tmfthing, ld, sx=ld->v1->x, sy=ld->v1->y, x, y);
|
||||||
}
|
}
|
||||||
else if (r >= (1<<24))
|
else if (r >= (1<<24))
|
||||||
{
|
{
|
||||||
|
@ -188,7 +183,7 @@ static bool PIT_FindFloorCeiling (line_t *ld, AActor *tmfthing, const FBoundingB
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_LineOpening (open, tmfthing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx),
|
P_LineOpening (open, tmfthing, ld, sx=ld->v1->x + MulScale24 (r, ld->dx),
|
||||||
sy=ld->v1->y + MulScale24 (r, ld->dy), tmx, tmy);
|
sy=ld->v1->y + MulScale24 (r, ld->dy), x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,54 +248,6 @@ void P_FindFloorCeiling (AActor *actor)
|
||||||
// TELEPORT MOVE
|
// TELEPORT MOVE
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
|
||||||
// PIT_StompThing
|
|
||||||
//
|
|
||||||
static bool StompAlwaysFrags;
|
|
||||||
|
|
||||||
bool PIT_StompThing (AActor *thing)
|
|
||||||
{
|
|
||||||
fixed_t blockdist;
|
|
||||||
|
|
||||||
if (!(thing->flags & MF_SHOOTABLE))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// don't clip against self
|
|
||||||
if (thing == tmthing)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
blockdist = thing->radius + tmthing->radius;
|
|
||||||
|
|
||||||
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
|
|
||||||
{
|
|
||||||
// didn't hit it
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RH] Z-Check
|
|
||||||
// But not if not MF2_PASSMOBJ or MF3_DONTOVERLAP are set!
|
|
||||||
// Otherwise those things would get stuck inside each other.
|
|
||||||
if ((tmthing->flags2 & MF2_PASSMOBJ || thing->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
|
|
||||||
{
|
|
||||||
if (!(thing->flags3 & tmthing->flags3 & MF3_DONTOVERLAP))
|
|
||||||
{
|
|
||||||
if (tmz > thing->z + thing->height)
|
|
||||||
return true; // overhead
|
|
||||||
if (tmz+tmthing->height < thing->z)
|
|
||||||
return true; // underneath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// monsters don't stomp things except on boss level
|
|
||||||
// [RH] Some Heretic/Hexen monsters can telestomp
|
|
||||||
if (StompAlwaysFrags || (tmthing->flags2 & MF2_TELESTOMP))
|
|
||||||
{
|
|
||||||
P_DamageMobj (thing, tmthing, tmthing, 1000000, NAME_Telefrag);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_TeleportMove
|
// P_TeleportMove
|
||||||
//
|
//
|
||||||
|
@ -312,29 +259,9 @@ bool PIT_StompThing (AActor *thing)
|
||||||
// was being teleported between two non-overlapping height ranges.
|
// was being teleported between two non-overlapping height ranges.
|
||||||
bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag)
|
bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag)
|
||||||
{
|
{
|
||||||
static TArray<AActor *> telebt;
|
|
||||||
|
|
||||||
int xl;
|
|
||||||
int xh;
|
|
||||||
int yl;
|
|
||||||
int yh;
|
|
||||||
int bx;
|
|
||||||
int by;
|
|
||||||
|
|
||||||
sector_t* newsec;
|
sector_t* newsec;
|
||||||
|
|
||||||
// kill anything occupying the position
|
// kill anything occupying the position
|
||||||
tmthing = thing;
|
|
||||||
tmflags = thing->flags;
|
|
||||||
|
|
||||||
tmx = x;
|
|
||||||
tmy = y;
|
|
||||||
tmz = z;
|
|
||||||
|
|
||||||
tmbbox[BOXTOP] = y + tmthing->radius;
|
|
||||||
tmbbox[BOXBOTTOM] = y - tmthing->radius;
|
|
||||||
tmbbox[BOXRIGHT] = x + tmthing->radius;
|
|
||||||
tmbbox[BOXLEFT] = x - tmthing->radius;
|
|
||||||
|
|
||||||
newsec = P_PointInSector (x,y);
|
newsec = P_PointInSector (x,y);
|
||||||
ceilingline = NULL;
|
ceilingline = NULL;
|
||||||
|
@ -348,11 +275,9 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr
|
||||||
tmfceilingpic = newsec->ceilingpic;
|
tmfceilingpic = newsec->ceilingpic;
|
||||||
tmfceilingsector = newsec;
|
tmfceilingsector = newsec;
|
||||||
|
|
||||||
validcount++;
|
|
||||||
spechit.Clear ();
|
spechit.Clear ();
|
||||||
telebt.Clear();
|
|
||||||
|
|
||||||
StompAlwaysFrags = tmthing->player || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag;
|
bool StompAlwaysFrags = thing->player || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag;
|
||||||
|
|
||||||
FBoundingBox box(x, y, thing->radius);
|
FBoundingBox box(x, y, thing->radius);
|
||||||
FBlockLinesIterator it(box);
|
FBlockLinesIterator it(box);
|
||||||
|
@ -373,23 +298,40 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr
|
||||||
int savecpic = tmffloorpic;
|
int savecpic = tmffloorpic;
|
||||||
fixed_t savedropoff = tmfdropoffz;
|
fixed_t savedropoff = tmfdropoffz;
|
||||||
|
|
||||||
// stomp on any things contacted
|
FRadiusThingsIterator it2(x, y, thing->radius);
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
AActor *th;
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
|
|
||||||
// stomp on any things contacted
|
while ((th = it2.Next()))
|
||||||
for (bx=xl ; bx<=xh ; bx++)
|
|
||||||
{
|
{
|
||||||
for (by=yl ; by<=yh ; by++)
|
if (!(th->flags & MF_SHOOTABLE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// don't clip against self
|
||||||
|
if (th == thing)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// [RH] Z-Check
|
||||||
|
// But not if not MF2_PASSMOBJ or MF3_DONTOVERLAP are set!
|
||||||
|
// Otherwise those things would get stuck inside each other.
|
||||||
|
if ((thing->flags2 & MF2_PASSMOBJ || th->flags4 & MF4_ACTLIKEBRIDGE) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
|
||||||
{
|
{
|
||||||
if (!P_BlockThingsIterator(bx,by,PIT_StompThing,telebt))
|
if (!(th->flags3 & thing->flags3 & MF3_DONTOVERLAP))
|
||||||
{
|
{
|
||||||
|
if (z > th->z + th->height || // overhead
|
||||||
|
z+thing->height < th->z) // underneath
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// monsters don't stomp things except on boss level
|
||||||
|
// [RH] Some Heretic/Hexen monsters can telestomp
|
||||||
|
if (StompAlwaysFrags || (thing->flags2 & MF2_TELESTOMP))
|
||||||
|
{
|
||||||
|
P_DamageMobj (th, thing, thing, 1000000, NAME_Telefrag);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the move is ok, so link the thing into its new position
|
// the move is ok, so link the thing into its new position
|
||||||
thing->SetOrigin (x, y, z);
|
thing->SetOrigin (x, y, z);
|
||||||
|
@ -424,72 +366,30 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr
|
||||||
// Like P_TeleportMove, but it doesn't move anything, and only monsters and other
|
// Like P_TeleportMove, but it doesn't move anything, and only monsters and other
|
||||||
// players get telefragged.
|
// players get telefragged.
|
||||||
//
|
//
|
||||||
bool PIT_StompThing2 (AActor *thing)
|
|
||||||
{
|
|
||||||
fixed_t blockdist;
|
|
||||||
|
|
||||||
if (!(thing->flags & MF_SHOOTABLE))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// don't clip against self, and don't kill your own voodoo dolls
|
|
||||||
if (thing == tmthing ||
|
|
||||||
(thing->player == tmthing->player && thing->player != NULL))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// only kill monsters and other players
|
|
||||||
if (thing->player == NULL && !(thing->flags3 & MF3_ISMONSTER))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
blockdist = thing->radius + tmthing->radius;
|
|
||||||
|
|
||||||
if (abs(thing->x - tmthing->x) >= blockdist || abs(thing->y - tmthing->y) >= blockdist)
|
|
||||||
{
|
|
||||||
// didn't hit it
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmthing->z > thing->z + thing->height)
|
|
||||||
return true; // overhead
|
|
||||||
if (tmthing->z + tmthing->height < thing->z)
|
|
||||||
return true; // underneath
|
|
||||||
|
|
||||||
P_DamageMobj (thing, tmthing, tmthing, 1000000, NAME_Telefrag);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void P_PlayerStartStomp (AActor *actor)
|
void P_PlayerStartStomp (AActor *actor)
|
||||||
{
|
{
|
||||||
static TArray<AActor *> telebt;
|
AActor *th;
|
||||||
|
FRadiusThingsIterator it(actor->x, actor->y, actor->radius);
|
||||||
|
|
||||||
int xl;
|
while ((th = it.Next()))
|
||||||
int xh;
|
|
||||||
int yl;
|
|
||||||
int yh;
|
|
||||||
int bx;
|
|
||||||
int by;
|
|
||||||
|
|
||||||
tmthing = actor;
|
|
||||||
tmflags = actor->flags;
|
|
||||||
|
|
||||||
tmbbox[BOXTOP] = actor->y + actor->radius;
|
|
||||||
tmbbox[BOXBOTTOM] = actor->y - actor->radius;
|
|
||||||
tmbbox[BOXRIGHT] = actor->x + actor->radius;
|
|
||||||
tmbbox[BOXLEFT] = actor->x - actor->radius;
|
|
||||||
|
|
||||||
telebt.Clear();
|
|
||||||
|
|
||||||
// stomp on any things contacted
|
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
|
|
||||||
for (bx = xl; bx <= xh; bx++)
|
|
||||||
{
|
{
|
||||||
for (by = yl; by <= yh; by++)
|
if (!(th->flags & MF_SHOOTABLE))
|
||||||
{
|
continue;
|
||||||
P_BlockThingsIterator (bx, by, PIT_StompThing2, telebt);
|
|
||||||
}
|
// don't clip against self, and don't kill your own voodoo dolls
|
||||||
|
if (th == actor || (th->player == actor->player && th->player != NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// only kill monsters and other players
|
||||||
|
if (th->player == NULL && !(th->flags3 & MF3_ISMONSTER))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (actor->z > th->z + th->height)
|
||||||
|
continue; // overhead
|
||||||
|
if (actor->z + actor->height < th->z)
|
||||||
|
continue; // underneath
|
||||||
|
|
||||||
|
P_DamageMobj (th, actor, actor, 1000000, NAME_Telefrag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1072,50 +972,6 @@ bool PIT_CheckThing (AActor *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PIT_CheckOnmobjZ
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool PIT_CheckOnmobjZ (AActor *thing)
|
|
||||||
{
|
|
||||||
if (!(thing->flags & MF_SOLID))
|
|
||||||
{ // Can't hit thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing->flags & (MF_SPECIAL|MF_NOCLIP|MF_CORPSE))
|
|
||||||
{ // [RH] Corpses and specials and noclippers don't block moves
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(thing->flags4 & MF4_ACTLIKEBRIDGE) && (tmthing->flags & MF_SPECIAL))
|
|
||||||
{ // [RH] Only bridges block pickup items
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing == tmthing)
|
|
||||||
{ // Don't clip against self
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (tmthing->z > thing->z+thing->height)
|
|
||||||
{ // over thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (tmthing->z+tmthing->height <= thing->z)
|
|
||||||
{ // under thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (!tmflags && onmobj != NULL && thing->z + thing->height < onmobj->z + onmobj->height)
|
|
||||||
{ // something higher is in the way
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fixed_t blockdist = thing->radius+tmthing->radius;
|
|
||||||
if (abs(thing->x-tmx) >= blockdist || abs(thing->y-tmy) >= blockdist)
|
|
||||||
{ // Didn't hit thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
onmobj = thing;
|
|
||||||
return !tmflags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -1185,9 +1041,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
static TArray<AActor *> checkpbt;
|
static TArray<AActor *> checkpbt;
|
||||||
|
|
||||||
int xl, xh;
|
|
||||||
int yl, yh;
|
|
||||||
int bx, by;
|
|
||||||
sector_t *newsec;
|
sector_t *newsec;
|
||||||
AActor *thingblocker;
|
AActor *thingblocker;
|
||||||
AActor *fakedblocker;
|
AActor *fakedblocker;
|
||||||
|
@ -1201,11 +1054,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
|
|
||||||
FBoundingBox box(x, y, thing->radius);
|
FBoundingBox box(x, y, thing->radius);
|
||||||
|
|
||||||
tmbbox[BOXTOP] = box.Top();
|
|
||||||
tmbbox[BOXBOTTOM] = box.Bottom();
|
|
||||||
tmbbox[BOXRIGHT] = box.Right();
|
|
||||||
tmbbox[BOXLEFT] = box.Left();
|
|
||||||
|
|
||||||
newsec = P_PointInSector (x,y);
|
newsec = P_PointInSector (x,y);
|
||||||
ceilingline = BlockingLine = NULL;
|
ceilingline = BlockingLine = NULL;
|
||||||
|
|
||||||
|
@ -1234,11 +1082,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
// because DActors are grouped into mapblocks
|
// because DActors are grouped into mapblocks
|
||||||
// based on their origin point, and can overlap
|
// based on their origin point, and can overlap
|
||||||
// into adjacent blocks by up to MAXRADIUS units.
|
// into adjacent blocks by up to MAXRADIUS units.
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
|
|
||||||
BlockingMobj = NULL;
|
BlockingMobj = NULL;
|
||||||
thingblocker = NULL;
|
thingblocker = NULL;
|
||||||
fakedblocker = NULL;
|
fakedblocker = NULL;
|
||||||
|
@ -1248,14 +1091,12 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
}
|
}
|
||||||
|
|
||||||
stepthing = NULL;
|
stepthing = NULL;
|
||||||
for (bx = xl; bx <= xh; bx++)
|
|
||||||
|
FRadiusThingsIterator it2(x, y, thing->radius);
|
||||||
|
AActor *th;
|
||||||
|
while ((th = it2.Next()))
|
||||||
{
|
{
|
||||||
for (by = yl; by <= yh; by++)
|
if (!PIT_CheckThing(th))
|
||||||
{
|
|
||||||
AActor *robin = NULL;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!P_BlockThingsIterator (bx, by, PIT_CheckThing, checkpbt, robin))
|
|
||||||
{ // [RH] If a thing can be stepped up on, we need to continue checking
|
{ // [RH] If a thing can be stepped up on, we need to continue checking
|
||||||
// other things in the blocks and see if we hit something that is
|
// other things in the blocks and see if we hit something that is
|
||||||
// definitely blocking. Otherwise, we need to check the lines, or we
|
// definitely blocking. Otherwise, we need to check the lines, or we
|
||||||
|
@ -1273,7 +1114,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
thingblocker = BlockingMobj;
|
thingblocker = BlockingMobj;
|
||||||
}
|
}
|
||||||
robin = BlockingMobj;
|
|
||||||
BlockingMobj = NULL;
|
BlockingMobj = NULL;
|
||||||
}
|
}
|
||||||
else if (thing->player &&
|
else if (thing->player &&
|
||||||
|
@ -1288,7 +1128,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
// Nothing is blocking us, but this actor potentially could
|
// Nothing is blocking us, but this actor potentially could
|
||||||
// if there is something else to step on.
|
// if there is something else to step on.
|
||||||
fakedblocker = BlockingMobj;
|
fakedblocker = BlockingMobj;
|
||||||
robin = BlockingMobj;
|
|
||||||
BlockingMobj = NULL;
|
BlockingMobj = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1297,12 +1136,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
robin = NULL;
|
|
||||||
}
|
|
||||||
} while (robin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check lines
|
// check lines
|
||||||
|
@ -1374,40 +1207,47 @@ AActor *P_CheckOnmobj (AActor *thing)
|
||||||
|
|
||||||
bool P_TestMobjZ (AActor *actor, bool quick)
|
bool P_TestMobjZ (AActor *actor, bool quick)
|
||||||
{
|
{
|
||||||
static TArray<AActor *> mobjzbt;
|
|
||||||
|
|
||||||
int xl,xh,yl,yh,bx,by;
|
|
||||||
fixed_t x, y;
|
|
||||||
|
|
||||||
onmobj = NULL;
|
onmobj = NULL;
|
||||||
if (actor->flags & MF_NOCLIP)
|
if (actor->flags & MF_NOCLIP)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
tmx = x = actor->x;
|
FRadiusThingsIterator it(actor->x, actor->y, actor->radius);
|
||||||
tmy = y = actor->y;
|
AActor *thing;
|
||||||
tmthing = actor;
|
|
||||||
tmflags = quick;
|
|
||||||
|
|
||||||
tmbbox[BOXTOP] = y + actor->radius;
|
while ((thing = it.Next()))
|
||||||
tmbbox[BOXBOTTOM] = y - actor->radius;
|
{
|
||||||
tmbbox[BOXRIGHT] = x + actor->radius;
|
if (!(thing->flags & MF_SOLID))
|
||||||
tmbbox[BOXLEFT] = x - actor->radius;
|
{ // Can't hit thing
|
||||||
//
|
continue;
|
||||||
// the bounding box is extended by MAXRADIUS because actors are grouped
|
}
|
||||||
// into mapblocks based on their origin point, and can overlap into adjacent
|
if (thing->flags & (MF_SPECIAL|MF_NOCLIP|MF_CORPSE))
|
||||||
// blocks by up to MAXRADIUS units
|
{ // [RH] Corpses and specials and noclippers don't block moves
|
||||||
//
|
continue;
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
}
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
if (!(thing->flags4 & MF4_ACTLIKEBRIDGE) && (actor->flags & MF_SPECIAL))
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
{ // [RH] Only bridges block pickup items
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
continue;
|
||||||
|
}
|
||||||
|
if (thing == actor)
|
||||||
|
{ // Don't clip against self
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (actor->z > thing->z+thing->height)
|
||||||
|
{ // over thing
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (actor->z+actor->height <= thing->z)
|
||||||
|
{ // under thing
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!quick && onmobj != NULL && thing->z + thing->height < onmobj->z + onmobj->height)
|
||||||
|
{ // something higher is in the way
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
onmobj = thing;
|
||||||
|
if (quick) break;
|
||||||
|
}
|
||||||
|
|
||||||
mobjzbt.Clear();
|
|
||||||
|
|
||||||
for (bx = xl; bx <= xh; bx++)
|
|
||||||
for (by = yl; by <= yh; by++)
|
|
||||||
if (!P_BlockThingsIterator (bx, by, PIT_CheckOnmobjZ, mobjzbt))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return onmobj == NULL;
|
return onmobj == NULL;
|
||||||
}
|
}
|
||||||
|
@ -3525,16 +3365,6 @@ bool P_UsePuzzleItem (AActor *actor, int itemType)
|
||||||
//
|
//
|
||||||
// RADIUS ATTACK
|
// RADIUS ATTACK
|
||||||
//
|
//
|
||||||
AActor* bombsource;
|
|
||||||
AActor* bombspot;
|
|
||||||
int bombdamage;
|
|
||||||
float bombdamagefloat;
|
|
||||||
int bombdistance;
|
|
||||||
float bombdistancefloat;
|
|
||||||
bool DamageSource;
|
|
||||||
FName bombmod;
|
|
||||||
FVector3 bombvec;
|
|
||||||
bool bombdodamage;
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
|
@ -3555,19 +3385,36 @@ CUSTOM_CVAR (Float, splashfactor, 1.f, CVAR_SERVERINFO)
|
||||||
selfthrustscale = 1.f / self;
|
selfthrustscale = 1.f / self;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PIT_RadiusAttack (AActor *thing)
|
//
|
||||||
|
// P_RadiusAttack
|
||||||
|
// Source is the creature that caused the explosion at spot.
|
||||||
|
//
|
||||||
|
void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int bombdistance, FName bombmod,
|
||||||
|
bool DamageSource, bool bombdodamage)
|
||||||
|
{
|
||||||
|
if (bombdistance <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float bombdistancefloat = 1.f / (float)bombdistance;
|
||||||
|
float bombdamagefloat = (float)bombdamage;
|
||||||
|
FVector3 bombvec(FIXED2FLOAT(bombspot->x), FIXED2FLOAT(bombspot->y), FIXED2FLOAT(bombspot->z));
|
||||||
|
|
||||||
|
FRadiusThingsIterator it(bombspot->x, bombspot->y, bombdistance<<FRACBITS);
|
||||||
|
AActor *thing;
|
||||||
|
|
||||||
|
while ((thing = it.Next()))
|
||||||
{
|
{
|
||||||
if (!(thing->flags & MF_SHOOTABLE) )
|
if (!(thing->flags & MF_SHOOTABLE) )
|
||||||
return true;
|
continue;
|
||||||
|
|
||||||
// Boss spider and cyborg and Heretic's ep >= 2 bosses
|
// Boss spider and cyborg and Heretic's ep >= 2 bosses
|
||||||
// take no damage from concussion.
|
// take no damage from concussion.
|
||||||
if (thing->flags3 & MF3_NORADIUSDMG && !(bombspot->flags4 & MF4_FORCERADIUSDMG))
|
if (thing->flags3 & MF3_NORADIUSDMG && !(bombspot->flags4 & MF4_FORCERADIUSDMG))
|
||||||
return true;
|
continue;
|
||||||
|
|
||||||
if (!DamageSource && thing == bombsource)
|
if (!DamageSource && thing == bombsource)
|
||||||
{ // don't damage the source of the explosion
|
{ // don't damage the source of the explosion
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a much needed option: monsters that fire explosive projectiles cannot
|
// a much needed option: monsters that fire explosive projectiles cannot
|
||||||
|
@ -3577,7 +3424,7 @@ bool PIT_RadiusAttack (AActor *thing)
|
||||||
thing->GetClass() == bombsource->GetClass() &&
|
thing->GetClass() == bombsource->GetClass() &&
|
||||||
!thing->player &&
|
!thing->player &&
|
||||||
bombsource->flags4 & MF4_DONTHURTSPECIES
|
bombsource->flags4 & MF4_DONTHURTSPECIES
|
||||||
) return true;
|
) continue;
|
||||||
|
|
||||||
// Barrels always use the original code, since this makes
|
// Barrels always use the original code, since this makes
|
||||||
// them far too "active." BossBrains also use the old code
|
// them far too "active." BossBrains also use the old code
|
||||||
|
@ -3687,7 +3534,7 @@ bool PIT_RadiusAttack (AActor *thing)
|
||||||
dist = 0;
|
dist = 0;
|
||||||
|
|
||||||
if (dist >= bombdistance)
|
if (dist >= bombdistance)
|
||||||
return true; // out of range
|
continue; // out of range
|
||||||
|
|
||||||
if (P_CheckSight (thing, bombspot, 1))
|
if (P_CheckSight (thing, bombspot, 1))
|
||||||
{ // OK to damage; target is in direct path
|
{ // OK to damage; target is in direct path
|
||||||
|
@ -3702,48 +3549,7 @@ bool PIT_RadiusAttack (AActor *thing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// P_RadiusAttack
|
|
||||||
// Source is the creature that caused the explosion at spot.
|
|
||||||
//
|
|
||||||
void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, FName damageType,
|
|
||||||
bool hurtSource, bool dodamage)
|
|
||||||
{
|
|
||||||
static TArray<AActor *> radbt;
|
|
||||||
|
|
||||||
int x, y;
|
|
||||||
int xl, xh, yl, yh;
|
|
||||||
fixed_t dist;
|
|
||||||
|
|
||||||
if (distance <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dist = (distance + MAXRADIUS)<<FRACBITS;
|
|
||||||
yh = (spot->y + dist - bmaporgy)>>MAPBLOCKSHIFT;
|
|
||||||
yl = (spot->y - dist - bmaporgy)>>MAPBLOCKSHIFT;
|
|
||||||
xh = (spot->x + dist - bmaporgx)>>MAPBLOCKSHIFT;
|
|
||||||
xl = (spot->x - dist - bmaporgx)>>MAPBLOCKSHIFT;
|
|
||||||
bombspot = spot;
|
|
||||||
bombsource = source;
|
|
||||||
bombdamage = damage;
|
|
||||||
bombdistance = distance;
|
|
||||||
bombdistancefloat = 1.f / (float)distance;
|
|
||||||
DamageSource = hurtSource;
|
|
||||||
bombdamagefloat = (float)damage;
|
|
||||||
bombmod = damageType;
|
|
||||||
bombdodamage = dodamage;
|
|
||||||
bombvec.X = FIXED2FLOAT(spot->x);
|
|
||||||
bombvec.Y = FIXED2FLOAT(spot->y);
|
|
||||||
bombvec.Z = FIXED2FLOAT(spot->z);
|
|
||||||
|
|
||||||
radbt.Clear();
|
|
||||||
|
|
||||||
for (y = yl; y <= yh; y++)
|
|
||||||
for (x = xl; x <= xh; x++)
|
|
||||||
P_BlockThingsIterator (x, y, PIT_RadiusAttack, radbt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3812,72 +3618,6 @@ bool P_AdjustFloorCeil (AActor *thing, FChangePosition *cpos)
|
||||||
return isgood;
|
return isgood;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
//
|
|
||||||
// PIT_FindAboveIntersectors
|
|
||||||
//
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
bool PIT_FindAboveIntersectors (AActor *thing)
|
|
||||||
{
|
|
||||||
if (!(thing->flags & MF_SOLID))
|
|
||||||
{ // Can't hit thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing->flags & (MF_CORPSE|MF_SPECIAL))
|
|
||||||
{ // [RH] Corpses and specials don't block moves
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing == tmthing)
|
|
||||||
{ // Don't clip against self
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fixed_t blockdist = thing->radius+tmthing->radius;
|
|
||||||
if (abs(thing->x-tmx) >= blockdist || abs(thing->y-tmy) >= blockdist)
|
|
||||||
{ // Didn't hit thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing->z >= tmthing->z &&
|
|
||||||
thing->z <= tmthing->z + tmthing->height)
|
|
||||||
{ // Thing intersects above the base
|
|
||||||
intersectors.Push (thing);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
//
|
|
||||||
// PIT_FindBelowIntersectors
|
|
||||||
//
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
bool PIT_FindBelowIntersectors (AActor *thing)
|
|
||||||
{
|
|
||||||
if (!(thing->flags & MF_SOLID))
|
|
||||||
{ // Can't hit thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing->flags & (MF_CORPSE|MF_SPECIAL))
|
|
||||||
{ // [RH] Corpses and specials don't block moves
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing == tmthing)
|
|
||||||
{ // Don't clip against self
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fixed_t blockdist = thing->radius+tmthing->radius;
|
|
||||||
if (abs(thing->x-tmx) >= blockdist || abs(thing->y-tmy) >= blockdist)
|
|
||||||
{ // Didn't hit thing
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (thing->z + thing->height <= tmthing->z + tmthing->height &&
|
|
||||||
thing->z + thing->height > tmthing->z)
|
|
||||||
{ // Thing intersects below the base
|
|
||||||
intersectors.Push (thing);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
// P_FindAboveIntersectors
|
// P_FindAboveIntersectors
|
||||||
|
@ -3886,43 +3626,34 @@ bool PIT_FindBelowIntersectors (AActor *thing)
|
||||||
|
|
||||||
void P_FindAboveIntersectors (AActor *actor)
|
void P_FindAboveIntersectors (AActor *actor)
|
||||||
{
|
{
|
||||||
static TArray<AActor *> abovebt;
|
|
||||||
|
|
||||||
int xl,xh,yl,yh,bx,by;
|
|
||||||
fixed_t x, y;
|
|
||||||
|
|
||||||
if (actor->flags & MF_NOCLIP)
|
if (actor->flags & MF_NOCLIP)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(actor->flags & MF_SOLID))
|
if (!(actor->flags & MF_SOLID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmx = x = actor->x;
|
AActor *thing;
|
||||||
tmy = y = actor->y;
|
FRadiusThingsIterator it(actor->x, actor->y, actor->radius);
|
||||||
tmthing = actor;
|
while ((thing = it.Next()))
|
||||||
|
{
|
||||||
tmbbox[BOXTOP] = y + actor->radius;
|
if (!(thing->flags & MF_SOLID))
|
||||||
tmbbox[BOXBOTTOM] = y - actor->radius;
|
{ // Can't hit thing
|
||||||
tmbbox[BOXRIGHT] = x + actor->radius;
|
continue;
|
||||||
tmbbox[BOXLEFT] = x - actor->radius;
|
}
|
||||||
//
|
if (thing->flags & (MF_CORPSE|MF_SPECIAL))
|
||||||
// the bounding box is extended by MAXRADIUS because actors are grouped
|
{ // [RH] Corpses and specials don't block moves
|
||||||
// into mapblocks based on their origin point, and can overlap into adjacent
|
continue;
|
||||||
// blocks by up to MAXRADIUS units
|
}
|
||||||
//
|
if (thing == actor)
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
{ // Don't clip against self
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
continue;
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
}
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
if (thing->z >= actor->z &&
|
||||||
|
thing->z <= actor->z + actor->height)
|
||||||
abovebt.Clear();
|
{ // Thing intersects above the base
|
||||||
|
intersectors.Push (thing);
|
||||||
for (bx = xl; bx <= xh; bx++)
|
}
|
||||||
for (by = yl; by <= yh; by++)
|
}
|
||||||
if (!P_BlockThingsIterator (bx, by, PIT_FindAboveIntersectors, abovebt))
|
|
||||||
return;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -3933,43 +3664,34 @@ void P_FindAboveIntersectors (AActor *actor)
|
||||||
|
|
||||||
void P_FindBelowIntersectors (AActor *actor)
|
void P_FindBelowIntersectors (AActor *actor)
|
||||||
{
|
{
|
||||||
static TArray<AActor *> belowbt;
|
|
||||||
|
|
||||||
int xl,xh,yl,yh,bx,by;
|
|
||||||
fixed_t x, y;
|
|
||||||
|
|
||||||
if (actor->flags & MF_NOCLIP)
|
if (actor->flags & MF_NOCLIP)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(actor->flags & MF_SOLID))
|
if (!(actor->flags & MF_SOLID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmx = x = actor->x;
|
AActor *thing;
|
||||||
tmy = y = actor->y;
|
FRadiusThingsIterator it(actor->x, actor->y, actor->radius);
|
||||||
tmthing = actor;
|
while ((thing = it.Next()))
|
||||||
|
{
|
||||||
tmbbox[BOXTOP] = y + actor->radius;
|
if (!(thing->flags & MF_SOLID))
|
||||||
tmbbox[BOXBOTTOM] = y - actor->radius;
|
{ // Can't hit thing
|
||||||
tmbbox[BOXRIGHT] = x + actor->radius;
|
continue;
|
||||||
tmbbox[BOXLEFT] = x - actor->radius;
|
}
|
||||||
//
|
if (thing->flags & (MF_CORPSE|MF_SPECIAL))
|
||||||
// the bounding box is extended by MAXRADIUS because actors are grouped
|
{ // [RH] Corpses and specials don't block moves
|
||||||
// into mapblocks based on their origin point, and can overlap into adjacent
|
continue;
|
||||||
// blocks by up to MAXRADIUS units
|
}
|
||||||
//
|
if (thing == tmthing)
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
{ // Don't clip against self
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
continue;
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
}
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
if (thing->z + thing->height <= actor->z + actor->height &&
|
||||||
|
thing->z + thing->height > actor->z)
|
||||||
belowbt.Clear();
|
{ // Thing intersects below the base
|
||||||
|
intersectors.Push (thing);
|
||||||
for (bx = xl; bx <= xh; bx++)
|
}
|
||||||
for (by = yl; by <= yh; by++)
|
}
|
||||||
if (!P_BlockThingsIterator (bx, by, PIT_FindBelowIntersectors, belowbt))
|
|
||||||
return;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
216
src/p_maputl.cpp
216
src/p_maputl.cpp
|
@ -676,9 +676,11 @@ void FBlockNode::Release ()
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FBlockLinesIterator
|
// FBlockLinesIterator
|
||||||
//
|
//
|
||||||
|
//===========================================================================
|
||||||
extern polyblock_t **PolyBlockMap;
|
extern polyblock_t **PolyBlockMap;
|
||||||
|
|
||||||
FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _maxy, bool keepvalidcount)
|
FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _maxy, bool keepvalidcount)
|
||||||
|
@ -702,12 +704,18 @@ FBlockLinesIterator::FBlockLinesIterator(const FBoundingBox &box)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FBlockLinesIterator :: StartBlock
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
void FBlockLinesIterator::StartBlock(int x, int y)
|
void FBlockLinesIterator::StartBlock(int x, int y)
|
||||||
{
|
|
||||||
if (x >= 0 && y >= 0 && x < bmapwidth && y <bmapheight)
|
|
||||||
{
|
{
|
||||||
curx = x;
|
curx = x;
|
||||||
cury = y;
|
cury = y;
|
||||||
|
if (x >= 0 && y >= 0 && x < bmapwidth && y <bmapheight)
|
||||||
|
{
|
||||||
int offset = y*bmapwidth + x;
|
int offset = y*bmapwidth + x;
|
||||||
polyLink = PolyBlockMap? PolyBlockMap[offset] : NULL;
|
polyLink = PolyBlockMap? PolyBlockMap[offset] : NULL;
|
||||||
polyIndex = 0;
|
polyIndex = 0;
|
||||||
|
@ -725,6 +733,12 @@ void FBlockLinesIterator::StartBlock(int x, int y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FBlockLinesIterator :: Next
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
line_t *FBlockLinesIterator::Next()
|
line_t *FBlockLinesIterator::Next()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -792,66 +806,164 @@ line_t *FBlockLinesIterator::Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// P_BlockThingsIterator
|
// FBlockThingsIterator :: GetCheckArray
|
||||||
//
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
bool P_BlockThingsIterator (int x, int y, bool(*func)(AActor*), TArray<AActor *> &checkarray, AActor *actor)
|
TDeletingArray< FBlockThingsIterator::BTChecked* > FBlockThingsIterator::FreeBTChecked;
|
||||||
|
|
||||||
|
FBlockThingsIterator::BTChecked *FBlockThingsIterator::GetCheckArray()
|
||||||
{
|
{
|
||||||
if ((unsigned int)x >= (unsigned int)bmapwidth ||
|
if (FreeBTChecked.Size() != 0)
|
||||||
(unsigned int)y >= (unsigned int)bmapheight)
|
|
||||||
{
|
{
|
||||||
return true;
|
BTChecked *ret;
|
||||||
|
FreeBTChecked.Pop(ret);
|
||||||
|
ret->Clear();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return new BTChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FBlockThingsIterator :: FreeCheckArray
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void FBlockThingsIterator::FreeCheckArray()
|
||||||
|
{
|
||||||
|
FreeBTChecked.Push(checkarray);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FBlockThingsIterator :: FBlockThingsIterator
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FBlockThingsIterator::FBlockThingsIterator(int _minx, int _miny, int _maxx, int _maxy, TArray<AActor *> *Check)
|
||||||
|
{
|
||||||
|
if (Check != NULL)
|
||||||
|
{
|
||||||
|
checkarray = Check;
|
||||||
|
dontfreecheck = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FBlockNode *block;
|
checkarray = GetCheckArray();
|
||||||
int index = y*bmapwidth + x;
|
}
|
||||||
|
minx = _minx;
|
||||||
|
maxx = _maxx;
|
||||||
|
miny = _miny;
|
||||||
|
maxy = _maxy;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (actor == NULL)
|
FBlockThingsIterator::FBlockThingsIterator(const FBoundingBox &box)
|
||||||
{
|
{
|
||||||
block = blocklinks[index];
|
checkarray = GetCheckArray();
|
||||||
|
maxy = (box.Top() - bmaporgy) >> MAPBLOCKSHIFT;
|
||||||
|
miny = (box.Bottom() - bmaporgy) >> MAPBLOCKSHIFT;
|
||||||
|
maxx = (box.Right() - bmaporgx) >> MAPBLOCKSHIFT;
|
||||||
|
minx = (box.Left() - bmaporgx) >> MAPBLOCKSHIFT;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FBlockThingsIterator :: StartBlock
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void FBlockThingsIterator::StartBlock(int x, int y)
|
||||||
|
{
|
||||||
|
if (x >= 0 && y >= 0 && x < bmapwidth && y <bmapheight)
|
||||||
|
{
|
||||||
|
curx = x;
|
||||||
|
cury = y;
|
||||||
|
block = blocklinks[y*bmapwidth + x];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
block = actor->BlockNode;
|
// invalid block
|
||||||
while (block != NULL && block->BlockIndex != index)
|
block = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FBlockThingsIterator :: Next
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AActor *FBlockThingsIterator::Next()
|
||||||
{
|
{
|
||||||
block = block->NextBlock;
|
while (true)
|
||||||
}
|
|
||||||
if (block != NULL)
|
|
||||||
{
|
{
|
||||||
block = block->NextActor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (block != NULL)
|
while (block != NULL)
|
||||||
{
|
{
|
||||||
FBlockNode *next = block->NextActor;
|
AActor *me = block->Me;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
block = block->NextActor;
|
||||||
// Don't recheck things that were already checked
|
// Don't recheck things that were already checked
|
||||||
for (i = (int)checkarray.Size() - 1; i >= 0; --i)
|
for (i = (int)checkarray->Size() - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
if (checkarray[i] == block->Me)
|
if ((*checkarray)[i] == me)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
{
|
{
|
||||||
checkarray.Push (block->Me);
|
checkarray->Push (me);
|
||||||
if (!func (block->Me))
|
return me;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (++curx > maxx)
|
||||||
|
{
|
||||||
|
curx = minx;
|
||||||
|
if (++cury > maxy) return NULL;
|
||||||
|
}
|
||||||
|
StartBlock(curx, cury);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FRadiusThingsIterator :: Next
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FRadiusThingsIterator::FRadiusThingsIterator(fixed_t x, fixed_t y, fixed_t radius)
|
||||||
|
: FBlockThingsIterator(FBoundingBox(x, y, radius))
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FRadiusThingsIterator :: Next
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
AActor *FRadiusThingsIterator::Next()
|
||||||
|
{
|
||||||
|
AActor *actor;
|
||||||
|
while ((actor = FBlockThingsIterator::Next()))
|
||||||
|
{
|
||||||
|
fixed_t blockdist = actor->radius + Radius;
|
||||||
|
if ( abs(actor->x - X) < blockdist && abs(actor->y - Y) < blockdist)
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -860,7 +972,6 @@ bool P_BlockThingsIterator (int x, int y, bool(*func)(AActor*), TArray<AActor *>
|
||||||
TArray<intercept_t> intercepts (128);
|
TArray<intercept_t> intercepts (128);
|
||||||
|
|
||||||
divline_t trace;
|
divline_t trace;
|
||||||
INTBOOL earlyout;
|
|
||||||
int ptflags;
|
int ptflags;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -871,7 +982,6 @@ int ptflags;
|
||||||
//
|
//
|
||||||
// A line is crossed if its endpoints
|
// A line is crossed if its endpoints
|
||||||
// are on opposite sides of the trace.
|
// are on opposite sides of the trace.
|
||||||
// Returns true if earlyout and a solid line hit.
|
|
||||||
//
|
//
|
||||||
void P_AddLineIntercepts(int bx, int by)
|
void P_AddLineIntercepts(int bx, int by)
|
||||||
{
|
{
|
||||||
|
@ -908,17 +1018,6 @@ void P_AddLineIntercepts(int bx, int by)
|
||||||
|
|
||||||
if (frac < 0) continue; // behind source
|
if (frac < 0) continue; // behind source
|
||||||
|
|
||||||
/* unused code
|
|
||||||
// try to early out the check
|
|
||||||
if (earlyout
|
|
||||||
&& frac < FRACUNIT
|
|
||||||
&& !ld->backsector)
|
|
||||||
{
|
|
||||||
return false; // stop checking
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
intercept_t newintercept;
|
intercept_t newintercept;
|
||||||
|
|
||||||
newintercept.frac = frac;
|
newintercept.frac = frac;
|
||||||
|
@ -932,7 +1031,12 @@ void P_AddLineIntercepts(int bx, int by)
|
||||||
//
|
//
|
||||||
// PIT_AddThingIntercepts
|
// PIT_AddThingIntercepts
|
||||||
//
|
//
|
||||||
bool PIT_AddThingIntercepts (AActor* thing)
|
void P_AddThingIntercepts (int bx, int by, TArray<AActor*> &checkbt)
|
||||||
|
{
|
||||||
|
FBlockThingsIterator it(bx, by, bx, by, &checkbt);
|
||||||
|
AActor *thing;
|
||||||
|
|
||||||
|
while ((thing = it.Next()))
|
||||||
{
|
{
|
||||||
int numfronts = 0;
|
int numfronts = 0;
|
||||||
divline_t line;
|
divline_t line;
|
||||||
|
@ -988,7 +1092,7 @@ bool PIT_AddThingIntercepts (AActor* thing)
|
||||||
fixed_t frac = P_InterceptVector (&trace, &line);
|
fixed_t frac = P_InterceptVector (&trace, &line);
|
||||||
if (frac < 0)
|
if (frac < 0)
|
||||||
{ // behind source
|
{ // behind source
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
intercept_t newintercept;
|
intercept_t newintercept;
|
||||||
|
@ -996,7 +1100,7 @@ bool PIT_AddThingIntercepts (AActor* thing)
|
||||||
newintercept.isaline = false;
|
newintercept.isaline = false;
|
||||||
newintercept.d.thing = thing;
|
newintercept.d.thing = thing;
|
||||||
intercepts.Push (newintercept);
|
intercepts.Push (newintercept);
|
||||||
return true; // keep going
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1010,11 +1114,8 @@ bool PIT_AddThingIntercepts (AActor* thing)
|
||||||
newintercept.isaline = false;
|
newintercept.isaline = false;
|
||||||
newintercept.d.thing = thing;
|
newintercept.d.thing = thing;
|
||||||
intercepts.Push (newintercept);
|
intercepts.Push (newintercept);
|
||||||
return true; // keep going
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Didn't hit it
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1093,8 +1194,6 @@ bool P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags,
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
earlyout = flags & PT_EARLYOUT;
|
|
||||||
|
|
||||||
validcount++;
|
validcount++;
|
||||||
intercepts.Clear ();
|
intercepts.Clear ();
|
||||||
pathbt.Clear ();
|
pathbt.Clear ();
|
||||||
|
@ -1197,8 +1296,7 @@ bool P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags,
|
||||||
|
|
||||||
if (flags & PT_ADDTHINGS)
|
if (flags & PT_ADDTHINGS)
|
||||||
{
|
{
|
||||||
if (!P_BlockThingsIterator (mapx, mapy, PIT_AddThingIntercepts, pathbt))
|
P_AddThingIntercepts(mapx, mapy, pathbt);
|
||||||
return false; // early out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapx == xt2 && mapy == yt2)
|
if (mapx == xt2 && mapy == yt2)
|
||||||
|
@ -1236,9 +1334,8 @@ bool P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags,
|
||||||
|
|
||||||
if (flags & PT_ADDTHINGS)
|
if (flags & PT_ADDTHINGS)
|
||||||
{
|
{
|
||||||
if (!P_BlockThingsIterator (mapx + mapxstep, mapy, PIT_AddThingIntercepts, pathbt) ||
|
P_AddThingIntercepts(mapx + mapxstep, mapy, pathbt);
|
||||||
!P_BlockThingsIterator (mapx, mapy + mapystep, PIT_AddThingIntercepts, pathbt))
|
P_AddThingIntercepts(mapx, mapy + mapystep, pathbt);
|
||||||
return false; // early out
|
|
||||||
}
|
}
|
||||||
xintercept += xstep;
|
xintercept += xstep;
|
||||||
yintercept += ystep;
|
yintercept += ystep;
|
||||||
|
@ -1376,4 +1473,3 @@ static AActor *RoughBlockCheck (AActor *mo, int index)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1684,58 +1684,17 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle,
|
||||||
m_Affectee = affectee;
|
m_Affectee = affectee;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////
|
|
||||||
//
|
|
||||||
// PIT_PushThing determines the angle and magnitude of the effect.
|
|
||||||
// The object's x and y momentum values are changed.
|
|
||||||
//
|
|
||||||
// tmpusher belongs to the point source (MT_PUSH/MT_PULL).
|
|
||||||
//
|
|
||||||
|
|
||||||
DPusher *tmpusher; // pusher structure for blockmap searches
|
|
||||||
|
|
||||||
bool PIT_PushThing (AActor *thing)
|
|
||||||
{
|
|
||||||
if ((thing->flags2 & MF2_WINDTHRUST) && !(thing->flags & MF_NOCLIP))
|
|
||||||
{
|
|
||||||
int sx = tmpusher->m_X;
|
|
||||||
int sy = tmpusher->m_Y;
|
|
||||||
int dist = P_AproxDistance (thing->x - sx,thing->y - sy);
|
|
||||||
int speed = (tmpusher->m_Magnitude -
|
|
||||||
((dist>>FRACBITS)>>1))<<(FRACBITS-PUSH_FACTOR-1);
|
|
||||||
|
|
||||||
// If speed <= 0, you're outside the effective radius. You also have
|
|
||||||
// to be able to see the push/pull source point.
|
|
||||||
|
|
||||||
if ((speed > 0) && (P_CheckSight (thing, tmpusher->m_Source, 1)))
|
|
||||||
{
|
|
||||||
angle_t pushangle = R_PointToAngle2 (thing->x, thing->y, sx, sy);
|
|
||||||
if (tmpusher->m_Source->IsA (RUNTIME_CLASS(APointPusher)))
|
|
||||||
pushangle += ANG180; // away
|
|
||||||
pushangle >>= ANGLETOFINESHIFT;
|
|
||||||
thing->momx += FixedMul (speed, finecosine[pushangle]);
|
|
||||||
thing->momy += FixedMul (speed, finesine[pushangle]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
//
|
//
|
||||||
// T_Pusher looks for all objects that are inside the radius of
|
// T_Pusher looks for all objects that are inside the radius of
|
||||||
// the effect.
|
// the effect.
|
||||||
//
|
//
|
||||||
extern fixed_t tmbbox[4];
|
|
||||||
|
|
||||||
void DPusher::Tick ()
|
void DPusher::Tick ()
|
||||||
{
|
{
|
||||||
static TArray<AActor *> pushbt;
|
|
||||||
sector_t *sec;
|
sector_t *sec;
|
||||||
AActor *thing;
|
AActor *thing;
|
||||||
msecnode_t *node;
|
msecnode_t *node;
|
||||||
int xspeed,yspeed;
|
int xspeed,yspeed;
|
||||||
int xl,xh,yl,yh,bx,by;
|
|
||||||
int radius;
|
|
||||||
int ht;
|
int ht;
|
||||||
|
|
||||||
if (!var_pushers)
|
if (!var_pushers)
|
||||||
|
@ -1773,22 +1732,32 @@ void DPusher::Tick ()
|
||||||
// Seek out all pushable things within the force radius of this
|
// Seek out all pushable things within the force radius of this
|
||||||
// point pusher. Crosses sectors, so use blockmap.
|
// point pusher. Crosses sectors, so use blockmap.
|
||||||
|
|
||||||
tmpusher = this; // MT_PUSH/MT_PULL point source
|
FBlockThingsIterator it(FBoundingBox(m_X, m_Y, m_Radius));
|
||||||
radius = m_Radius; // where force goes to zero
|
AActor *thing;
|
||||||
tmbbox[BOXTOP] = m_Y + radius;
|
|
||||||
tmbbox[BOXBOTTOM] = m_Y - radius;
|
|
||||||
tmbbox[BOXRIGHT] = m_X + radius;
|
|
||||||
tmbbox[BOXLEFT] = m_X - radius;
|
|
||||||
|
|
||||||
pushbt.Clear();
|
while ((thing = it.Next()))
|
||||||
|
{
|
||||||
|
if ((thing->flags2 & MF2_WINDTHRUST) && !(thing->flags & MF_NOCLIP))
|
||||||
|
{
|
||||||
|
int sx = m_X;
|
||||||
|
int sy = m_Y;
|
||||||
|
int dist = P_AproxDistance (thing->x - sx,thing->y - sy);
|
||||||
|
int speed = (m_Magnitude - ((dist>>FRACBITS)>>1))<<(FRACBITS-PUSH_FACTOR-1);
|
||||||
|
|
||||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
// If speed <= 0, you're outside the effective radius. You also have
|
||||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
// to be able to see the push/pull source point.
|
||||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
|
||||||
yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
if ((speed > 0) && (P_CheckSight (thing, m_Source, 1)))
|
||||||
for (bx=xl ; bx<=xh ; bx++)
|
{
|
||||||
for (by=yl ; by<=yh ; by++)
|
angle_t pushangle = R_PointToAngle2 (thing->x, thing->y, sx, sy);
|
||||||
P_BlockThingsIterator (bx, by, PIT_PushThing, pushbt);
|
if (m_Source->IsA (RUNTIME_CLASS(APointPusher)))
|
||||||
|
pushangle += ANG180; // away
|
||||||
|
pushangle >>= ANGLETOFINESHIFT;
|
||||||
|
thing->momx += FixedMul (speed, finecosine[pushangle]);
|
||||||
|
thing->momy += FixedMul (speed, finesine[pushangle]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue