diff --git a/README.md b/README.md
index 8f5dd96..a53ff85 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ repositories {
}
dependencies {
- implementation("com.github.DebitCardz:mc-chestui-plus:1.3.1")
+ implementation("com.github.DebitCardz:mc-chestui-plus:1.3.2")
}
```
### Maven
@@ -34,7 +34,7 @@ dependencies {
com.github.DebitCardz
mc-chestui-plus
- 1.3.1
+ 1.3.2
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 4744fe9..305771c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ val githubActor = project.findProperty("gpr.user") as String? ?: System.getenv("
val githubToken = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
group = "me.tech"
-version = "1.3.1"
+version = "1.3.2"
repositories {
mavenCentral()
diff --git a/src/main/kotlin/me/tech/mcchestui/GUI.kt b/src/main/kotlin/me/tech/mcchestui/GUI.kt
index 151ca91..cd7fbda 100644
--- a/src/main/kotlin/me/tech/mcchestui/GUI.kt
+++ b/src/main/kotlin/me/tech/mcchestui/GUI.kt
@@ -8,7 +8,9 @@
package me.tech.mcchestui
import me.tech.mcchestui.item.GUIItem
-import me.tech.mcchestui.listeners.GUIListener
+import me.tech.mcchestui.listeners.*
+import me.tech.mcchestui.listeners.item.*
+import me.tech.mcchestui.listeners.hotbar.*
import me.tech.mcchestui.utils.GUICloseEvent
import me.tech.mcchestui.utils.GUIDragItemEvent
import me.tech.mcchestui.utils.GUIItemPickupEvent
@@ -138,7 +140,17 @@ class GUI(
*/
internal var templateSlots = mutableMapOf()
- private val guiListener = GUIListener(this)
+ private val eventListeners = listOf(
+ GUISlotClickListener(this),
+
+ GUIItemPickupListener(this),
+ GUIItemPlaceListener(this),
+ GUIItemDragListener(this),
+
+ GUIHotbarListener(this),
+
+ GUICloseListener(this)
+ )
/**
* Define weather the [GUI] has been unregistered.
@@ -147,8 +159,10 @@ class GUI(
internal var unregistered = false
init {
- plugin.server.pluginManager
- .registerEvents(guiListener, plugin)
+ eventListeners.forEach {
+ plugin.server.pluginManager
+ .registerEvents(it, plugin)
+ }
}
/**
@@ -308,7 +322,7 @@ class GUI(
* Mark a [GUI] as unregistered and remove its [Listener].
*/
fun unregister() {
- HandlerList.unregisterAll(guiListener)
+ eventListeners.forEach(HandlerList::unregisterAll)
unregistered = true
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/GUICloseListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/GUICloseListener.kt
new file mode 100644
index 0000000..deae2a3
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/GUICloseListener.kt
@@ -0,0 +1,28 @@
+package me.tech.mcchestui.listeners
+
+import me.tech.mcchestui.GUI
+import org.bukkit.event.EventHandler
+import org.bukkit.event.inventory.InventoryCloseEvent
+
+internal class GUICloseListener(gui: GUI) : GUIEventListener(gui) {
+ @EventHandler
+ internal fun InventoryCloseEvent.onClose() {
+ if(!gui.isBukkitInventory(inventory)) {
+ return
+ }
+
+ gui.onCloseInventory?.let { uiEvent ->
+ uiEvent(this, player)
+ }
+
+ if(gui.singleInstance) {
+ return
+ }
+
+ if(inventory.viewers.size > 1) {
+ return
+ }
+
+ gui.unregister()
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/GUIEventListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/GUIEventListener.kt
new file mode 100644
index 0000000..f1f5ea4
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/GUIEventListener.kt
@@ -0,0 +1,45 @@
+package me.tech.mcchestui.listeners
+
+import me.tech.mcchestui.GUI
+import org.bukkit.event.Listener
+import org.bukkit.event.inventory.InventoryAction
+
+internal abstract class GUIEventListener(
+ protected val gui: GUI
+) : Listener {
+ companion object {
+ /**
+ * All actions related to placing an item.
+ */
+ @JvmStatic
+ protected val PLACE_ACTIONS = listOf(
+ InventoryAction.PLACE_ONE,
+ InventoryAction.PLACE_SOME,
+ InventoryAction.PLACE_ALL,
+ InventoryAction.SWAP_WITH_CURSOR
+ )
+
+ /**
+ * All actions related to using hotkeys to place/pickup
+ * an item.
+ */
+ @JvmStatic
+ protected val HOTBAR_ACTIONS = listOf(
+ InventoryAction.HOTBAR_SWAP,
+ InventoryAction.HOTBAR_MOVE_AND_READD
+ )
+
+ /**
+ * All actions related to picking up an item.
+ */
+ @JvmStatic
+ protected val PICKUP_ACTIONS = listOf(
+ InventoryAction.PICKUP_ONE,
+ InventoryAction.PICKUP_SOME,
+ InventoryAction.PICKUP_HALF,
+ InventoryAction.PICKUP_ALL,
+ InventoryAction.SWAP_WITH_CURSOR,
+ InventoryAction.COLLECT_TO_CURSOR
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/GUIListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/GUIListener.kt
deleted file mode 100644
index a19840e..0000000
--- a/src/main/kotlin/me/tech/mcchestui/listeners/GUIListener.kt
+++ /dev/null
@@ -1,337 +0,0 @@
-package me.tech.mcchestui.listeners
-
-import me.tech.mcchestui.GUI
-import org.bukkit.Material
-import org.bukkit.entity.Player
-import org.bukkit.event.Cancellable
-import org.bukkit.event.EventHandler
-import org.bukkit.event.Listener
-import org.bukkit.event.inventory.*
-import org.bukkit.inventory.Inventory
-
-internal class GUIListener(private val gui: GUI): Listener {
- /**
- * When a [GUI.Slot] is clicked in the [Inventory].
- *
- * This listener should not be used to modify the [Cancellable] of
- * the bukkit event, handle that in the onPickup event.
- */
- @EventHandler
- internal fun InventoryClickEvent.onSlotClick() {
- // ensure clicked inventory is ui inventory.
- if(!gui.isBukkitInventory(clickedInventory)) {
- return
- }
-
- val guiSlot = gui.slots.getOrNull(slot)
- ?: return // handle cancellation of task in onPlace.
-
- guiSlot.onClick?.let { uiEvent ->
- uiEvent(this, whoClicked as Player)
- }
- }
-
- @EventHandler
- internal fun InventoryClickEvent.onItemPlace() {
- // ensure top inventory is ui inventory.
- if(!gui.isBukkitInventory(inventory)) {
- return
- }
-
- if(
- action == InventoryAction.MOVE_TO_OTHER_INVENTORY
- && isShiftClick
- && !gui.isBukkitInventory(clickedInventory) // make sure its incoming.
- ) {
- if(!gui.allowItemPlacement) {
- isCancelled = true
- return
- }
- } else if(
- action in PLACE_ACTIONS
- && gui.isBukkitInventory(clickedInventory)
- ) {
- if(!gui.allowItemPlacement) {
- isCancelled = true
- return
- }
- } else {
- return
- }
-
- val guiSlot = gui.slots.getOrNull(slot)
- if(guiSlot != null) {
- if(!guiSlot.allowPickup) {
- isCancelled = true
- return
- }
- }
-
- val itemStack = cursor
- ?: return
- if(itemStack.type == Material.AIR) {
- return
- }
-
- gui.onPlaceItem?.let { uiEvent ->
- uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
- isCancelled = outcome
- }
- }
- }
-
- @EventHandler
- internal fun InventoryDragEvent.onItemDrag() {
- if(!gui.isBukkitInventory(inventory)) {
- return
- }
-
- if(!gui.allowItemPlacement) {
- isCancelled = true
- return
- }
-
- // single item drag handler, move to onPlaceItem event.
- if(rawSlots.size == 1 && newItems.size == 1) {
- val slotIndex = rawSlots.first()
-
- val guiSlot = gui.slots.getOrNull(slotIndex)
- if(guiSlot != null) {
- if(!guiSlot.allowPickup) {
- isCancelled = true
- return
- }
- }
-
- val itemStack = newItems.values.firstOrNull()
- ?: return
- if(itemStack.type == Material.AIR) {
- return
- }
-
- gui.onPlaceItem?.let { uiEvent ->
- // TODO: Look for better method of handling this.
- val fakeEvent = InventoryClickEvent(
- view,
- InventoryType.SlotType.CONTAINER,
- slotIndex,
- if(type == DragType.SINGLE) ClickType.RIGHT else ClickType.LEFT,
- InventoryAction.PLACE_ALL
- )
-
- uiEvent(fakeEvent, whoClicked as Player, itemStack, slotIndex).let { outcome ->
- isCancelled = outcome
- }
- }
- return
- }
-
- if(!gui.allowItemDrag) {
- isCancelled = true
- return
- }
-
- // ensure our drag doesn't override a slot.
- if(newItems.any { (index, _) ->
- val guiSlot = gui.slots.getOrNull(index)
- ?: return@any false
-
- !guiSlot.allowPickup
- }) {
- isCancelled = true
- return
- }
-
- gui.onDragItem?.let { uiEvent ->
- uiEvent(this, whoClicked as Player, newItems).let { outcome ->
- isCancelled = outcome
- }
- }
- }
-
- @EventHandler(ignoreCancelled = true)
- internal fun InventoryClickEvent.onHotBarSwitchToUIInventory() {
- if(!gui.isBukkitInventory(inventory)) {
- return
- }
-
- // player inv -> gui inv
- if(
- action !in HOTBAR_ACTIONS
- || click != ClickType.NUMBER_KEY
- ) {
- return
- }
-
- if(!gui.allowHotBarSwap) {
- if(gui.isBukkitInventory(clickedInventory)) {
- isCancelled = true
- }
-
- return
- }
-
- if(clickedInventory == whoClicked.inventory) {
- return
- }
-
- val itemStack = if(click == ClickType.NUMBER_KEY) {
- whoClicked.inventory.getItem(hotbarButton)
- } else {
- currentItem
- } ?: return
-
- if(itemStack.type == Material.AIR) {
- return
- }
-
- gui.onPlaceItem?.let { uiEvent ->
- uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
- isCancelled = outcome
- }
- }
- }
-
- @EventHandler(ignoreCancelled = true)
- internal fun InventoryClickEvent.onHotBarSwitchToPlayerInventory() {
- if(!gui.isBukkitInventory(inventory)) {
- return
- }
-
- // gui inv -> player inv
- if(
- action !in HOTBAR_ACTIONS
- || click != ClickType.NUMBER_KEY
- ) {
- return
- }
-
- if(!gui.allowHotBarSwap) {
- if(gui.isBukkitInventory(clickedInventory)) {
- isCancelled = true
- }
-
- return
- }
-
- if(clickedInventory == whoClicked.inventory) {
- return
- }
-
- val itemStack = currentItem
- ?: return
- if(itemStack.type == Material.AIR) {
- return
- }
-
- gui.onPickupItem?.let { uiEvent ->
- uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
- isCancelled = outcome
- }
- }
- }
-
- @EventHandler
- internal fun InventoryClickEvent.onItemPickup() {
- // ensure top inventory is ui inventory.
- if(!gui.isBukkitInventory(inventory)) {
- return
- }
-
- // handle shift click
- if(
- action == InventoryAction.MOVE_TO_OTHER_INVENTORY
- && isShiftClick
- && gui.isBukkitInventory(clickedInventory) // make sure its outgoing.
- ) {
- if(!gui.allowItemPickup) {
- isCancelled = true
- return
- }
- } else if(
- action in PICKUP_ACTIONS
- && gui.isBukkitInventory(clickedInventory)
- ) {
- if(!gui.allowItemPickup) {
- isCancelled = true
- return
- }
- } else {
- return
- }
-
- val guiSlot = gui.slots.getOrNull(slot)
- if(guiSlot != null) {
- if(!guiSlot.allowPickup) {
- isCancelled = true
- return
- }
- }
-
- val itemStack = currentItem
- ?: return
- if(itemStack.type == Material.AIR) {
- return
- }
-
- gui.onPickupItem?.let { uiEvent ->
- uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
- isCancelled = outcome
- }
- }
- }
-
- @EventHandler
- internal fun InventoryCloseEvent.onClose() {
- if(!gui.isBukkitInventory(inventory)) {
- return
- }
-
- gui.onCloseInventory?.let { uiEvent ->
- uiEvent(this, player)
- }
-
- if(gui.singleInstance) {
- return
- }
-
- if(inventory.viewers.size > 1) {
- return
- }
-
- gui.unregister()
- }
-
- companion object {
- /**
- * All actions related to placing an item.
- */
- private val PLACE_ACTIONS = listOf(
- InventoryAction.PLACE_ONE,
- InventoryAction.PLACE_SOME,
- InventoryAction.PLACE_ALL,
- InventoryAction.SWAP_WITH_CURSOR
- )
-
- /**
- * All actions related to using hotkeys to place/pickup
- * an item.
- */
- private val HOTBAR_ACTIONS = listOf(
- InventoryAction.HOTBAR_SWAP,
- InventoryAction.HOTBAR_MOVE_AND_READD
- )
-
- /**
- * All actions related to picking up an item.
- */
- private val PICKUP_ACTIONS = listOf(
- InventoryAction.PICKUP_ONE,
- InventoryAction.PICKUP_SOME,
- InventoryAction.PICKUP_HALF,
- InventoryAction.PICKUP_ALL,
- InventoryAction.SWAP_WITH_CURSOR,
- InventoryAction.COLLECT_TO_CURSOR
- )
- }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/GUISlotClickListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/GUISlotClickListener.kt
new file mode 100644
index 0000000..2b65971
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/GUISlotClickListener.kt
@@ -0,0 +1,23 @@
+package me.tech.mcchestui.listeners
+
+import me.tech.mcchestui.GUI
+import org.bukkit.entity.Player
+import org.bukkit.event.EventHandler
+import org.bukkit.event.inventory.InventoryClickEvent
+
+internal class GUISlotClickListener(gui: GUI) : GUIEventListener(gui) {
+ @EventHandler
+ internal fun InventoryClickEvent.slotClick() {
+ // ensure clicked inventory is ui inventory.
+ if(!gui.isBukkitInventory(clickedInventory)) {
+ return
+ }
+
+ val guiSlot = gui.slots.getOrNull(slot)
+ ?: return // handle cancellation of task in onPlace.
+
+ guiSlot.onClick?.let { uiEvent ->
+ uiEvent(this, whoClicked as Player)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/hotbar/GUIHotbarListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/hotbar/GUIHotbarListener.kt
new file mode 100644
index 0000000..98e1dfb
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/hotbar/GUIHotbarListener.kt
@@ -0,0 +1,93 @@
+package me.tech.mcchestui.listeners.hotbar
+
+import me.tech.mcchestui.GUI
+import me.tech.mcchestui.listeners.GUIEventListener
+import org.bukkit.Material
+import org.bukkit.entity.Player
+import org.bukkit.event.EventHandler
+import org.bukkit.event.inventory.ClickType
+import org.bukkit.event.inventory.InventoryClickEvent
+
+internal class GUIHotbarListener(gui: GUI) : GUIEventListener(gui) {
+ @EventHandler(ignoreCancelled = true)
+ internal fun InventoryClickEvent.hotBarSwitchToUIInventory() {
+ if(!gui.isBukkitInventory(inventory)) {
+ return
+ }
+
+ // player inv -> gui inv
+ if(
+ action !in HOTBAR_ACTIONS
+ || click != ClickType.NUMBER_KEY
+ ) {
+ return
+ }
+
+ if(!gui.allowHotBarSwap) {
+ if(gui.isBukkitInventory(clickedInventory)) {
+ isCancelled = true
+ }
+
+ return
+ }
+
+ if(clickedInventory == whoClicked.inventory) {
+ return
+ }
+
+ val itemStack = if(click == ClickType.NUMBER_KEY) {
+ whoClicked.inventory.getItem(hotbarButton)
+ } else {
+ currentItem
+ } ?: return
+
+ if(itemStack.type == Material.AIR) {
+ return
+ }
+
+ gui.onPlaceItem?.let { uiEvent ->
+ uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
+ isCancelled = outcome
+ }
+ }
+ }
+
+ @EventHandler(ignoreCancelled = true)
+ internal fun InventoryClickEvent.hotBarSwitchToPlayerInventory() {
+ if(!gui.isBukkitInventory(inventory)) {
+ return
+ }
+
+ // gui inv -> player inv
+ if(
+ action !in HOTBAR_ACTIONS
+ || click != ClickType.NUMBER_KEY
+ ) {
+ return
+ }
+
+ if(!gui.allowHotBarSwap) {
+ if(gui.isBukkitInventory(clickedInventory)) {
+ isCancelled = true
+ }
+
+ return
+ }
+
+ if(clickedInventory == whoClicked.inventory) {
+ return
+ }
+
+ val itemStack = currentItem
+ ?: return
+ if(itemStack.type == Material.AIR) {
+ return
+ }
+
+ gui.onPickupItem?.let { uiEvent ->
+ uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
+ isCancelled = outcome
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemDragListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemDragListener.kt
new file mode 100644
index 0000000..4afbab1
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemDragListener.kt
@@ -0,0 +1,79 @@
+package me.tech.mcchestui.listeners.item
+
+import me.tech.mcchestui.GUI
+import me.tech.mcchestui.listeners.GUIEventListener
+import org.bukkit.Material
+import org.bukkit.entity.Player
+import org.bukkit.event.EventHandler
+import org.bukkit.event.inventory.*
+
+internal class GUIItemDragListener(gui: GUI) : GUIEventListener(gui) {
+ @EventHandler
+ internal fun InventoryDragEvent.itemDrag() {
+ if(!gui.isBukkitInventory(inventory)) {
+ return
+ }
+
+ if(!gui.allowItemPlacement) {
+ isCancelled = true
+ return
+ }
+
+ // single item drag handler, move to onPlaceItem event.
+ if(rawSlots.size == 1 && newItems.size == 1) {
+ val slotIndex = rawSlots.first()
+
+ val guiSlot = gui.slots.getOrNull(slotIndex)
+ if(guiSlot != null) {
+ if(!guiSlot.allowPickup) {
+ isCancelled = true
+ return
+ }
+ }
+
+ val itemStack = newItems.values.firstOrNull()
+ ?: return
+ if(itemStack.type == Material.AIR) {
+ return
+ }
+
+ gui.onPlaceItem?.let { uiEvent ->
+ // TODO: Look for better method of handling this.
+ val fakeEvent = InventoryClickEvent(
+ view,
+ InventoryType.SlotType.CONTAINER,
+ slotIndex,
+ if(type == DragType.SINGLE) ClickType.RIGHT else ClickType.LEFT,
+ InventoryAction.PLACE_ALL
+ )
+
+ uiEvent(fakeEvent, whoClicked as Player, itemStack, slotIndex).let { outcome ->
+ isCancelled = outcome
+ }
+ }
+ return
+ }
+
+ if(!gui.allowItemDrag) {
+ isCancelled = true
+ return
+ }
+
+ // ensure our drag doesn't override a slot.
+ if(newItems.any { (index, _) ->
+ val guiSlot = gui.slots.getOrNull(index)
+ ?: return@any false
+
+ !guiSlot.allowPickup
+ }) {
+ isCancelled = true
+ return
+ }
+
+ gui.onDragItem?.let { uiEvent ->
+ uiEvent(this, whoClicked as Player, newItems).let { outcome ->
+ isCancelled = outcome
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemPickupListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemPickupListener.kt
new file mode 100644
index 0000000..5b0c3a7
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemPickupListener.kt
@@ -0,0 +1,61 @@
+package me.tech.mcchestui.listeners.item
+
+import me.tech.mcchestui.GUI
+import me.tech.mcchestui.listeners.GUIEventListener
+import org.bukkit.Material
+import org.bukkit.entity.Player
+import org.bukkit.event.EventHandler
+import org.bukkit.event.inventory.InventoryAction
+import org.bukkit.event.inventory.InventoryClickEvent
+
+internal class GUIItemPickupListener(gui: GUI): GUIEventListener(gui) {
+ @EventHandler
+ internal fun InventoryClickEvent.onItemPickup() {
+ // ensure top inventory is ui inventory.
+ if(!gui.isBukkitInventory(inventory)) {
+ return
+ }
+
+ // handle shift click
+ if(
+ action == InventoryAction.MOVE_TO_OTHER_INVENTORY
+ && isShiftClick
+ && gui.isBukkitInventory(clickedInventory) // make sure its outgoing.
+ ) {
+ if(!gui.allowItemPickup) {
+ isCancelled = true
+ return
+ }
+ } else if(
+ action in PICKUP_ACTIONS
+ && gui.isBukkitInventory(clickedInventory)
+ ) {
+ if(!gui.allowItemPickup) {
+ isCancelled = true
+ return
+ }
+ } else {
+ return
+ }
+
+ val guiSlot = gui.slots.getOrNull(slot)
+ if(guiSlot != null) {
+ if(!guiSlot.allowPickup) {
+ isCancelled = true
+ return
+ }
+ }
+
+ val itemStack = currentItem
+ ?: return
+ if(itemStack.type == Material.AIR) {
+ return
+ }
+
+ gui.onPickupItem?.let { uiEvent ->
+ uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
+ isCancelled = outcome
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemPlaceListener.kt b/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemPlaceListener.kt
new file mode 100644
index 0000000..915d98b
--- /dev/null
+++ b/src/main/kotlin/me/tech/mcchestui/listeners/item/GUIItemPlaceListener.kt
@@ -0,0 +1,60 @@
+package me.tech.mcchestui.listeners.item
+
+import me.tech.mcchestui.GUI
+import me.tech.mcchestui.listeners.GUIEventListener
+import org.bukkit.Material
+import org.bukkit.entity.Player
+import org.bukkit.event.EventHandler
+import org.bukkit.event.inventory.InventoryAction
+import org.bukkit.event.inventory.InventoryClickEvent
+
+internal class GUIItemPlaceListener(gui: GUI) : GUIEventListener(gui) {
+ @EventHandler
+ internal fun InventoryClickEvent.itemPlace() {
+ // ensure top inventory is ui inventory.
+ if(!gui.isBukkitInventory(inventory)) {
+ return
+ }
+
+ if(
+ action == InventoryAction.MOVE_TO_OTHER_INVENTORY
+ && isShiftClick
+ && !gui.isBukkitInventory(clickedInventory) // make sure its incoming.
+ ) {
+ if(!gui.allowItemPlacement) {
+ isCancelled = true
+ return
+ }
+ } else if(
+ action in PLACE_ACTIONS
+ && gui.isBukkitInventory(clickedInventory)
+ ) {
+ if(!gui.allowItemPlacement) {
+ isCancelled = true
+ return
+ }
+ } else {
+ return
+ }
+
+ val guiSlot = gui.slots.getOrNull(slot)
+ if(guiSlot != null) {
+ if(!guiSlot.allowPickup) {
+ isCancelled = true
+ return
+ }
+ }
+
+ val itemStack = cursor
+ ?: return
+ if(itemStack.type == Material.AIR) {
+ return
+ }
+
+ gui.onPlaceItem?.let { uiEvent ->
+ uiEvent(this, whoClicked as Player, itemStack, slot).let { outcome ->
+ isCancelled = outcome
+ }
+ }
+ }
+}
\ No newline at end of file