From 430915e37731cda019f25b2b8c38cef0a60470ef Mon Sep 17 00:00:00 2001 From: asofold Date: Sun, 26 May 2013 21:10:47 +0200 Subject: [PATCH] [BLEEDING/INCOMPLETE] Attempt to fix issues with blockinteract.visible. Done: Check if the end point of ray-tracing is passable. Problem: Might lead to problems with non-full blocks squeezed between full blocks. Missing: Implement corrected outer bounds getting for use with this. --- .../checks/blockinteract/Visible.java | 55 +++++++++++++++++-- .../nocheatplus/utilities/BlockCache.java | 21 +++++++ .../utilities/BlockProperties.java | 38 +++++++++++-- .../utilities/InteractRayTracing.java | 2 +- 4 files changed, 106 insertions(+), 10 deletions(-) diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/Visible.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/Visible.java index b8703d2b..d131e995 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/Visible.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/Visible.java @@ -11,10 +11,16 @@ import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.utilities.BlockCache; +import fr.neatmonster.nocheatplus.utilities.BlockProperties; import fr.neatmonster.nocheatplus.utilities.InteractRayTracing; public class Visible extends Check { + /** + * Factor for the block-face mod. + */ + private static final double fModFull = 0.6; + private BlockCache blockCache; private final InteractRayTracing rayTracing = new InteractRayTracing(false); @@ -34,6 +40,27 @@ public class Visible extends Check { // Renew the BlockCache instance. blockCache = mcAccess.getBlockCache(null); } + + private static final double getEnd(final double[] bounds, final int index, final int mod){ + if (bounds == null){ + return 0.5 + fModFull * mod; + } + if (mod == 0){ + // TODO: Middle or middle of block ? + return (bounds[index] + bounds[index + 3]) / 2.0; + } + else if (mod == 1){ + // TODO: Slightly outside or dependent on exact position (inside, exact edge, outside)? + return bounds[index + 3]; + } + else if (mod == -1){ + // TODO: Slightly outside or dependent on exact position (inside, exact edge, outside)? + return bounds[index]; + } + else{ + throw new IllegalArgumentException("BlockFace.getModX|Y|Z must be 0, 1 or -1."); + } + } public boolean check(final Player player, final Location loc, final Block block, final BlockFace face, final Action action, final BlockInteractData data, final BlockInteractConfig cc) { @@ -46,12 +73,30 @@ public class Visible extends Check { } else{ blockCache.setAccess(loc.getWorld()); - rayTracing.setBlockCache(blockCache); - rayTracing.set(loc.getX(), loc.getY() + eyeHeight, loc.getZ(), 0.5 + block.getX() + 0.6 * face.getModX(), 0.5 + block.getY() + 0.6 * face.getModY(), 0.5 + block.getZ() + 0.6 * face.getModZ()); - rayTracing.loop(); - collides = rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps(); + + // Guess some end-coordinates. + @SuppressWarnings("deprecation") + final double[] bounds = BlockProperties.getCorrectedBounds(blockCache, block.getX(), block.getY(), block.getZ()); + final int modX = face.getModX(); + final int modY = face.getModY(); + final int modZ = face.getModZ(); + final double eX = (double) block.getX() + getEnd(bounds, 0, modX); + final double eY = (double) block.getY() + getEnd(bounds, 1, modY); + final double eZ = (double) block.getZ() + getEnd(bounds, 2, modZ); + + if (BlockProperties.isPassable(blockCache, eX, eY, eZ, blockCache.getTypeId(eX, eY, eZ))){ + // Perform ray-tracing. + rayTracing.setBlockCache(blockCache); + rayTracing.set(loc.getX(), loc.getY() + eyeHeight, loc.getZ(), eX, eY, eZ); + rayTracing.loop(); + collides = rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps(); + rayTracing.cleanup(); + } + else{ + // Not passable = not possible. + collides = true; + } blockCache.cleanup(); - rayTracing.cleanup(); } if (cc.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){ diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java index 0a54eb28..b131c61e 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockCache.java @@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.utilities; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.entity.Entity; import fr.neatmonster.nocheatplus.utilities.ds.CoordMap; @@ -127,6 +128,26 @@ public abstract class BlockCache { boundsMap.clear(); } + /** + * (convenience method, uses cache). + * @param eX + * @param eY + * @param eZ + * @return + */ + public int getTypeId(double x, double y, double z) { + return getTypeId(Location.locToBlock(x), Location.locToBlock(y), Location.locToBlock(z)); + } + + /** + * (convenience method, uses cache). + * @param block + * @return + */ + public int getTypeId(final Block block) { + return getTypeId(block.getX(), block.getY(), block.getZ()); + } + /** * Get type id with cache access. * @param x diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java index 6db9530b..4c829a7a 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/BlockProperties.java @@ -1899,7 +1899,7 @@ public class BlockProperties { * @return */ public static final boolean collidesBlock(final BlockCache access, final double minX, double minY, final double minZ, final double maxX, final double maxY, final double maxZ, final int x, final int y, final int z, final int id, final double[] bounds, final long flags){ - final double bminX, bminZ, bminY; + final double bminX, bminZ, bminY; final double bmaxX, bmaxY, bmaxZ; // TODO: Consider a quick shortcut checks flags == F_NORMAL_GROUND if ((flags & F_STAIRS) != 0){ // TODO: make this a full block flag ? @@ -1969,9 +1969,39 @@ public class BlockProperties { else if (minY >= bmaxY + y || maxY < bminY + y) return false; else if (minZ >= bmaxZ + z || maxZ < bminZ + z) return false; else return true; - } - + } + /** + * Attempt to return the exact outside bounds, corrected by flags and other. + * @deprecated Not yet for real (only used in certain checks/contexts). + * @param access + * @param x + * @param y + * @param z + * @return + */ + public static double[] getCorrectedBounds(final BlockCache access, final int x, final int y, final int z) { + return getCorrectedBounds(x, y, z, access.getTypeId(x, y, z), access.getBounds(x, y, z)); + } + + /** + * Attempt to return the exact outside bounds, corrected by flags and other. + * @deprecated Not yet for real (only used in certain checks/contexts). + * @param x + * @param y + * @param z + * @param typeId + * @param bounds + * @return + */ + public static double[] getCorrectedBounds(final int x, final int y, final int z, final int id, final double[] bounds) { + if (bounds == null) return null; + //final long flags = blockFlags[id]; + // TODO: IMPLEMENT ! + return null; + } + +/** * Similar to collides(... , F_GROUND), but also checks the block above (against spider).
* NOTE: This does not return true if stuck, to check for that use collidesBlock for the players location. * @param access @@ -1985,7 +2015,7 @@ public class BlockProperties { */ public static final boolean isOnGround(final BlockCache access, final double minX, double minY, final double minZ, final double maxX, final double maxY, final double maxZ){ return isOnGround(access, minX, minY, minZ, maxX, maxY, maxZ, 0L); - } + } /** * Similar to collides(... , F_GROUND), but also checks the block above (against spider).
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InteractRayTracing.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InteractRayTracing.java index c756ee64..c614a775 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InteractRayTracing.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InteractRayTracing.java @@ -3,7 +3,7 @@ package fr.neatmonster.nocheatplus.utilities; import org.bukkit.Location; /** - * Rough ray-tracing for interaction with something. + * Rough ray-tracing for interaction with something. This does not do any smart end-point guessing. * @author mc_dev * */