Sharpen NoFall: Deal damage on SF violations, include the players

location into max/min.
This commit is contained in:
asofold 2012-11-10 13:32:31 +01:00
parent f18b7b2c7d
commit 915987f9d3
4 changed files with 105 additions and 53 deletions

View File

@ -139,7 +139,6 @@ public class MovingData extends ACheckData {
public final ActionFrequency vDistCount = new ActionFrequency(3, 333);
// Locations shared between all checks.
public Location ground;
public Location setBack;
public Location teleported;

View File

@ -209,18 +209,22 @@ public class MovingListener implements Listener {
* |___/
*/
final Player player = event.getPlayer();
final MovingData data = MovingData.getData(player);
if (!creativeFly.isEnabled(player) && survivalFly.isEnabled(player) && survivalFly.check(player)) {
// To cancel the event, we simply teleport the player to his last
// safe location.
Location target = null;
if (data.ground != null) target = data.ground;
else if (data.setBack != null) target = data.setBack;
// else target = player.getLocation(); // TODO
if (target != null) player.teleport(target);// TODO: schedule / other measures ?
if (!player.hasPermission(Permissions.MOVING_CREATIVEFLY) && survivalFly.isEnabled(player)) {
final MovingData data = MovingData.getData(player);
// Check if the player has to be reset.
final Location target = survivalFly.checkBed(player, data);
// To cancel the event, we teleport the player.
if (target != null){
if (noFall.isEnabled(player)){
// Check if to deal damage.
noFall.checkDamage(player, data);
}
// Teleport.
data.teleported = target;
player.teleport(target);// TODO: schedule / other measures ?
}
}
}
@ -394,11 +398,6 @@ public class MovingListener implements Listener {
} else if (data.verticalFreedom > 0.001D)
// Counter has run out, now reduce the vertical freedom over time.
data.verticalFreedom *= 0.93D;
if (pFrom.isOnGround()){
data.ground = from; // pFrom.getLocation();
}
Location newTo = null;
@ -417,10 +416,17 @@ public class MovingListener implements Listener {
&& cc.survivalFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_SURVIVALFLY) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY)){
// If he is handled by the survival fly check, execute it.
newTo = survivalFly.check(player, mcPlayer, pFrom, pTo, data, cc);
// If don't have a new location and if he is handled by the no fall check, execute it.
if (newTo == null && cc.noFallCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_NOFALL) && !player.hasPermission(Permissions.MOVING_NOFALL))
// NOTE: noFall might set yOnGround for the positions.
noFall.check(player, pFrom, pTo, data, cc);
// Check NoFall if no reset is done.
if (cc.noFallCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_NOFALL) && !player.hasPermission(Permissions.MOVING_NOFALL)) {
if (newTo == null) {
// NOTE: noFall might set yOnGround for the positions.
noFall.check(player, pFrom, pTo, data, cc);
}
else{
// Deal damage if necessary.
noFall.checkDamage(player, data);
}
}
}
else if (cc.creativeFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_CREATIVEFLY)){
// If the player is handled by the creative fly check, execute it.
@ -601,7 +607,6 @@ public class MovingListener implements Listener {
data.clearMorePacketsData();
if (survivalFly.isEnabled(player)) {
data.setBack = event.getRespawnLocation();
data.ground = event.getRespawnLocation();
}
}
@ -615,6 +620,7 @@ public class MovingListener implements Listener {
final MovingData data = MovingData.getData(player);
data.clearFlyData();
data.clearMorePacketsData();
data.setBack = player.getLocation(); // TODO: Monitor this change (!).
}
/**

View File

@ -64,19 +64,23 @@ public class NoFall extends Check {
// 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;
dealFallDamage(mcPlayer, maxD);
}
else data.clearNoFallData();
}
/**
private static void dealFallDamage(EntityPlayer mcPlayer, int damage) {
final EntityDamageEvent event = new EntityDamageEvent(mcPlayer.getBukkitEntity(), DamageCause.FALL, damage);
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;
}
/**
* Checks a player.
*
* @param player
@ -90,6 +94,8 @@ public class NoFall extends Check {
final double fromY = from.getY();
final double toY = to.getY();
// TODO: account for player.getLocation.getY (how exactly ?)
final double yDiff = toY - fromY;
// Adapt yOnGround if necessary (sf uses another setting).
@ -182,5 +188,37 @@ public class NoFall extends Check {
parameters.put(ParameterName.FALL_DISTANCE, String.format(Locale.US, "%.2f", MovingData.getData(violationData.player).noFallFallDistance));
return parameters;
}
/**
* This is called if a player fails a check and gets set back, to avoid using that to avoid fall damage the player might be dealt damage here.
* @param player
* @param data
*/
public void checkDamage(final Player player, final MovingData data) {
final MovingConfig cc = MovingConfig.getConfig(player);
// Get the max difference for fall distance.
final float fallDistance = player.getFallDistance();
final float yDiff = (float) (data.noFallMaxY - player.getLocation().getY());
final double maxDiff = Math.max(yDiff, Math.max(data.noFallFallDistance, fallDistance));
// Calculate damage that would be dealt (plus return if none).
final int damage = NoFall.getDamage((float) maxDiff);
if (damage <= 0) return;
// // Heuristic check for if damage would count at all.
// final long fDamage = BlockProperties.F_GROUND | BlockProperties.F_SOLID | BlockProperties.F_STAIRS | BlockProperties.F_LAVA;
// final long fNoDamage = BlockProperties.F_LIQUID; // Checked second.
// final IBlockAccess access = ((CraftWorld) player.getWorld()).getHandle();
// final Location loc = player.getLocation();
// final int x = loc.getBlockX();
// final int y = loc.getBlockY();
// final int z = loc.getBlockZ();
// while (y > 0){
//
// }
// // TODO
// Deal damage.
if (cc.debug) System.out.println(player.getName() + " NoFall deal damage (violation): " + damage);
dealFallDamage(((CraftPlayer) player).getHandle(), damage);
}
}

View File

@ -62,29 +62,38 @@ public class SurvivalFly extends Check {
super(CheckType.MOVING_SURVIVALFLY);
}
/**
* Checks a player.
*
* @param player
* the player
* @return true, if successful
*/
public boolean check(final Player player) {
final MovingData data = MovingData.getData(player);
/**
* Checks a player.
*
* @param player
* the player
* @return Location to teleport to if it is a violation.
*/
public Location checkBed(final Player player, final MovingData data) {
Location newTo = null;
// Check if the player had been in bed at all.
if (!data.sfWasInBed) {
// Violation ...
data.survivalFlyVL += 100D;
// Check if the player has entered the bed he is trying to leave.
if (!data.sfWasInBed) {
// He hasn't, increment his violation level.
data.survivalFlyVL += 100D;
// And return if we need to do something or not.
return executeActions(player, data.survivalFlyVL, 100D, MovingConfig.getConfig(player).survivalFlyActions);
} else
// He has, everything is alright.
data.sfWasInBed = false;
return false;
}
// And return if we need to do something or not.
if (executeActions(player, data.survivalFlyVL, 100D, MovingConfig.getConfig(player).survivalFlyActions)){
final Location loc = player.getLocation();
newTo = data.setBack;
if (newTo == null){
// TODO: Add something to guess the best set back location (possibly data.guessSetBack(Location)).
newTo = loc;
}
newTo.setPitch(loc.getPitch());
newTo.setYaw(loc.getYaw());
}
} else{
// He has, everything is alright.
data.sfWasInBed = false;
}
return newTo;
}
/**
* Checks a player.