mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-13 07:57:52 +00:00
- fixed: Due to the iteration limit of 100 in the path traverse code, running a trace was effectively limited to somewhere around 12800 map units. Also added the safer exit condition checks from the sight checking code to FPathTraverse.
This commit is contained in:
parent
70b8afc5ec
commit
3f5e0c682e
2 changed files with 17 additions and 8 deletions
|
@ -1545,7 +1545,7 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
|
||||||
|
|
||||||
// we want to use one list of checked actors for the entire operation
|
// we want to use one list of checked actors for the entire operation
|
||||||
FBlockThingsIterator btit;
|
FBlockThingsIterator btit;
|
||||||
for (count = 0 ; count < 100 ; count++)
|
for (count = 0 ; count < 1000 ; count++)
|
||||||
{
|
{
|
||||||
if (flags & PT_ADDLINES)
|
if (flags & PT_ADDLINES)
|
||||||
{
|
{
|
||||||
|
@ -1557,26 +1557,30 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
|
||||||
AddThingIntercepts(mapx, mapy, btit, compatible);
|
AddThingIntercepts(mapx, mapy, btit, compatible);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapx == xt2 && mapy == yt2)
|
// both coordinates reached the end, so end the traversing.
|
||||||
{
|
if ((mapxstep | mapystep) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// [RH] Handle corner cases properly instead of pretending they don't exist.
|
// [RH] Handle corner cases properly instead of pretending they don't exist.
|
||||||
switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx))
|
switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx))
|
||||||
{
|
{
|
||||||
case 0: // neither xintercept nor yintercept match!
|
case 0: // neither xintercept nor yintercept match!
|
||||||
count = 100; // Stop traversing, because somebody screwed up.
|
count = 1000; // Stop traversing, because somebody screwed up.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // xintercept matches
|
case 1: // xintercept matches
|
||||||
xintercept += xstep;
|
xintercept += xstep;
|
||||||
mapy += mapystep;
|
mapy += mapystep;
|
||||||
|
if (mapy == mapey)
|
||||||
|
mapystep = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // yintercept matches
|
case 2: // yintercept matches
|
||||||
yintercept += ystep;
|
yintercept += ystep;
|
||||||
mapx += mapxstep;
|
mapx += mapxstep;
|
||||||
|
if (mapx == mapex)
|
||||||
|
mapxstep = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // xintercept and yintercept both match
|
case 3: // xintercept and yintercept both match
|
||||||
|
@ -1584,6 +1588,7 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
|
||||||
// being entered need to be checked (which will happen when this loop
|
// 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
|
// continues), but the other two blocks adjacent to the corner also need to
|
||||||
// be checked.
|
// be checked.
|
||||||
|
// Since Doom.exe did not do this, this code won't either if run in compatibility mode.
|
||||||
if (!compatible)
|
if (!compatible)
|
||||||
{
|
{
|
||||||
if (flags & PT_ADDLINES)
|
if (flags & PT_ADDLINES)
|
||||||
|
@ -1601,10 +1606,14 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
|
||||||
yintercept += ystep;
|
yintercept += ystep;
|
||||||
mapx += mapxstep;
|
mapx += mapxstep;
|
||||||
mapy += mapystep;
|
mapy += mapystep;
|
||||||
|
if (mapx == mapex)
|
||||||
|
mapxstep = 0;
|
||||||
|
if (mapy == mapey)
|
||||||
|
mapystep = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
count = 100; // Doom originally did not handle this case so do the same in compatibility mode.
|
count = 1000; // Doom originally did not handle this case so do the same in compatibility mode.
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -713,7 +713,7 @@ bool SightCheck::P_SightPathTraverse ()
|
||||||
// step through map blocks
|
// step through map blocks
|
||||||
// Count is present to prevent a round off error from skipping the break
|
// Count is present to prevent a round off error from skipping the break
|
||||||
|
|
||||||
for (count = 0 ; count < 100 ; count++)
|
for (count = 0 ; count < 1000 ; count++)
|
||||||
{
|
{
|
||||||
// end traversing when reaching the end of the blockmap
|
// end traversing when reaching the end of the blockmap
|
||||||
// an early out is not possible because with portals a trace can easily land outside the map's bounds.
|
// an early out is not possible because with portals a trace can easily land outside the map's bounds.
|
||||||
|
@ -737,7 +737,7 @@ bool SightCheck::P_SightPathTraverse ()
|
||||||
case 0: // neither xintercept nor yintercept match!
|
case 0: // neither xintercept nor yintercept match!
|
||||||
sightcounts[5]++;
|
sightcounts[5]++;
|
||||||
// Continuing won't make things any better, so we might as well stop right here
|
// Continuing won't make things any better, so we might as well stop right here
|
||||||
count = 100;
|
count = 1000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // xintercept matches
|
case 1: // xintercept matches
|
||||||
|
|
Loading…
Reference in a new issue