From 2849f41335b9376b19d12db05c3def262a639625 Mon Sep 17 00:00:00 2001 From: Sylvye Date: Thu, 3 Sep 2026 10:38:53 -0400 Subject: [PATCH] Return Optional for villager pickup; skip traders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PickupManager.toItemStack now returns Optional and will skip (return empty) for Villagers that are currently trading — it also closes the trader inventory to avoid issues. Call sites (VillagerEditMenu, HopperTicker, InteractListener) were updated to handle the Optional. Also updated plugin.yml authors to include 'Sylvye' and fixed a trailing newline. --- .../clickvillagers/gui/VillagerEditMenu.java | 4 +++- .../clickvillagers/hopper/HopperTicker.java | 4 ++-- .../clickvillagers/listener/InteractListener.java | 4 +++- .../clickvillagers/villager/PickupManager.java | 14 +++++++++++--- paper/src/main/resources/plugin.yml | 4 ++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/paper/src/main/java/de/clickism/clickvillagers/gui/VillagerEditMenu.java b/paper/src/main/java/de/clickism/clickvillagers/gui/VillagerEditMenu.java index 129d73d..ad99a1a 100644 --- a/paper/src/main/java/de/clickism/clickvillagers/gui/VillagerEditMenu.java +++ b/paper/src/main/java/de/clickism/clickvillagers/gui/VillagerEditMenu.java @@ -47,7 +47,9 @@ public VillagerEditMenu(Player viewer, LivingEntity villager, ClaimManager claim if (!CLAIMED_VILLAGERS_BYPASS_PERMISSIONS.get()) { if (Permission.PICKUP.lacksAndNotify(player)) return; } - Utils.setHandOrGive(player, pickupManager.toItemStack(villager)); + var itemResult = pickupManager.toItemStack(villager); + if (itemResult.isEmpty()) return; + Utils.setHandOrGive(player, itemResult.get()); PICK_UP_VILLAGER.sendActionbarSilently(player); pickupManager.sendPickupEffect(villager); })); diff --git a/paper/src/main/java/de/clickism/clickvillagers/hopper/HopperTicker.java b/paper/src/main/java/de/clickism/clickvillagers/hopper/HopperTicker.java index f103002..ea9b571 100644 --- a/paper/src/main/java/de/clickism/clickvillagers/hopper/HopperTicker.java +++ b/paper/src/main/java/de/clickism/clickvillagers/hopper/HopperTicker.java @@ -117,8 +117,8 @@ private void tickHopper(Iterator setIterator, Location hopperLoc) { for (LivingEntity villager : villagers) { if (emptySlots <= 0) break; try { - ItemStack item = pickupManager.toItemStack(villager); - inventory.addItem(item); + var itemResult = pickupManager.toItemStack(villager); + itemResult.ifPresent(inventory::addItem); } catch (Exception exception) { ClickVillagers.LOGGER.severe("Failed to write villager data: " + exception.getMessage()); } diff --git a/paper/src/main/java/de/clickism/clickvillagers/listener/InteractListener.java b/paper/src/main/java/de/clickism/clickvillagers/listener/InteractListener.java index 9b9527f..020269b 100644 --- a/paper/src/main/java/de/clickism/clickvillagers/listener/InteractListener.java +++ b/paper/src/main/java/de/clickism/clickvillagers/listener/InteractListener.java @@ -212,7 +212,9 @@ private void handlePickup(Player player, LivingEntity villager) { } ItemStack item; try { - item = pickupManager.toItemStack(villager); + var itemResult = pickupManager.toItemStack(villager); + if (itemResult.isEmpty()) return; + item = itemResult.get(); } catch (IllegalArgumentException exception) { Message.WRITE_ERROR.send(player); ClickVillagers.LOGGER.severe("Failed to write villager data: " + exception.getMessage()); diff --git a/paper/src/main/java/de/clickism/clickvillagers/villager/PickupManager.java b/paper/src/main/java/de/clickism/clickvillagers/villager/PickupManager.java index a7d61d7..bd8b6ae 100644 --- a/paper/src/main/java/de/clickism/clickvillagers/villager/PickupManager.java +++ b/paper/src/main/java/de/clickism/clickvillagers/villager/PickupManager.java @@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Optional; import static de.clickism.clickvillagers.ClickVillagersConfig.*; import static de.clickism.clickvillagers.message.Message.VILLAGER_WITH_PROFESSION; @@ -106,14 +107,21 @@ private void onPlace(BlockPlaceEvent event) { } @NotNull - public ItemStack toItemStack(LivingEntity entity) throws IllegalArgumentException { + public Optional toItemStack(LivingEntity entity) throws IllegalArgumentException { if (!(entity instanceof Villager) && !(entity instanceof ZombieVillager)) { throw new IllegalArgumentException("Entity is not a villager"); } + if (entity instanceof Villager villager && villager.isTrading()) { + var trader = villager.getTrader(); + if (trader != null) { + trader.closeInventory(); + } + return Optional.empty(); + } ItemStack item = createItem(entity); writeData(entity, item); entity.remove(); - return item; + return Optional.of(item); } private ItemResult getHeldVillagerItem(PlayerInventory inventory) { @@ -229,4 +237,4 @@ void decrementAmount(PlayerInventory inventory) { inventory.setItem(slot, item); } } -} \ No newline at end of file +} diff --git a/paper/src/main/resources/plugin.yml b/paper/src/main/resources/plugin.yml index d53e220..5a03e86 100644 --- a/paper/src/main/resources/plugin.yml +++ b/paper/src/main/resources/plugin.yml @@ -2,7 +2,7 @@ name: ClickVillagers version: '${version}' main: de.clickism.clickvillagers.ClickVillagers api-version: '1.21' -authors: [Clickism] +authors: [Clickism, Sylvye] description: A simple plugin that makes handling villagers a lot easier folia-supported: true commands: @@ -42,4 +42,4 @@ permissions: default: op clickvillagers.bypass-cooldowns: description: Allows players to bypass pick up and claim cooldowns. - default: false \ No newline at end of file + default: false