diff options
-rw-r--r-- | src/server/game/Movement/Spline/MoveSpline.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 62e4de326b2..10819b81da2 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -218,14 +218,25 @@ bool MoveSplineInitArgs::Validate(Unit* unit) const // each vertex offset packed into 11 bytes bool MoveSplineInitArgs::_checkPathBounds() const { + constexpr float MIN_XY_OFFSET = -(1 << 11) / 4.0f; + constexpr float MIN_Z_OFFSET = -(1 << 10) / 4.0f; + + // positive values have 1 less bit limit (if the highest bit was set, value would be sign extended into negative when decompressing) + constexpr float MAX_XY_OFFSET = (1 << 10) / 4.0f; + constexpr float MAX_Z_OFFSET = (1 << 9) / 4.0f; + + auto isValidPackedXYOffset = [](float coord) -> bool { return coord > MIN_XY_OFFSET && coord < MAX_XY_OFFSET; }; + auto isValidPackedZOffset = [](float coord) -> bool { return coord > MIN_Z_OFFSET && coord < MAX_Z_OFFSET; }; + if (!(flags & MoveSplineFlag::Mask_CatmullRom) && path.size() > 2) { - constexpr float MAX_OFFSET = float((1 << 11) / 2); - Vector3 middle = (path.front()+path.back()) / 2; - for (uint32 i = 1; i < path.size()-1; ++i) + Vector3 middle = (path.front() + path.back()) / 2; + for (uint32 i = 1; i < path.size() - 1; ++i) { - Vector3 offset = path[i] - middle; - if (std::fabs(offset.x) >= MAX_OFFSET || std::fabs(offset.y) >= MAX_OFFSET || std::fabs(offset.z) >= MAX_OFFSET) + // when compression is enabled, each point coord is packed into 11 bits (10 for Z) + if (!isValidPackedXYOffset(middle.x - path[i].x) + || !isValidPackedXYOffset(middle.y - path[i].y) + || !isValidPackedZOffset(middle.z - path[i].z)) { TC_LOG_ERROR("misc", "MoveSplineInitArgs::_checkPathBounds check failed"); return false; |