From a9c4a81abe82dd3cda2ab4b6e795460e81a88568 Mon Sep 17 00:00:00 2001 From: sk89q Date: Thu, 9 Dec 2010 23:59:44 -0800 Subject: [PATCH] Added suffocation damage prevention. --- src/WorldGuardListener.java | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/WorldGuardListener.java b/src/WorldGuardListener.java index 08d5562b..32260ffd 100644 --- a/src/WorldGuardListener.java +++ b/src/WorldGuardListener.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.Random; import java.io.*; +import com.sk89q.worldedit.blocks.BlockType; /** * Event listener for Hey0's server mod. @@ -94,6 +95,8 @@ public class WorldGuardListener extends PluginListener { private boolean disableLavaDamage; private boolean disableFireDamage; private boolean disableWaterDamage; + private boolean disableSuffocationDamage; + private boolean teleportOnSuffocation; private int loginProtection; private int spawnProtection; private boolean teleportToHome; @@ -198,6 +201,8 @@ public void loadConfiguration() { disableLavaDamage = properties.getBoolean("disable-lava-damage", false); disableFireDamage = properties.getBoolean("disable-fire-damage", false); disableWaterDamage = properties.getBoolean("disable-water-damage", false); + disableSuffocationDamage = properties.getBoolean("disable-suffocation-damage", false); + teleportOnSuffocation = properties.getBoolean("teleport-on-suffocation", false); loginProtection = properties.getInt("login-protection", 3); spawnProtection = properties.getInt("spawn-protection", 0); kickOnDeath = properties.getBoolean("kick-on-death", false); @@ -960,6 +965,22 @@ public boolean onBlockPhysics(Block block, boolean placed) { public boolean onHealthChange(Player player, int oldValue, int newValue) { String playerName = player.getName(); + if (disableSuffocationDamage && oldValue - newValue == 1) { + Location loc = player.getLocation(); + int x = (int)Math.floor(loc.x); + int y = (int)Math.floor(loc.y); + int z = (int)Math.floor(loc.z); + int type = etc.getServer().getBlockIdAt(x, y + 1, z); // Head + + // Assuming that this is suffocation damage + if ((type < 8 || type > 11) && !BlockType.canPassThrough(type)) { + if (teleportOnSuffocation) { + findFreePosition(player, x, y, z); + } + return true; + } + } + if (invinciblePlayers.contains(playerName)) { return oldValue > newValue; } @@ -1121,4 +1142,43 @@ public void disable() { blacklist.getLogger().close(); } } + + /** + * Find a position for the player to stand that is not inside a block. + * Blocks above the player will be iteratively tested until there is + * a series of two free blocks. The player will be teleported to + * that free position. + * + * @param player + * @param sx + * @param sy + * @param sz + */ + public void findFreePosition(Player player, int sx, int sy, int sz) { + int x = sx; + int y = Math.max(0, sy); + int origY = y; + int z = sz; + + byte free = 0; + + while (y <= 129) { + if (BlockType.canPassThrough(etc.getServer().getBlockIdAt(x, y, z))) { + free++; + } else { + free = 0; + } + + if (free == 2) { + if (y - 1 != origY) { + player.teleportTo(x + 0.5, y, z + 0.5, + player.getRotation(), player.getPitch()); + } + + return; + } + + y++; + } + } } \ No newline at end of file