mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 22:51:39 +00:00
- restored original Doom behavior for hitscans to only check actors which have their center in the blockmap cells being checked, compatibility optioned by COMPATF_HITSCAN.
SVN r2341 (trunk)
This commit is contained in:
parent
8f881be0fb
commit
6c4d070095
6 changed files with 83 additions and 76 deletions
|
@ -292,7 +292,7 @@ class FBlockThingsIterator
|
|||
public:
|
||||
FBlockThingsIterator(int minx, int miny, int maxx, int maxy);
|
||||
FBlockThingsIterator(const FBoundingBox &box);
|
||||
AActor *Next();
|
||||
AActor *Next(bool centeronly = false);
|
||||
void Reset() { StartBlock(minx, miny); }
|
||||
};
|
||||
|
||||
|
@ -307,7 +307,7 @@ class FPathTraverse
|
|||
unsigned int count;
|
||||
|
||||
void AddLineIntercepts(int bx, int by);
|
||||
void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it);
|
||||
void AddThingIntercepts(int bx, int by, FBlockThingsIterator &it, bool compatible);
|
||||
public:
|
||||
|
||||
intercept_t *Next();
|
||||
|
@ -320,6 +320,7 @@ public:
|
|||
|
||||
#define PT_ADDLINES 1
|
||||
#define PT_ADDTHINGS 2
|
||||
#define PT_COMPATIBLE 4
|
||||
|
||||
AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params = NULL);
|
||||
AActor *P_RoughMonsterSearch (AActor *mo, int distance);
|
||||
|
|
|
@ -1276,10 +1276,6 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
|
|||
return true;
|
||||
|
||||
// Check things first, possibly picking things up.
|
||||
// The bounding box is extended by MAXRADIUS
|
||||
// because DActors are grouped into mapblocks
|
||||
// based on their origin point, and can overlap
|
||||
// into adjacent blocks by up to MAXRADIUS units.
|
||||
thing->BlockingMobj = NULL;
|
||||
thingblocker = NULL;
|
||||
fakedblocker = NULL;
|
||||
|
@ -2943,7 +2939,7 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in)
|
|||
|
||||
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target)
|
||||
{
|
||||
FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS);
|
||||
FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS|PT_COMPATIBLE);
|
||||
intercept_t *in;
|
||||
|
||||
while ((in = it.Next()))
|
||||
|
@ -3426,9 +3422,12 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
|
|||
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
||||
|
||||
// Hit a thing, so it could be either a puff or blood
|
||||
hitx = t1->x + FixedMul (vx, trace.Distance);
|
||||
hity = t1->y + FixedMul (vy, trace.Distance);
|
||||
hitz = shootz + FixedMul (vz, trace.Distance);
|
||||
fixed_t dist = trace.Distance;
|
||||
// position a bit closer for puffs/blood if using compatibility mode.
|
||||
if (i_compatflags & COMPATF_HITSCAN) dist -= 10*FRACUNIT;
|
||||
hitx = t1->x + FixedMul (vx, dist);
|
||||
hity = t1->y + FixedMul (vy, dist);
|
||||
hitz = shootz + FixedMul (vz, dist);
|
||||
|
||||
// Spawn bullet puffs or blood spots, depending on target type.
|
||||
if ((puffDefaults->flags3 & MF3_PUFFONACTORS) ||
|
||||
|
|
109
src/p_maputl.cpp
109
src/p_maputl.cpp
|
@ -825,7 +825,7 @@ void FBlockThingsIterator::SwitchBlock(int x, int y)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AActor *FBlockThingsIterator::Next()
|
||||
AActor *FBlockThingsIterator::Next(bool centeronly)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
@ -842,37 +842,55 @@ AActor *FBlockThingsIterator::Next()
|
|||
{ // This actor doesn't span blocks, so we know it can only ever be checked once.
|
||||
return me;
|
||||
}
|
||||
size_t hash = ((size_t)me >> 3) % countof(Buckets);
|
||||
for (i = Buckets[hash]; i >= 0; )
|
||||
if (centeronly)
|
||||
{
|
||||
entry = GetHashEntry(i);
|
||||
if (entry->Actor == me)
|
||||
{ // I've already been checked. Skip to the next actor.
|
||||
break;
|
||||
// Block boundaries for compatibility mode
|
||||
fixed_t blockleft = (curx << MAPBLOCKSHIFT) + bmaporgx;
|
||||
fixed_t blockright = blockleft + MAPBLOCKSIZE;
|
||||
fixed_t blockbottom = (cury << MAPBLOCKSHIFT) + bmaporgy;
|
||||
fixed_t blocktop = blockbottom + MAPBLOCKSIZE;
|
||||
|
||||
// only return actors with the center in this block
|
||||
if (me->x >= blockleft && me->x < blockright &&
|
||||
me->y >= blockbottom && me->y < blocktop)
|
||||
{
|
||||
return me;
|
||||
}
|
||||
i = entry->Next;
|
||||
}
|
||||
if (i < 0)
|
||||
{ // Add me to the hash table and return me.
|
||||
if (NumFixedHash < (int)countof(FixedHash))
|
||||
else
|
||||
{
|
||||
size_t hash = ((size_t)me >> 3) % countof(Buckets);
|
||||
for (i = Buckets[hash]; i >= 0; )
|
||||
{
|
||||
entry = &FixedHash[NumFixedHash];
|
||||
entry->Next = Buckets[hash];
|
||||
Buckets[hash] = NumFixedHash++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DynHash.Size() == 0)
|
||||
{
|
||||
DynHash.Grow(50);
|
||||
entry = GetHashEntry(i);
|
||||
if (entry->Actor == me)
|
||||
{ // I've already been checked. Skip to the next actor.
|
||||
break;
|
||||
}
|
||||
i = DynHash.Reserve(1);
|
||||
entry = &DynHash[i];
|
||||
entry->Next = Buckets[hash];
|
||||
Buckets[hash] = i + countof(FixedHash);
|
||||
i = entry->Next;
|
||||
}
|
||||
if (i < 0)
|
||||
{ // Add me to the hash table and return me.
|
||||
if (NumFixedHash < (int)countof(FixedHash))
|
||||
{
|
||||
entry = &FixedHash[NumFixedHash];
|
||||
entry->Next = Buckets[hash];
|
||||
Buckets[hash] = NumFixedHash++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DynHash.Size() == 0)
|
||||
{
|
||||
DynHash.Grow(50);
|
||||
}
|
||||
i = DynHash.Reserve(1);
|
||||
entry = &DynHash[i];
|
||||
entry->Next = Buckets[hash];
|
||||
Buckets[hash] = i + countof(FixedHash);
|
||||
}
|
||||
entry->Actor = me;
|
||||
return me;
|
||||
}
|
||||
entry->Actor = me;
|
||||
return me;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,19 +977,19 @@ void FPathTraverse::AddLineIntercepts(int bx, int by)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it)
|
||||
void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it, bool compatible)
|
||||
{
|
||||
AActor *thing;
|
||||
|
||||
it.SwitchBlock(bx, by);
|
||||
while ((thing = it.Next()))
|
||||
while ((thing = it.Next(compatible)))
|
||||
{
|
||||
int numfronts = 0;
|
||||
divline_t line;
|
||||
int i;
|
||||
|
||||
|
||||
if (!(i_compatflags & COMPATF_HITSCAN))
|
||||
if (!compatible)
|
||||
{
|
||||
// [RH] Don't check a corner to corner crossection for hit.
|
||||
// Instead, check against the actual bounding box (but not if compatibility optioned.)
|
||||
|
@ -1251,6 +1269,8 @@ FPathTraverse::FPathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, in
|
|||
// from skipping the break statement.
|
||||
mapx = xt1;
|
||||
mapy = yt1;
|
||||
|
||||
bool compatible = (flags & PT_COMPATIBLE) && (i_compatflags & COMPATF_HITSCAN);
|
||||
|
||||
// we want to use one list of checked actors for the entire operation
|
||||
FBlockThingsIterator btit;
|
||||
|
@ -1263,7 +1283,7 @@ FPathTraverse::FPathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, in
|
|||
|
||||
if (flags & PT_ADDTHINGS)
|
||||
{
|
||||
AddThingIntercepts(mapx, mapy, btit);
|
||||
AddThingIntercepts(mapx, mapy, btit, compatible);
|
||||
}
|
||||
|
||||
if (mapx == xt2 && mapy == yt2)
|
||||
|
@ -1293,21 +1313,28 @@ FPathTraverse::FPathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, in
|
|||
// 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 (!compatible)
|
||||
{
|
||||
AddLineIntercepts(mapx + mapxstep, mapy);
|
||||
AddLineIntercepts(mapx, mapy + mapystep);
|
||||
if (flags & PT_ADDLINES)
|
||||
{
|
||||
AddLineIntercepts(mapx + mapxstep, mapy);
|
||||
AddLineIntercepts(mapx, mapy + mapystep);
|
||||
}
|
||||
|
||||
if (flags & PT_ADDTHINGS)
|
||||
{
|
||||
AddThingIntercepts(mapx + mapxstep, mapy, btit, false);
|
||||
AddThingIntercepts(mapx, mapy + mapystep, btit, false);
|
||||
}
|
||||
xintercept += xstep;
|
||||
yintercept += ystep;
|
||||
mapx += mapxstep;
|
||||
mapy += mapystep;
|
||||
}
|
||||
|
||||
if (flags & PT_ADDTHINGS)
|
||||
else
|
||||
{
|
||||
AddThingIntercepts(mapx + mapxstep, mapy, btit);
|
||||
AddThingIntercepts(mapx, mapy + mapystep, btit);
|
||||
count = 100; // Doom originally did not handle this case so do the same in compatibility mode.
|
||||
}
|
||||
xintercept += xstep;
|
||||
yintercept += ystep;
|
||||
mapx += mapxstep;
|
||||
mapy += mapystep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3077,26 +3077,6 @@ static void P_GroupLines (bool buildmap)
|
|||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
int block;
|
||||
|
||||
// adjust bounding box to map blocks
|
||||
block = (bbox.Top()-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
block = block >= bmapheight ? bmapheight-1 : block;
|
||||
//sector->blockbox.Top()=block;
|
||||
|
||||
block = (bbox.Bottom()-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
block = block < 0 ? 0 : block;
|
||||
//sector->blockbox.Bottom()=block;
|
||||
|
||||
block = (bbox.Right()-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
block = block >= bmapwidth ? bmapwidth-1 : block;
|
||||
//sector->blockbox.Right()=block;
|
||||
|
||||
block = (bbox.Left()-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
block = block < 0 ? 0 : block;
|
||||
//sector->blockbox.Left()=block;
|
||||
#endif
|
||||
}
|
||||
delete[] linesDoneInEachSector;
|
||||
times[3].Unclock();
|
||||
|
|
|
@ -74,7 +74,7 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector,
|
|||
int ptflags;
|
||||
FTraceInfo inf;
|
||||
|
||||
ptflags = actorMask ? PT_ADDLINES|PT_ADDTHINGS : PT_ADDLINES;
|
||||
ptflags = actorMask ? PT_ADDLINES|PT_ADDTHINGS|PT_COMPATIBLE : PT_ADDLINES;
|
||||
|
||||
inf.StartX = x;
|
||||
inf.StartY = y;
|
||||
|
|
|
@ -1156,10 +1156,10 @@ static bool CheckMobjBlocking (seg_t *seg, FPolyObj *po)
|
|||
|
||||
ld = seg->linedef;
|
||||
|
||||
top = (ld->bbox[BOXTOP]-bmaporgy+MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
bottom = (ld->bbox[BOXBOTTOM]-bmaporgy-MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
left = (ld->bbox[BOXLEFT]-bmaporgx-MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
right = (ld->bbox[BOXRIGHT]-bmaporgx+MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
top = (ld->bbox[BOXTOP]-bmaporgy) >> MAPBLOCKSHIFT;
|
||||
bottom = (ld->bbox[BOXBOTTOM]-bmaporgy) >> MAPBLOCKSHIFT;
|
||||
left = (ld->bbox[BOXLEFT]-bmaporgx) >> MAPBLOCKSHIFT;
|
||||
right = (ld->bbox[BOXRIGHT]-bmaporgx) >> MAPBLOCKSHIFT;
|
||||
|
||||
blocked = false;
|
||||
checker.Clear();
|
||||
|
|
Loading…
Reference in a new issue