From 4b1c2078eb883a448e9d63713e934e465eadb045 Mon Sep 17 00:00:00 2001 From: akastijn Date: Wed, 21 Jan 2026 07:10:46 +0100 Subject: [PATCH] Add BlockDispenseEvent listener to ensure armor stands placed through dispensers respect the armor stand chunk limit --- .../event_listeners/LimitArmorStands.java | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/alttd/playerutils/event_listeners/LimitArmorStands.java b/src/main/java/com/alttd/playerutils/event_listeners/LimitArmorStands.java index c51b8cc..4969d4c 100644 --- a/src/main/java/com/alttd/playerutils/event_listeners/LimitArmorStands.java +++ b/src/main/java/com/alttd/playerutils/event_listeners/LimitArmorStands.java @@ -11,13 +11,16 @@ import org.bukkit.Chunk; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.block.Block; +import org.bukkit.block.Dispenser; import org.bukkit.block.TrialSpawner; +import org.bukkit.block.data.Directional; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockDispenseEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.persistence.PersistentDataContainer; @@ -87,8 +90,10 @@ import java.util.Optional; if (!willBreak) { return; } - Optional optionalResult = getGetChunkContainerAndNamespacedKey(armorStand.getLocation().getChunk(), player); + Optional optionalResult = getGetChunkContainerAndNamespacedKey(armorStand.getLocation().getChunk()); if (optionalResult.isEmpty()) { + player.sendRichMessage("Something went wrong while checking the armor stand count. " + + "You will not be able to place this until this is fixed. Please contact a staff member"); event.setCancelled(true); return; } @@ -100,6 +105,40 @@ import java.util.Optional; private record ChunkContainerAndNamespacedKey(NamespacedKey namespacedKey, PersistentDataContainer persistentDataContainer, int armorStandCount) { } + @EventHandler + public void onBlockDispense(BlockDispenseEvent event) { + if (!event.getItem().getType().equals(Material.ARMOR_STAND)) { + return; + } + Block block = event.getBlock(); + if (!(block.getState() instanceof Dispenser)) { + return; + } + if (!(block.getBlockData() instanceof Directional directional)) { + return; + } + + Chunk targetChunk = block.getRelative(directional.getFacing()).getChunk(); + Optional optional = getGetChunkContainerAndNamespacedKey(targetChunk); + if (optional.isEmpty()) { + event.setCancelled(true); + return; + } + ChunkContainerAndNamespacedKey result = optional.get(); + + Optional optionalLimit = Config.ARMOR_STAND_LIMIT.LIMIT.values().stream().min(Integer::compareTo); + if (optionalLimit.isEmpty()) { + log.error("Unable to find a valid limit for armor stands"); + event.setCancelled(true); + return; + } + if (result.armorStandCount() >= optionalLimit.get()) { + event.setCancelled(true); + return; + } + result.persistentDataContainer().set(result.namespacedKey(), PersistentDataType.INTEGER, result.armorStandCount() + 1); + } + private void handleArmorStandPlacing(PlayerInteractEvent event, ArmorStandCountConsumer consumer) { if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { return; @@ -112,8 +151,10 @@ import java.util.Optional; } Player player = event.getPlayer(); Chunk chunk = event.getClickedBlock().getChunk(); - Optional getChunkContainerAndNamespacedKey = getGetChunkContainerAndNamespacedKey(chunk, player); + Optional getChunkContainerAndNamespacedKey = getGetChunkContainerAndNamespacedKey(chunk); if (getChunkContainerAndNamespacedKey.isEmpty()) { + player.sendRichMessage("Something went wrong while checking the armor stand count. " + + "You will not be able to place this until this is fixed. Please contact a staff member"); event.setCancelled(true); return; } @@ -121,12 +162,10 @@ import java.util.Optional; consumer.apply(result.armorStandCount(), event.getPlayer(), result.namespacedKey(), result.persistentDataContainer()); } - private Optional getGetChunkContainerAndNamespacedKey(Chunk chunk, Player player) { + private Optional getGetChunkContainerAndNamespacedKey(Chunk chunk) { NamespacedKey namespacedKey = NamespacedKey.fromString("armor_stand_count", playerUtils); if (namespacedKey == null) { log.warn("Unable to retrieve name spaced key for armor stand count."); - player.sendRichMessage("Something went wrong while checking the armor stand count. " + - "You will not be able to place this until this is fixed. Please contact a staff member"); return Optional.empty(); } PersistentDataContainer persistentDataContainer = chunk.getPersistentDataContainer();