Reduce false positives with Passable + stairs, move some code.

This commit is contained in:
asofold 2013-09-08 01:17:43 +02:00
parent d365cd5b75
commit ab3770161c

View File

@ -40,10 +40,7 @@ public class Passable extends Check {
final int maxBlockDist = manhattan <= 1 ? manhattan : from.maxBlockDist(to); final int maxBlockDist = manhattan <= 1 ? manhattan : from.maxBlockDist(to);
if (maxBlockDist <= 1 && rayTracing.getStepsDone() == 1 && !from.isPassable()){ if (maxBlockDist <= 1 && rayTracing.getStepsDone() == 1 && !from.isPassable()){
// Redo ray-tracing for moving out of blocks. // Redo ray-tracing for moving out of blocks.
rayTracing.set(from, to); if (collidesIgnoreFirst(from, to)){
rayTracing.setIgnorefirst();
rayTracing.loop();
if (rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps()){
toPassable = false; toPassable = false;
tags = "raytracing_2x_"; tags = "raytracing_2x_";
} }
@ -52,10 +49,12 @@ public class Passable extends Check {
} }
} }
else{ else{
if (!allowsSplitMove(from, to, manhattan)) {
toPassable = false; toPassable = false;
tags = "raytracing_"; tags = "raytracing_";
} }
} }
}
// TODO: Future: If accuracy is demanded, also check the head position (or bounding box right away). // TODO: Future: If accuracy is demanded, also check the head position (or bounding box right away).
rayTracing.cleanup(); rayTracing.cleanup();
} }
@ -66,8 +65,13 @@ public class Passable extends Check {
// (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...) // (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...)
data.passableVL *= 0.99; data.passableVL *= 0.99;
return null; return null;
} else {
return potentialViolation(player, loc, from, to, manhattan, tags, data, cc);
} }
}
private Location potentialViolation(final Player player, Location loc, final PlayerLocation from, final PlayerLocation to, final int manhattan, String tags, final MovingData data, final MovingConfig cc) {
// Moving into a block, possibly a violation. // Moving into a block, possibly a violation.
// Check the players location if different from others. // Check the players location if different from others.
@ -150,4 +154,58 @@ public class Passable extends Check {
} }
} }
/**
* Test collision with ignoring the first block.
* @param from
* @param to
* @return
*/
private boolean collidesIgnoreFirst(PlayerLocation from, PlayerLocation to) {
rayTracing.set(from, to);
rayTracing.setIgnorefirst();
rayTracing.loop();
return rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps();
}
/**
* Test the move split into y-move and horizontal move, provided some pre-conditions are met.
* @param from
* @param to
* @param manhattan
* @return
*/
private boolean allowsSplitMove(final PlayerLocation from, final PlayerLocation to, int manhattan) {
final double yDiff = to.getY() - from.getY() ;
if (manhattan <= 3 && yDiff > 0.0 && Math.abs(yDiff) < 1.0){
// Workaround for client-side calculations not being possible (y vs. horizontal move).
// TODO: Alternative: Test if "real" ray-tracing would fix it (might not!).
if (yDiff > 0.0) {
// y first.
rayTracing.set(from.getX(), from.getY(), from.getZ(), from.getX(), to.getY(), from.getZ());
rayTracing.loop();
if (!rayTracing.collides()) {
// horizontal second.
rayTracing.set(from.getX(), to.getY(), from.getZ(), to.getX(), to.getY(), to.getZ());
rayTracing.loop();
if (!rayTracing.collides()) {
return true;
}
}
} else {
// horizontal first.
rayTracing.set(from.getX(), from.getY(), from.getZ(), to.getX(), from.getY(), to.getZ());
rayTracing.loop();
if (!rayTracing.collides()) {
// y second.
rayTracing.set(to.getX(), from.getY(), to.getZ(), to.getX(), to.getY(), to.getZ());
rayTracing.loop();
if (!rayTracing.collides()) {
return true;
}
}
}
}
return false;
}
} }