diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java
index 259853e8..a31877a8 100644
--- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java
+++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java
@@ -105,13 +105,45 @@ public class SurvivalFly extends Check {
// "Lost ground" workaround.
if (fromOnGround || from.isResetCond()) resetFrom = true;
// TODO: Extra workarounds for toOnGround ?
- else if (lostGround(player, from, to, hDistance, yDistance, sprinting, data, cc)){
- // TODO: Consider && !resetTo ?
- // TODO: Confine by max y distance and min xz-distance?
- resetFrom = true;
+ else{
+ // TODO: Consider if (!resetTo) ?
+ // Check lost-ground workarounds.
+ boolean lostGround = false; // Just used for better overview.
+
+ // TODO: Move more conditions here (!)
+ // TODO: Confine by max y distance and max/min xz-distance?
+ if (yDistance >= -0.5 && yDistance <= 0.52 + data.jumpAmplifier * 0.2){
+ // "Mild" Ascending / descending.
+ // Stairs.
+ // TODO: More safety guards.
+ if (from.isAboveStairs()) {
+ applyLostGround(player, from, true, data, "stairs");
+ lostGround = true;
+ }
+ // Descending.
+ if (!lostGround && yDistance <= 0){
+ if (lostGroundDescend(player, from, to, hDistance, yDistance, sprinting, data, cc)){
+ lostGround = true;
+ }
+ }
+ //Ascending
+ if (!lostGround && yDistance >= 0){
+ if (lostGroundAscend(player, from, to, hDistance, yDistance, sprinting, data, cc)){
+ lostGround = true;
+ }
+ }
+ }
+ else if (yDistance < -0.5){
+ // Clearly descending.
+ if (hDistance <= 0.5){
+ if (lostGroundFastDescend(player, from, to, hDistance, yDistance, sprinting, data, cc)){
+ lostGround = true;
+ }
+ }
+ }
+ resetFrom = lostGround;
// Note: if not setting resetFrom, other places have to check assumeGround...
}
- else resetFrom = false;
// TODO: Account for lift-off medium / if in air [i.e. account for medium + friction]?
// (Might set some margin for buffering if cutting down hAllowedDistance.)
@@ -119,6 +151,7 @@ public class SurvivalFly extends Check {
// Account for flowing liquids (only if needed).
// Assume: If in liquids this would be placed right here.
+ // TODO: Consider data.mediumLiftOff != ...GROUND
if (hDistance > swimmingSpeed && from.isInLiquid() && from.isDownStream(xDistance, zDistance)) {
hAllowedDistance *= modDownStream;
}
@@ -216,22 +249,7 @@ public class SurvivalFly extends Check {
}
}
-
final boolean resetTo = toOnGround || to.isResetCond();
-
-// if (cc.survivalFlyAccountingH && !resetFrom && !resetTo) {
-// // Currently only for "air" phases.
-// // Horizontal.
-// if (data.horizontalFreedom <= 0.001D) {
-// // This only checks general speed decrease once velocity is smoked up.
-// // TODO: account for bunny-hop
-// if (hDistance != 0.0) hDistanceAboveLimit = Math.max(hDistanceAboveLimit, doAccounting(now, hDistance, data.hDistSum, data.hDistCount, tags, "hacc"));
-// } else {
-// // TODO: Just to exclude source of error, might be redundant.
-// data.hDistCount.clear(now);
-// data.hDistSum.clear(now);
-// }
-// }
// Horizontal buffer.
if (hDistanceAboveLimit > 0D && data.sfHorizontalBuffer != 0D) {
@@ -578,128 +596,166 @@ public class SurvivalFly extends Check {
builder.append(" value=" + vel.value + " counter=" + vel.actCount);
}
}
-
+
/**
- * Check if the player might have been on ground due to moving down and jumping up again, but somehow no event showing him on ground has been fired.
+ * Check if a ground-touch has been lost due to event-sending-frequency or other reasons.
+ * This is for ascending only (yDistance >= 0).
* @param player
* @param from
* @param to
+ * @param hDistance
* @param yDistance
+ * @param sprinting
* @param data
* @param cc
* @return
*/
- private boolean lostGround(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
-
- // TODO: fast exclusion returns.
- // TODO: order checks such that most frequent match comes first.
+ private boolean lostGroundAscend(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
// TODO: re-organize for faster exclusions (hDistance, yDistance).
-
- // Check for moving off stairs.
// TODO: more strict conditions ?
- if (from.isAboveStairs()) {
- // TODO: This needs some safety guards.
- // TODO: At least test putting this after yDistance > 0.5 check.
- return applyWorkaround(player, from, true, data, "stairs");
- }
-
- if (yDistance > 0.52 + 0.2 * data.jumpAmplifier){
- // TODO: 0.52 instead of 0.5 - not sure if this helps with sprinting.
- // All following checks are ruled out by this.
- // (This should rarely ever happen, except for velocity and pistons.)
- return false;
- }
- else if (yDistance < -0.5){
- // Too fast falling.
- return false;
- }
final double setBackYDistance = to.getY() - data.getSetBackY();
- if (yDistance <= 0){
- if (data.sfJumpPhase <= 7){
- // Check for sprinting down blocks etc.
- if (data.sfLastYDist <= yDistance && setBackYDistance < 0 && !to.isOnGround()){
- // TODO: setbackydist: <= - 1.0 or similar
- // TODO: <= 7 might work with speed II, not sure with above.
- // TODO: account for speed/sprint
- // TODO: account for half steps !?
- if (from.isOnGround(0.6, 0.4, 0, 0L) ){
- // TODO: further narrow down bounds ?
- // Temporary "fix".
- return applyWorkaround(player, from, true, data, "pyramid");
- }
- }
-
- // Check for jumping up strange blocks like flower pots on top of other blocks.
- if (yDistance == 0 && data.sfLastYDist > 0 && data.sfLastYDist < 0.25 && data.sfJumpPhase <= 6 + data.jumpAmplifier * 3 && setBackYDistance > 1.0 && setBackYDistance < 1.5 + 0.2 * data.jumpAmplifier && !to.isOnGround()){
- // TODO: confine by block types ?
- if (from.isOnGround(0.25, 0.4, 0, 0L) ){
- // Temporary "fix".
- return applyWorkaround(player, from, true, data, "ministep");
- }
- }
- }
- // Lost ground while falling onto/over edges of blocks.
- if (yDistance < 0 && hDistance <= 0.5 && data.sfLastYDist < 0 && yDistance > data.sfLastYDist && !to.isOnGround()){
- // TODO: Should this be an extra lost-ground(to) check, setting toOnGround [for no-fall no difference]?
- // TODO: yDistance <= 0 might be better.
- // Also clear accounting data.
- if (to.isOnGround(0.5) || from.isOnGround(0.5)){
- return applyWorkaround(player, from, true, data, "edge");
- }
+ // Half block step up.
+ if (yDistance <= 0.5 && hDistance < 0.5 && setBackYDistance <= 1.3 + 0.1 * data.jumpAmplifier && to.isOnGround()){
+ if (data.sfLastYDist < 0 || from.isOnGround(0.5 - Math.abs(yDistance))){
+ return applyLostGround(player, from, true, data, "step");
}
}
- if (yDistance >= 0){
- // Half block step up.
- if (yDistance <= 0.5 && hDistance < 0.5 && setBackYDistance <= 1.3 + 0.1 * data.jumpAmplifier && to.isOnGround()){
- if (data.sfLastYDist < 0 || from.isOnGround(0.5 - Math.abs(yDistance))){
- return applyWorkaround(player, from, true, data, "step");
- }
- }
-
- // Interpolation check.
- // TODO: Check if still needed [most expensive...]!
- // TODO: Check if the set-back distance still has relevance.
- // TODO: Interpolation might also be necessary between from and to !
- // TODO: Check use of jump-amplifier.
- // TODO: Might check fall distance.
- if (data.fromX != Double.MAX_VALUE && yDistance > 0 && data.sfLastYDist < 0 && !to.isOnGround()) {
- // TODO: Check if last-y-dist or sprinting should be considered.
- if (setBackYDistance > 0D && setBackYDistance <= 1.5D + 0.2 * data.jumpAmplifier || setBackYDistance < 0 && Math.abs(setBackYDistance) < 3.0) {
- // Interpolate from last to-coordinates to the from
- // coordinates (with some safe-guard).
- final double dX = from.getX() - data.fromX;
- final double dY = from.getY() - data.fromY;
- final double dZ = from.getZ() - data.fromZ;
- if (dX * dX + dY * dY + dZ * dZ < 0.5) {
- // TODO: adjust limit according to ... speed etc ?
- // Check full bounding box since last from.
- final double minY = Math.min(data.toY, Math.min(data.fromY, from.getY()));
- final double iY = minY; // TODO ...
- final double r = from.getWidth() / 2.0; // TODO: check + 0.35;
- double yMargin = cc.yOnGround;
- // TODO: Might set margin higher depending on distance to 0 of block and last y distance etc.
- // TODO: check with iY + 0.25 removed.
- if (BlockProperties.isOnGround(from.getBlockCache(), Math.min(data.fromX, from.getX()) - r, iY - yMargin, Math.min(data.fromZ, from.getZ()) - r, Math.max(data.fromX, from.getX()) + r, iY + 0.25, Math.max(data.fromZ, from.getZ()) + r, 0L)) {
- return applyWorkaround(player, from, true, data, "interpolate");
- }
+ // Interpolation check.
+ // (Still needed, unless a faster workaround is found.)
+ // TODO: Check if the set-back distance still has relevance.
+ // TODO: Check use of jump-amplifier.
+ // TODO: Might check fall distance.
+ // && data.sfJumpPhase > 3 <- Seems to be a problem with cake on a block + jump over both mini edges (...).
+ if (data.fromX != Double.MAX_VALUE && yDistance > 0 && data.sfLastYDist < 0 && !to.isOnGround()) {
+ // TODO: Check if last-y-dist or sprinting should be considered.
+ if (setBackYDistance > 0D && setBackYDistance <= 1.5D + 0.2 * data.jumpAmplifier || setBackYDistance < 0 && Math.abs(setBackYDistance) < 3.0) {
+ // Interpolate from last to-coordinates to the from
+ // coordinates (with some safe-guard).
+ final double dX = from.getX() - data.fromX;
+ final double dY = from.getY() - data.fromY;
+ final double dZ = from.getZ() - data.fromZ;
+ if (dX * dX + dY * dY + dZ * dZ < 0.5) {
+// System.out.println("*** check lostground: INTERPOLATION");
+ // TODO: adjust limit according to ... speed etc ?
+ // Check full bounding box since last from.
+ final double minY = Math.min(data.toY, Math.min(data.fromY, from.getY()));
+ final double iY = minY; // TODO ...
+ final double r = from.getWidth() / 2.0; // TODO: check + 0.35;
+ double yMargin = cc.yOnGround;
+ // TODO: Might set margin higher depending on distance to 0 of block and last y distance etc.
+ // TODO: check with iY + 0.25 removed.
+ if (BlockProperties.isOnGround(from.getBlockCache(), Math.min(data.fromX, from.getX()) - r, iY - yMargin, Math.min(data.fromZ, from.getZ()) - r, Math.max(data.fromX, from.getX()) + r, iY + 0.25, Math.max(data.fromZ, from.getZ()) + r, 0L)) {
+ return applyLostGround(player, from, true, data, "interpolate");
}
}
}
}
-
// Nothing found.
return false;
}
/**
- *
- * @return true.
+ * Check if a ground-touch has been lost due to event-sending-frequency or other reasons.
+ * This is for descending "mildly" only (-0.5 <= yDistance <= 0).
+ * @param player
+ * @param from
+ * @param to
+ * @param hDistance
+ * @param yDistance
+ * @param sprinting
+ * @param data
+ * @param cc
+ * @return
*/
- private boolean applyWorkaround(final Player player, final PlayerLocation from, final boolean setBackSafe, final MovingData data, final String tag){
+ private boolean lostGroundDescend(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
+ // TODO: re-organize for faster exclusions (hDistance, yDistance).
+ // TODO: more strict conditions
+
+ final double setBackYDistance = to.getY() - data.getSetBackY();
+
+ if (data.sfJumpPhase <= 7){
+ // Check for sprinting down blocks etc.
+ if (data.sfLastYDist <= yDistance && setBackYDistance < 0 && !to.isOnGround()){
+ // TODO: setbackydist: <= - 1.0 or similar
+ // TODO: <= 7 might work with speed II, not sure with above.
+ // TODO: account for speed/sprint
+ // TODO: account for half steps !?
+ if (from.isOnGround(0.6, 0.4, 0, 0L) ){
+ // TODO: further narrow down bounds ?
+ // Temporary "fix".
+ return applyLostGround(player, from, true, data, "pyramid");
+ }
+ }
+
+ // Check for jumping up strange blocks like flower pots on top of other blocks.
+ if (yDistance == 0 && data.sfLastYDist > 0 && data.sfLastYDist < 0.25 && data.sfJumpPhase <= 6 + data.jumpAmplifier * 3 && setBackYDistance > 1.0 && setBackYDistance < 1.5 + 0.2 * data.jumpAmplifier && !to.isOnGround()){
+ // TODO: confine by block types ?
+ if (from.isOnGround(0.25, 0.4, 0, 0L) ){
+ // Temporary "fix".
+ return applyLostGround(player, from, true, data, "ministep");
+ }
+ }
+ }
+ // Lost ground while falling onto/over edges of blocks.
+ if (yDistance < 0 && hDistance <= 0.5 && data.sfLastYDist < 0 && yDistance > data.sfLastYDist && !to.isOnGround()){
+ // TODO: Should this be an extra lost-ground(to) check, setting toOnGround [for no-fall no difference]?
+ // TODO: yDistance <= 0 might be better.
+ // Also clear accounting data.
+ if (to.isOnGround(0.5) || from.isOnGround(0.5)){
+ return applyLostGround(player, from, true, data, "edge");
+ }
+ }
+
+ // Nothing found.
+ return false;
+ }
+
+ /**
+ * Check if a ground-touch has been lost due to event-sending-frequency or other reasons.
+ * This is for fast descending only (yDistance < -0.5).
+ * @param player
+ * @param from
+ * @param to
+ * @param hDistance
+ * @param yDistance
+ * @param sprinting
+ * @param data
+ * @param cc
+ * @return
+ */
+ private boolean lostGroundFastDescend(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
+ // TODO: re-organize for faster exclusions (hDistance, yDistance).
+ // TODO: more strict conditions
+ // Lost ground while falling onto/over edges of blocks.
+ if (yDistance > data.sfLastYDist && !to.isOnGround()){
+ // TODO: Should this be an extra lost-ground(to) check, setting toOnGround [for no-fall no difference]?
+ // TODO: yDistance <= 0 might be better.
+ // Also clear accounting data.
+ // TODO: stairs ?
+ // TODO: Can it be safe to only check to with raised margin ? [in fact should be checked from higher yMin down]
+ // TODO: Interpolation method (from to)?
+ if (from.isOnGround(0.5) || to.isOnGround(0.5, Math.min(0.2, 0.01 + hDistance), Math.min(0.1, 0.01 + -yDistance))){
+ // (Usually yDistance should be -0.078)
+ return applyLostGround(player, from, true, data, "fastedge");
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Apply lost-ground workaround,
+ * @param player
+ * @param from
+ * @param setBackSafe If to use from as set-back (if set to false: currently nothing changed).
+ * @param data
+ * @param tag Tag extra to "lostground"
+ * @return Always true.
+ */
+ private boolean applyLostGround(final Player player, final PlayerLocation from, final boolean setBackSafe, final MovingData data, final String tag){
// Set the new setBack and reset the jumpPhase.
// TODO: Some interpolated position ?
// TODO: (Task list: sharpen when this is used, might remove isAboveStairs!)