From 3f5e0c682eab9e369f65667a43ae86cf35ad5118 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Apr 2016 21:41:58 +0200 Subject: [PATCH] - 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. --- src/p_maputl.cpp | 21 +++++++++++++++------ src/p_sight.cpp | 4 ++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 6279a054f..f51baac16 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -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 FBlockThingsIterator btit; - for (count = 0 ; count < 100 ; count++) + for (count = 0 ; count < 1000 ; count++) { 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); } - if (mapx == xt2 && mapy == yt2) - { + // both coordinates reached the end, so end the traversing. + if ((mapxstep | mapystep) == 0) break; - } + // [RH] Handle corner cases properly instead of pretending they don't exist. switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx)) { case 0: // neither xintercept nor yintercept match! - count = 100; // Stop traversing, because somebody screwed up. + count = 1000; // Stop traversing, because somebody screwed up. break; case 1: // xintercept matches xintercept += xstep; mapy += mapystep; + if (mapy == mapey) + mapystep = 0; break; case 2: // yintercept matches yintercept += ystep; mapx += mapxstep; + if (mapx == mapex) + mapxstep = 0; break; 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 // continues), but the other two blocks adjacent to the corner also need to // be checked. + // Since Doom.exe did not do this, this code won't either if run in compatibility mode. if (!compatible) { if (flags & PT_ADDLINES) @@ -1601,10 +1606,14 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, yintercept += ystep; mapx += mapxstep; mapy += mapystep; + if (mapx == mapex) + mapxstep = 0; + if (mapy == mapey) + mapystep = 0; } 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; } diff --git a/src/p_sight.cpp b/src/p_sight.cpp index b69daa0cf..57106b2cf 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -713,7 +713,7 @@ bool SightCheck::P_SightPathTraverse () // step through map blocks // 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 // 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! sightcounts[5]++; // Continuing won't make things any better, so we might as well stop right here - count = 100; + count = 1000; break; case 1: // xintercept matches