[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.
This commit is contained in:
asofold 2013-05-26 21:10:47 +02:00
parent 3b22ca2e6a
commit 430915e377
4 changed files with 106 additions and 10 deletions

View File

@ -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);
@ -35,6 +41,27 @@ public class Visible extends Check {
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) {
// TODO: Might confine what to check for (left/right, target blocks depending on item in hand, container blocks).
@ -46,13 +73,31 @@ public class Visible extends Check {
}
else{
blockCache.setAccess(loc.getWorld());
// 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(), 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.set(loc.getX(), loc.getY() + eyeHeight, loc.getZ(), eX, eY, eZ);
rayTracing.loop();
collides = rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps();
blockCache.cleanup();
rayTracing.cleanup();
}
else{
// Not passable = not possible.
collides = true;
}
blockCache.cleanup();
}
if (cc.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
player.sendMessage("Interact visible: " + (action == Action.RIGHT_CLICK_BLOCK ? "right" : "left") + " collide=" + rayTracing.collides());

View File

@ -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

View File

@ -1972,6 +1972,36 @@ public class BlockProperties {
}
/**
* 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).<br>
* NOTE: This does not return true if stuck, to check for that use collidesBlock for the players location.
* @param access

View File

@ -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
*
*/