SF: Optimization and fixes with bunny and permchecks.

* Currently bunny applies very often on sprinting, thus it can be pre-
  checked before permchecks, and if necessary re-checked after 
  permchecks.
* Remove heuristic permchecks, since the above should do better.
* Fix bunny not trigger for assumeonground && jumpphase == 0.

Further we will try to get rid of the horizontal buffer as we know it,
 confining it to special cases. However we have to extend bunny hop to
 apply without sprinting as well. Might need a more general concept
 for ground-move-modifiers and friction to achieve it.
This commit is contained in:
asofold 2013-07-23 10:43:23 +02:00
parent 9e920b89cb
commit d77c63a228

View File

@ -192,27 +192,17 @@ public class SurvivalFly extends Check {
data.sfOnIce--; data.sfOnIce--;
} }
// Get the allowed distance, first determine if to check permissions already here. // Get the allowed distance.
final boolean permChecksDone; double hAllowedDistance = getAllowedhDist(player, from, to, sprinting, downStream, hDistance, walkSpeed, data, cc, false);
if (hDistance > walkSpeed * modSprint) {
// Simple heuristic.
// Might check other stuff (really sneaking).
permChecksDone = true;
tags.add("permchecks");
}
else {
permChecksDone = false;
}
double hAllowedDistance = getAllowedhDist(player, from, to, sprinting, downStream, hDistance, walkSpeed, data, cc, permChecksDone);
// Judge if horizontal speed is above limit. // Judge if horizontal speed is above limit.
double hDistanceAboveLimit = hDistance - hAllowedDistance; double hDistanceAboveLimit = hDistance - hAllowedDistance;
// Velocity, buffers and after failure checks. // Velocity, buffers and after failure checks.
final double hFreedom; final double hFreedom;
if (hDistanceAboveLimit > 0){ if (hDistanceAboveLimit > 0){
// TODO: Move more of the workarounds (buffer, bunny, ...) into this method. // TODO: Move more of the workarounds (buffer, bunny, ...) into this method.
final double[] res = hDistAfterFailure(player, from, to, walkSpeed, hAllowedDistance, hDistance, hDistanceAboveLimit, yDistance, sprinting, downStream, data, cc, permChecksDone); final double[] res = hDistAfterFailure(player, from, to, walkSpeed, hAllowedDistance, hDistance, hDistanceAboveLimit, yDistance, sprinting, downStream, data, cc, false);
hAllowedDistance = res[0]; hAllowedDistance = res[0];
hDistanceAboveLimit = res[1]; hDistanceAboveLimit = res[1];
hFreedom = res[2]; hFreedom = res[2];
@ -827,73 +817,42 @@ public class SurvivalFly extends Check {
private double[] hDistAfterFailure(final Player player, final PlayerLocation from, final PlayerLocation to, final double walkSpeed, double hAllowedDistance, final double hDistance, double hDistanceAboveLimit, final double yDistance, final boolean sprinting, final boolean downStream, final MovingData data, final MovingConfig cc, final boolean skipPermChecks) { private double[] hDistAfterFailure(final Player player, final PlayerLocation from, final PlayerLocation to, final double walkSpeed, double hAllowedDistance, final double hDistance, double hDistanceAboveLimit, final double yDistance, final boolean sprinting, final boolean downStream, final MovingData data, final MovingConfig cc, final boolean skipPermChecks) {
// TODO: Still not entirely sure about this checking order. // TODO: Still not entirely sure about this checking order.
// TODO: Return on 0 over dist. // TODO: Would quick returns make sense for hDistanceAfterFailure == 0.0?
// TODO: Bunny hop: check here with simplified pre-conditions, if not matching re-check below.
// Test bunny early, because it applies often and destroys as little as possible.
hDistanceAboveLimit = bunnyHop(from, to, hDistance, hAllowedDistance, hDistanceAboveLimit, yDistance, sprinting, data);
// After failure permission checks ( + speed modifier + sneaking + blocking + speeding) and velocity (!). // After failure permission checks ( + speed modifier + sneaking + blocking + speeding) and velocity (!).
if (!skipPermChecks){ if (hDistanceAboveLimit > 0.0 && !skipPermChecks) {
// TODO: Most cases these will not apply. Consider redesign to do these last or checking right away and skip here on some conditions. // TODO: Most cases these will not apply. Consider redesign to do these last or checking right away and skip here on some conditions.
hAllowedDistance = getAllowedhDist(player, from, to, sprinting, downStream, hDistance, walkSpeed, data, cc, true); hAllowedDistance = getAllowedhDist(player, from, to, sprinting, downStream, hDistance, walkSpeed, data, cc, true);
hDistanceAboveLimit = hDistance - hAllowedDistance; hDistanceAboveLimit = hDistance - hAllowedDistance;
tags.add("permchecks(recheck)"); tags.add("permchecks");
} }
// Check velocity. // Check velocity.
double hFreedom = 0.0; // Horizontal velocity used. double hFreedom = 0.0; // Horizontal velocity used.
if (hDistanceAboveLimit > 0.0){ if (hDistanceAboveLimit > 0.0) {
// (hDistanceAboveLimit > 0.0) // (hDistanceAboveLimit > 0.0)
hFreedom = data.getHorizontalFreedom(); hFreedom = data.getHorizontalFreedom();
if (hFreedom < hDistanceAboveLimit){ if (hFreedom < hDistanceAboveLimit) {
// Use queued velocity if possible. // Use queued velocity if possible.
hFreedom += data.useHorizontalVelocity(hDistanceAboveLimit - hFreedom); hFreedom += data.useHorizontalVelocity(hDistanceAboveLimit - hFreedom);
} }
if (hFreedom > 0.0){ if (hFreedom > 0.0) {
tags.add("hvel"); tags.add("hvel");
hDistanceAboveLimit = Math.max(0.0, hDistanceAboveLimit - hFreedom); hDistanceAboveLimit = Math.max(0.0, hDistanceAboveLimit - hFreedom);
} }
} }
// "Bunny-hop". // After failure bunny (2nd).
if (hDistanceAboveLimit > 0){ if (hDistanceAboveLimit > 0) {
// Check "bunny fly" here, to not fall over sprint resetting on the way. // (Could distinguish tags from above call).
final double someThreshold = hAllowedDistance / 3.3; hDistanceAboveLimit = bunnyHop(from, to, hDistance, hAllowedDistance, hDistanceAboveLimit, yDistance, sprinting, data);
if (data.bunnyhopDelay > 0 && hDistance > walkSpeed * modSprint){
// Increase buffer if hDistance is decreasing properly.
if (data.sfLastHDist != Double.MAX_VALUE && data.sfLastHDist - hDistance >= data.sfLastHDist / 110.0 && hDistanceAboveLimit <= someThreshold){
// Speed must decrease by "a lot" at first, then by some minimal amount per event.
// TODO: 100.0, 110.0, ...
if (!(data.toWasReset && from.isOnGround() && to.isOnGround())){
// TODO: Confine further (max. amount)?
// Allow the move.
hDistanceAboveLimit = 0.0;
if (data.bunnyhopDelay <= 1 && !to.isOnGround() && !to.isResetCond()){
data.bunnyhopDelay ++;
tags.add("bunnyfly(keep)");
} else {
tags.add("bunnyfly");
}
}
}
}
else if (sprinting){
// Check activation of bunny hop,
// Roughly twice the sprinting speed is reached.
if (hDistanceAboveLimit > 0.05D && hDistanceAboveLimit <= hAllowedDistance + someThreshold
&& yDistance >= 0.4 && data.mediumLiftOff != MediumLiftOff.LIMIT_JUMP
&& (data.sfLastHDist == Double.MAX_VALUE || hDistance - data.sfLastHDist >= someThreshold )
&& (data.sfJumpPhase == 0 && from.isOnGround() || data.sfJumpPhase == 1 && data.noFallAssumeGround)
&& !from.isResetCond() && !to.isResetCond()) {
// TODO: Jump effect might allow more strictness.
// TODO: Expected minimum gain depends on last speed (!).
// TODO: Speed effect affects hDistanceAboveLimit?
data.bunnyhopDelay = bunnyHopMax;
hDistanceAboveLimit = 0D;
tags.add("bunnyhop"); // TODO: Which here...
}
}
} }
// Horizontal buffer. // Horizontal buffer.
// TODO: Consider to confine use to "not in air" and similar.
if (hDistanceAboveLimit > 0.0 && data.sfHorizontalBuffer > 0.0) { if (hDistanceAboveLimit > 0.0 && data.sfHorizontalBuffer > 0.0) {
// Handle buffer only if moving too far. // Handle buffer only if moving too far.
// Consume buffer. // Consume buffer.
@ -905,12 +864,65 @@ public class SurvivalFly extends Check {
} }
// Add the hspeed tag on violation. // Add the hspeed tag on violation.
if (hDistanceAboveLimit > 0.0){ if (hDistanceAboveLimit > 0.0) {
tags.add("hspeed"); tags.add("hspeed");
} }
return new double[]{hAllowedDistance, hDistanceAboveLimit, hFreedom}; return new double[]{hAllowedDistance, hDistanceAboveLimit, hFreedom};
} }
/**
* Test bunny hop / bunny fly. Does modify data only if 0.0 is returned.
* @param from
* @param to
* @param hDistance
* @param hAllowedDistance
* @param hDistanceAboveLimit
* @param yDistance
* @param sprinting
* @param data
* @return hDistanceAboveLimit
*/
private double bunnyHop(final PlayerLocation from, final PlayerLocation to, final double hDistance, final double hAllowedDistance, double hDistanceAboveLimit, final double yDistance, final boolean sprinting, final MovingData data){
// Check "bunny fly" here, to not fall over sprint resetting on the way.
final double someThreshold = hAllowedDistance / 3.3;
if (data.bunnyhopDelay > 0 && hDistance > walkSpeed * modSprint){
// Increase buffer if hDistance is decreasing properly.
if (data.sfLastHDist != Double.MAX_VALUE && data.sfLastHDist - hDistance >= data.sfLastHDist / 130.0 && hDistanceAboveLimit <= someThreshold){
// Speed must decrease by "a lot" at first, then by some minimal amount per event.
// TODO: 100.0, 110.0, ... might allow to confine buffer to low jump phase.
if (!(data.toWasReset && from.isOnGround() && to.isOnGround())){
// TODO: Confine further (max. amount)?
// Allow the move.
hDistanceAboveLimit = 0.0;
if (data.bunnyhopDelay <= 1 && !to.isOnGround() && !to.isResetCond()){
data.bunnyhopDelay ++;
tags.add("bunnyfly(keep)");
} else {
tags.add("bunnyfly");
}
}
}
}
else if (sprinting){
// Check activation of bunny hop,
// Roughly twice the sprinting speed is reached.
// TODO: Allow slightly higher speed on lost ground.
if (hDistanceAboveLimit > 0.05D && hDistanceAboveLimit <= hAllowedDistance + someThreshold
&& yDistance >= 0.4 && data.mediumLiftOff != MediumLiftOff.LIMIT_JUMP
&& (data.sfLastHDist == Double.MAX_VALUE || hDistance - data.sfLastHDist >= someThreshold )
&& (data.sfJumpPhase == 0 && from.isOnGround() || data.sfJumpPhase <= 1 && data.noFallAssumeGround)
&& !from.isResetCond() && !to.isResetCond()) {
// TODO: Jump effect might allow more strictness.
// TODO: Expected minimum gain depends on last speed (!).
// TODO: Speed effect affects hDistanceAboveLimit?
data.bunnyhopDelay = bunnyHopMax;
hDistanceAboveLimit = 0D;
tags.add("bunnyhop"); // TODO: Which here...
}
}
return hDistanceAboveLimit;
}
/** /**
* Legitimate move: increase horizontal buffer somehow. * Legitimate move: increase horizontal buffer somehow.
* @param hDistance * @param hDistance
@ -918,8 +930,13 @@ public class SurvivalFly extends Check {
* @param data * @param data
*/ */
private void hBufRegain(final double hDistance, final double hDistanceAboveLimit, final MovingData data){ private void hBufRegain(final double hDistance, final double hDistanceAboveLimit, final MovingData data){
// TODO: Consider different concepts (full resetting with harder conditions | maximum regain amount). /*
// TODO: Confine general conditions for buffer regain further ? * TODO: Consider different concepts:
* - full resetting with harder conditions.
* - maximum regain amount.
* - reset or regain only every x blocks h distance.
*/
// TODO: Confine general conditions for buffer regain further (regain in air, whatever)?
data.sfHorizontalBuffer = Math.min(hBufMax, data.sfHorizontalBuffer - hDistanceAboveLimit); data.sfHorizontalBuffer = Math.min(hBufMax, data.sfHorizontalBuffer - hDistanceAboveLimit);
} }