Index: source/simulation2/components/CCmpRangeManager.cpp =================================================================== --- source/simulation2/components/CCmpRangeManager.cpp +++ source/simulation2/components/CCmpRangeManager.cpp @@ -2179,6 +2179,9 @@ // (so that we never render the sharp edge of the map) i32 j0 = ((pos.Y - visionRange)/(int)TERRAIN_TILE_SIZE).ToInt_RoundToInfinity(); i32 j1 = ((pos.Y + visionRange)/(int)TERRAIN_TILE_SIZE).ToInt_RoundToNegInfinity(); + if (j1 <= j0) + // Make sure that we highlight at least one tile. + j1 = j0 + 1; i32 j0clamp = std::max(j0, 1); i32 j1clamp = std::min(j1, m_TerrainVerticesPerSide-2); @@ -2193,6 +2196,7 @@ i32 xceil = (x + entity_pos_t::Epsilon()).ToInt_RoundToInfinity(); // Initialise the strip (i0, i1) to a rough guess + // Here i1 > i0; i32 i0 = xfloor; i32 i1 = xceil; @@ -2202,16 +2206,17 @@ // the circle's radius (i.e. require dy^2 + dx^2 <= r^2). // When moving the points inwards, clamp them to xceil+1 or xfloor-1 // so they don't accidentally shoot off in the wrong direction forever. + // Also make sure that we have at least one tile difference between i0 and i1 entity_pos_t dy = entity_pos_t::FromInt(j) - y; entity_pos_t dy2 = dy.Square(); while (dy2 + (entity_pos_t::FromInt(i0-1) - x).Square() <= r2) --i0; - while (i0 < xceil && dy2 + (entity_pos_t::FromInt(i0) - x).Square() > r2) + while (i0 < xceil && i0 < i1 - 1 && dy2 + (entity_pos_t::FromInt(i0) - x).Square() > r2) ++i0; while (dy2 + (entity_pos_t::FromInt(i1+1) - x).Square() <= r2) ++i1; - while (i1 > xfloor && dy2 + (entity_pos_t::FromInt(i1) - x).Square() > r2) + while (i1 > xfloor && i1 - 1 > i0 && dy2 + (entity_pos_t::FromInt(i1) - x).Square() > r2) --i1; #if DEBUG_RANGE_MANAGER_BOUNDS