From 08ce599075b33dc8c95b3f11be79685195795b71 Mon Sep 17 00:00:00 2001 From: Esophose Date: Wed, 5 Jun 2019 03:40:36 -0600 Subject: [PATCH] Spawner Place/Break events --- .../events/SpawnerBreakEvent.java | 41 +++++++++++ .../ultimatestacker/events/SpawnerEvent.java | 51 +++++++++++++ .../events/SpawnerPlaceEvent.java | 41 +++++++++++ .../listeners/BlockListeners.java | 71 +++++++++++++------ .../spawner/SpawnerStackManager.java | 4 ++ 5 files changed, 186 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/songoda/ultimatestacker/events/SpawnerBreakEvent.java create mode 100644 src/main/java/com/songoda/ultimatestacker/events/SpawnerEvent.java create mode 100644 src/main/java/com/songoda/ultimatestacker/events/SpawnerPlaceEvent.java diff --git a/src/main/java/com/songoda/ultimatestacker/events/SpawnerBreakEvent.java b/src/main/java/com/songoda/ultimatestacker/events/SpawnerBreakEvent.java new file mode 100644 index 0000000..50069a3 --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/events/SpawnerBreakEvent.java @@ -0,0 +1,41 @@ +package com.songoda.ultimatestacker.events; + +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a spawner has been broken in the world + */ +public class SpawnerBreakEvent extends SpawnerEvent implements Cancellable { + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean cancelled = false; + + public SpawnerBreakEvent(Player player, Block block, EntityType spawnerType, int amount) { + super(player, block, spawnerType, amount); + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean canceled) { + this.cancelled = canceled; + } + +} diff --git a/src/main/java/com/songoda/ultimatestacker/events/SpawnerEvent.java b/src/main/java/com/songoda/ultimatestacker/events/SpawnerEvent.java new file mode 100644 index 0000000..9d8ee41 --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/events/SpawnerEvent.java @@ -0,0 +1,51 @@ +package com.songoda.ultimatestacker.events; + +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerEvent; + +/** + * Represents an abstract spawner event + */ +public abstract class SpawnerEvent extends PlayerEvent { + + protected final Block block; + protected final EntityType spawnerType; + protected final int amount; + + public SpawnerEvent(Player who, Block block, EntityType spawnerType, int amount) { + super(who); + this.block = block; + this.spawnerType = spawnerType; + this.amount = amount; + } + + /** + * Get the {@link Block} involved in this event + * + * @return the block + */ + public Block getBlock() { + return this.block; + } + + /** + * Get the {@link EntityType} of the spawner + * + * @return the spawner type + */ + public EntityType getSpawnerType() { + return this.spawnerType; + } + + /** + * Get the amount of spawners affected in this event + * + * @return the amount + */ + public int getAmount() { + return this.amount; + } + +} diff --git a/src/main/java/com/songoda/ultimatestacker/events/SpawnerPlaceEvent.java b/src/main/java/com/songoda/ultimatestacker/events/SpawnerPlaceEvent.java new file mode 100644 index 0000000..77dea4a --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/events/SpawnerPlaceEvent.java @@ -0,0 +1,41 @@ +package com.songoda.ultimatestacker.events; + +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a spawner has been placed in the world + */ +public class SpawnerPlaceEvent extends SpawnerEvent implements Cancellable { + + private static final HandlerList HANDLERS = new HandlerList(); + + private boolean canceled = false; + + public SpawnerPlaceEvent(Player player, Block block, EntityType spawnerType, int amount) { + super(player, block, spawnerType, amount); + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public boolean isCancelled() { + return this.canceled; + } + + @Override + public void setCancelled(boolean canceled) { + this.canceled = canceled; + } + +} diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java index 38da299..8a05a9d 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/BlockListeners.java @@ -1,6 +1,8 @@ package com.songoda.ultimatestacker.listeners; import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.events.SpawnerBreakEvent; +import com.songoda.ultimatestacker.events.SpawnerPlaceEvent; import com.songoda.ultimatestacker.spawner.SpawnerStack; import com.songoda.ultimatestacker.utils.Methods; import com.songoda.ultimatestacker.utils.ServerVersion; @@ -70,16 +72,26 @@ public class BlockListeners implements Listener { if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { if (stack.getAmount() == maxStackSize) return; + ItemStack overflowItem = null; if ((stack.getAmount() + itemAmount) > maxStackSize) { - ItemStack newItem = Methods.getSpawnerItem(blockType, (stack.getAmount() + itemAmount) - maxStackSize); - if (player.getInventory().firstEmpty() == -1) - block.getLocation().getWorld().dropItemNaturally(block.getLocation().add(.5, 0, .5), newItem); - else - player.getInventory().addItem(newItem); - + overflowItem = Methods.getSpawnerItem(blockType, (stack.getAmount() + itemAmount) - maxStackSize); itemAmount = maxStackSize - stack.getAmount(); } + SpawnerPlaceEvent placeEvent = new SpawnerPlaceEvent(player, block, blockType, itemAmount); + Bukkit.getPluginManager().callEvent(placeEvent); + if (placeEvent.isCancelled()) { + event.setCancelled(true); + return; + } + + if (overflowItem != null) { + if (player.getInventory().firstEmpty() == -1) + block.getLocation().getWorld().dropItemNaturally(block.getLocation().add(.5, 0, .5), overflowItem); + else + player.getInventory().addItem(overflowItem); + } + stack.setAmount(stack.getAmount() + itemAmount); if (instance.getHologram() != null) instance.getHologram().update(stack); @@ -88,23 +100,32 @@ public class BlockListeners implements Listener { } if (instance.getHologram() != null) - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, () -> instance.getHologram().processChange(block), 10L); - + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, () -> instance.getHologram().processChange(block), 10L); } @EventHandler public void onSpawnerPlace(BlockPlaceEvent event) { Block block = event.getBlock(); + Player player = event.getPlayer(); if (!event.isCancelled()) { if (block.getType() != (instance.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.SPAWNER : Material.valueOf("MOB_SPAWNER")) || !instance.spawnersEnabled()) return; - SpawnerStack stack = instance.getSpawnerStackManager().addSpawner(new SpawnerStack(block.getLocation(), getSpawnerAmount(event.getItemInHand()))); - CreatureSpawner cs = (CreatureSpawner) block.getState(); CreatureSpawner cs2 = (CreatureSpawner) ((BlockStateMeta) event.getItemInHand().getItemMeta()).getBlockState(); + int amount = getSpawnerAmount(event.getItemInHand()); + + SpawnerPlaceEvent placeEvent = new SpawnerPlaceEvent(player, block, cs2.getSpawnedType(), amount); + Bukkit.getPluginManager().callEvent(placeEvent); + if (placeEvent.isCancelled()) { + event.setCancelled(true); + return; + } + + SpawnerStack stack = instance.getSpawnerStackManager().addSpawner(new SpawnerStack(block.getLocation(), amount)); + cs.setSpawnedType(cs2.getSpawnedType()); cs.update(); @@ -136,25 +157,31 @@ public class BlockListeners implements Listener { event.setCancelled(true); int amt = 1; + boolean remove = false; if (player.isSneaking()) { - event.setCancelled(false); amt = stack.getAmount(); + remove = true; + } else if (stack.getAmount() <= 1) { + remove = true; + } + + SpawnerBreakEvent breakEvent = new SpawnerBreakEvent(player, block, blockType, amt); + Bukkit.getPluginManager().callEvent(breakEvent); + if (breakEvent.isCancelled()) + return; + + if (remove) { + event.setCancelled(false); if (instance.getHologram() != null) - instance.getHologram().remove(stack); + instance.getHologram().remove(stack); instance.getSpawnerStackManager().removeSpawner(block.getLocation()); } else { - if (stack.getAmount() <= 1) { - event.setCancelled(false); - instance.getSpawnerStackManager().removeSpawner(block.getLocation()); - if (instance.getHologram() != null) - instance.getHologram().remove(stack); - } else { - stack.setAmount(stack.getAmount() - 1); - if (instance.getHologram() != null) - instance.getHologram().update(stack); - } + stack.setAmount(stack.getAmount() - 1); + if (instance.getHologram() != null) + instance.getHologram().update(stack); } + if (player.hasPermission("ultimatestacker.spawner.nosilkdrop") || item != null && item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && player.hasPermission("ultimatestacker.spawner.silktouch")) block.getWorld().dropItemNaturally(block.getLocation(), Methods.getSpawnerItem(blockType, amt)); } diff --git a/src/main/java/com/songoda/ultimatestacker/spawner/SpawnerStackManager.java b/src/main/java/com/songoda/ultimatestacker/spawner/SpawnerStackManager.java index f3c4636..e1b09e0 100644 --- a/src/main/java/com/songoda/ultimatestacker/spawner/SpawnerStackManager.java +++ b/src/main/java/com/songoda/ultimatestacker/spawner/SpawnerStackManager.java @@ -32,6 +32,10 @@ public class SpawnerStackManager { return this.getSpawner(block.getLocation()); } + public boolean isSpawner(Location location) { + return registeredSpawners.get(location) != null; + } + public Collection getStacks() { return Collections.unmodifiableCollection(registeredSpawners.values()); }