From b5e8ee793532751e369badf921083338ecf94e9f Mon Sep 17 00:00:00 2001 From: asofold Date: Thu, 14 Mar 2013 08:27:58 +0100 Subject: [PATCH] Fix PassablRayTracing not respecting block flags. Heavier but more consistent: use BlockProperties.collidesBlock, since we don't really check the blocks bounding box against a ray anyway, but collision with the full moves bounding box. Getting a blocks shape should some day be routed through BlockProperties so the shape is correct from the start. --- .../utilities/BlockProperties.java | 70 +++++++++++++++++++ .../utilities/PassableRayTracing.java | 59 ++-------------- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java b/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java index 53487afc..f78f3904 100644 --- a/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java +++ b/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java @@ -2177,5 +2177,75 @@ public class BlockProperties { blockCache = null; // TODO: might empty mappings... } + + /** + * + * @param access + * @param blockX Block location. + * @param blockY + * @param blockZ + * @param oX Origin / offset from block location. + * @param oY + * @param oZ + * @param dX Direction (multiplied by dT to get end point of move). + * @param dY + * @param dZ + * @param dT + * @return + */ + public static final boolean isPassableRay(final BlockCache access, final int blockX, final int blockY, final int blockZ, final double oX, final double oY, final double oZ, final double dX, final double dY, final double dZ, final double dT) { + final int id = access.getTypeId(blockX, blockY, blockZ); + if (BlockProperties.isPassable(id)) return true; + double[] bounds = access.getBounds(blockX, blockY, blockZ); + if (bounds == null) return true; + + // Simplified check: Only collision of bounds of the full move is checked. + final double minX, maxX; + if (dX < 0){ + minX = dX * dT + oX + blockX; + maxX = oX + blockX; + } + else{ + maxX = dX * dT + oX + blockX; + minX = oX + blockX; + } + final double minY, maxY; + if (dY < 0){ + minY = dY * dT + oY + blockY; + maxY = oY + blockY; + } + else{ + maxY = dY * dT + oY + blockY; + minY = oY + blockY; + } + final double minZ, maxZ; + if (dX < 0){ + minZ = dZ * dT + oZ + blockZ; + maxZ = oZ + blockZ; + } + else{ + maxZ = dZ * dT + oZ + blockZ; + minZ = oZ + blockZ; + } + if (!collidesBlock(access, minX, minY, minZ, maxX, maxY, maxZ, blockX, blockY, blockZ, id, bounds, blockFlags[id])){ + // TODO: Might check for fence too, here. + return true; + } + + // TODO: Actual ray-collision checking? + // TODO: Heuristic workaround for certain situations [might be better outside of this, probably a simplified version ofr the normal case]? + + // Check for workarounds. + // TODO: check f_itchy once exists. + if (BlockProperties.isPassableWorkaround(access, blockX, blockY, blockZ, oX, oY, oZ, id, dX, dY, dZ, dT)){ + return true; + } + // Does collide (most likely). + // TODO: This is not entirely accurate. + // TODO: Moving such that the full move rect overlaps, but no real collision (diagonal moves). + // TODO: "Wrong" moves through edges of blocks (not sure, needs reproducing). + // (Could allow start-end if passable + check first collision time or some estimate.) + return false; + } } diff --git a/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/PassableRayTracing.java b/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/PassableRayTracing.java index f1b2b919..81759af9 100644 --- a/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/PassableRayTracing.java +++ b/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/PassableRayTracing.java @@ -49,61 +49,14 @@ public class PassableRayTracing extends RayTracing{ @Override protected boolean step(final int blockX, final int blockY, final int blockZ, final double oX, final double oY, final double oZ, final double dT) { - final int id = blockCache.getTypeId(blockX, blockY, blockZ); - if (BlockProperties.isPassable(id)) return true; - double[] bounds = blockCache.getBounds(blockX, blockY, blockZ); - if (bounds == null) return true; - - // TODO: Other problem (forgot)... - -// // Check if is already inside. -// // TODO: This might be superfluous since below method used. -// if (oX >= bounds[0] && oX < bounds[3] && oY >= bounds[1] && oY < bounds[4] && oZ >= bounds[2] && oZ < bounds[5]){ -// if (!BlockProperties.isPassableWorkaround(blockCache, blockX, blockY, blockZ, oX, oY, oZ, id, 0, 0, 0, 0)){ -// collides = true; -// return true; -// } -// } - // Check extrapolation [all three intervals must be hit]. - if (dX < 0){ - if (oX < bounds[0]) return true; - else if (oX + dX * dT >= bounds[3]) return true; - } - else{ - if (oX >= bounds[3]) return true; - else if (oX + dX * dT < bounds[0]) return true; - } - if (dY < 0){ - if (oY < bounds[1]) return true; - else if (oY + dY * dT >= bounds[4]) return true; - } - else{ - if (oY >= bounds[4]) return true; - else if (oY + dY * dT < bounds[1]) return true; - } - if (dZ < 0){ - if (oZ < bounds[2]) return true; - else if (oZ + dZ * dT >= bounds[5]) return true; - } - else{ - if (oZ >= bounds[5]) return true; - else if (oZ + dZ * dT < bounds[2]) return true; - } - - // TODO: Heuristic workaround for certain situations [might be better outside of this, probably a simplified version ofr the normal case]? - - // Check for workarounds. - // TODO: check f_itchy once exists. - if (BlockProperties.isPassableWorkaround(blockCache, blockX, blockY, blockZ, oX, oY, oZ, id, dX, dY, dZ, dT)){ + // Just delegate. + if (BlockProperties.isPassableRay(blockCache, blockX, blockY, blockZ, oX, oY, oZ, dX, dY, dZ, dT)){ return true; } - // Does collide (most likely). - // TODO: This is not entirely accurate. - // TODO: Moving such that the full move rect overlaps, but no real collision (diagonal moves). - // TODO: "Wrong" moves through edges of blocks (not sure, needs reproducing). - // (Could allow start-end if passable + check first collision time or some estimate.) - collides = true; - return false; + else{ + collides = true; + return false; + } } }