diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/player/ShowFakeCommand.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/player/ShowFakeCommand.java index 738eeb8964..73ac752fc1 100644 --- a/src/main/java/net/aufdemrand/denizen/scripts/commands/player/ShowFakeCommand.java +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/player/ShowFakeCommand.java @@ -92,17 +92,11 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException { boolean shouldCancel = cancel.asBoolean(); - for (dPlayer plr : players.filter(dPlayer.class)) { - - if (plr == null || !plr.isOnline()) continue; - - for (dLocation loc : list.filter(dLocation.class)) { - if (!shouldCancel) - FakeBlock.showFakeBlockTo(plr, loc, material, duration); - else - FakeBlock.stopShowingTo(plr, loc); - } - + for (dLocation loc : list.filter(dLocation.class)) { + if (!shouldCancel) + FakeBlock.showFakeBlockTo(players.filter(dPlayer.class), loc, material, duration); + else + FakeBlock.stopShowingTo(players.filter(dPlayer.class), loc); } } } diff --git a/src/main/java/net/aufdemrand/denizen/utilities/blocks/FakeBlock.java b/src/main/java/net/aufdemrand/denizen/utilities/blocks/FakeBlock.java index 1d67078e41..420bac8dba 100644 --- a/src/main/java/net/aufdemrand/denizen/utilities/blocks/FakeBlock.java +++ b/src/main/java/net/aufdemrand/denizen/utilities/blocks/FakeBlock.java @@ -6,13 +6,14 @@ import net.aufdemrand.denizen.objects.dMaterial; import net.aufdemrand.denizen.objects.dPlayer; import net.aufdemrand.denizen.utilities.DenizenAPI; -import org.bukkit.block.Block; +import net.aufdemrand.denizen.utilities.debugging.dB; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; /** * Creates a temporary fake block and shows it to a dPlayer. @@ -25,6 +26,7 @@ public class FakeBlock { private final dPlayer player; private final dLocation location; private dMaterial material; + private long cancelTime = -1; private BukkitTask currentTask = null; private FakeBlock(dPlayer player, dLocation location) { @@ -32,24 +34,46 @@ private FakeBlock(dPlayer player, dLocation location) { this.location = location; } - public static void showFakeBlockTo(dPlayer player, dLocation location, dMaterial material, Duration duration) { - UUID uuid = player.getPlayerEntity().getUniqueId(); - if (!blocks.containsKey(uuid)) - blocks.put(uuid, new HashMap()); - Map playerBlocks = blocks.get(uuid); - if (!playerBlocks.containsKey(location)) { - playerBlocks.put(location, new FakeBlock(player, location)); + public static void showFakeBlockTo(List players, dLocation location, dMaterial material, Duration duration) { + for (dPlayer player : players) { + if (!player.isOnline() || !player.isValid()) + continue; + UUID uuid = player.getPlayerEntity().getUniqueId(); + if (!blocks.containsKey(uuid)) + blocks.put(uuid, new HashMap()); + Map playerBlocks = blocks.get(uuid); + if (!playerBlocks.containsKey(location)) { + playerBlocks.put(location, new FakeBlock(player, location)); + } + playerBlocks.get(location).updateBlock(material, duration.getTicks()); } - playerBlocks.get(location).updateBlock(material, duration); } - public static void stopShowingTo(dPlayer player, dLocation location) { - UUID uuid = player.getPlayerEntity().getUniqueId(); - if (blocks.containsKey(uuid)) { - Map playerBlocks = blocks.get(uuid); - if (playerBlocks.containsKey(location)) - playerBlocks.get(location).cancelBlock(); + public static void stopShowingTo(List players, final dLocation location) { + final List uuids = new ArrayList(); + for (dPlayer player : players) { + if (!player.isOnline() || !player.isValid()) + continue; + UUID uuid = player.getPlayerEntity().getUniqueId(); + uuids.add(uuid); + if (blocks.containsKey(uuid)) { + Map playerBlocks = blocks.get(uuid); + if (playerBlocks.containsKey(location)) + playerBlocks.get(location).cancelBlock(); + } } + new BukkitRunnable() { + @Override + public void run() { + for (UUID uuid : blocks.keySet()) { + if (uuids.contains(uuid)) + continue; + Map playerBlocks = blocks.get(uuid); + if (playerBlocks.containsKey(location)) + playerBlocks.get(location).updateBlock(); + } + } + }.runTaskLater(DenizenAPI.getCurrentInstance(), 2); } private void cancelBlock() { @@ -57,23 +81,49 @@ private void cancelBlock() { currentTask.cancel(); currentTask = null; } - Block block = location.getBlock(); - player.getPlayerEntity().sendBlockChange(location, block.getType(), block.getData()); + cancelTime = -1; + location.getBlock().getState().update(); } - private void updateBlock(dMaterial material, Duration duration) { + private void updateBlock() { + updateBlock(material, cancelTime == -1 ? 0 : cancelTime - location.getWorld().getFullTime()); + } + + private void updateBlock(dMaterial material, long ticks) { if (currentTask != null) currentTask.cancel(); + this.material = material; player.getPlayerEntity().sendBlockChange(location, material.getMaterial(), material.getMaterialData().getData()); - currentTask = duration.getTicks() > 0 ? new BukkitRunnable() { - @Override - public void run() { - currentTask = null; - if (player.isValid() && player.isOnline()) - cancelBlock(); - } - }.runTaskLater(DenizenAPI.getCurrentInstance(), duration.getTicks()) : null; + if (ticks > 0) { + cancelTime = location.getWorld().getFullTime() + ticks; + currentTask = new BukkitRunnable() { + @Override + public void run() { + currentTask = null; + if (player.isValid() && player.isOnline()) + cancelBlock(); + } + }.runTaskLater(DenizenAPI.getCurrentInstance(), ticks); + } + } + + static { + final FakeBlockListeners listeners = new FakeBlockListeners(); + } + + public static class FakeBlockListeners implements Listener { + public FakeBlockListeners() { + DenizenAPI.getCurrentInstance().getServer().getPluginManager() + .registerEvents(this, DenizenAPI.getCurrentInstance()); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) { + UUID uuid = event.getPlayer().getUniqueId(); + if (blocks.containsKey(uuid)) + blocks.remove(uuid); + } } }