Workarounds for cobweb and slime blocks.

* Add workaorunds for gravity with exiting cobweb.
* Allow multiple times zero y-distance (cobweb several times, slime 2).

Cobweb may need adjusting the bounding box to check with, instead.
This commit is contained in:
asofold 2015-10-26 00:31:35 +01:00
parent 377689b0bd
commit bb25a0da0b
2 changed files with 74 additions and 12 deletions

View File

@ -131,9 +131,8 @@ public class MovingData extends ACheckData {
* Last valid horizontal distance covered by a move. Integer.MAX_VALUE indicates "not set".
*/
public double lastHDist = Double.MAX_VALUE;
/** Only used during processing, to keep track of sub-checks using velocity. Reset in velocityTick, before checks run. */
/** Just used velocity, during processing of moving checks. */
public SimpleEntry verVelUsed = null;
/** Compatibility entry for bouncing of slime blocks and the like. */
public SimpleEntry verticalBounce = null;
@ -205,6 +204,10 @@ public class MovingData extends ACheckData {
/** Event-counter to cover up for sprinting resetting server side only. Set in the FighListener. */
public int lostSprintCount = 0;
public int sfJumpPhase = 0;
/** Count how many times in a row v-dist has been zero, at very low h-dist (aimed at in-air checks). */
public int sfZeroVdist = 0;
/** Only used during processing, to keep track of sub-checks using velocity. Reset in velocityTick, before checks run. */
/** "Dirty" flag, for receiving velocity and similar while in air. */
private boolean sfDirty = false;
@ -255,6 +258,7 @@ public class MovingData extends ACheckData {
jumpAmplifier = 0;
setBack = null;
lastYDist = lastHDist = Double.MAX_VALUE;
sfZeroVdist = 0;
fromX = toX = Double.MAX_VALUE;
toYaw = Float.MAX_VALUE;
clearAccounting();
@ -314,6 +318,7 @@ public class MovingData extends ACheckData {
clearAccounting();
sfJumpPhase = 0;
lastYDist = lastHDist = Double.MAX_VALUE;
sfZeroVdist = 0;
toWasReset = false;
fromWasReset = false;
verticalBounce = null;
@ -368,6 +373,7 @@ public class MovingData extends ACheckData {
toYaw = yaw;
toPitch = pitch;
lastYDist = lastHDist = Double.MAX_VALUE;
sfZeroVdist = 0;
sfDirty = false;
sfLowJump = false;
liftOffEnvelope = defaultLiftOffEnvelope;

View File

@ -523,6 +523,13 @@ public class SurvivalFly extends Check {
data.fromWasReset = resetFrom || data.noFallAssumeGround;
data.lastFrictionHorizontal = data.nextFrictionHorizontal;
data.lastFrictionVertical = data.nextFrictionVertical;
if (yDistance == 0.0 && hDistance < 0.125) {
// TODO: Check h-dist envelope.
data.sfZeroVdist ++;
} else {
data.sfZeroVdist = 0;
}
// Log tags added after violation handling.
if (data.debug && tags.size() > tagsLength) {
logPostViolationTags(player);
}
@ -732,6 +739,19 @@ public class SurvivalFly extends Check {
double vAllowedDistance = 0.0;
double vDistanceAboveLimit = 0.0;
// Change seen from last yDistance.
final double yDistChange = data.lastYDist == Double.MAX_VALUE ? Double.MAX_VALUE : yDistance - data.lastYDist;
// Hacks.
final boolean envelopeHack;
if (!resetFrom && !resetTo && venvHacks(from, to, yDistance, yDistChange, data)) {
envelopeHack = true;
tags.add("hack_venv");
}
else{
envelopeHack = false;
}
// Relative distance (friction, lift-off).
// Estimate expected yDistance.
// TODO: Friction might need same treatment as with horizontal (medium transitions: data.lastFrictionVertical).
@ -743,7 +763,7 @@ public class SurvivalFly extends Check {
// TODO: Cleanup pending.
final boolean strictVdistRel;
final double maxJumpGain = data.liftOffEnvelope.getMaxJumpGain(data.jumpAmplifier);
final double jumpGainMargin = 0.005; // TODO: Model differently, workarounds where needed. 0.05 interferes with max height vs. velocity (<= 0.47 gain).
final double jumpGainMargin = 0.005; // TODO: Model differently, workarounds where needed. 0.05 interferes with max height vs. velocity (<= 0.47 gain).
if (fallingEnvelope(yDistance, data.lastYDist, 0.0)) {
// Less headache: Always allow falling.
vAllowedDistance = data.lastYDist * FRICTION_MEDIUM_AIR - GRAVITY_MIN; // Upper bound.
@ -788,11 +808,13 @@ public class SurvivalFly extends Check {
// Compare yDistance to expected, use velocity on violation.
// TODO: data.noFallAssumeGround needs more precise flags (refactor to per move data objects, store 123)
boolean vDistRelVL = false;
// Change seen from last yDistance.
final double yDistChange = data.lastYDist == Double.MAX_VALUE ? Double.MAX_VALUE : yDistance - data.lastYDist;
// Difference from vAllowedDistance to yDistance.
final double yDistDiffEx = yDistance - vAllowedDistance;
if (yDistDiffEx > 0.0) { // Upper bound violation.
if (envelopeHack) {
vDistRelVL = false;
//vAllowedDistance = yDistance;
}
else if (yDistDiffEx > 0.0) { // Upper bound violation.
// && (yDistance > 0.0 || (!resetTo && !data.noFallAssumeGround))
if (yDistance <= 0.0 && (resetTo || data.noFallAssumeGround)) {
// Allow falling shorter than expected, if onto ground.
@ -921,9 +943,13 @@ public class SurvivalFly extends Check {
}
}
if (data.sfLowJump) {
tags.add("lowjump");
}
// More in air checks.
// TODO: move into the in air checking above !?
if (!resetFrom && !resetTo) {
if (!envelopeHack && !resetFrom && !resetTo) {
// "On-air" checks (vertical, already use velocity if needed).
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, inAirChecks(now, from, to, hDistance, yDistance, data, cc));
}
@ -951,7 +977,7 @@ public class SurvivalFly extends Check {
// Air-stay-time.
// TODO: max-phase only when from is not reset !?
final int maxJumpPhase = data.liftOffEnvelope.getMaxJumpPhase(data.jumpAmplifier);
if (data.sfJumpPhase > maxJumpPhase && !data.isVelocityJumpPhase()) {
if (!envelopeHack && data.sfJumpPhase > maxJumpPhase && !data.isVelocityJumpPhase()) {
if (yDistance < 0) {
// Ignore falling, and let accounting deal with it.
}
@ -969,6 +995,40 @@ public class SurvivalFly extends Check {
return new double[]{vAllowedDistance, vDistanceAboveLimit};
}
/**
* Vertical envelope "hacks". Directly check for certain transitions, on
* match, skip sub-checks: vdistrel, maxphase, inAirChecks.
*
* @param from
* @param to
* @param yDistance
* @param data
* @return If to skip those sub-checks.
*/
private static boolean venvHacks(final PlayerLocation from, final PlayerLocation to, final double yDistance, final double yDistChange, final MovingData data) {
return
// Intended for cobweb.
// TODO: Bounding box issue ?
data.liftOffEnvelope == LiftOffEnvelope.NO_JUMP && data.sfJumpPhase < 60
&& (
data.lastYDist < 0.0
&& (
// Switch to 0 y-Dist on early jump phase.
yDistance == 0.0 && data.lastYDist < -GRAVITY_ODD / 3.0 && data.lastYDist > -GRAVITY_MIN
// Decrease too few.
|| yDistChange < -GRAVITY_MIN / 3.0 && yDistChange > -GRAVITY_MAX
// Keep negative y-distance (very likely a player height issue).
|| yDistChange == 0.0 && data.lastYDist > -GRAVITY_MAX && data.lastYDist < -GRAVITY_ODD / 3.0
)
// Keep yDist == 0.0 on first falling.
// TODO: Do test if hdist == 0.0 or something small can be assumed.
|| yDistance == 0.0 && data.sfZeroVdist > 0 && data.sfZeroVdist < 10
)
// Jumping on slimes, change viewing direction at the max. height.
|| yDistance == 0.0 && data.sfZeroVdist == 1
&& (data.isVelocityJumpPhase() || data.hasSetBack() && to.getY() - data.getSetBackY() < 1.35);
}
/**
* Odd decrease after lift-off.
* @param to
@ -1146,10 +1206,6 @@ public class SurvivalFly extends Check {
private double inAirChecks(final long now, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final MovingData data, final MovingConfig cc) {
double vDistanceAboveLimit = 0;
if (data.sfLowJump) {
tags.add("lowjump");
}
// y direction change detection.
// TODO: Consider using accounting for y-change detection. <- Nope :).
final boolean yDirChange = data.lastYDist != Double.MAX_VALUE && data.lastYDist != yDistance && (yDistance <= 0 && data.lastYDist >= 0 || yDistance >= 0 && data.lastYDist <= 0 );