Bleeding/Instable: More aggressive NoFall [no violations], creativefly

with accounting option.
This commit is contained in:
asofold 2012-10-05 03:37:10 +02:00
parent 59063c7497
commit 73d2f79f8a
7 changed files with 283 additions and 99 deletions

View File

@ -79,6 +79,7 @@ public class MovingConfig extends ACheckConfig {
public final ActionList morePacketsVehicleActions;
public final boolean noFallCheck;
public final boolean noFallDealDamage;
public final ActionList noFallActions;
public final boolean passableCheck;
@ -92,6 +93,7 @@ public class MovingConfig extends ACheckConfig {
public final int survivalFlySwimmingSpeed;
public final int survivalFlyWalkingSpeed;
public final boolean survivalFlyCobwebHack;
public final boolean survivalFlyAccounting;
public final ActionList survivalFlyActions;
// Special tolerance values:
@ -125,6 +127,7 @@ public class MovingConfig extends ACheckConfig {
Permissions.MOVING_MOREPACKETS);
noFallCheck = data.getBoolean(ConfPaths.MOVING_NOFALL_CHECK);
noFallDealDamage = data.getBoolean(ConfPaths.MOVING_NOFALL_DEALDAMAGE);
noFallActions = data.getActionList(ConfPaths.MOVING_NOFALL_ACTIONS, Permissions.MOVING_NOFALL);
passableCheck = data.getBoolean(ConfPaths.MOVING_PASSABLE_CHECK);
@ -139,6 +142,7 @@ public class MovingConfig extends ACheckConfig {
survivalFlySwimmingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_SWIMMINGSPEED, 100);
survivalFlyWalkingSpeed = data.getInt(ConfPaths.MOVING_SURVIVALFLY_WALKINGSPEED, 100);
survivalFlyCobwebHack = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_COBWEBHACK, true);
survivalFlyAccounting = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_ACCOUNTING);
survivalFlyActions = data.getActionList(ConfPaths.MOVING_SURVIVALFLY_ACTIONS, Permissions.MOVING_SURVIVALFLY);
yOnGround = data.getDouble(ConfPaths.MOVING_YONGROUND, 0.001, 2.0, 0.001);

View File

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.utilities.ActionFrequency;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
/*
@ -101,9 +102,11 @@ public class MovingData extends ACheckData {
public Location morePacketsVehicleSetback;
// Data of the no fall check.
public double noFallFallDistance;
public boolean noFallOnGround;
public boolean noFallWasOnGround;
public float noFallFallDistance;
// public boolean noFallOnGround;
// public boolean noFallWasOnGround;
/** Last y coordinate from when the player was on ground. */
public double noFallMaxY;
// Passable check.
public double passableVL;
@ -118,9 +121,10 @@ public class MovingData extends ACheckData {
// Accounting info.
// TODO: optimize later.
// public final ActionFrequency hDistSum = new ActionFrequency(3, 333);
// public final ActionFrequency vDistSum = new ActionFrequency(3, 333);
// public final ActionFrequency hvDistCount = new ActionFrequency(3, 333);
public final ActionFrequency hDistSum = new ActionFrequency(3, 333);
public final ActionFrequency vDistSum = new ActionFrequency(3, 333);
public final ActionFrequency hDistCount = new ActionFrequency(3, 333);
public final ActionFrequency vDistCount = new ActionFrequency(3, 333);
// Locations shared between all checks.
public final PlayerLocation from = new PlayerLocation();
@ -130,20 +134,24 @@ public class MovingData extends ACheckData {
public final PlayerLocation to = new PlayerLocation();
/**
* Clear the data of the fly checks.
* Clear the data of the fly checks (not more-packets).
*/
public void clearFlyData() {
bunnyhopDelay = 0;
noFallFallDistance = 0D;
survivalFlyJumpPhase = 0;
setBack = null;
// final long now = System.currentTimeMillis();
// hDistSum.clear(now);
// vDistSum.clear(now);
// hvDistCount.clear(now);
clearAccounting();
clearNoFallData();
}
public void clearAccounting() {
final long now = System.currentTimeMillis();
hDistSum.clear(now);
vDistSum.clear(now);
hDistCount.clear(now);
vDistCount.clear(now);
}
/**
* Clear the data of the more packets checks.
*/
@ -156,7 +164,8 @@ public class MovingData extends ACheckData {
* Clear the data of the new fall check.
*/
public void clearNoFallData() {
noFallOnGround = noFallWasOnGround = true;
noFallFallDistance = 0D;
// noFallOnGround = noFallWasOnGround = true;
noFallFallDistance = 0;
noFallMaxY = 0D;
}
}

View File

@ -12,6 +12,8 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBedLeaveEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
@ -448,6 +450,7 @@ public class MovingListener implements Listener {
data.clearMorePacketsData();
// Always drop data from fly checks, as it always loses its validity after teleports. Always!
// TODO: NoFall might be necessary to be checked here ?
data.teleported = null;
data.clearFlyData();
}
@ -549,4 +552,27 @@ public class MovingListener implements Listener {
}
}.set(vehicle, newTo), 1L);
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
public void onEntityDamage(final EntityDamageEvent event){
if (event.getCause() != DamageCause.FALL) return;
final Entity entity = event.getEntity();
if (!(entity instanceof Player)) return;
final Player player = (Player) entity;
if (!survivalFly.isEnabled(player)) return;
if (!noFall.isEnabled(player)) return;
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingData data = MovingData.getData(player);
final float fallDistance = player.getFallDistance();
final int damage = event.getDamage();
if (cc.debug) System.out.println(player.getName() + " damage(FALL): " + damage + " / dist=" + player.getFallDistance() + " nf=" + data.noFallFallDistance);
// Fall-back check.
final int maxD = NoFall.getDamage(Math.max(fallDistance, Math.max(data.noFallFallDistance, (float) (data.noFallMaxY - player.getLocation().getY()))));
if (maxD > damage){
event.setDamage(maxD);
if (cc.debug) System.out.println(player.getName() + " Adjust fall damage to: " + maxD);
}
data.clearNoFallData();
// Entity fall-distance should be reset elsewhere.
}
}

View File

@ -3,11 +3,14 @@ package fr.neatmonster.nocheatplus.checks.moving;
import java.util.Locale;
import java.util.Map;
import net.minecraft.server.DamageSource;
import net.minecraft.server.EntityPlayer;
import org.bukkit.Location;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
@ -35,6 +38,43 @@ public class NoFall extends Check {
public NoFall() {
super(CheckType.MOVING_NOFALL);
}
/**
* Calculate the damage in hearts from the given fall distance.
* @param fallDistance
* @return
*/
protected static final int getDamage(final float fallDistance){
return 1 + (int) (fallDistance - 3.5);
}
/**
* Deal damage if appropriate. To be used for if the player is on ground somehow.
* @param mcPlayer
* @param data
* @param y
*/
private static final void handleOnGround(final EntityPlayer mcPlayer, final MovingData data, final double y, final MovingConfig cc) {
// final int pD = getDamage(mcPlayer.fallDistance);
// final int nfD = getDamage(data.noFallFallDistance);
// final int yD = getDamage((float) (data.noFallMaxY - y));
// final int maxD = Math.max(Math.max(pD, nfD), yD);
final int maxD = getDamage(Math.max(mcPlayer.fallDistance, Math.max(data.noFallFallDistance, (float) (data.noFallMaxY - y))));
if (maxD > 0){
// Damage to be dealt.
// TODO: more effects like sounds, maybe use custom event with violation added.
if (cc.debug) System.out.println(mcPlayer.name + " NoFall deal damage: " + maxD);
final EntityDamageEvent event = new EntityDamageEvent(mcPlayer.getBukkitEntity(), DamageCause.FALL, maxD);
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()){
mcPlayer.damageEntity(DamageSource.FALL, event.getDamage());
}
// TODO: let this be done by the damage event (!).
// data.clearNoFallData(); // -> currently done in the damage eventhandling method.
mcPlayer.fallDistance = 0;
}
else data.clearNoFallData();
}
/**
* Checks a player.
@ -49,52 +89,120 @@ public class NoFall extends Check {
public void check(final Player player, final MovingData data, final MovingConfig cc) {
final PlayerLocation from = data.from;
final PlayerLocation to = data.to;
// Reset the on ground properties only if necessary.
if (from.getY() > to.getY()){
// Reset the on ground properties only if necessary.
if (from.getyOnGround() != cc.noFallyOnGround && (from.getY() - (double) Location.locToBlock(from.getY()) < cc.noFallyOnGround))
if (from.getyOnGround() != cc.noFallyOnGround && from.getY() - from.getBlockY() < cc.noFallyOnGround)
from.setyOnGround(cc.noFallyOnGround);
if (to.getyOnGround() != cc.noFallyOnGround && (to.getY() - (double) Location.locToBlock(to.getY()) < cc.noFallyOnGround))
if (to.getyOnGround() != cc.noFallyOnGround && to.getY() - to.getBlockY() < cc.noFallyOnGround)
to.setyOnGround(cc.noFallyOnGround);
}
data.noFallWasOnGround = data.noFallOnGround;
data.noFallOnGround = to.isOnGround();
// If the player is on the ground, is falling into a liquid, in web or is on a ladder.
if (from.isOnGround() && to.isOnGround() || to.isInLiquid() || to.isInWeb() || to.isOnLadder())
data.noFallFallDistance = 0D;
// If the player just touched the ground for the server.
if (!data.noFallWasOnGround && data.noFallOnGround) {
// If the difference between the fall distance recorded by Bukkit and NoCheatPlus is too big and the fall
// distance bigger than 2.
if (data.noFallFallDistance - player.getFallDistance() > 0.1D && data.noFallFallDistance > 3) {
// Add the difference to the violation level.
data.noFallVL += data.noFallFallDistance - player.getFallDistance();
// Execute the actions to find out if we need to cancel the event or not.
if (executeActions(player, data.noFallVL, data.noFallFallDistance - player.getFallDistance(),
cc.noFallActions))
// Set the fall distance to its right value.
player.setFallDistance((float) data.noFallFallDistance);
} else
// Reward the player by lowering his violation level.
data.noFallVL *= 0.95D;
} else
// Reward the player by lowering his violation level.
data.noFallVL *= 0.95D;
// The player has touched the ground somewhere, reset his fall distance.
if (!data.noFallWasOnGround && data.noFallOnGround || data.noFallWasOnGround && !data.noFallOnGround)
data.noFallFallDistance = 0D;
final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
if (to.getY() > 0 && entityPlayer.locY > to.getY())
data.noFallFallDistance += entityPlayer.locY - to.getY();
// TODO: Distinguish water depth vs. fall distance!
final boolean fromOnGround = from.isOnGround();
final boolean fromReset = from.isInLiquid() || from.isInWeb() || from.isOnLadder();
final boolean toOnGround = to.isOnGround();
final boolean toReset = to.isInLiquid() || to.isInWeb() || to.isOnLadder();
final EntityPlayer mcPlayer = ((CraftPlayer) player).getHandle();
// TODO: early returns (...)
if (fromReset){
// Just reset.
data.clearNoFallData();
}
else if (fromOnGround){
// Check if to deal damage (fall back damage check).
if (cc.noFallDealDamage) handleOnGround(mcPlayer, data, from.getY(), cc);
else data.clearNoFallData();
}
else if (toReset){
// Just reset.
data.clearNoFallData();
}
else if (toOnGround){
// Check if to deal damage.
if (cc.noFallDealDamage) handleOnGround(mcPlayer, data, to.getY(), cc);
else data.clearNoFallData();
}
else{
// Ensure fall distance is correct ? or anyway !
}
// Set reference y for nofall (always).
data.noFallMaxY = Math.max(Math.max(from.getY(), to.getY()), data.noFallMaxY);
// TODO: fall distance might be behind (!)
// TODO: should be the data.noFallMaxY be counted in ?
if (cc.debug) System.out.println(player.getName() + " NoFall: mc="+mcPlayer.fallDistance +" / nf=" + data.noFallFallDistance);
data.noFallFallDistance = Math.max(mcPlayer.fallDistance, data.noFallFallDistance);
final double yDiff = to.getY() - from.getY();
// Add y distance.
if (!toReset && !toOnGround && yDiff < 0){
data.noFallFallDistance -= yDiff;
}
// // OLD ----------------------------------------
//
//
// data.noFallWasOnGround = data.noFallOnGround;
// data.noFallOnGround = to.isOnGround();
//
// // If the player is on the ground, is falling into a liquid, in web or is on a ladder.
// if (from.isOnGround() && to.isOnGround() || to.isInLiquid() || to.isInWeb() || to.isOnLadder())
// data.noFallFallDistance = 0;
//
// // If the player just touched the ground for the server.
// if (data.noFallFallDistance > 3.5){
//
//
//
// if (!data.noFallWasOnGround && data.noFallOnGround) {
// // If the difference between the fall distance recorded by Bukkit and NoCheatPlus is too big and the fall
// // distance bigger than 2.
//
// // TODO: 3.5 ?
// if (data.noFallFallDistance - player.getFallDistance() > 0.1D) {
// // Add the difference to the violation level.
// data.noFallVL += data.noFallFallDistance - player.getFallDistance();
//
// // Execute the actions to find out if we need to cancel the event or not.
// if (executeActions(player, data.noFallVL, data.noFallFallDistance - player.getFallDistance(),
// cc.noFallActions))
// // Set the fall distance to its right value.
// if (cc.noFallDealDamage){
// // TODO: round ?
// ((CraftPlayer) player).getHandle().damageEntity(DamageSource.FALL, 1 + (int) (data.noFallFallDistance - 3.5));
// data.clearNoFallData();
// }
// else player.setFallDistance((float) data.noFallFallDistance);
// } else
// // Reward the player by lowering his violation level.
// data.noFallVL *= 0.95D;
// } else{
// // Reward the player by lowering his violation level.
// data.noFallVL *= 0.95D;
// if (cc.noFallDealDamage && data.noFallOnGround){
// // TODO: round ?
// ((CraftPlayer) player).getHandle().damageEntity(DamageSource.FALL, 1 + (int) (data.noFallFallDistance - 3.5));
// data.clearNoFallData();
// }
// }
// }
// else data.noFallVL *= 0.95D;
//
// // The player has touched the ground somewhere, reset his fall distance.
// if (!data.noFallWasOnGround && data.noFallOnGround || data.noFallWasOnGround && !data.noFallOnGround)
// data.noFallFallDistance = 0;
//
// if (to.getY() > 0 && from.getY() > to.getY())
// data.noFallFallDistance += from.getY() - to.getY();
}
@Override
@Override
protected Map<ParameterName, String> getParameterMap(final ViolationData violationData) {
final Map<ParameterName, String> parameters = super.getParameterMap(violationData);
parameters.put(ParameterName.FALL_DISTANCE, String.format(Locale.US, "%.2f", MovingData.getData(violationData.player).noFallFallDistance));

View File

@ -207,16 +207,18 @@ public class SurvivalFly extends Check {
// If the player has touched the ground but it hasn't been noticed by the plugin, the workaround is here.
final double setBackYDistance = to.getY() - data.setBack.getY();
if (!fromOnGround
&& (from.getY() < data.survivalFlyLastFromY && yDistance > 0D && yDistance < 0.5D
if (!fromOnGround && (from.getY() < data.survivalFlyLastFromY && yDistance > 0D && yDistance < 0.5D
&& setBackYDistance > 0D && setBackYDistance <= 1.5D || !toOnGround && to.isAboveStairs())) {
// System.out.println("*** reset setback.");
// Set the new setBack and reset the jumpPhase.
// TODO: this allows exploits !
data.setBack = from.getLocation();
data.setBack.setY(Math.floor(data.setBack.getY()));
data.survivalFlyJumpPhase = 0;
// Reset the no fall data.
data.clearNoFallData();
if (cc.debug) System.out.println(player.getName() + " RESET NOFALL (WORKAROUND)");
}
data.survivalFlyLastFromY = from.getY();
@ -226,7 +228,7 @@ public class SurvivalFly extends Check {
// Very simple: force players to descend or stay.
vAllowedDistance = from.isOnGround() ? 0.1D : 0;
data.jumpAmplifier = 0;
vDistanceAboveLimit = to.getY() - from.getY();
vDistanceAboveLimit = yDistance;
if (cc.survivalFlyCobwebHack && vDistanceAboveLimit > 0 && hDistanceAboveLimit <= 0){
if (now - data.survivalFlyCobwebTime > 3000){
data.survivalFlyCobwebTime = now;
@ -253,14 +255,43 @@ public class SurvivalFly extends Check {
// System.out.println("vda = " +vDistanceAboveLimit + " / vc = " + data.verticalVelocityCounter + " / vf = " + data.verticalFreedom + " / v = " + player.getVelocity().length());
// Step can also be blocked.
if (fromOnGround && toOnGround && Math.abs(to.getY() - from.getY() - 1D) <= cc.yStep && vDistanceAboveLimit <= 0D
if (fromOnGround && toOnGround && Math.abs(yDistance - 1D) <= cc.yStep && vDistanceAboveLimit <= 0D
&& !player.hasPermission(Permissions.MOVING_SURVIVALFLY_STEP))
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.abs(to.getY() - from.getY()));
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.abs(yDistance));
}
if (fromOnGround || toOnGround)
data.jumpAmplifier = 0D;
final boolean resetFrom = fromOnGround || from.isInLiquid() || from.isOnLadder() || from.isInWeb();
if (cc.survivalFlyAccounting && !resetFrom){
final boolean useH = data.horizontalFreedom <= 0.001D;
final boolean useV = data.verticalFreedom <= 0.001D;
if (useH){
data.hDistSum.add(now, (float) hDistance);
data.hDistCount.add(now, 1f);
}
if (useV){
data.vDistSum.add(now, (float) (yDistance));
data.vDistCount.add(now, 1f);
}
if (useH && data.hDistCount.getScore(2) > 0){
final float hsc0 = data.hDistSum.getScore(1);
final float hsc1 = data.hDistSum.getScore(2);
if (hsc0 < hsc1 || hDistance < 3.9 && hsc0 == hsc1){
hDistanceAboveLimit = Math.max(hDistanceAboveLimit, hsc0 - hsc1);
}
}
if (useV && data.vDistCount.getScore(2) > 0){
final float vsc0 = data.vDistSum.getScore(1);
final float vsc1 = data.vDistSum.getScore(2);
if (vsc0 < vsc1 || yDistance < 3.9 && vsc0 == vsc1){
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, vsc0 - vsc1);
}
}
}
final double result = (Math.max(hDistanceAboveLimit, 0D) + Math.max(vDistanceAboveLimit, 0D)) * 100D;
data.survivalFlyJumpPhase++;
@ -268,15 +299,11 @@ public class SurvivalFly extends Check {
// Slowly reduce the level with each event.
data.survivalFlyVL *= 0.95D;
// data.hDistSum.add(now, (float) hDistance);
// data.vDistSum.add(now, (float) (to.getY() - from.getY()));
// data.hvDistCount.add(now, 1f);
if (cc.debug){
System.out.println(player.getName() + " vertical freedom: " + data.verticalFreedom + " ("+data.verticalVelocity+"/"+data.verticalVelocityCounter+")");
System.out.println(player.getName() + " hDist: " + hDistance + " / " + hAllowedDistance + " , vDist: " + (to.getY() - from.getY()) + " ("+player.getVelocity().getY()+")" + " / " + vAllowedDistance + " / from passable: " + BlockProperties.isPassable(from));
System.out.println(player.getName() + " hDist: " + hDistance + " / " + hAllowedDistance + " , vDist: " + (yDistance) + " ("+player.getVelocity().getY()+")" + " / " + vAllowedDistance);
System.out.println(player.getName() + " y: " + from.getY() +"(" + player.getLocation().getY() + ") -> " + to.getY()) ;
// System.out.println(player.getName() + " h=" + data.hDistSum.getScore(1f)+"/" + data.hDistSum.getScore(1) + " , v=" + data.vDistSum.getScore(1f)+"/"+data.vDistSum.getScore(1) );
if (cc.survivalFlyAccounting) System.out.println(player.getName() + " h=" + data.hDistSum.getScore(1f)+"/" + data.hDistSum.getScore(1) + " , v=" + data.vDistSum.getScore(1f)+"/"+data.vDistSum.getScore(1) );
}
// Did the player move in unexpected ways?// Did the player move in unexpected ways?
@ -284,49 +311,55 @@ public class SurvivalFly extends Check {
// System.out.println(BlockProperties.isStairs(from.getTypeIdBelow()) + " / " + BlockProperties.isStairs(to.getTypeIdBelow()));
// Increment violation counter.
data.survivalFlyVL += result;
data.clearAccounting();
data.survivalFlyJumpPhase = 0;
// If the other plugins haven't decided to cancel the execution of the actions, then do it. If one of the
// actions was a cancel, cancel it.
if (executeActions(player, data.survivalFlyVL, result, MovingConfig.getConfig(player).survivalFlyActions))
if (executeActions(player, data.survivalFlyVL, result, MovingConfig.getConfig(player).survivalFlyActions)){
// Compose a new location based on coordinates of "newTo" and viewing direction of "event.getTo()" to
// allow the player to look somewhere else despite getting pulled back by NoCheatPlus.
return new Location(player.getWorld(), data.setBack.getX(), data.setBack.getY(), data.setBack.getZ(),
to.getYaw(), to.getPitch());
}
else if (to.isInLiquid() || to.isInWeb() || toOnGround || to.isOnLadder()) {
// In case it only gets logged, not stopped by NoCheatPlus, update the setback location at least a bit.
data.setBack = to.getLocation();
data.survivalFlyJumpPhase = 0;
}
}
else{
final boolean resetTo = toOnGround || to.isInLiquid() || to.isOnLadder()|| to.isInWeb();
// if (to.isInLiquid()) {
// // If the player moved into liquid.
// data.setBack = to.getLocation();
// data.setBack.setY(Math.ceil(data.setBack.getY()));
// data.survivalFlyJumpPhase = 0;
// data.clearAccounting();
// } else if (resetTo && (from.getY() >= to.getY() || data.setBack.getY() <= Math.floor(to.getY()))) {
// // Set set back and jump phase, if:
// // 1. Moving onto ladder/vine.
// /*
// * 2. If the player moved down "onto" the ground or in web and ...
// * the new setback point is higher up than the old or at
// * least at the same height.
// */
// data.setBack = to.getLocation();
// data.survivalFlyJumpPhase = 0;
// data.clearAccounting();
// } else
if (resetTo){
// The player has moved onto ground.
data.setBack = to.getLocation();
data.survivalFlyJumpPhase = 0;
data.clearAccounting();
}
else if (resetFrom){
// The player moved from ground.
data.setBack = from.getLocation();
data.clearAccounting();
}
}
// Decide if we should create a new setBack point. These are the result of a lot of bug reports, experience and
// trial and error.
else if (to.isInLiquid()) {
// If the player moved into liquid.
data.setBack = to.getLocation();
data.setBack.setY(Math.ceil(data.setBack.getY()));
data.survivalFlyJumpPhase = 0;
} else if (to.isOnLadder()
|| (to.isInWeb() || toOnGround) && (from.getY() >= to.getY() || data.setBack.getY() <= Math.floor(to.getY()))) {
// Set set back and jump phase, if:
// 1. Moving onto ladder/vine.
/*
* 2. If the player moved down "onto" the ground or in web and ...
* the new setback point is higher up than the old or at
* least at the same height.
*/
data.setBack = to.getLocation();
data.survivalFlyJumpPhase = 0;
} else {
if (from.isInLiquid() || fromOnGround || from.isInWeb() || from.isOnLadder()){
data.setBack = from.getLocation();
if ( to.isInLiquid() || to.isInWeb() || toOnGround || to.isOnLadder()){
// The player at least touched the ground somehow.
data.survivalFlyJumpPhase = 0;
}
}
}
return null;
}

View File

@ -452,6 +452,7 @@ public abstract class ConfPaths {
private static final String MOVING_NOFALL = MOVING + "nofall.";
public static final String MOVING_NOFALL_CHECK = MOVING_NOFALL + "active";
public static final String MOVING_NOFALL_DEALDAMAGE = MOVING_NOFALL + "dealdamage";
public static final String MOVING_NOFALL_ACTIONS = MOVING_NOFALL + "actions";
public static final String MOVING_PASSABLE = MOVING + "passable.";
@ -467,6 +468,7 @@ public abstract class ConfPaths {
public static final String MOVING_SURVIVALFLY_SWIMMINGSPEED = MOVING_SURVIVALFLY + "swimmingspeed";
public static final String MOVING_SURVIVALFLY_WALKINGSPEED = MOVING_SURVIVALFLY + "walkingspeed";
public static final String MOVING_SURVIVALFLY_COBWEBHACK = MOVING_SURVIVALFLY + "cobwebhack";
public static final String MOVING_SURVIVALFLY_ACCOUNTING = MOVING_SURVIVALFLY + "accounting";
public static final String MOVING_SURVIVALFLY_ACTIONS = MOVING_SURVIVALFLY + "actions";
// Special (to be sorted in or factored out).

View File

@ -345,16 +345,18 @@ public class DefaultConfig extends ConfigFile {
"cancel vl>10 log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_NOFALL_CHECK, true);
set(ConfPaths.MOVING_NOFALL_DEALDAMAGE, true);
set(ConfPaths.MOVING_NOFALL_ACTIONS, "cancel vl>0 log:nofall:0:5:if cancel vl>6 log:nofall:0:5:icf cancel");
set(ConfPaths.MOVING_PASSABLE_CHECK, true);
set(ConfPaths.MOVING_PASSABLE_ACTIONS, "cancel vl>5 log:passable:0:5:if cancel vl>50 log:passable:0:5:icf cancel");
set(ConfPaths.MOVING_SURVIVALFLY_CHECK, true);
set(ConfPaths.MOVING_SURVIVALFLY_ACCOUNTING, true);
// The settings aren't enabled by default. Simply write them yourself in the configuration file.
// set(ConfPaths.MOVING_SURVIVALFLY_BLOCKINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SNEAKINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SPEEDINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SPEEDINGSPEED, 200);
// set(ConfPaths.MOVING_SURVIVALFLY_SPRINTINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_SWIMMINGSPEED, 100);
// set(ConfPaths.MOVING_SURVIVALFLY_WALKINGSPEED, 100);