From 0354b349a01346422d9ce343c2e76eb4dabb1805 Mon Sep 17 00:00:00 2001 From: Eshed Date: Sat, 16 Jul 2016 19:26:52 +0300 Subject: [PATCH] Fix #5302 --- rts/Sim/MoveTypes/MoveDefHandler.cpp | 11 +++----- rts/Sim/MoveTypes/MoveMath/MoveMath.cpp | 34 ++++++++++++++++++++++++- rts/Sim/MoveTypes/MoveMath/MoveMath.h | 1 + 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/rts/Sim/MoveTypes/MoveDefHandler.cpp b/rts/Sim/MoveTypes/MoveDefHandler.cpp index 7b9707e3c85..ef7042e85fb 100644 --- a/rts/Sim/MoveTypes/MoveDefHandler.cpp +++ b/rts/Sim/MoveTypes/MoveDefHandler.cpp @@ -350,13 +350,10 @@ bool MoveDef::TestMoveSquare( // GetPosSpeedMod only checks *one* square of terrain // (heightmap/slopemap/typemap), not the blocking-map - for (int z = zMin; (z <= zMax) && retTestMove; z++) { - for (int x = xMin; (x <= xMax) && retTestMove; x++) { - const CMoveMath::BlockType blockBits = CMoveMath::SquareIsBlocked(*this, xTestMoveSqr + x, zTestMoveSqr + z, collider); - - maxBlockBit |= blockBits; - retTestMove &= (!testObjects || (blockBits & CMoveMath::BLOCK_STRUCTURE) == 0); - } + if (retTestMove) { + const CMoveMath::BlockType blockBits = CMoveMath::RangeIsBlocked(*this, xTestMoveSqr + xMin, xTestMoveSqr + xMax, zTestMoveSqr + zMin, zTestMoveSqr + zMax, collider); + maxBlockBit |= blockBits; + retTestMove &= (!testObjects || (blockBits & CMoveMath::BLOCK_STRUCTURE) == 0); } // don't use std::min or |= because the values might be garbage diff --git a/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp b/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp index d18b9bc3e24..18df17bcde0 100644 --- a/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp +++ b/rts/Sim/MoveTypes/MoveMath/MoveMath.cpp @@ -106,7 +106,6 @@ float CMoveMath::GetPosSpeedMod(const MoveDef& moveDef, unsigned xSquare, unsign /* Check if a given square-position is accessable by the MoveDef footprint. */ CMoveMath::BlockType CMoveMath::IsBlockedNoSpeedModCheck(const MoveDef& moveDef, int xSquare, int zSquare, const CSolidObject* collider) { - BlockType ret = BLOCK_NONE; const int xmin = xSquare - moveDef.xsizeh, xmax = xSquare + moveDef.xsizeh; if ((unsigned)xmin >= mapDims.mapx || (unsigned)xmax >= mapDims.mapx) return BLOCK_IMPASSABLE; @@ -114,6 +113,7 @@ CMoveMath::BlockType CMoveMath::IsBlockedNoSpeedModCheck(const MoveDef& moveDef, if ((unsigned)zmin >= mapDims.mapy || (unsigned)zmax >= mapDims.mapy) return BLOCK_IMPASSABLE; + BlockType ret = BLOCK_NONE; const int xstep = 2, zstep = 2; // (footprints are point-symmetric around ) @@ -252,3 +252,35 @@ CMoveMath::BlockType CMoveMath::SquareIsBlocked(const MoveDef& moveDef, int xSqu return r; } +CMoveMath::BlockType CMoveMath::RangeIsBlocked(const MoveDef& moveDef, int xmin, int xmax, int zmin, int zmax, const CSolidObject* collider) +{ + if ((unsigned)xmin >= mapDims.mapx || (unsigned)xmax >= mapDims.mapx) + return BLOCK_IMPASSABLE; + + if ((unsigned)zmin >= mapDims.mapy || (unsigned)zmax >= mapDims.mapy) + return BLOCK_IMPASSABLE; + + BlockType ret = BLOCK_NONE; + const int xstep = 2, zstep = 2; + const int tempNum = gs->GetTempNum(); + + // (footprints are point-symmetric around ) + for (int z = zmin; z <= zmax; z += zstep) { + const int zOffset = z * mapDims.mapx; + for (int x = xmin; x <= xmax; x += xstep) { + const BlockingMapCell& cell = groundBlockingObjectMap->GetCellUnsafeConst(zOffset + x); + for (CSolidObject* collidee: cell) { + if (collidee->tempNum == tempNum) + continue; + + collidee->tempNum = tempNum; + ret |= ObjectBlockType(moveDef, collidee, collider); + if (ret & BLOCK_STRUCTURE) + return ret; + } + } + } + + return ret; +} + diff --git a/rts/Sim/MoveTypes/MoveMath/MoveMath.h b/rts/Sim/MoveTypes/MoveMath/MoveMath.h index cc5ac77dd54..e844e784161 100644 --- a/rts/Sim/MoveTypes/MoveMath/MoveMath.h +++ b/rts/Sim/MoveTypes/MoveMath/MoveMath.h @@ -70,6 +70,7 @@ class CMoveMath { static BlockType SquareIsBlocked(const MoveDef& moveDef, const float3& pos, const CSolidObject* collider) { return (SquareIsBlocked(moveDef, pos.x / SQUARE_SIZE, pos.z / SQUARE_SIZE, collider)); } + static BlockType RangeIsBlocked(const MoveDef& moveDef, int xmin, int xmax, int zmin, int zmax, const CSolidObject* collider); public: static bool noHoverWaterMove;