mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-03-12 22:49:31 +01:00
Move code between classes of magic. More on splash moves.
Move/split: * Generic/general/multipurpose stays in ...moving.magic.Magic. * vDistAir -> MagicAir. * vDistLiquid -> MagicLiquid. Workarounds: * Splash moves up/down (higher speeds). * Other adjustments (in-water near-zero inversion thing).
This commit is contained in:
parent
8b6d1324a3
commit
8c1b21a96c
@ -12,6 +12,7 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
|
|||||||
import fr.neatmonster.nocheatplus.checks.Check;
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying;
|
import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
|
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
|
||||||
|
@ -16,6 +16,7 @@ import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
|
|||||||
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
|
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.locations.LocUtil;
|
import fr.neatmonster.nocheatplus.checks.moving.locations.LocUtil;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.locations.LocationTrace;
|
import fr.neatmonster.nocheatplus.checks.moving.locations.LocationTrace;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveConsistency;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveConsistency;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
|
@ -60,6 +60,7 @@ import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
|
|||||||
import fr.neatmonster.nocheatplus.checks.moving.locations.LocUtil;
|
import fr.neatmonster.nocheatplus.checks.moving.locations.LocUtil;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.locations.MoveInfo;
|
import fr.neatmonster.nocheatplus.checks.moving.locations.MoveInfo;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.locations.VehicleSetBack;
|
import fr.neatmonster.nocheatplus.checks.moving.locations.VehicleSetBack;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveConsistency;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveConsistency;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
|
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
|
||||||
|
@ -16,6 +16,9 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
|
|||||||
import fr.neatmonster.nocheatplus.checks.Check;
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.magic.MagicAir;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.magic.MagicLiquid;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
|
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
|
||||||
@ -813,7 +816,7 @@ public class SurvivalFly extends Check {
|
|||||||
|
|
||||||
// Hacks.
|
// Hacks.
|
||||||
final boolean envelopeHack;
|
final boolean envelopeHack;
|
||||||
if (!resetFrom && !resetTo && Magic.venvHacks(from, to, yDistance, yDistChange, lastMove, data)) {
|
if (!resetFrom && !resetTo && MagicAir.venvHacks(from, to, yDistance, yDistChange, lastMove, data)) {
|
||||||
envelopeHack = true;
|
envelopeHack = true;
|
||||||
tags.add("hack_venv");
|
tags.add("hack_venv");
|
||||||
}
|
}
|
||||||
@ -930,7 +933,7 @@ public class SurvivalFly extends Check {
|
|||||||
&& yDistance < lastMove.yDistance - 0.001) {
|
&& yDistance < lastMove.yDistance - 0.001) {
|
||||||
// Odd decrease with water.
|
// Odd decrease with water.
|
||||||
}
|
}
|
||||||
else if (lastMove.toIsValid && Magic.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, lastMove, data, cc)) {
|
else if (lastMove.toIsValid && MagicAir.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, lastMove, data, cc)) {
|
||||||
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
|
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -958,7 +961,7 @@ public class SurvivalFly extends Check {
|
|||||||
else if (data.thisMove.headObstructed || lastMove.toIsValid && lastMove.headObstructed && lastMove.yDistance >= 0.0) {
|
else if (data.thisMove.headObstructed || lastMove.toIsValid && lastMove.headObstructed && lastMove.yDistance >= 0.0) {
|
||||||
// Head is blocked, thus a shorter move.
|
// Head is blocked, thus a shorter move.
|
||||||
}
|
}
|
||||||
else if (lastMove.toIsValid && Magic.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, lastMove, data, cc)) {
|
else if (lastMove.toIsValid && MagicAir.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, lastMove, data, cc)) {
|
||||||
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
|
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -994,7 +997,7 @@ public class SurvivalFly extends Check {
|
|||||||
&& (data.thisMove.headObstructed || lastMove.toIsValid && lastMove.headObstructed && lastMove.yDistance >= 0.0)) {
|
&& (data.thisMove.headObstructed || lastMove.toIsValid && lastMove.headObstructed && lastMove.yDistance >= 0.0)) {
|
||||||
// Head was blocked, thus faster decrease than expected.
|
// Head was blocked, thus faster decrease than expected.
|
||||||
}
|
}
|
||||||
else if (lastMove.toIsValid && Magic.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, lastMove, data, cc)) {
|
else if (lastMove.toIsValid && MagicAir.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, lastMove, data, cc)) {
|
||||||
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
|
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1580,91 +1583,11 @@ public class SurvivalFly extends Check {
|
|||||||
// ("== 0.0" is covered by the minimal speed check above.)
|
// ("== 0.0" is covered by the minimal speed check above.)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special cases.
|
// Workarounds for special cases.
|
||||||
if (yDistance >= 0) {
|
final Double wRes = MagicLiquid.liquidWorkarounds(from, to, baseSpeed, frictDist, lastMove, data);
|
||||||
// TODO: liftOffEnvelope: refine conditions (general) , should be near water level.
|
if (wRes != null) {
|
||||||
// TODO: 1.5 high blocks ?
|
return new double[]{wRes, 0.0};
|
||||||
// TODO: Conditions seem warped.
|
|
||||||
if (yDistance <= 0.5) {
|
|
||||||
if (lastMove.toIsValid && yDistance < lastMove.yDistance
|
|
||||||
&& lastMove.yDistance - yDistance > Math.max(0.001, yDistance - baseSpeed)) {
|
|
||||||
// Decrease more than difference to baseSpeed.
|
|
||||||
return new double[]{yDistance, 0.0};
|
|
||||||
}
|
|
||||||
if (yDistance <= data.liftOffEnvelope.getMaxJumpGain(data.jumpAmplifier) && !BlockProperties.isLiquid(from.getTypeIdAbove())
|
|
||||||
// TODO: What now !?
|
|
||||||
|| !to.isInLiquid() // TODO: impossible !?
|
|
||||||
|| (toOnGround || lastMove.toIsValid && lastMove.yDistance - yDistance >= 0.010 || to.isAboveStairs())) {
|
|
||||||
double vAllowedDistance = baseSpeed + 0.5;
|
|
||||||
double vDistanceAboveLimit = yDistance - vAllowedDistance;
|
|
||||||
if (vDistanceAboveLimit <= 0.0) {
|
|
||||||
return new double[]{vAllowedDistance, 0.0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastMove.toIsValid) {
|
|
||||||
// Lenient on marginal violation if speed decreases by 'enough'.
|
|
||||||
// (Observed on 'dirty' phase.)
|
|
||||||
if (Math.abs(frictDist - yDistance) <= 2.0 * Magic.GRAVITY_MAX
|
|
||||||
&& yDistance < lastMove.yDistance - 4.0 * Math.abs(frictDist - yDistance)
|
|
||||||
) {
|
|
||||||
return new double[]{yDistance, 0.0};
|
|
||||||
}
|
|
||||||
// Jumping with velocity into water from below, just slightly more decrease than gravity, twice.
|
|
||||||
if (yDistance > frictDist && yDistance < lastMove.yDistance - Magic.GRAVITY_MAX && data.insideMediumCount <= 1) {
|
|
||||||
// (Should be able to do without aw-ww-ww confinement.)
|
|
||||||
// (dirty seems to be set/kept reliably)
|
|
||||||
return new double[]{yDistance, 0.0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Otherwise, only if last move is available.
|
|
||||||
else if (lastMove.toIsValid) {
|
|
||||||
// Falling into water, mid-speed (second move after diving in).
|
|
||||||
if (yDistance > -0.9 && yDistance < lastMove.yDistance
|
|
||||||
&& Math.abs(yDistance - lastMove.yDistance) <= Magic.GRAVITY_MAX + Magic.GRAVITY_MIN
|
|
||||||
&& yDistance - lastMove.yDistance < -Magic.GRAVITY_MIN
|
|
||||||
//&& !BlockProperties.isLiquid(to.getTypeId(to.getBlockX(), Location.locToBlock(to.getY() + to.getEyeHeight()), to.getBlockZ()))
|
|
||||||
) {
|
|
||||||
return new double[]{lastMove.yDistance - Magic.GRAVITY_MAX - Magic.GRAVITY_MIN, 0.0};
|
|
||||||
}
|
|
||||||
// Increase speed slightly on second in-medium move (dirty flag may have been reset).
|
|
||||||
else if (data.insideMediumCount <= 1 && lastMove.yDistance < 0.8
|
|
||||||
&& yDistance < lastMove.yDistance - Magic.GRAVITY_ODD / 2.0 && yDistance > lastMove.yDistance - Magic.GRAVITY_MAX
|
|
||||||
) {
|
|
||||||
return new double[]{yDistance, 0.0};
|
|
||||||
}
|
|
||||||
// In-water rough near-0-inversion from allowed speed to a negative amount, little more than allowed (magic -0.2 roughly).
|
|
||||||
else if (lastMove.yDistance >= Magic.GRAVITY_MAX / 2.0 && lastMove.yDistance <= Magic.GRAVITY_MAX + Magic.GRAVITY_MIN / 2.0
|
|
||||||
&& yDistance < 0.0 && yDistance > -2.0 * Magic.GRAVITY_MAX - Magic.GRAVITY_MIN / 2.0
|
|
||||||
&& data.isVelocityJumpPhase() && to.isInLiquid() // TODO: Might skip the liquid check, though.
|
|
||||||
&& lastMove.from.inLiquid && lastMove.to.extraPropertiesValid && lastMove.to.inLiquid // TODO: in water only?
|
|
||||||
) {
|
|
||||||
return new double[]{yDistance, 0.0};
|
|
||||||
}
|
|
||||||
// Lava rather.
|
|
||||||
else if (data.lastFrictionVertical < 0.65 // (Random, but smaller than water.)
|
|
||||||
&& (
|
|
||||||
// Moving downstream.
|
|
||||||
lastMove.yDistance < 0.0 && yDistance > -0.5 && yDistance < lastMove.yDistance
|
|
||||||
&& lastMove.yDistance - yDistance < Magic.GRAVITY_MIN && BlockProperties.isDownStream(from, to)
|
|
||||||
// Mix of gravity and base speed [careful: relates to water base speed].
|
|
||||||
|| lastMove.yDistance < 0.0 && yDistance > -baseSpeed - Magic.GRAVITY_MAX && yDistance < lastMove.yDistance
|
|
||||||
&& lastMove.yDistance - yDistance > Magic.GRAVITY_SPAN
|
|
||||||
&& Math.abs(lastMove.yDistance + baseSpeed) < 0.25 * baseSpeed
|
|
||||||
// Falling slightly too fast in lava.
|
|
||||||
|| data.insideMediumCount == 1 || data.insideMediumCount == 2
|
|
||||||
&& lastMove.yDistance < 0.0 && yDistance < lastMove.yDistance
|
|
||||||
&& yDistance - lastMove.yDistance > -Magic.GRAVITY_MIN && yDistance > -0.65
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return new double[]{yDistance, 0.0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Also DOWNSTREAM !?
|
|
||||||
|
|
||||||
|
|
||||||
// Try to use velocity for compensation.
|
// Try to use velocity for compensation.
|
||||||
if (data.getOrUseVerticalVelocity(yDistance) != null) {
|
if (data.getOrUseVerticalVelocity(yDistance) != null) {
|
||||||
|
@ -0,0 +1,251 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.checks.moving.magic;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeping some of the magic confined in here.
|
||||||
|
*
|
||||||
|
* @author asofold
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Magic {
|
||||||
|
|
||||||
|
// Gravity.
|
||||||
|
public static final double GRAVITY_MAX = 0.0834;
|
||||||
|
public static final double GRAVITY_MIN = 0.0624; // TODO: Special cases go down to 0.05.
|
||||||
|
public static final double GRAVITY_SPAN = GRAVITY_MAX - GRAVITY_MIN;
|
||||||
|
public static final double GRAVITY_ODD = 0.05; // 19; // TODO: This should probably be min. / cleanup.
|
||||||
|
/** Assumed minimal average decrease per move, suitable for regarding 3 moves. */
|
||||||
|
public static final float GRAVITY_VACC = (float) (GRAVITY_MIN * 0.6);
|
||||||
|
|
||||||
|
// Friction factor by medium (move inside of).
|
||||||
|
public static final double FRICTION_MEDIUM_AIR = 0.98;
|
||||||
|
/** Friction for water (default). */
|
||||||
|
public static final double FRICTION_MEDIUM_WATER = 0.89;
|
||||||
|
/** Friction for lava. */
|
||||||
|
public static final double FRICTION_MEDIUM_LAVA = 0.535;
|
||||||
|
|
||||||
|
// Horizontal speeds/modifiers.
|
||||||
|
public static final double WALK_SPEED = 0.221D;
|
||||||
|
public static final double modSneak = 0.13D / WALK_SPEED;
|
||||||
|
// public static final double modSprint = 0.29 / walkSpeed; // TODO: without bunny 0.29 / practical is 0.35
|
||||||
|
public static final double modBlock = 0.16D / WALK_SPEED;
|
||||||
|
public static final double modSwim = 0.115D / WALK_SPEED;
|
||||||
|
public static final double[] modDepthStrider = new double[] {
|
||||||
|
1.0,
|
||||||
|
0.1645 / modSwim / WALK_SPEED,
|
||||||
|
0.1995 / modSwim / WALK_SPEED,
|
||||||
|
1.0 / modSwim, // Results in walkspeed.
|
||||||
|
};
|
||||||
|
public static final double modWeb = 0.105D / WALK_SPEED; // TODO: walkingSpeed * 0.15D; <- does not work
|
||||||
|
public static final double modIce = 2.5D; //
|
||||||
|
/** Faster moving down stream (water mainly). */
|
||||||
|
public static final double modDownStream = 0.19 / (WALK_SPEED * modSwim);
|
||||||
|
/** Maximal horizontal buffer. It can be higher, but normal resetting should keep this limit. */
|
||||||
|
|
||||||
|
public static final double hBufMax = 1.0;
|
||||||
|
// Vertical speeds/modifiers.
|
||||||
|
public static final double climbSpeed = WALK_SPEED * 1.3; // TODO: Check if the factor is needed!
|
||||||
|
|
||||||
|
// Other constants.
|
||||||
|
public static final double PAPER_DIST = 0.01;
|
||||||
|
/**
|
||||||
|
* Extreme move check threshold (Actual like 3.9 upwards with velocity,
|
||||||
|
* velocity downwards may be like -1.835 max., but falling will be near 3
|
||||||
|
* too.)
|
||||||
|
*/
|
||||||
|
public static final double EXTREME_MOVE_DIST_VERTICAL = 4.0;
|
||||||
|
public static final double EXTREME_MOVE_DIST_HORIZONTAL = 22.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute per-tick base speed for swimming vertically.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double swimBaseSpeedV() {
|
||||||
|
// TODO: Does this have to be the dynamic walk speed (refactoring)?
|
||||||
|
return WALK_SPEED * modSwim + 0.02;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if the player is (well) within in-air falling envelope.
|
||||||
|
* @param yDistance
|
||||||
|
* @param lastYDist
|
||||||
|
* @param extraGravity Extra amount to fall faster.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean fallingEnvelope(final double yDistance, final double lastYDist, final double lastFrictionVertical, final double extraGravity) {
|
||||||
|
if (yDistance >= lastYDist) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO: data.lastFrictionVertical (see vDistAir).
|
||||||
|
final double frictDist = lastYDist * lastFrictionVertical - GRAVITY_MIN;
|
||||||
|
// TODO: Extra amount: distinguish pos/neg?
|
||||||
|
return yDistance <= frictDist + extraGravity && yDistance > frictDist - GRAVITY_SPAN - extraGravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Friction envelope testing, with a different kind of leniency (relate
|
||||||
|
* off-amount to decreased amount), testing if 'friction' has been accounted
|
||||||
|
* for in a sufficient but not necessarily exact way.<br>
|
||||||
|
* In the current shape this method is meant for higher speeds rather (needs
|
||||||
|
* a twist for low speed comparison).
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @param lastMove
|
||||||
|
* @param friction
|
||||||
|
* Friction factor to apply.
|
||||||
|
* @param minGravity
|
||||||
|
* Amount to subtract from frictDist by default.
|
||||||
|
* @param maxOff
|
||||||
|
* Amount yDistance may be off the friction distance.
|
||||||
|
* @param decreaseByOff
|
||||||
|
* Factor, how many times the amount being off friction distance
|
||||||
|
* must fit into the decrease from lastMove to thisMove.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean enoughFrictionEnvelope(final MoveData thisMove, final MoveData lastMove, final double friction,
|
||||||
|
final double minGravity, final double maxOff, final double decreaseByOff) {
|
||||||
|
// TODO: Elaborate... could have one method to test them all?
|
||||||
|
final double frictDist = lastMove.yDistance * friction - minGravity;
|
||||||
|
final double off = Math.abs(thisMove.yDistance - frictDist);
|
||||||
|
return off <= maxOff && thisMove.yDistance - lastMove.yDistance <= off * decreaseByOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for a specific move in-air -> water, then water -> in-air.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* Not strictly the latest move in MovingData.
|
||||||
|
* @param lastMove
|
||||||
|
* Move before thisMove.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean splashMove(final MoveData thisMove, final MoveData lastMove) {
|
||||||
|
// Use past move data for two moves.
|
||||||
|
return !thisMove.touchedGround && thisMove.from.inWater && !thisMove.to.resetCond // Out of water.
|
||||||
|
&& !lastMove.touchedGround && !lastMove.from.resetCond && lastMove.to.inWater // Into water.
|
||||||
|
&& excludeStaticSpeed(thisMove) && excludeStaticSpeed(lastMove)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for a specific move ground/in-air -> water, then water -> in-air.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* Not strictly the latest move in MovingData.
|
||||||
|
* @param lastMove
|
||||||
|
* Move before thisMove.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean splashMoveNonStrict(final MoveData thisMove, final MoveData lastMove) {
|
||||||
|
// Use past move data for two moves.
|
||||||
|
return !thisMove.touchedGround && thisMove.from.inWater && !thisMove.to.resetCond // Out of water.
|
||||||
|
&& !lastMove.from.resetCond && lastMove.to.inWater // Into water.
|
||||||
|
&& excludeStaticSpeed(thisMove) && excludeStaticSpeed(lastMove)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Fully in-air move.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* Not strictly the latest move in MovingData.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean inAir(final MoveData thisMove) {
|
||||||
|
return !thisMove.touchedGround && !thisMove.from.resetCond && !thisMove.to.resetCond;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A liquid -> liquid move. Exclude web and climbable.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean inLiquid(final MoveData thisMove) {
|
||||||
|
return thisMove.from.inLiquid && thisMove.to.inLiquid && excludeStaticSpeed(thisMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if either point is in reset condition (liquid, web, ladder).
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean resetCond(final MoveData thisMove) {
|
||||||
|
return thisMove.from.resetCond || thisMove.to.resetCond;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moving out of liquid, might move onto ground. Exclude web and climbable.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean leavingLiquid(final MoveData thisMove) {
|
||||||
|
return thisMove.from.inLiquid && !thisMove.to.inLiquid && excludeStaticSpeed(thisMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moving into liquid., might move onto ground. Exclude web and climbable.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean intoLiquid(final MoveData thisMove) {
|
||||||
|
return !thisMove.from.inLiquid && thisMove.to.inLiquid && excludeStaticSpeed(thisMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude moving from/to blocks with static (vertical) speed, such as web
|
||||||
|
* or climbable.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean excludeStaticSpeed(final MoveData thisMove) {
|
||||||
|
return !thisMove.from.inWeb && !thisMove.to.inWeb
|
||||||
|
&& !thisMove.from.onClimbable && !thisMove.to.onClimbable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First move after set-back / teleport. Originally has been found with
|
||||||
|
* PaperSpigot for MC 1.7.10, however it also does occur on Spigot for MC
|
||||||
|
* 1.7.10.
|
||||||
|
*
|
||||||
|
* @param thisMove
|
||||||
|
* @param lastMove
|
||||||
|
* @param data
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean skipPaper(final MoveData thisMove, final MoveData lastMove, final MovingData data) {
|
||||||
|
// TODO: Confine to from at block level (offset 0)?
|
||||||
|
final double setBackYDistance = thisMove.to.y - data.getSetBackY();
|
||||||
|
return !lastMove.toIsValid && data.sfJumpPhase == 0 && thisMove.mightBeMultipleMoves
|
||||||
|
&& setBackYDistance > 0.0 && setBackYDistance < PAPER_DIST
|
||||||
|
&& thisMove.yDistance > 0.0 && thisMove.yDistance < PAPER_DIST && inAir(thisMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disregarding this move, test if all the way falling after head being
|
||||||
|
* obstructed.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean fallAfterHeadObstructed(final MovingData data, int limit) {
|
||||||
|
limit = Math.min(limit, data.moveData.size());
|
||||||
|
for (int i = 0; i < limit; i++) {
|
||||||
|
final MoveData move = data.moveData.get(i);
|
||||||
|
if (!move.toIsValid || move.yDistance >= 0.0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (move.headObstructed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,74 +1,13 @@
|
|||||||
package fr.neatmonster.nocheatplus.checks.moving;
|
package fr.neatmonster.nocheatplus.checks.moving.magic;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
||||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
|
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
|
||||||
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
||||||
|
|
||||||
/**
|
public class MagicAir {
|
||||||
* Keeping some of the magic confined in here.
|
|
||||||
*
|
|
||||||
* @author asofold
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Magic {
|
|
||||||
|
|
||||||
// Gravity.
|
|
||||||
public static final double GRAVITY_MAX = 0.0834;
|
|
||||||
public static final double GRAVITY_MIN = 0.0624; // TODO: Special cases go down to 0.05.
|
|
||||||
public static final double GRAVITY_SPAN = GRAVITY_MAX - GRAVITY_MIN;
|
|
||||||
public static final double GRAVITY_ODD = 0.05; // 19; // TODO: This should probably be min. / cleanup.
|
|
||||||
/** Assumed minimal average decrease per move, suitable for regarding 3 moves. */
|
|
||||||
public static final float GRAVITY_VACC = (float) (GRAVITY_MIN * 0.6);
|
|
||||||
|
|
||||||
// Friction factor by medium (move inside of).
|
|
||||||
public static final double FRICTION_MEDIUM_AIR = 0.98;
|
|
||||||
/** Friction for water (default). */
|
|
||||||
public static final double FRICTION_MEDIUM_WATER = 0.89;
|
|
||||||
/** Friction for lava. */
|
|
||||||
public static final double FRICTION_MEDIUM_LAVA = 0.535;
|
|
||||||
|
|
||||||
// Horizontal speeds/modifiers.
|
|
||||||
public static final double WALK_SPEED = 0.221D;
|
|
||||||
public static final double modSneak = 0.13D / WALK_SPEED;
|
|
||||||
// public static final double modSprint = 0.29 / walkSpeed; // TODO: without bunny 0.29 / practical is 0.35
|
|
||||||
public static final double modBlock = 0.16D / WALK_SPEED;
|
|
||||||
public static final double modSwim = 0.115D / WALK_SPEED;
|
|
||||||
public static final double[] modDepthStrider = new double[] {
|
|
||||||
1.0,
|
|
||||||
0.1645 / modSwim / WALK_SPEED,
|
|
||||||
0.1995 / modSwim / WALK_SPEED,
|
|
||||||
1.0 / modSwim, // Results in walkspeed.
|
|
||||||
};
|
|
||||||
public static final double modWeb = 0.105D / WALK_SPEED; // TODO: walkingSpeed * 0.15D; <- does not work
|
|
||||||
public static final double modIce = 2.5D; //
|
|
||||||
/** Faster moving down stream (water mainly). */
|
|
||||||
public static final double modDownStream = 0.19 / (WALK_SPEED * modSwim);
|
|
||||||
/** Maximal horizontal buffer. It can be higher, but normal resetting should keep this limit. */
|
|
||||||
|
|
||||||
public static final double hBufMax = 1.0;
|
|
||||||
// Vertical speeds/modifiers.
|
|
||||||
public static final double climbSpeed = WALK_SPEED * 1.3; // TODO: Check if the factor is needed!
|
|
||||||
|
|
||||||
// Other constants.
|
|
||||||
public static final double PAPER_DIST = 0.01;
|
|
||||||
/**
|
|
||||||
* Extreme move check threshold (Actual like 3.9 upwards with velocity,
|
|
||||||
* velocity downwards may be like -1.835 max., but falling will be near 3
|
|
||||||
* too.)
|
|
||||||
*/
|
|
||||||
public static final double EXTREME_MOVE_DIST_VERTICAL = 4.0;
|
|
||||||
public static final double EXTREME_MOVE_DIST_HORIZONTAL = 22.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The absolute per-tick base speed for swimming vertically.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static double swimBaseSpeedV() {
|
|
||||||
// TODO: Does this have to be the dynamic walk speed (refactoring)?
|
|
||||||
return WALK_SPEED * modSwim + 0.02;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vertical envelope "hacks". Directly check for certain transitions, on
|
* Vertical envelope "hacks". Directly check for certain transitions, on
|
||||||
@ -80,7 +19,7 @@ public class Magic {
|
|||||||
* @param data
|
* @param data
|
||||||
* @return If to skip those sub-checks.
|
* @return If to skip those sub-checks.
|
||||||
*/
|
*/
|
||||||
static boolean venvHacks(final PlayerLocation from, final PlayerLocation to, final double yDistance, final double yDistChange, final MoveData lastMove, final MovingData data) {
|
public static boolean venvHacks(final PlayerLocation from, final PlayerLocation to, final double yDistance, final double yDistChange, final MoveData lastMove, final MovingData data) {
|
||||||
return
|
return
|
||||||
// 0: Intended for cobweb.
|
// 0: Intended for cobweb.
|
||||||
// TODO: Bounding box issue ?
|
// TODO: Bounding box issue ?
|
||||||
@ -89,11 +28,11 @@ public class Magic {
|
|||||||
lastMove.toIsValid && lastMove.yDistance < 0.0
|
lastMove.toIsValid && lastMove.yDistance < 0.0
|
||||||
&& (
|
&& (
|
||||||
// 2: Switch to 0 y-Dist on early jump phase.
|
// 2: Switch to 0 y-Dist on early jump phase.
|
||||||
yDistance == 0.0 && lastMove.yDistance < -GRAVITY_ODD / 3.0 && lastMove.yDistance > -GRAVITY_MIN
|
yDistance == 0.0 && lastMove.yDistance < -Magic.GRAVITY_ODD / 3.0 && lastMove.yDistance > -Magic.GRAVITY_MIN
|
||||||
// 2: Decrease too few.
|
// 2: Decrease too few.
|
||||||
|| yDistChange < -GRAVITY_MIN / 3.0 && yDistChange > -GRAVITY_MAX
|
|| yDistChange < -Magic.GRAVITY_MIN / 3.0 && yDistChange > -Magic.GRAVITY_MAX
|
||||||
// 2: Keep negative y-distance (very likely a player height issue).
|
// 2: Keep negative y-distance (very likely a player height issue).
|
||||||
|| yDistChange == 0.0 && lastMove.yDistance > -GRAVITY_MAX && lastMove.yDistance < -GRAVITY_ODD / 3.0
|
|| yDistChange == 0.0 && lastMove.yDistance > -Magic.GRAVITY_MAX && lastMove.yDistance < -Magic.GRAVITY_ODD / 3.0
|
||||||
)
|
)
|
||||||
// 1: Keep yDist == 0.0 on first falling.
|
// 1: Keep yDist == 0.0 on first falling.
|
||||||
// TODO: Do test if hdist == 0.0 or something small can be assumed.
|
// TODO: Do test if hdist == 0.0 or something small can be assumed.
|
||||||
@ -119,7 +58,7 @@ public class Magic {
|
|||||||
*/
|
*/
|
||||||
private static boolean oddSlope(final PlayerLocation to, final double yDistance, final double maxJumpGain, final double yDistDiffEx, final MoveData lastMove, final MovingData data) {
|
private static boolean oddSlope(final PlayerLocation to, final double yDistance, final double maxJumpGain, final double yDistDiffEx, final MoveData lastMove, final MovingData data) {
|
||||||
return data.sfJumpPhase == 1 //&& data.fromWasReset
|
return data.sfJumpPhase == 1 //&& data.fromWasReset
|
||||||
&& Math.abs(yDistDiffEx) < 2.0 * GRAVITY_SPAN
|
&& Math.abs(yDistDiffEx) < 2.0 * Magic.GRAVITY_SPAN
|
||||||
&& lastMove.yDistance > 0.0 && yDistance < lastMove.yDistance
|
&& lastMove.yDistance > 0.0 && yDistance < lastMove.yDistance
|
||||||
&& to.getY() - data.getSetBackY() <= data.liftOffEnvelope.getMaxJumpHeight(data.jumpAmplifier)
|
&& to.getY() - data.getSetBackY() <= data.liftOffEnvelope.getMaxJumpHeight(data.jumpAmplifier)
|
||||||
&& (
|
&& (
|
||||||
@ -128,55 +67,10 @@ public class Magic {
|
|||||||
//&& fallingEnvelope(yDistance, lastMove.yDistance, 2.0 * GRAVITY_SPAN)
|
//&& fallingEnvelope(yDistance, lastMove.yDistance, 2.0 * GRAVITY_SPAN)
|
||||||
// Decrease more after going through liquid (but normal ground envelope).
|
// Decrease more after going through liquid (but normal ground envelope).
|
||||||
|| lastMove.yDistance > 0.5 * maxJumpGain && lastMove.yDistance < 0.84 * maxJumpGain
|
|| lastMove.yDistance > 0.5 * maxJumpGain && lastMove.yDistance < 0.84 * maxJumpGain
|
||||||
&& lastMove.yDistance - yDistance <= GRAVITY_MAX + GRAVITY_SPAN
|
&& lastMove.yDistance - yDistance <= Magic.GRAVITY_MAX + Magic.GRAVITY_SPAN
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test if the player is (well) within in-air falling envelope.
|
|
||||||
* @param yDistance
|
|
||||||
* @param lastYDist
|
|
||||||
* @param extraGravity Extra amount to fall faster.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static boolean fallingEnvelope(final double yDistance, final double lastYDist, final double lastFrictionVertical, final double extraGravity) {
|
|
||||||
if (yDistance >= lastYDist) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// TODO: data.lastFrictionVertical (see vDistAir).
|
|
||||||
final double frictDist = lastYDist * lastFrictionVertical - GRAVITY_MIN;
|
|
||||||
// TODO: Extra amount: distinguish pos/neg?
|
|
||||||
return yDistance <= frictDist + extraGravity && yDistance > frictDist - GRAVITY_SPAN - extraGravity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Friction envelope testing, with a different kind of leniency (relate
|
|
||||||
* off-amount to decreased amount), testing if 'friction' has been accounted
|
|
||||||
* for in a sufficient but not necessarily exact way.<br>
|
|
||||||
* In the current shape this method is meant for higher speeds rather (needs
|
|
||||||
* a twist for low speed comparison).
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* @param lastMove
|
|
||||||
* @param friction
|
|
||||||
* Friction factor to apply.
|
|
||||||
* @param minGravity
|
|
||||||
* Amount to subtract from frictDist by default.
|
|
||||||
* @param maxOff
|
|
||||||
* Amount yDistance may be off the friction distance.
|
|
||||||
* @param decreaseByOff
|
|
||||||
* Factor, how many times the amount being off friction distance
|
|
||||||
* must fit into the decrease from lastMove to thisMove.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static boolean enoughFrictionEnvelope(final MoveData thisMove, final MoveData lastMove, final double friction,
|
|
||||||
final double minGravity, final double maxOff, final double decreaseByOff) {
|
|
||||||
// TODO: Elaborate... could have one method to test them all?
|
|
||||||
final double frictDist = lastMove.yDistance * friction - minGravity;
|
|
||||||
final double off = Math.abs(thisMove.yDistance - frictDist);
|
|
||||||
return off <= maxOff && thisMove.yDistance - lastMove.yDistance <= off * decreaseByOff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jump after leaving the liquid near ground or jumping through liquid
|
* Jump after leaving the liquid near ground or jumping through liquid
|
||||||
* (rather friction envelope, problematic). Needs last move data.
|
* (rather friction envelope, problematic). Needs last move data.
|
||||||
@ -199,11 +93,11 @@ public class Magic {
|
|||||||
// TODO: Liquid-bound or not?
|
// TODO: Liquid-bound or not?
|
||||||
(data.liftOffEnvelope != LiftOffEnvelope.NORMAL || data.isVelocityJumpPhase())
|
(data.liftOffEnvelope != LiftOffEnvelope.NORMAL || data.isVelocityJumpPhase())
|
||||||
&& ( //
|
&& ( //
|
||||||
fallingEnvelope(yDistance, lastMove.yDistance, data.lastFrictionVertical, GRAVITY_ODD / 2.0)
|
Magic.fallingEnvelope(yDistance, lastMove.yDistance, data.lastFrictionVertical, Magic.GRAVITY_ODD / 2.0)
|
||||||
// Moving out of lava with velocity.
|
// Moving out of lava with velocity.
|
||||||
// TODO: Generalize / fix friction there (max/min!?)
|
// TODO: Generalize / fix friction there (max/min!?)
|
||||||
|| lastMove.from.extraPropertiesValid && lastMove.from.inLava
|
|| lastMove.from.extraPropertiesValid && lastMove.from.inLava
|
||||||
&& enoughFrictionEnvelope(data.thisMove, lastMove, FRICTION_MEDIUM_LAVA, 0.0, 2.0 * GRAVITY_MAX, 4.0)
|
&& Magic.enoughFrictionEnvelope(data.thisMove, lastMove, Magic.FRICTION_MEDIUM_LAVA, 0.0, 2.0 * Magic.GRAVITY_MAX, 4.0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// 0: Not normal envelope.
|
// 0: Not normal envelope.
|
||||||
@ -212,33 +106,33 @@ public class Magic {
|
|||||||
&& (
|
&& (
|
||||||
// 1: Jump or decrease falling speed after a small gain (could be bounding box?).
|
// 1: Jump or decrease falling speed after a small gain (could be bounding box?).
|
||||||
yDistDiffEx > 0.0 && yDistance > lastMove.yDistance && yDistance < 0.84 * maxJumpGain
|
yDistDiffEx > 0.0 && yDistance > lastMove.yDistance && yDistance < 0.84 * maxJumpGain
|
||||||
&& lastMove.yDistance >= -GRAVITY_MAX - GRAVITY_MIN && lastMove.yDistance < GRAVITY_MAX + GRAVITY_SPAN
|
&& lastMove.yDistance >= -Magic.GRAVITY_MAX - Magic.GRAVITY_MIN && lastMove.yDistance < Magic.GRAVITY_MAX + Magic.GRAVITY_SPAN
|
||||||
)
|
)
|
||||||
// 0: Moving out of water somehow.
|
// 0: Moving out of water somehow.
|
||||||
|| (data.liftOffEnvelope == LiftOffEnvelope.LIMIT_LIQUID || data.liftOffEnvelope == LiftOffEnvelope.LIMIT_NEAR_GROUND)
|
|| (data.liftOffEnvelope == LiftOffEnvelope.LIMIT_LIQUID || data.liftOffEnvelope == LiftOffEnvelope.LIMIT_NEAR_GROUND)
|
||||||
&& (
|
&& (
|
||||||
// 1: Too few decrease on first moves out of water (upwards).
|
// 1: Too few decrease on first moves out of water (upwards).
|
||||||
lastMove.yDistance > 0.0 && yDistance < lastMove.yDistance - GRAVITY_MAX && yDistDiffEx > 0.0 && yDistDiffEx < GRAVITY_MAX + GRAVITY_ODD
|
lastMove.yDistance > 0.0 && yDistance < lastMove.yDistance - Magic.GRAVITY_MAX && yDistDiffEx > 0.0 && yDistDiffEx < Magic.GRAVITY_MAX + Magic.GRAVITY_ODD
|
||||||
// 1: Odd decrease of speed as if still in water, moving out of water (downwards).
|
// 1: Odd decrease of speed as if still in water, moving out of water (downwards).
|
||||||
// TODO: data.lastFrictionVertical might not catch it (jump phase 0 -> next = air).
|
// TODO: data.lastFrictionVertical might not catch it (jump phase 0 -> next = air).
|
||||||
// TODO: Could not reproduce since first time (use DebugUtil.debug(String, boolean)).
|
// TODO: Could not reproduce since first time (use DebugUtil.debug(String, boolean)).
|
||||||
|| lastMove.yDistance < -2.0 * GRAVITY_MAX && data.sfJumpPhase == 1
|
|| lastMove.yDistance < -2.0 * Magic.GRAVITY_MAX && data.sfJumpPhase == 1
|
||||||
&& yDistance < -GRAVITY_MAX && yDistance > lastMove.yDistance
|
&& yDistance < -Magic.GRAVITY_MAX && yDistance > lastMove.yDistance
|
||||||
&& Math.abs(yDistance - lastMove.yDistance * data.lastFrictionVertical) < GRAVITY_MAX
|
&& Math.abs(yDistance - lastMove.yDistance * data.lastFrictionVertical) < Magic.GRAVITY_MAX
|
||||||
// 1: Falling too slow, keeping roughly gravity-once speed.
|
// 1: Falling too slow, keeping roughly gravity-once speed.
|
||||||
|| data.sfJumpPhase == 1
|
|| data.sfJumpPhase == 1
|
||||||
&& lastMove.yDistance < -GRAVITY_ODD && lastMove.yDistance > -GRAVITY_MAX - GRAVITY_MIN
|
&& lastMove.yDistance < -Magic.GRAVITY_ODD && lastMove.yDistance > -Magic.GRAVITY_MAX - Magic.GRAVITY_MIN
|
||||||
&& Math.abs(lastMove.yDistance - yDistance) < GRAVITY_SPAN
|
&& Math.abs(lastMove.yDistance - yDistance) < Magic.GRAVITY_SPAN
|
||||||
&& (yDistance < lastMove.yDistance || yDistance < GRAVITY_MIN)
|
&& (yDistance < lastMove.yDistance || yDistance < Magic.GRAVITY_MIN)
|
||||||
// 1: Falling slightly too slow.
|
// 1: Falling slightly too slow.
|
||||||
|| yDistDiffEx > 0.0 && (
|
|| yDistDiffEx > 0.0 && (
|
||||||
// 2: Falling too slow around 0 yDistance.
|
// 2: Falling too slow around 0 yDistance.
|
||||||
lastMove.yDistance > -2.0 * GRAVITY_MAX - GRAVITY_ODD
|
lastMove.yDistance > -2.0 * Magic.GRAVITY_MAX - Magic.GRAVITY_ODD
|
||||||
&& yDistance < lastMove.yDistance && lastMove.yDistance - yDistance < GRAVITY_MAX
|
&& yDistance < lastMove.yDistance && lastMove.yDistance - yDistance < Magic.GRAVITY_MAX
|
||||||
&& lastMove.yDistance - yDistance > GRAVITY_MIN / 4.0
|
&& lastMove.yDistance - yDistance > Magic.GRAVITY_MIN / 4.0
|
||||||
// 2: Moving out of liquid with velocity.
|
// 2: Moving out of liquid with velocity.
|
||||||
|| yDistance > 0.0 && data.sfJumpPhase == 1 && yDistDiffEx < 4.0 * GRAVITY_MAX
|
|| yDistance > 0.0 && data.sfJumpPhase == 1 && yDistDiffEx < 4.0 * Magic.GRAVITY_MAX
|
||||||
&& yDistance < lastMove.yDistance - GRAVITY_MAX && data.isVelocityJumpPhase()
|
&& yDistance < lastMove.yDistance - Magic.GRAVITY_MAX && data.isVelocityJumpPhase()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
; // (return)
|
; // (return)
|
||||||
@ -264,61 +158,61 @@ public class Magic {
|
|||||||
// || from.isHeadObstructed(from.getyOnGround()) || data.fromWasReset && from.isHeadObstructed())
|
// || from.isHeadObstructed(from.getyOnGround()) || data.fromWasReset && from.isHeadObstructed())
|
||||||
return
|
return
|
||||||
// 0: Any envelope (supposedly normal) near 0 yDistance.
|
// 0: Any envelope (supposedly normal) near 0 yDistance.
|
||||||
yDistance > -2.0 * GRAVITY_MAX - GRAVITY_MIN && yDistance < 2.0 * GRAVITY_MAX + GRAVITY_MIN
|
yDistance > -2.0 * Magic.GRAVITY_MAX - Magic.GRAVITY_MIN && yDistance < 2.0 * Magic.GRAVITY_MAX + Magic.GRAVITY_MIN
|
||||||
&& (
|
&& (
|
||||||
// 1: Too big chunk of change, but within reasonable bounds (should be contained in some other generic case?).
|
// 1: Too big chunk of change, but within reasonable bounds (should be contained in some other generic case?).
|
||||||
lastMove.yDistance < 3.0 * GRAVITY_MAX + GRAVITY_MIN && yDistChange < -GRAVITY_MIN && yDistChange > -2.5 * GRAVITY_MAX -GRAVITY_MIN
|
lastMove.yDistance < 3.0 * Magic.GRAVITY_MAX + Magic.GRAVITY_MIN && yDistChange < -Magic.GRAVITY_MIN && yDistChange > -2.5 * Magic.GRAVITY_MAX -Magic.GRAVITY_MIN
|
||||||
// Transition to 0.0 yDistance.
|
// Transition to 0.0 yDistance.
|
||||||
|| lastMove.yDistance > GRAVITY_ODD / 2.0 && lastMove.yDistance < GRAVITY_MIN && yDistance == 0.0
|
|| lastMove.yDistance > Magic.GRAVITY_ODD / 2.0 && lastMove.yDistance < Magic.GRAVITY_MIN && yDistance == 0.0
|
||||||
// 1: yDist inversion near 0 (almost). TODO: This actually happens near liquid, but NORMAL env!?
|
// 1: yDist inversion near 0 (almost). TODO: This actually happens near liquid, but NORMAL env!?
|
||||||
// lastYDist < Gravity max + min happens with dirty phase (slimes),. previously: max + span
|
// lastYDist < Gravity max + min happens with dirty phase (slimes),. previously: max + span
|
||||||
// TODO: Can all cases be reduced to change sign with max. neg. gain of max + span ?
|
// TODO: Can all cases be reduced to change sign with max. neg. gain of max + span ?
|
||||||
|| lastMove.yDistance <= GRAVITY_MAX + GRAVITY_MIN && lastMove.yDistance > GRAVITY_ODD
|
|| lastMove.yDistance <= Magic.GRAVITY_MAX + Magic.GRAVITY_MIN && lastMove.yDistance > Magic.GRAVITY_ODD
|
||||||
&& yDistance < GRAVITY_ODD && yDistance > -2.0 * GRAVITY_MAX - GRAVITY_ODD / 2.0
|
&& yDistance < Magic.GRAVITY_ODD && yDistance > -2.0 * Magic.GRAVITY_MAX - Magic.GRAVITY_ODD / 2.0
|
||||||
// 1: Head is obstructed.
|
// 1: Head is obstructed.
|
||||||
// TODO: Cover this in a more generic way elsewhere (<= friction envelope + obstructed).
|
// TODO: Cover this in a more generic way elsewhere (<= friction envelope + obstructed).
|
||||||
|| lastMove.yDistance >= 0.0 && yDistance < GRAVITY_ODD
|
|| lastMove.yDistance >= 0.0 && yDistance < Magic.GRAVITY_ODD
|
||||||
&& (data.thisMove.headObstructed || lastMove.headObstructed)
|
&& (data.thisMove.headObstructed || lastMove.headObstructed)
|
||||||
// 1: Break the block underneath.
|
// 1: Break the block underneath.
|
||||||
|| lastMove.yDistance < 0.0 && lastMove.to.extraPropertiesValid && lastMove.to.onGround
|
|| lastMove.yDistance < 0.0 && lastMove.to.extraPropertiesValid && lastMove.to.onGround
|
||||||
&& yDistance >= -GRAVITY_MAX - GRAVITY_SPAN && yDistance <= GRAVITY_MIN
|
&& yDistance >= -Magic.GRAVITY_MAX - Magic.GRAVITY_SPAN && yDistance <= Magic.GRAVITY_MIN
|
||||||
// 1: Slope with slimes (also near ground without velocityJumpPhase, rather lowjump but not always).
|
// 1: Slope with slimes (also near ground without velocityJumpPhase, rather lowjump but not always).
|
||||||
|| lastMove.yDistance < -GRAVITY_MAX && yDistChange < - GRAVITY_ODD / 2.0 && yDistChange > -GRAVITY_MIN
|
|| lastMove.yDistance < -Magic.GRAVITY_MAX && yDistChange < - Magic.GRAVITY_ODD / 2.0 && yDistChange > -Magic.GRAVITY_MIN
|
||||||
// 1: Near ground (slime block).
|
// 1: Near ground (slime block).
|
||||||
|| lastMove.yDistance == 0.0 && yDistance < -GRAVITY_ODD / 2.5 && yDistance > -GRAVITY_MIN && to.isOnGround(GRAVITY_MIN)
|
|| lastMove.yDistance == 0.0 && yDistance < -Magic.GRAVITY_ODD / 2.5 && yDistance > -Magic.GRAVITY_MIN && to.isOnGround(Magic.GRAVITY_MIN)
|
||||||
// 1: Start to fall after touching ground somehow (possibly too slowly).
|
// 1: Start to fall after touching ground somehow (possibly too slowly).
|
||||||
|| (lastMove.touchedGround || lastMove.to.resetCond) && lastMove.yDistance <= GRAVITY_MIN && lastMove.yDistance >= - GRAVITY_MAX
|
|| (lastMove.touchedGround || lastMove.to.resetCond) && lastMove.yDistance <= Magic.GRAVITY_MIN && lastMove.yDistance >= - Magic.GRAVITY_MAX
|
||||||
&& yDistance < lastMove.yDistance - GRAVITY_SPAN && yDistance < GRAVITY_ODD && yDistance > lastMove.yDistance - GRAVITY_MAX
|
&& yDistance < lastMove.yDistance - Magic.GRAVITY_SPAN && yDistance < Magic.GRAVITY_ODD && yDistance > lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
)
|
)
|
||||||
// 0: With velocity.
|
// 0: With velocity.
|
||||||
|| data.isVelocityJumpPhase()
|
|| data.isVelocityJumpPhase()
|
||||||
&& (
|
&& (
|
||||||
// 1: Near zero inversion with slimes (rather dirty phase).
|
// 1: Near zero inversion with slimes (rather dirty phase).
|
||||||
lastMove.yDistance > GRAVITY_ODD && lastMove.yDistance < GRAVITY_MAX + GRAVITY_MIN
|
lastMove.yDistance > Magic.GRAVITY_ODD && lastMove.yDistance < Magic.GRAVITY_MAX + Magic.GRAVITY_MIN
|
||||||
&& yDistance <= -lastMove.yDistance && yDistance > -lastMove.yDistance - GRAVITY_MAX - GRAVITY_ODD
|
&& yDistance <= -lastMove.yDistance && yDistance > -lastMove.yDistance - Magic.GRAVITY_MAX - Magic.GRAVITY_ODD
|
||||||
// 1: Odd mini-decrease with dirty phase (slime).
|
// 1: Odd mini-decrease with dirty phase (slime).
|
||||||
|| lastMove.yDistance < -0.204 && yDistance > -0.26
|
|| lastMove.yDistance < -0.204 && yDistance > -0.26
|
||||||
&& yDistChange > -GRAVITY_MIN && yDistChange < -GRAVITY_ODD / 4.0
|
&& yDistChange > -Magic.GRAVITY_MIN && yDistChange < -Magic.GRAVITY_ODD / 4.0
|
||||||
// 1: Lot's of decrease near zero TODO: merge later.
|
// 1: Lot's of decrease near zero TODO: merge later.
|
||||||
|| lastMove.yDistance < -GRAVITY_ODD && lastMove.yDistance > -GRAVITY_MIN
|
|| lastMove.yDistance < -Magic.GRAVITY_ODD && lastMove.yDistance > -Magic.GRAVITY_MIN
|
||||||
&& yDistance > -2.0 * GRAVITY_MAX - 2.0 * GRAVITY_MIN && yDistance < -GRAVITY_MAX
|
&& yDistance > -2.0 * Magic.GRAVITY_MAX - 2.0 * Magic.GRAVITY_MIN && yDistance < -Magic.GRAVITY_MAX
|
||||||
// 1: Odd decrease less near zero.
|
// 1: Odd decrease less near zero.
|
||||||
|| yDistChange > -GRAVITY_MIN && yDistChange < -GRAVITY_ODD
|
|| yDistChange > -Magic.GRAVITY_MIN && yDistChange < -Magic.GRAVITY_ODD
|
||||||
&& lastMove.yDistance < 0.5 && lastMove.yDistance > 0.4
|
&& lastMove.yDistance < 0.5 && lastMove.yDistance > 0.4
|
||||||
// 1: Small decrease after high edge.
|
// 1: Small decrease after high edge.
|
||||||
// TODO: Consider min <-> span, generic.
|
// TODO: Consider min <-> span, generic.
|
||||||
|| lastMove.yDistance == 0.0 && yDistance > -GRAVITY_MIN && yDistance < -GRAVITY_ODD
|
|| lastMove.yDistance == 0.0 && yDistance > -Magic.GRAVITY_MIN && yDistance < -Magic.GRAVITY_ODD
|
||||||
// 1: Too small but decent decrease moving up, marginal violation.
|
// 1: Too small but decent decrease moving up, marginal violation.
|
||||||
|| yDistDiffEx > 0.0 && yDistDiffEx < 0.01
|
|| yDistDiffEx > 0.0 && yDistDiffEx < 0.01
|
||||||
&& yDistance > GRAVITY_MAX && yDistance < lastMove.yDistance - GRAVITY_MAX
|
&& yDistance > Magic.GRAVITY_MAX && yDistance < lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
)
|
)
|
||||||
// 0: Small distance to set.back. .
|
// 0: Small distance to set.back. .
|
||||||
|| data.hasSetBack() && Math.abs(data.getSetBackY() - from.getY()) < 1.0
|
|| data.hasSetBack() && Math.abs(data.getSetBackY() - from.getY()) < 1.0
|
||||||
// TODO: Consider low fall distance as well.
|
// TODO: Consider low fall distance as well.
|
||||||
&& (
|
&& (
|
||||||
// 1: Near ground small decrease.
|
// 1: Near ground small decrease.
|
||||||
lastMove.yDistance > GRAVITY_MAX && lastMove.yDistance < 3.0 * GRAVITY_MAX
|
lastMove.yDistance > Magic.GRAVITY_MAX && lastMove.yDistance < 3.0 * Magic.GRAVITY_MAX
|
||||||
&& yDistChange > - GRAVITY_MIN && yDistChange < -GRAVITY_ODD
|
&& yDistChange > - Magic.GRAVITY_MIN && yDistChange < -Magic.GRAVITY_ODD
|
||||||
// 1: Bounce without velocity set. TODO: wat?
|
// 1: Bounce without velocity set. TODO: wat?
|
||||||
//|| lastMove.yDistance == 0.0 && yDistance > -GRAVITY_MIN && yDistance < GRAVITY_SPAN
|
//|| lastMove.yDistance == 0.0 && yDistance > -GRAVITY_MIN && yDistance < GRAVITY_SPAN
|
||||||
// 1: Bounce with carpet.
|
// 1: Bounce with carpet.
|
||||||
@ -326,29 +220,29 @@ public class Magic {
|
|||||||
)
|
)
|
||||||
// 0: Jump-effect-specific
|
// 0: Jump-effect-specific
|
||||||
// TODO: Jump effect at reduced lift off envelope -> skip this?
|
// TODO: Jump effect at reduced lift off envelope -> skip this?
|
||||||
|| data.jumpAmplifier > 0 && lastMove.yDistance < GRAVITY_MAX + GRAVITY_MIN / 2.0 && lastMove.yDistance > -2.0 * GRAVITY_MAX - 0.5 * GRAVITY_MIN
|
|| data.jumpAmplifier > 0 && lastMove.yDistance < Magic.GRAVITY_MAX + Magic.GRAVITY_MIN / 2.0 && lastMove.yDistance > -2.0 * Magic.GRAVITY_MAX - 0.5 * Magic.GRAVITY_MIN
|
||||||
&& yDistance > -2.0 * GRAVITY_MAX - 2.0 * GRAVITY_MIN && yDistance < GRAVITY_MIN
|
&& yDistance > -2.0 * Magic.GRAVITY_MAX - 2.0 * Magic.GRAVITY_MIN && yDistance < Magic.GRAVITY_MIN
|
||||||
&& yDistChange < -GRAVITY_SPAN
|
&& yDistChange < -Magic.GRAVITY_SPAN
|
||||||
// 0: Another near 0 yDistance case.
|
// 0: Another near 0 yDistance case.
|
||||||
// TODO: Inaugurate into some more generic envelope.
|
// TODO: Inaugurate into some more generic envelope.
|
||||||
|| lastMove.yDistance > -GRAVITY_MAX && lastMove.yDistance < GRAVITY_MIN
|
|| lastMove.yDistance > -Magic.GRAVITY_MAX && lastMove.yDistance < Magic.GRAVITY_MIN
|
||||||
&& !(lastMove.touchedGround || lastMove.to.extraPropertiesValid && lastMove.to.onGroundOrResetCond)
|
&& !(lastMove.touchedGround || lastMove.to.extraPropertiesValid && lastMove.to.onGroundOrResetCond)
|
||||||
&& yDistance < lastMove.yDistance - GRAVITY_MIN / 2.0 && yDistance > lastMove.yDistance - GRAVITY_MAX - 0.5 * GRAVITY_MIN
|
&& yDistance < lastMove.yDistance - Magic.GRAVITY_MIN / 2.0 && yDistance > lastMove.yDistance - Magic.GRAVITY_MAX - 0.5 * Magic.GRAVITY_MIN
|
||||||
// 0: Reduced jumping envelope.
|
// 0: Reduced jumping envelope.
|
||||||
|| data.liftOffEnvelope != LiftOffEnvelope.NORMAL
|
|| data.liftOffEnvelope != LiftOffEnvelope.NORMAL
|
||||||
&& (
|
&& (
|
||||||
// 1: Wild-card allow half gravity near 0 yDistance. TODO: Check for removal of included cases elsewhere.
|
// 1: Wild-card allow half gravity near 0 yDistance. TODO: Check for removal of included cases elsewhere.
|
||||||
lastMove.yDistance > -10.0 * GRAVITY_ODD / 2.0 && lastMove.yDistance < 10.0 * GRAVITY_ODD
|
lastMove.yDistance > -10.0 * Magic.GRAVITY_ODD / 2.0 && lastMove.yDistance < 10.0 * Magic.GRAVITY_ODD
|
||||||
&& yDistance < lastMove.yDistance - GRAVITY_MIN / 2.0 && yDistance > lastMove.yDistance - GRAVITY_MAX
|
&& yDistance < lastMove.yDistance - Magic.GRAVITY_MIN / 2.0 && yDistance > lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
// 1:
|
// 1:
|
||||||
|| lastMove.yDistance < GRAVITY_MAX + GRAVITY_SPAN && lastMove.yDistance > GRAVITY_ODD
|
|| lastMove.yDistance < Magic.GRAVITY_MAX + Magic.GRAVITY_SPAN && lastMove.yDistance > Magic.GRAVITY_ODD
|
||||||
&& yDistance > 0.4 * GRAVITY_ODD && yDistance - lastMove.yDistance < -GRAVITY_ODD / 2.0
|
&& yDistance > 0.4 * Magic.GRAVITY_ODD && yDistance - lastMove.yDistance < -Magic.GRAVITY_ODD / 2.0
|
||||||
// 1:
|
// 1:
|
||||||
|| lastMove.yDistance < 0.2 && lastMove.yDistance >= 0.0 && yDistance > -0.2 && yDistance < 2.0 * GRAVITY_MAX
|
|| lastMove.yDistance < 0.2 && lastMove.yDistance >= 0.0 && yDistance > -0.2 && yDistance < 2.0 * Magic.GRAVITY_MAX
|
||||||
// 1:
|
// 1:
|
||||||
|| lastMove.yDistance > 0.4 * GRAVITY_ODD && lastMove.yDistance < GRAVITY_MIN && yDistance == 0.0
|
|| lastMove.yDistance > 0.4 * Magic.GRAVITY_ODD && lastMove.yDistance < Magic.GRAVITY_MIN && yDistance == 0.0
|
||||||
// 1: Too small decrease, right after lift off.
|
// 1: Too small decrease, right after lift off.
|
||||||
|| data.sfJumpPhase == 1 && lastMove.yDistance > -GRAVITY_ODD && lastMove.yDistance <= GRAVITY_MAX + GRAVITY_SPAN
|
|| data.sfJumpPhase == 1 && lastMove.yDistance > -Magic.GRAVITY_ODD && lastMove.yDistance <= Magic.GRAVITY_MAX + Magic.GRAVITY_SPAN
|
||||||
&& yDistance - lastMove.yDistance < 0.0114
|
&& yDistance - lastMove.yDistance < 0.0114
|
||||||
// 1: Any leaving liquid and keeping distance once.
|
// 1: Any leaving liquid and keeping distance once.
|
||||||
|| data.sfJumpPhase == 1
|
|| data.sfJumpPhase == 1
|
||||||
@ -357,82 +251,6 @@ public class Magic {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for a specific move in-air -> water, then water -> in-air.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* Not strictly the latest move in MovingData.
|
|
||||||
* @param lastMove
|
|
||||||
* Move before thisMove.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean splashMove(final MoveData thisMove, final MoveData lastMove) {
|
|
||||||
// Use past move data for two moves.
|
|
||||||
return !thisMove.touchedGround && thisMove.from.inWater && !thisMove.to.resetCond // Out of water.
|
|
||||||
&& !lastMove.touchedGround && !lastMove.from.resetCond && lastMove.to.inWater // Into water.
|
|
||||||
&& excludeStaticSpeed(thisMove) && excludeStaticSpeed(lastMove)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test for a specific move ground/in-air -> water, then water -> in-air.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* Not strictly the latest move in MovingData.
|
|
||||||
* @param lastMove
|
|
||||||
* Move before thisMove.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean splashMoveNonStrict(final MoveData thisMove, final MoveData lastMove) {
|
|
||||||
// Use past move data for two moves.
|
|
||||||
return !thisMove.touchedGround && thisMove.from.inWater && !thisMove.to.resetCond // Out of water.
|
|
||||||
&& !lastMove.from.resetCond && lastMove.to.inWater // Into water.
|
|
||||||
&& excludeStaticSpeed(thisMove) && excludeStaticSpeed(lastMove)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Fully in-air move.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* Not strictly the latest move in MovingData.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean inAir(final MoveData thisMove) {
|
|
||||||
return !thisMove.touchedGround && !thisMove.from.resetCond && !thisMove.to.resetCond;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A liquid -> liquid move. Exclude web and climbable.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean inLiquid(final MoveData thisMove) {
|
|
||||||
return thisMove.from.inLiquid && thisMove.to.inLiquid && excludeStaticSpeed(thisMove);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moving out of liquid, might move onto ground. Exclude web and climbable.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean leavingLiquid(final MoveData thisMove) {
|
|
||||||
return thisMove.from.inLiquid && !thisMove.to.inLiquid && excludeStaticSpeed(thisMove);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exclude moving from/to blocks with static (vertical) speed, such as web
|
|
||||||
* or climbable.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static boolean excludeStaticSpeed(final MoveData thisMove) {
|
|
||||||
return !thisMove.from.inWeb && !thisMove.to.inWeb
|
|
||||||
&& !thisMove.from.onClimbable && !thisMove.to.onClimbable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Odd behavior with moving up or (slightly) down, not like the ordinary
|
* Odd behavior with moving up or (slightly) down, not like the ordinary
|
||||||
* friction mechanics, accounting for more than one past move. Needs
|
* friction mechanics, accounting for more than one past move. Needs
|
||||||
@ -454,77 +272,61 @@ public class Magic {
|
|||||||
// 0: First move into air, moving out of liquid.
|
// 0: First move into air, moving out of liquid.
|
||||||
// (These should probably be oddLiquid cases, might pull pastMove1 to vDistAir later.)
|
// (These should probably be oddLiquid cases, might pull pastMove1 to vDistAir later.)
|
||||||
(data.liftOffEnvelope == LiftOffEnvelope.LIMIT_NEAR_GROUND || data.liftOffEnvelope == LiftOffEnvelope.LIMIT_LIQUID)
|
(data.liftOffEnvelope == LiftOffEnvelope.LIMIT_NEAR_GROUND || data.liftOffEnvelope == LiftOffEnvelope.LIMIT_LIQUID)
|
||||||
&& data.sfJumpPhase == 1 && inAir(thisMove)
|
&& data.sfJumpPhase == 1 && Magic.inAir(thisMove)
|
||||||
&& (
|
&& (
|
||||||
// 1: Towards ascending rather.
|
// 1: Towards ascending rather.
|
||||||
pastMove1.yDistance > lastMove.yDistance - GRAVITY_MAX // Some speed decrease.
|
pastMove1.yDistance > lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
&& lastMove.yDistance > yDistance + GRAVITY_MAX && lastMove.yDistance > 0.0 // Positive speed. TODO: rather > 1.0 (!).
|
&& lastMove.yDistance > yDistance + Magic.GRAVITY_MAX && lastMove.yDistance > 0.0 // Positive speed. TODO: rather > 1.0 (!).
|
||||||
&& (
|
&& (
|
||||||
// 2: Odd speed decrease bumping into a block sideways somehow, having moved through water.
|
// 2: Odd speed decrease bumping into a block sideways somehow, having moved through water.
|
||||||
yDistDiffEx < 0.0 && splashMove(lastMove, pastMove1)
|
yDistDiffEx < 0.0 && Magic.splashMove(lastMove, pastMove1)
|
||||||
&& (
|
&& (
|
||||||
// 3: Odd too high decrease, after middle move being within friction envelope.
|
// 3: Odd too high decrease, after middle move being within friction envelope.
|
||||||
yDistance > lastMove.yDistance / 5.0
|
yDistance > lastMove.yDistance / 5.0
|
||||||
// 3: Two times about the same decrease (e.g. near 1.0), ending up near zero distance.
|
// 3: Two times about the same decrease (e.g. near 1.0), ending up near zero distance.
|
||||||
|| yDistance > -GRAVITY_MAX
|
|| yDistance > -Magic.GRAVITY_MAX
|
||||||
&& Math.abs(pastMove1.yDistance - lastMove.yDistance - (lastMove.yDistance - thisMove.yDistance)) < GRAVITY_MAX
|
&& Math.abs(pastMove1.yDistance - lastMove.yDistance - (lastMove.yDistance - thisMove.yDistance)) < Magic.GRAVITY_MAX
|
||||||
)
|
)
|
||||||
// 2: Almost keep speed (gravity only), moving out of lava with (high) velocity.
|
// 2: Almost keep speed (gravity only), moving out of lava with (high) velocity.
|
||||||
// (Needs jump phase == 1, to confine decrease from pastMove1 to lastMove.)
|
// (Needs jump phase == 1, to confine decrease from pastMove1 to lastMove.)
|
||||||
// TODO: Never seems to apply.
|
// TODO: Never seems to apply.
|
||||||
// TODO: Might explicitly demand (lava) friction decrease from pastMove1 to lastMove.
|
// TODO: Might explicitly demand (lava) friction decrease from pastMove1 to lastMove.
|
||||||
|| inLiquid(pastMove1) && leavingLiquid(lastMove) && lastMove.yDistance > 4.0 * GRAVITY_MAX
|
|| Magic.inLiquid(pastMove1) && Magic.leavingLiquid(lastMove) && lastMove.yDistance > 4.0 * Magic.GRAVITY_MAX
|
||||||
// TODO: Store applicable or used friction in MoveData and use enoughFrictionEnvelope?
|
// TODO: Store applicable or used friction in MoveData and use enoughFrictionEnvelope?
|
||||||
&& yDistance < lastMove.yDistance - Magic.GRAVITY_MAX
|
&& yDistance < lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
&& yDistance > lastMove.yDistance - 2.0 * Magic.GRAVITY_MAX
|
&& yDistance > lastMove.yDistance - 2.0 * Magic.GRAVITY_MAX
|
||||||
&& Math.abs(lastMove.yDistance - pastMove1.yDistance) > 4.0 * GRAVITY_MAX
|
&& Math.abs(lastMove.yDistance - pastMove1.yDistance) > 4.0 * Magic.GRAVITY_MAX
|
||||||
|
|
||||||
)
|
)
|
||||||
// 1: Less 'strict' speed increase, descending rather.
|
// 1: Less 'strict' speed increase, descending rather.
|
||||||
|| pastMove1.yDistance < 0.0
|
|| pastMove1.yDistance < 0.0
|
||||||
// Actual speed decrease due to water.
|
// Actual speed decrease due to water.
|
||||||
&& lastMove.yDistance - GRAVITY_MAX < yDistance && yDistance < 0.7 * lastMove.yDistance
|
&& lastMove.yDistance - Magic.GRAVITY_MAX < yDistance && yDistance < 0.7 * lastMove.yDistance
|
||||||
&& Math.abs(pastMove1.yDistance + lastMove.yDistance) > 2.5
|
&& Math.abs(pastMove1.yDistance + lastMove.yDistance) > 2.5
|
||||||
// (Actually splashMove or aw-ww-wa-aa)
|
// (Actually splashMove or aw-ww-wa-aa)
|
||||||
&& (splashMove(lastMove, pastMove1) && pastMove1.yDistance > lastMove.yDistance
|
&& (Magic.splashMove(lastMove, pastMove1) && pastMove1.yDistance > lastMove.yDistance
|
||||||
// Allow more decrease if moving through more solid water.
|
// Allow more decrease if moving through more solid water.
|
||||||
|| inLiquid(pastMove1) && leavingLiquid(lastMove) && pastMove1.yDistance *.7 > lastMove.yDistance)
|
|| Magic.inLiquid(pastMove1) && Magic.leavingLiquid(lastMove) && pastMove1.yDistance *.7 > lastMove.yDistance)
|
||||||
|
// 1: Strong decrease after rough keeping speed (hold space bar, with velocity, descending).
|
||||||
|
|| yDistance < - 0.5 // Arbitrary, actually observed was around 2.
|
||||||
|
&& pastMove1.yDistance < yDistance && lastMove.yDistance < yDistance
|
||||||
|
&& Math.abs(pastMove1.yDistance - lastMove.yDistance) < Magic.GRAVITY_ODD
|
||||||
|
&& yDistance < lastMove.yDistance * 0.67 && yDistance > lastMove.yDistance * data.lastFrictionVertical - Magic.GRAVITY_MIN
|
||||||
|
&& (Magic.splashMoveNonStrict(lastMove, pastMove1) || Magic.inLiquid(pastMove1) && Magic.leavingLiquid(lastMove))
|
||||||
)
|
)
|
||||||
// // 0: Odd normal envelope set
|
// 0: Odd normal envelope set.
|
||||||
// // TODO: (special case with splash move in SurvivalFly.check, might need replacing by new style workaround.)
|
// TODO: Replace special case with splash move in SurvivalFly.check by a new style workaround.
|
||||||
// || data.liftOffEnvelope == LiftOffEnvelope.NORMAL && data.sfJumpPhase == 1 && inAir(thisMove)
|
|| data.liftOffEnvelope == LiftOffEnvelope.NORMAL && data.sfJumpPhase == 1 && Magic.inAir(thisMove)
|
||||||
// && DebugUtil.debug("TEST1", true)
|
// && data.isVelocityJumpPhase()
|
||||||
// // && data.isVelocityJumpPhase()
|
// Velocity very fast into water above.
|
||||||
// // Velocity very fast into water above.
|
&& (Magic.splashMoveNonStrict(lastMove, pastMove1) || Magic.inLiquid(pastMove1) && Magic.leavingLiquid(lastMove))
|
||||||
// && (splashMoveNonStrict(lastMove, pastMove1) || inLiquid(pastMove1) && leavingLiquid(lastMove))
|
&& yDistance < lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
// // TODO: Store applicable or used friction in MoveData and use enoughFrictionEnvelope?
|
&& yDistance > lastMove.yDistance - 2.0 * Magic.GRAVITY_MAX
|
||||||
// && DebugUtil.debug("TEST2", true)
|
&& (Math.abs(lastMove.yDistance - pastMove1.yDistance) > 4.0 * Magic.GRAVITY_MAX
|
||||||
// && yDistance < lastMove.yDistance - Magic.GRAVITY_MAX
|
|| pastMove1.yDistance > 3.0 && lastMove.yDistance > 3.0 && Math.abs(lastMove.yDistance - pastMove1.yDistance) < 2.0 * Magic.GRAVITY_MAX)
|
||||||
// && yDistance > lastMove.yDistance - 2.0 * Magic.GRAVITY_MAX
|
|
||||||
// && DebugUtil.debug("TEST3", true)
|
|
||||||
// && (Math.abs(lastMove.yDistance - pastMove1.yDistance) > 4.0 * GRAVITY_MAX
|
|
||||||
// || pastMove1.yDistance > 3.0 && lastMove.yDistance > 3.0 && Math.abs(lastMove.yDistance - pastMove1.yDistance) < 2.0 * GRAVITY_MAX)
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* First move after set-back / teleport. Originally has been found with
|
|
||||||
* PaperSpigot for MC 1.7.10, however it also does occur on Spigot for MC
|
|
||||||
* 1.7.10.
|
|
||||||
*
|
|
||||||
* @param thisMove
|
|
||||||
* @param lastMove
|
|
||||||
* @param data
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static boolean skipPaper(final MoveData thisMove, final MoveData lastMove, final MovingData data) {
|
|
||||||
// TODO: Confine to from at block level (offset 0)?
|
|
||||||
final double setBackYDistance = thisMove.to.y - data.getSetBackY();
|
|
||||||
return !lastMove.toIsValid && data.sfJumpPhase == 0 && thisMove.mightBeMultipleMoves
|
|
||||||
&& setBackYDistance > 0.0 && setBackYDistance < PAPER_DIST
|
|
||||||
&& thisMove.yDistance > 0.0 && thisMove.yDistance < PAPER_DIST && inAir(thisMove);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Several types of odd in-air moves, mostly with gravity near maximum,
|
* Several types of odd in-air moves, mostly with gravity near maximum,
|
||||||
* friction, medium change. Needs lastMove.toIsValid.
|
* friction, medium change. Needs lastMove.toIsValid.
|
||||||
@ -541,49 +343,28 @@ public class Magic {
|
|||||||
* @param cc
|
* @param cc
|
||||||
* @return true if a workaround applies.
|
* @return true if a workaround applies.
|
||||||
*/
|
*/
|
||||||
static boolean oddJunction(final PlayerLocation from, final PlayerLocation to,
|
public static boolean oddJunction(final PlayerLocation from, final PlayerLocation to,
|
||||||
final double yDistance, final double yDistChange, final double yDistDiffEx,
|
final double yDistance, final double yDistChange, final double yDistDiffEx,
|
||||||
final double maxJumpGain, final boolean resetTo,
|
final double maxJumpGain, final boolean resetTo,
|
||||||
final MoveData lastMove, final MovingData data, final MovingConfig cc) {
|
final MoveData lastMove, final MovingData data, final MovingConfig cc) {
|
||||||
// TODO: Cleanup/reduce signature (accept thisMove.yDistance etc.).
|
// TODO: Cleanup/reduce signature (accept thisMove.yDistance etc.).
|
||||||
if (Magic.oddLiquid(yDistance, yDistDiffEx, maxJumpGain, resetTo, lastMove, data)) {
|
if (MagicAir.oddLiquid(yDistance, yDistDiffEx, maxJumpGain, resetTo, lastMove, data)) {
|
||||||
// Jump after leaving the liquid near ground.
|
// Jump after leaving the liquid near ground.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Magic.oddGravity(from, to, yDistance, yDistChange, yDistDiffEx, lastMove, data)) {
|
if (MagicAir.oddGravity(from, to, yDistance, yDistChange, yDistDiffEx, lastMove, data)) {
|
||||||
// Starting to fall / gravity effects.
|
// Starting to fall / gravity effects.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((yDistDiffEx > 0.0 || yDistance >= 0.0) && Magic.oddSlope(to, yDistance, maxJumpGain, yDistDiffEx, lastMove, data)) {
|
if ((yDistDiffEx > 0.0 || yDistance >= 0.0) && MagicAir.oddSlope(to, yDistance, maxJumpGain, yDistDiffEx, lastMove, data)) {
|
||||||
// Odd decrease after lift-off.
|
// Odd decrease after lift-off.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Magic.oddFriction(yDistance, yDistDiffEx, lastMove, data)) {
|
if (MagicAir.oddFriction(yDistance, yDistDiffEx, lastMove, data)) {
|
||||||
// Odd behavior with moving up or (slightly) down, accounting for more than one past move.
|
// Odd behavior with moving up or (slightly) down, accounting for more than one past move.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Disregarding this move, test if all the way falling after head being
|
|
||||||
* obstructed.
|
|
||||||
*
|
|
||||||
* @param data
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static boolean fallAfterHeadObstructed(final MovingData data, int limit) {
|
|
||||||
limit = Math.min(limit, data.moveData.size());
|
|
||||||
for (int i = 0; i < limit; i++) {
|
|
||||||
final MoveData move = data.moveData.get(i);
|
|
||||||
if (!move.toIsValid || move.yDistance >= 0.0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (move.headObstructed) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.checks.moving.magic;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic workarounds for moving in liquid (SurvivalFly.vDistLiquid).
|
||||||
|
*
|
||||||
|
* @author asofold
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MagicLiquid {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param from
|
||||||
|
* @param to
|
||||||
|
* @param baseSpeed
|
||||||
|
* @param frictDist
|
||||||
|
* @param thisMove
|
||||||
|
* @param lastMove
|
||||||
|
* @param data
|
||||||
|
* @return The allowed distance for reference, in case the move is allowed.
|
||||||
|
* If no workaround applies, null is returned.
|
||||||
|
*/
|
||||||
|
public static Double liquidWorkarounds(final PlayerLocation from, final PlayerLocation to, final double baseSpeed, final double frictDist, final MoveData lastMove, final MovingData data) {
|
||||||
|
final MoveData thisMove = data.thisMove;
|
||||||
|
final double yDistance = thisMove.yDistance;
|
||||||
|
// Special cases.
|
||||||
|
// TODO: Re-arrange.
|
||||||
|
final MoveData pastMove1 = data.moveData.get(1);
|
||||||
|
if (yDistance >= 0) {
|
||||||
|
// TODO: liftOffEnvelope: refine conditions (general) , should be near water level.
|
||||||
|
// TODO: 1.5 high blocks ?
|
||||||
|
// TODO: Conditions seem warped.
|
||||||
|
if (yDistance <= 0.5) {
|
||||||
|
if (lastMove.toIsValid && yDistance < lastMove.yDistance
|
||||||
|
&& lastMove.yDistance - yDistance > Math.max(0.001, yDistance - baseSpeed)) {
|
||||||
|
// Decrease more than difference to baseSpeed.
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
if (yDistance <= data.liftOffEnvelope.getMaxJumpGain(data.jumpAmplifier) && !BlockProperties.isLiquid(from.getTypeIdAbove())
|
||||||
|
// TODO: What now !?
|
||||||
|
|| !to.isInLiquid() // TODO: impossible !?
|
||||||
|
|| (thisMove.to.onGround || lastMove.toIsValid && lastMove.yDistance - yDistance >= 0.010 || to.isAboveStairs())) {
|
||||||
|
double vAllowedDistance = baseSpeed + 0.5;
|
||||||
|
double vDistanceAboveLimit = yDistance - vAllowedDistance;
|
||||||
|
if (vDistanceAboveLimit <= 0.0) {
|
||||||
|
return vAllowedDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastMove.toIsValid) {
|
||||||
|
// Lenient on marginal violation if speed decreases by 'enough'.
|
||||||
|
// (Observed on 'dirty' phase.)
|
||||||
|
if (Math.abs(frictDist - yDistance) <= 2.0 * Magic.GRAVITY_MAX
|
||||||
|
&& yDistance < lastMove.yDistance - 4.0 * Math.abs(frictDist - yDistance)
|
||||||
|
) {
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
// Jumping with velocity into water from below, just slightly more decrease than gravity, twice.
|
||||||
|
if (yDistance > frictDist && yDistance < lastMove.yDistance - Magic.GRAVITY_MAX && data.insideMediumCount <= 1) {
|
||||||
|
// (Should be able to do without aw-ww-ww confinement.)
|
||||||
|
// (dirty seems to be set/kept reliably)
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
if (pastMove1.toIsValid && pastMove1.to.extraPropertiesValid) {
|
||||||
|
// Cases considering two past moves with moving up.
|
||||||
|
// Splash move with space space pressed (this move leaving liquid).
|
||||||
|
if (pastMove1.yDistance > 0.0 && thisMove.yDistance > 0.0
|
||||||
|
&& pastMove1.yDistance - Magic.GRAVITY_MAX > lastMove.yDistance
|
||||||
|
&& lastMove.yDistance - Magic.GRAVITY_ODD > thisMove.yDistance
|
||||||
|
&& Magic.intoLiquid(lastMove) && Magic.leavingLiquid(thisMove)
|
||||||
|
) {
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
// Velocity use in lastMove, keep air friction roughly.
|
||||||
|
if (!Magic.resetCond(pastMove1) && lastMove.yDistance - Magic.GRAVITY_MAX > thisMove.yDistance
|
||||||
|
&& Magic.intoLiquid(lastMove) && Magic.leavingLiquid(thisMove)
|
||||||
|
) {
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise, only if last move is available.
|
||||||
|
else if (lastMove.toIsValid) {
|
||||||
|
// TODO: Are all these cases really for descending?
|
||||||
|
// Falling into water, mid-speed (second move after diving in).
|
||||||
|
if (yDistance > -0.9 && yDistance < lastMove.yDistance
|
||||||
|
&& Math.abs(yDistance - lastMove.yDistance) <= Magic.GRAVITY_MAX + Magic.GRAVITY_MIN
|
||||||
|
&& yDistance - lastMove.yDistance < -Magic.GRAVITY_MIN
|
||||||
|
//&& !BlockProperties.isLiquid(to.getTypeId(to.getBlockX(), Location.locToBlock(to.getY() + to.getEyeHeight()), to.getBlockZ()))
|
||||||
|
) {
|
||||||
|
return lastMove.yDistance - Magic.GRAVITY_MAX - Magic.GRAVITY_MIN;
|
||||||
|
}
|
||||||
|
// Increase speed slightly on second in-medium move (dirty flag may have been reset).
|
||||||
|
else if (data.insideMediumCount <= 1
|
||||||
|
// (No strong decrease:)
|
||||||
|
&& yDistance > lastMove.yDistance - Magic.GRAVITY_MAX
|
||||||
|
&& (
|
||||||
|
// Ordinary (some old case).
|
||||||
|
lastMove.yDistance < 0.8 && yDistance < lastMove.yDistance - Magic.GRAVITY_ODD / 2.0
|
||||||
|
// Check with three moves, rather shortly touching water.
|
||||||
|
|| lastMove.yDistance < -0.5 // Arbitrary, actually observed has been < -1.0
|
||||||
|
&& pastMove1.toIsValid && pastMove1.to.extraPropertiesValid
|
||||||
|
&& Math.abs(pastMove1.yDistance - lastMove.yDistance) < Magic.GRAVITY_MIN
|
||||||
|
&& yDistance <= lastMove.yDistance
|
||||||
|
&& Magic.inLiquid(lastMove) && Magic.intoLiquid(pastMove1)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
// In-water rough near-0-inversion from allowed speed to a negative amount, little more than allowed (magic -0.2 roughly).
|
||||||
|
else if (lastMove.yDistance >= Magic.GRAVITY_MAX / 10.0 && lastMove.yDistance <= Magic.GRAVITY_MAX + Magic.GRAVITY_MIN / 2.0
|
||||||
|
&& yDistance < 0.0 && yDistance > -2.0 * Magic.GRAVITY_MAX - Magic.GRAVITY_MIN / 2.0
|
||||||
|
&& to.isInLiquid() // TODO: Might skip the liquid check, though.
|
||||||
|
&& lastMove.from.inLiquid && lastMove.to.extraPropertiesValid && lastMove.to.inLiquid // TODO: in water only?
|
||||||
|
) {
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
// Lava rather.
|
||||||
|
else if (data.lastFrictionVertical < 0.65 // (Random, but smaller than water.)
|
||||||
|
&& (
|
||||||
|
// Moving downstream.
|
||||||
|
lastMove.yDistance < 0.0 && yDistance > -0.5 && yDistance < lastMove.yDistance
|
||||||
|
&& lastMove.yDistance - yDistance < Magic.GRAVITY_MIN && BlockProperties.isDownStream(from, to)
|
||||||
|
// Mix of gravity and base speed [careful: relates to water base speed].
|
||||||
|
|| lastMove.yDistance < 0.0 && yDistance > -baseSpeed - Magic.GRAVITY_MAX && yDistance < lastMove.yDistance
|
||||||
|
&& lastMove.yDistance - yDistance > Magic.GRAVITY_SPAN
|
||||||
|
&& Math.abs(lastMove.yDistance + baseSpeed) < 0.25 * baseSpeed
|
||||||
|
// Falling slightly too fast in lava.
|
||||||
|
|| data.insideMediumCount == 1 || data.insideMediumCount == 2
|
||||||
|
&& lastMove.yDistance < 0.0 && yDistance < lastMove.yDistance
|
||||||
|
&& yDistance - lastMove.yDistance > -Magic.GRAVITY_MIN && yDistance > -0.65
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return yDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Also DOWNSTREAM !?
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user