From 6046f4defcfa43e9ed644f0e72edc75b0f93c74b Mon Sep 17 00:00:00 2001 From: sk89q Date: Thu, 20 Jan 2011 01:07:39 -0800 Subject: [PATCH] Fixed teleport-on-suffocation setting. --- .../bukkit/WorldGuardEntityListener.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java b/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java index f55f7e12..1558ab08 100644 --- a/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java +++ b/src/com/sk89q/worldguard/bukkit/WorldGuardEntityListener.java @@ -20,12 +20,15 @@ package com.sk89q.worldguard.bukkit; import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.entity.*; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BlockType; import static com.sk89q.worldguard.bukkit.BukkitUtil.*; public class WorldGuardEntityListener extends EntityListener { @@ -131,6 +134,12 @@ public void onEntityDamage(EntityDamageEvent event) { event.setCancelled(true); return; } + + if (plugin.teleportOnSuffocation && type == DamageCause.SUFFOCATION) { + findFreePosition(player); + event.setCancelled(true); + return; + } if (plugin.disableSuffocationDamage && type == DamageCause.SUFFOCATION) { event.setCancelled(true); @@ -187,4 +196,44 @@ public void onEntityExplode(EntityExplodeEvent event) { } } } + + /** + * 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 + */ + public void findFreePosition(Player player) { + Location loc = player.getLocation(); + int x = loc.getBlockX(); + int y = Math.max(0, loc.getBlockY()); + int origY = y; + int z = loc.getBlockZ(); + World world = player.getWorld(); + + byte free = 0; + + while (y <= 129) { + if (BlockType.canPassThrough(world.getBlockTypeIdAt(x, y, z))) { + free++; + } else { + free = 0; + } + + if (free == 2) { + if (y - 1 != origY) { + loc.setX(x + 0.5); + loc.setY(y); + loc.setZ(z + 0.5); + player.teleportTo(loc); + } + + return; + } + + y++; + } + } }