mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-24 12:42:55 +00:00
Add thing argument to P_BlockThingsIterator and P_DoBlockThingsIterate
This commit is contained in:
parent
9c74a73e57
commit
f836f9e145
6 changed files with 116 additions and 43 deletions
|
@ -5582,7 +5582,7 @@ void A_MinusDigging(mobj_t *actor)
|
|||
|
||||
minus = actor;
|
||||
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_MinusCarry);
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_MinusCarry, minus);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -13726,7 +13726,7 @@ void A_DustDevilThink(mobj_t *actor)
|
|||
|
||||
dustdevil = actor;
|
||||
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_DustDevilLaunch);
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_DustDevilLaunch, dustdevil);
|
||||
|
||||
//Whirlwind sound effect.
|
||||
if (leveltime % 70 == 0)
|
||||
|
@ -13842,7 +13842,7 @@ void A_TNTExplode(mobj_t *actor)
|
|||
|
||||
barrel = actor;
|
||||
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_TNTExplode);
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_TNTExplode, barrel);
|
||||
|
||||
// cause a quake -- P_StartQuake does not exist yet
|
||||
epicenter.x = actor->x;
|
||||
|
|
|
@ -2264,7 +2264,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
for (bx = xl; bx <= xh; bx++)
|
||||
for (by = yl; by <= yh; by++)
|
||||
{
|
||||
if (!P_BlockThingsIterator(bx, by, PIT_CheckThing))
|
||||
if (!P_BlockThingsIterator(bx, by, PIT_CheckThing, tmthing))
|
||||
blockval = false;
|
||||
else
|
||||
tmhitthing = tmfloorthing;
|
||||
|
@ -2883,7 +2883,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
standx = x;
|
||||
standy = y;
|
||||
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushableMoved);
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushableMoved, stand);
|
||||
}
|
||||
|
||||
// Link the thing into its new position
|
||||
|
@ -4229,7 +4229,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama
|
|||
bombdamagetype = damagetype;
|
||||
bombsightcheck = sightcheck;
|
||||
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_RadiusAttack);
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_RadiusAttack, bombspot);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
139
src/p_maputl.c
139
src/p_maputl.c
|
@ -1050,10 +1050,14 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
|
|||
//
|
||||
// P_BlockThingsIterator
|
||||
//
|
||||
boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
|
||||
boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *), mobj_t *thing)
|
||||
{
|
||||
mobj_t *bnext = NULL;
|
||||
blocknode_t *block, *next = NULL;
|
||||
|
||||
boolean checkthing = false;
|
||||
if (thing)
|
||||
checkthing = true;
|
||||
|
||||
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
|
||||
return true;
|
||||
|
@ -1071,7 +1075,7 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
|
|||
return false;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemoved(tmthing) // func just popped our tmthing, cannot continue.
|
||||
if ((checkthing && P_MobjWasRemoved(thing)) // func just popped our tmthing, cannot continue.
|
||||
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
|
||||
{
|
||||
P_SetTarget(&bnext, NULL);
|
||||
|
@ -1084,13 +1088,13 @@ boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean (*func)(mobj_t *))
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *))
|
||||
boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *), mobj_t *thing)
|
||||
{
|
||||
boolean status = true;
|
||||
|
||||
for (INT32 bx = x1; bx <= x2; bx++)
|
||||
for (INT32 by = y1; by <= y2; by++)
|
||||
if (!P_BlockThingsIterator(bx, by, func))
|
||||
if (!P_BlockThingsIterator(bx, by, func, thing))
|
||||
status = false;
|
||||
|
||||
return status;
|
||||
|
@ -1463,7 +1467,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
|
|||
INT32 flags, traverser_t trav)
|
||||
{
|
||||
fixed_t xt1, yt1, xt2, yt2;
|
||||
fixed_t xstep, ystep, partial, xintercept, yintercept;
|
||||
fixed_t xstep, ystep, partialx, partialy, xintercept, yintercept;
|
||||
INT32 mapx, mapy, mapxstep, mapystep, count;
|
||||
|
||||
earlyout = flags & PT_EARLYOUT;
|
||||
|
@ -1481,57 +1485,83 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
|
|||
trace.y = py1;
|
||||
trace.dx = px2 - px1;
|
||||
trace.dy = py2 - py1;
|
||||
|
||||
px1 -= bmaporgx;
|
||||
py1 -= bmaporgy;
|
||||
xt1 = (unsigned)px1>>MAPBLOCKSHIFT;
|
||||
yt1 = (unsigned)py1>>MAPBLOCKSHIFT;
|
||||
|
||||
px2 -= bmaporgx;
|
||||
py2 -= bmaporgy;
|
||||
xt2 = (unsigned)px2>>MAPBLOCKSHIFT;
|
||||
yt2 = (unsigned)py2>>MAPBLOCKSHIFT;
|
||||
|
||||
xt1 = px1>>MAPBLOCKSHIFT;
|
||||
yt1 = py2>>MAPBLOCKSHIFT;
|
||||
px1 = (unsigned)(px1 - bmaporgx);
|
||||
py1 = (unsigned)(py1 - bmaporgy);
|
||||
|
||||
xt2 = px2>>MAPBLOCKSHIFT;
|
||||
yt2 = py2>>MAPBLOCKSHIFT;
|
||||
px2 = (unsigned)(px2 - bmaporgx);
|
||||
py2 = (unsigned)(py2 - bmaporgy);
|
||||
|
||||
if (xt2 > xt1)
|
||||
{
|
||||
mapxstep = 1;
|
||||
partial = FRACUNIT - ((px1>>MAPBTOFRAC) & FRACMASK);
|
||||
partialx = FRACUNIT - (((unsigned)px1>>MAPBTOFRAC) & FRACMASK);
|
||||
ystep = FixedDiv(py2 - py1, abs(px2 - px1));
|
||||
}
|
||||
else if (xt2 < xt1)
|
||||
{
|
||||
mapxstep = -1;
|
||||
partial = (px1>>MAPBTOFRAC) & FRACMASK;
|
||||
partialx = ((unsigned)px1>>MAPBTOFRAC) & FRACMASK;
|
||||
ystep = FixedDiv(py2 - py1, abs(px2 - px1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mapxstep = 0;
|
||||
partial = FRACUNIT;
|
||||
partialx = FRACUNIT;
|
||||
ystep = 256*FRACUNIT;
|
||||
}
|
||||
|
||||
yintercept = (py1>>MAPBTOFRAC) + FixedMul(partial, ystep);
|
||||
yintercept = ((unsigned)py1>>MAPBTOFRAC) + FixedMul(partialx, ystep);
|
||||
|
||||
if (yt2 > yt1)
|
||||
{
|
||||
mapystep = 1;
|
||||
partial = FRACUNIT - ((py1>>MAPBTOFRAC) & FRACMASK);
|
||||
partialy = FRACUNIT - (((unsigned)py1>>MAPBTOFRAC) & FRACMASK);
|
||||
xstep = FixedDiv(px2 - px1, abs(py2 - py1));
|
||||
}
|
||||
else if (yt2 < yt1)
|
||||
{
|
||||
mapystep = -1;
|
||||
partial = (py1>>MAPBTOFRAC) & FRACMASK;
|
||||
partialy = ((unsigned)py1>>MAPBTOFRAC) & FRACMASK;
|
||||
xstep = FixedDiv(px2 - px1, abs(py2 - py1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mapystep = 0;
|
||||
partial = FRACUNIT;
|
||||
partialy = FRACUNIT;
|
||||
xstep = 256*FRACUNIT;
|
||||
}
|
||||
xintercept = (px1>>MAPBTOFRAC) + FixedMul(partial, xstep);
|
||||
xintercept = ((unsigned)px1>>MAPBTOFRAC) + FixedMul(partialy, xstep);
|
||||
|
||||
// [RH] Fix for traces that pass only through blockmap corners. In that case,
|
||||
// xintercept and yintercept can both be set ahead of mapx and mapy, so the
|
||||
// for loop would never advance anywhere.
|
||||
|
||||
if (abs(xstep) == 1 && abs(ystep) == 1)
|
||||
{
|
||||
if (ystep < 0)
|
||||
{
|
||||
partialx = FRACUNIT - partialx;
|
||||
}
|
||||
if (xstep < 0)
|
||||
{
|
||||
partialy = FRACUNIT - partialy;
|
||||
}
|
||||
if (partialx == partialy)
|
||||
{
|
||||
xintercept = xt1;
|
||||
yintercept = yt1;
|
||||
}
|
||||
}
|
||||
|
||||
xt1 = (unsigned)px1>>MAPBLOCKSHIFT;
|
||||
yt1 = (unsigned)py1>>MAPBLOCKSHIFT;
|
||||
xt2 = (unsigned)px2>>MAPBLOCKSHIFT;
|
||||
yt2 = (unsigned)py2>>MAPBLOCKSHIFT;
|
||||
|
||||
// Step through map blocks.
|
||||
// Count is present to prevent a round off error
|
||||
|
@ -1546,21 +1576,64 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2,
|
|||
return false; // early out
|
||||
|
||||
if (flags & PT_ADDTHINGS)
|
||||
if (!P_BlockThingsIterator(mapx, mapy, PIT_AddThingIntercepts))
|
||||
if (!P_BlockThingsIterator(mapx, mapy, PIT_AddThingIntercepts, NULL))
|
||||
return false; // early out
|
||||
|
||||
if (mapx == xt2 && mapy == yt2)
|
||||
// both coordinates reached the end, so end the traversing.
|
||||
if ((mapxstep | mapystep) == 0)
|
||||
break;
|
||||
|
||||
if ((yintercept >> FRACBITS) == mapy)
|
||||
// [RH] Handle corner cases properly instead of pretending they don't exist.
|
||||
switch ((((yintercept >> FRACBITS) == mapy) << 1) | ((xintercept >> FRACBITS) == mapx))
|
||||
{
|
||||
yintercept += ystep;
|
||||
mapx += mapxstep;
|
||||
}
|
||||
else if ((xintercept >> FRACBITS) == mapx)
|
||||
{
|
||||
xintercept += xstep;
|
||||
mapy += mapystep;
|
||||
case 0: // neither xintercept nor yintercept match!
|
||||
count = 64; // Stop traversing, because somebody screwed up.
|
||||
break;
|
||||
|
||||
case 1: // xintercept matches
|
||||
xintercept += xstep;
|
||||
mapy += mapystep;
|
||||
if (mapy == yt2)
|
||||
mapystep = 0;
|
||||
break;
|
||||
|
||||
case 2: // yintercept matches
|
||||
yintercept += ystep;
|
||||
mapx += mapxstep;
|
||||
if (mapx == xt2)
|
||||
mapxstep = 0;
|
||||
break;
|
||||
|
||||
case 3: // xintercept and yintercept both match
|
||||
// The trace is exiting a block through its corner. Not only does the block
|
||||
// being entered need to be checked (which will happen when this loop
|
||||
// continues), but the other two blocks adjacent to the corner also need to
|
||||
// be checked.
|
||||
if (flags & PT_ADDLINES)
|
||||
{
|
||||
if (!P_BlockLinesIterator(mapx + mapxstep, mapy, PIT_AddLineIntercepts))
|
||||
return false; // early out
|
||||
if (!P_BlockLinesIterator(mapx, mapy + mapystep, PIT_AddLineIntercepts))
|
||||
return false; // early out
|
||||
}
|
||||
|
||||
if (flags & PT_ADDTHINGS)
|
||||
{
|
||||
if (!P_BlockThingsIterator(mapx + mapxstep, mapy, PIT_AddThingIntercepts, NULL))
|
||||
return false; // early out
|
||||
if (!P_BlockThingsIterator(mapx, mapy + mapystep, PIT_AddThingIntercepts, NULL))
|
||||
return false; // early out
|
||||
}
|
||||
|
||||
xintercept += xstep;
|
||||
yintercept += ystep;
|
||||
mapx += mapxstep;
|
||||
mapy += mapystep;
|
||||
if (mapx == xt2)
|
||||
mapxstep = 0;
|
||||
if (mapy == yt2)
|
||||
mapystep = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Go through the sorted list
|
||||
|
|
|
@ -61,7 +61,7 @@ extern ffloor_t *openfloorrover, *openceilingrover;
|
|||
void P_LineOpening(line_t *plinedef, mobj_t *mobj);
|
||||
|
||||
boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *));
|
||||
boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *));
|
||||
boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *), mobj_t *thing);
|
||||
|
||||
void P_ClearBlockNodes(void);
|
||||
|
||||
|
@ -94,7 +94,7 @@ typedef struct bthingit_s
|
|||
bthingit_t *P_NewBlockThingsIterator(int x1, int y1, int x2, int y2);
|
||||
mobj_t *P_BlockThingsIteratorNext(bthingit_t *it, boolean centeronly);
|
||||
void P_FreeBlockThingsIterator(bthingit_t *it);
|
||||
boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *));
|
||||
boolean P_DoBlockThingsIterate(int x1, int y1, int x2, int y2, boolean (*func)(mobj_t *), mobj_t *thing);
|
||||
|
||||
#define PT_ADDLINES 1
|
||||
#define PT_ADDTHINGS 2
|
||||
|
|
|
@ -9342,7 +9342,7 @@ static void P_PointPushThink(mobj_t *mobj)
|
|||
yl = (unsigned)(mobj->y - radius - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(mobj->y + radius - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushThing);
|
||||
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_PushThing, pushmobj);
|
||||
}
|
||||
|
||||
static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||
|
|
|
@ -4126,7 +4126,7 @@ static void P_DoTeeter(player_t *player)
|
|||
teeteryl = teeteryh = player->mo->y;
|
||||
couldteeter = false;
|
||||
solidteeter = teeter;
|
||||
if (!P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_CheckSolidsTeeter))
|
||||
if (!P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_CheckSolidsTeeter, tmthing))
|
||||
goto teeterdone; // we've found something that stops us teetering at all
|
||||
teeterdone:
|
||||
teeter = solidteeter;
|
||||
|
|
Loading…
Reference in a new issue