From 6107f36ad225890d9c4da0369bd4c557fb40e3e4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Jan 2018 18:00:55 +0100 Subject: [PATCH] - iterating through portal groups must check for situations where badly constructed maps let items end up in another portal group. --- src/p_maputl.cpp | 27 ++++++++++++++++++--------- src/p_maputl.h | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 24c30375e..6b19942e0 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -809,11 +809,13 @@ bool FMultiBlockLinesIterator::GoUp(double x, double y) { if (!cursector->PortalBlocksMovement(sector_t::ceiling)) { - startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling)); - portalflags = FFCF_NOFLOOR; - return true; + if (startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling))) + { + portalflags = FFCF_NOFLOOR; + return true; + } } - else continueup = false; + continueup = false; } return false; } @@ -830,11 +832,13 @@ bool FMultiBlockLinesIterator::GoDown(double x, double y) { if (!cursector->PortalBlocksMovement(sector_t::floor)) { - startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor)); - portalflags = FFCF_NOCEILING; - return true; + if (startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor))) + { + portalflags = FFCF_NOCEILING; + return true; + } } - else continuedown = false; + continuedown = false; } return false; } @@ -906,14 +910,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) // //=========================================================================== -void FMultiBlockLinesIterator::startIteratorForGroup(int group) +bool FMultiBlockLinesIterator::startIteratorForGroup(int group) { offset = Displacements.getOffset(basegroup, group); offset.X += checkpoint.X; offset.Y += checkpoint.Y; cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset); + // If we ended up in a different group, + // presumably because the spot to be checked is too far outside the actual portal group, + // the search needs to abort. + if (cursector->PortalGroup != group) return false; bbox.setBox(offset.X, offset.Y, checkpoint.Z); blockIterator.init(bbox); + return true; } //=========================================================================== diff --git a/src/p_maputl.h b/src/p_maputl.h index 8ac3ea76a..4dfa99e0f 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -240,7 +240,7 @@ class FMultiBlockLinesIterator bool GoUp(double x, double y); bool GoDown(double x, double y); - void startIteratorForGroup(int group); + bool startIteratorForGroup(int group); public: