- Refined "nofall" check, to only "punish" for the perceived

difference in fall distances
- slightly modified falldamage calculation in general, to always count
the "last step" as part of the fall (fixes a loophole that could be
used for bypassing the nofall check)
- replaced default nofall damage multiplier with 120 (was 200)
This commit is contained in:
Evenprime 2011-10-03 18:23:33 +02:00
parent e67a1f2c0c
commit 3d28e5738f
7 changed files with 42 additions and 20 deletions

View File

@ -3,7 +3,7 @@ name: NoCheat
author: Evenprime
main: cc.co.evenprime.bukkit.nocheat.NoCheat
version: 2.08b
version: 2.08c
commands:
nocheat:

View File

@ -85,7 +85,7 @@ public class DefaultConfiguration {
walkactions.add(400, "moveLogHighShort moveCancel");
runflyNode.add(new BooleanOption("checknofall", true, false));
runflyNode.add(new IntegerOption("nofallmultiplier", 200));
runflyNode.add(new IntegerOption("nofallmultiplier", 120));
ActionListOption nofallactions = new ActionListOption("nofallactions");
runflyNode.add(nofallactions);
nofallactions.add(0, "nofallLog nofallDamage");

View File

@ -50,36 +50,59 @@ public class NoFallCheck {
// Start with zero fall distance
data.fallDistance = 0F;
}
// If we increased fall height before for no good reason, reduce now by the same amount
if(player.getFallDistance() > data.lastAddedFallDistance) {
player.setFallDistance(player.getFallDistance() - data.lastAddedFallDistance);
}
data.lastAddedFallDistance = 0;
// We want to know if the fallDistance recorded by the game is smaller
// than the fall distance recorded by the plugin
float distance = data.fallDistance - player.getFallDistance();
float difference = data.fallDistance - player.getFallDistance();
if(distance > 0.01 && toOnOrInGround && data.fallDistance > 2.0F) {
data.nofallViolationLevel += distance;
if(difference > 1.0F && toOnOrInGround && data.fallDistance > 2.0F) {
data.nofallViolationLevel += difference;
// Prepare some event-specific values for logging and custom actions
HashMap<String, String> params = new HashMap<String, String>();
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f", data.fallDistance));
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f", difference));
params.put(LogAction.CHECK, "nofall");
boolean cancel = action.executeActions(player, cc.moving.nofallActions, (int) data.nofallViolationLevel, params, cc);
// If "cancelled", the fall damage gets dealt in a way that's visible to other players
// If "cancelled", the fall damage gets dealt in a way that's visible to other plugins
if(cancel) {
// Increase the damage a bit :)
float totalDistance = (data.fallDistance - 2.0F)* cc.moving.nofallMultiplier + 2.0F;
// Increase the fall distance a bit :)
float totalDistance = data.fallDistance + difference * (cc.moving.nofallMultiplier - 1.0F);
player.setFallDistance(totalDistance);
}
data.fallDistance = 0F;
}
// Increase the fall distance that is recorded by the plugin, AND set the fall distance of the player
// to whatever he would get with this move event. This modifies Minecrafts fall damage calculation
// slightly, but that's still better than ignoring players that try to use "teleports" or "stepdown"
// to avoid falldamage. It is only added for big height differences anyway, as to avoid to much deviation
// from the original Minecraft feeling.
if(oldY > newY) {
float dist = (float) (oldY - newY);
data.fallDistance += dist;
if(dist > 1.0F) {
data.lastAddedFallDistance = dist;
player.setFallDistance(player.getFallDistance() + dist);
}
else {
data.lastAddedFallDistance = 0.0F;
}
}
else {
data.lastAddedFallDistance = 0.0F;
}
// Reduce falldamage violation level
data.nofallViolationLevel *= 0.99D;
// Increase the fall distance that is recorded by the plugin
if(!toOnOrInGround && oldY > newY) {
data.fallDistance += (float) (oldY - newY);
}
}
}

View File

@ -1,6 +1,5 @@
package cc.co.evenprime.bukkit.nocheat.checks.moving;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;

View File

@ -24,6 +24,7 @@ public class MovingData {
public double nofallViolationLevel = 0.0D;
public float fallDistance = 0.0F;
public float lastAddedFallDistance = 0.0F;
public int noclipX;
public int noclipY;

View File

@ -112,8 +112,6 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag
}
mdata.vertVelocityCounter = 50;
mdata.fallDistance = 0.0f; // Don't be too unforgiving with fall damage
newVal = Math.sqrt(Math.pow(v.getX(), 2) + Math.pow(v.getZ(), 2));
if(newVal > 0.0D) {

View File

@ -44,7 +44,7 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM
// This belongs to the move-check
// Override decision to cancel teleports initialized by NoCheat by
// uncancelling them
// uncancelling them, if possible
pm.registerEvent(Event.Type.PLAYER_TELEPORT, new PlayerListener() {
@Override
@ -91,7 +91,8 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM
data.morePacketsSetbackPoint = null;
data.jumpPhase = 0;
data.fallDistance = 0F;
data.lastAddedFallDistance = 0F;
if(newLocation != null) {
data.noclipX = newLocation.getBlockX();