diff --git a/src/de/craftinc/gates/listeners/PluginPortalListener.java b/src/de/craftinc/gates/listeners/PluginPortalListener.java index c61b075..522fb0c 100644 --- a/src/de/craftinc/gates/listeners/PluginPortalListener.java +++ b/src/de/craftinc/gates/listeners/PluginPortalListener.java @@ -1,25 +1,58 @@ package de.craftinc.gates.listeners; +import org.bukkit.GameMode; +import org.bukkit.Location; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerPortalEvent; import de.craftinc.gates.Gate; +import de.craftinc.gates.Plugin; +import de.craftinc.gates.util.GateUtil; -public class PluginPortalListener extends BaseLocationListener implements Listener +public class PluginPortalListener implements Listener { @EventHandler(priority = EventPriority.NORMAL) public void onPlayerPortal(PlayerPortalEvent event) { - if (event.isCancelled()) { + if (event.isCancelled()) + { + Plugin.log("event has already been cancelled"); return; } - // Find the gate at the current location. - Gate gateAtLocation = getGateAtPlayerLocation(event); + Location playerLocation = event.getPlayer().getLocation(); - if (gateAtLocation != null) { + // Find the gate at the current location. + Gate gateAtLocation = GateUtil.getGateAtPlayerLocation(playerLocation); + + + // If the player's gamemode is creative no gate might be found! + // It seems like players get teleported on a move event when the 'to' location is + // inside a gate. This meens the location obtained earlier is NOT inside a gate. + // + if (gateAtLocation == null && event.getPlayer().getGameMode() == GameMode.CREATIVE) + { + Gate closestGate = GateUtil.closestGate(playerLocation); + + if (closestGate != null) + { + // Make sure gate and player locations are on the same height (y-value). + // Otherwise the distance will be messed up when players are flying. + // FIX ME: this could potentially let a nearby nether portal fail! + playerLocation.setY(closestGate.getLocation().getY()); + double distToClosestGate = closestGate.getLocation().distance(playerLocation); + + if (distToClosestGate < 1.0) + { + gateAtLocation = closestGate; + } + } + } + + if (gateAtLocation != null) + { event.setCancelled(true); } }