From b21c5bf3a98fceb06554596f9b6a72c720fb1747 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Mon, 28 Nov 2022 13:57:41 +0000 Subject: [PATCH] Fixed captive filter and GUI drag bug --- .../com/willfp/eco/core/gui/slot/Slot.java | 2 +- .../eco/internal/gui/slot/EcoCaptiveSlot.kt | 11 +++-- .../willfp/eco/internal/gui/slot/EcoSlot.kt | 4 -- .../eco/internal/spigot/gui/GUIListener.kt | 40 ++++++++++++++++++- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/slot/Slot.java b/eco-api/src/main/java/com/willfp/eco/core/gui/slot/Slot.java index 34f25678..9a25750c 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/gui/slot/Slot.java +++ b/eco-api/src/main/java/com/willfp/eco/core/gui/slot/Slot.java @@ -57,7 +57,7 @@ public interface Slot extends GUIComponent { default boolean isAllowedCaptive(@NotNull final Player player, @NotNull final Menu menu, @Nullable final ItemStack itemStack) { - return true; + return this.isCaptive(player, menu); } /** diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptiveSlot.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptiveSlot.kt index d25b4ce3..01bad149 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptiveSlot.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptiveSlot.kt @@ -5,6 +5,7 @@ import com.willfp.eco.core.gui.slot.functional.CaptiveFilter import com.willfp.eco.core.gui.slot.functional.SlotHandler import com.willfp.eco.core.gui.slot.functional.SlotProvider import com.willfp.eco.util.toSingletonList +import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.event.inventory.ClickType import org.bukkit.inventory.ItemStack @@ -35,13 +36,15 @@ class EcoCaptiveSlot( } private fun captiveWithTest( - playerTest: (Player) -> Boolean, + notCaptiveFor: (Player) -> Boolean, filter: CaptiveFilter ): SlotHandler = SlotHandler { event, _, menu -> val player = event.whoClicked as Player - val allowedForPlayer = !playerTest(player) - val allowedForCondition = filter.isAllowed(player, menu, event.currentItem) + val item = event.currentItem.nullIfAir() ?: event.cursor.nullIfAir() - event.isCancelled = !(allowedForCondition && allowedForPlayer) + event.isCancelled = !filter.isAllowed(player, menu, item) || notCaptiveFor(player) } + +private fun ItemStack?.nullIfAir(): ItemStack? = + if (this?.type == Material.AIR) null else this diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlot.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlot.kt index e9b5f997..c9561a9b 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlot.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlot.kt @@ -33,9 +33,5 @@ open class EcoSlot( return updater.update(player, menu, base) ?: return ItemStack(Material.AIR) } - override fun isCaptive(player: Player, menu: Menu): Boolean { - return false - } - override fun getActionableSlot(player: Player, menu: Menu): EcoSlot = this } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/gui/GUIListener.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/gui/GUIListener.kt index 93a0122d..208d0cfd 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/gui/GUIListener.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/gui/GUIListener.kt @@ -17,6 +17,7 @@ import org.bukkit.event.Listener 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.player.PlayerItemHeldEvent import org.bukkit.inventory.PlayerInventory @@ -73,6 +74,33 @@ class GUIListener(private val plugin: EcoPlugin) : Listener { menu.getSlot(row, column, player).handle(player, event, menu) } + @EventHandler( + priority = EventPriority.HIGH + ) + fun handleSlotClick(event: InventoryDragEvent) { + val rendered = event.view.topInventory.asRenderedInventory() ?: return + + val player = event.whoClicked as? Player ?: return + + val menu = rendered.menu + + val slots = event.inventorySlots + + for (slotID in slots) { + val (row, column) = MenuUtils.convertSlotToRowColumn(slotID, menu.columns) + + val slot = menu.getSlot(row, column, player) + + if (slot.isCaptive(player, menu)) { + if (!slot.isAllowedCaptive(player, menu, event.oldCursor)) { + event.isCancelled = true + } + } else { + event.isCancelled = true + } + } + } + @EventHandler( priority = EventPriority.HIGH ) @@ -95,7 +123,11 @@ class GUIListener(private val plugin: EcoPlugin) : Listener { val slot = menu.getSlot(row, column, player) - if (!slot.isCaptive(player, menu) && slot.isAllowedCaptive(player, menu, event.currentItem)) { + if (slot.isCaptive(player, menu)) { + if (!slot.isAllowedCaptive(player, menu, event.currentItem)) { + event.isCancelled = true + } + } else { event.isCancelled = true } } @@ -115,6 +147,12 @@ class GUIListener(private val plugin: EcoPlugin) : Listener { player.renderActiveMenu() } + @EventHandler + fun forceRender(event: InventoryDragEvent) { + val player = event.whoClicked as? Player ?: return + player.renderActiveMenu() + } + @EventHandler( priority = EventPriority.HIGHEST )