diff --git a/src/main/java/de/diddiz/LogBlock/WorldEditor.java b/src/main/java/de/diddiz/LogBlock/WorldEditor.java index e36bb86..bac7c33 100644 --- a/src/main/java/de/diddiz/LogBlock/WorldEditor.java +++ b/src/main/java/de/diddiz/LogBlock/WorldEditor.java @@ -24,6 +24,7 @@ import org.bukkit.entity.Bee; import org.bukkit.entity.Entity; import org.bukkit.entity.ItemFrame; import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import de.diddiz.LogBlock.QueryParams.Order; @@ -374,7 +375,7 @@ public class WorldEditor implements Runnable { BlockState state = block.getState(); if (setBlock.equals(replacedBlock)) { if (ca != null) { - if (state instanceof Container && state.getType() == replacedBlock.getMaterial()) { + if (state instanceof InventoryHolder && state.getType() == replacedBlock.getMaterial()) { int leftover; try { leftover = modifyContainer(state, new ItemStack(ca.itemStack), !ca.remove); diff --git a/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java b/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java index 319b66b..bb12a1f 100644 --- a/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java +++ b/src/main/java/de/diddiz/LogBlock/listeners/ChestAccessLogging.java @@ -5,19 +5,28 @@ import de.diddiz.LogBlock.LogBlock; import de.diddiz.LogBlock.Logging; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.block.DecoratedPot; import org.bukkit.block.DoubleChest; +import org.bukkit.block.data.type.ChiseledBookshelf; import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.event.block.Action; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -300,4 +309,59 @@ public class ChestAccessLogging extends LoggingListener { } } } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + final Block clicked = event.getClickedBlock(); + if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getHand() != EquipmentSlot.HAND || !event.hasBlock() || clicked == null) { + return; + } + final Player player = event.getPlayer(); + if (!isLogging(player.getWorld(), Logging.CHESTACCESS)) { + return; + } + final Material type = clicked.getType(); + if (type == Material.DECORATED_POT) { + ItemStack mainHand = player.getInventory().getItemInMainHand(); + if (mainHand != null && mainHand.getType() != Material.AIR && clicked.getState() instanceof DecoratedPot pot) { + ItemStack currentInPot = pot.getSnapshotInventory().getItem(); + if (currentInPot == null || currentInPot.getType() == Material.AIR || currentInPot.isSimilar(mainHand) && currentInPot.getAmount() < currentInPot.getMaxStackSize()) { + ItemStack stack = mainHand.clone(); + stack.setAmount(1); + consumer.queueChestAccess(Actor.actorFromEntity(player), clicked.getLocation(), clicked.getBlockData(), stack, false); + } + } + } else if (type == Material.CHISELED_BOOKSHELF) { + if (clicked.getBlockData() instanceof ChiseledBookshelf blockData && blockData.getFacing() == event.getBlockFace() && clicked.getState() instanceof org.bukkit.block.ChiseledBookshelf bookshelf) { + // calculate the slot the same way as minecraft does it + Vector pos = event.getClickedPosition(); + double clickx = switch (blockData.getFacing()) { + case NORTH -> 1 - pos.getX(); + case SOUTH -> pos.getX(); + case EAST -> 1 - pos.getZ(); + case WEST -> pos.getZ(); + default -> throw new IllegalArgumentException("Unexpected facing for chiseled bookshelf: " + blockData.getFacing()); + }; + int col = clickx < 0.375 ? 0 : (clickx < 0.6875 ? 1 : 2); // 6/16 ; 11/16 + int row = pos.getY() >= 0.5 ? 0 : 1; + int slot = col + row * 3; + + ItemStack currentInSlot = bookshelf.getSnapshotInventory().getItem(slot); + if (blockData.isSlotOccupied(slot)) { + // not empty: always take + if (currentInSlot != null && currentInSlot.getType() != Material.AIR) { + consumer.queueChestAccess(Actor.actorFromEntity(player), clicked.getLocation(), clicked.getBlockData(), currentInSlot, true); + } + } else { + // empty: put if has tag BOOKSHELF_BOOKS + ItemStack mainHand = player.getInventory().getItemInMainHand(); + if (mainHand != null && mainHand.getType() != Material.AIR && Tag.ITEMS_BOOKSHELF_BOOKS.isTagged(mainHand.getType())) { + ItemStack stack = mainHand.clone(); + stack.setAmount(1); + consumer.queueChestAccess(Actor.actorFromEntity(player), clicked.getLocation(), clicked.getBlockData(), stack, false); + } + } + } + } + } } diff --git a/src/main/java/de/diddiz/LogBlock/util/BukkitUtils.java b/src/main/java/de/diddiz/LogBlock/util/BukkitUtils.java index b6cc81a..f13a07f 100644 --- a/src/main/java/de/diddiz/LogBlock/util/BukkitUtils.java +++ b/src/main/java/de/diddiz/LogBlock/util/BukkitUtils.java @@ -330,6 +330,7 @@ public class BukkitUtils { containerBlocks.add(Material.BLAST_FURNACE); containerBlocks.add(Material.SMOKER); containerBlocks.add(Material.CHISELED_BOOKSHELF); + containerBlocks.add(Material.DECORATED_POT); // Doesn't actually have a block inventory // containerBlocks.add(Material.ENDER_CHEST); @@ -602,8 +603,8 @@ public class BukkitUtils { } public static int modifyContainer(BlockState b, ItemStack item, boolean remove) { - if (b instanceof InventoryHolder) { - final Inventory inv = ((InventoryHolder) b).getInventory(); + if (b instanceof InventoryHolder c) { + final Inventory inv = c.getInventory(); if (remove) { final ItemStack tmp = inv.removeItem(item).get(0); return tmp != null ? tmp.getAmount() : 0;