diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java
index 156f8173..9265a4f2 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/Menu.java
@@ -4,8 +4,11 @@ import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
+import java.util.List;
+
/**
* GUI version of {@link Inventory}.
*
@@ -44,6 +47,14 @@ public interface Menu {
*/
Inventory open(@NotNull Player player);
+ /**
+ * Get captive items.
+ *
+ * @param player The player.
+ * @return The items.
+ */
+ List getCaptiveItems(@NotNull Player player);
+
/**
* Create a builder with a given amount of rows.
*
diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/slot/SlotBuilder.java b/eco-api/src/main/java/com/willfp/eco/core/gui/slot/SlotBuilder.java
index 267696c8..de8b4f8b 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/slot/SlotBuilder.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/slot/SlotBuilder.java
@@ -49,6 +49,13 @@ public interface SlotBuilder {
*/
SlotBuilder onMiddleClick(@NotNull BiConsumer action);
+ /**
+ * Set slot to be a captive slot.
+ *
+ * @return The builder.
+ */
+ SlotBuilder setCaptive();
+
/**
* Build the slot.
*
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt
index ca157311..a0a4215b 100644
--- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenu.kt
@@ -1,14 +1,13 @@
package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.gui.menu.Menu
-import com.willfp.eco.core.gui.slot.FillerSlot
import com.willfp.eco.core.gui.slot.Slot
-import com.willfp.eco.internal.gui.slot.EcoFillerSlot
import com.willfp.eco.util.StringUtils
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.Inventory
+import org.bukkit.inventory.ItemStack
import java.util.function.Consumer
class EcoMenu(
@@ -17,7 +16,6 @@ class EcoMenu(
private val title: String,
private val onClose: Consumer
): Menu {
-
override fun getSlot(row: Int, column: Int): Slot {
if (row < 1 || row > this.rows) {
throw IllegalArgumentException("Invalid row number!")
@@ -27,14 +25,7 @@ class EcoMenu(
throw IllegalArgumentException("Invalid column number!")
}
- val slot = slots[row - 1][column - 1]
- if (slot is FillerSlot) {
- slots[row - 1][column - 1] = EcoFillerSlot(slot.itemStack)
-
- return getSlot(row, column)
- }
-
- return slot
+ return slots[row - 1][column - 1]
}
override fun open(player: Player): Inventory {
@@ -77,4 +68,9 @@ class EcoMenu(
override fun getTitle(): String {
return title
}
+
+ override fun getCaptiveItems(player: Player): MutableList {
+ val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory)
+ return inventory.captiveItems
+ }
}
\ No newline at end of file
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt
index 06d0703c..4cb6239e 100644
--- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/EcoMenuBuilder.kt
@@ -3,6 +3,7 @@ package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.menu.MenuBuilder
import com.willfp.eco.core.gui.slot.FillerMask
+import com.willfp.eco.core.gui.slot.FillerSlot
import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.internal.gui.slot.EcoFillerSlot
import com.willfp.eco.util.ListUtils
@@ -58,7 +59,10 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
for (i in slots.indices) {
for (j in slots[i].indices) {
- val slot = slots[i][j]
+ var slot = slots[i][j]
+ if (slot is FillerSlot) {
+ slot = EcoFillerSlot(slot.itemStack)
+ }
finalSlots[i][j] = slot
}
}
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/ExtendedInventory.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/ExtendedInventory.kt
new file mode 100644
index 00000000..c5e882ec
--- /dev/null
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/ExtendedInventory.kt
@@ -0,0 +1,31 @@
+package com.willfp.eco.internal.gui.menu
+
+import com.willfp.eco.internal.gui.slot.EcoCaptivatorSlot
+import com.willfp.eco.util.MenuUtils
+import org.bukkit.entity.Player
+import org.bukkit.inventory.Inventory
+import org.bukkit.inventory.ItemStack
+
+class ExtendedInventory(
+ val inventory: Inventory,
+ private val menu: EcoMenu
+) {
+ val captiveItems: MutableList = ArrayList()
+
+ fun refresh(player: Player) {
+ captiveItems.clear()
+ for (i in 0 until inventory.size) {
+ val pair = MenuUtils.convertSlotToRowColumn(i);
+ val row = pair.first!!
+ val column = pair.second!!
+ val slot = menu.getSlot(row, column)
+ if (slot is EcoCaptivatorSlot) {
+ val defaultItem = slot.getItemStack(player)
+ val item = inventory.getItem(i) ?: continue
+ if (item != defaultItem) {
+ captiveItems.add(item)
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuHandler.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuHandler.kt
index 6c217d2d..3491c5b2 100644
--- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuHandler.kt
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuHandler.kt
@@ -4,20 +4,28 @@ import com.willfp.eco.core.gui.menu.Menu
import org.bukkit.inventory.Inventory
object MenuHandler {
- private val MENUS: MutableMap = HashMap()
+ private val MENUS: MutableMap = HashMap()
+ private val INVS: MutableMap = HashMap()
fun registerMenu(
inventory: Inventory,
- menu: Menu
+ menu: EcoMenu
) {
- MENUS[inventory] = menu
+ val extendedInventory = ExtendedInventory(inventory, menu)
+ INVS[inventory] = extendedInventory
+ MENUS[extendedInventory] = menu
}
fun unregisterMenu(inventory: Inventory) {
- MENUS.remove(inventory)
+ MENUS.remove(INVS[inventory])
+ INVS.remove(inventory)
}
fun getMenu(inventory: Inventory): Menu? {
- return MENUS[inventory]
+ return MENUS[INVS[inventory]]
+ }
+
+ fun getExtendedInventory(inventory: Inventory): ExtendedInventory {
+ return INVS[inventory]!!
}
}
\ No newline at end of file
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptivatorSlot.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptivatorSlot.kt
new file mode 100644
index 00000000..bef92639
--- /dev/null
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoCaptivatorSlot.kt
@@ -0,0 +1,34 @@
+package com.willfp.eco.internal.gui.slot
+
+import com.willfp.eco.core.Eco
+import com.willfp.eco.core.gui.slot.Slot
+import org.bukkit.entity.Player
+import org.bukkit.event.inventory.InventoryClickEvent
+import org.bukkit.inventory.ItemStack
+import java.util.function.BiConsumer
+import java.util.function.Function
+
+class EcoCaptivatorSlot(
+ provider: Function
+) : EcoSlot(
+ provider,
+ allowMovingItem,
+ allowMovingItem,
+ allowMovingItem,
+ allowMovingItem,
+ allowMovingItem
+) {
+ var captive: ItemStack? = null
+
+ override fun getItemStack(player: Player): ItemStack {
+ return captive ?: provider.apply(player);
+ }
+
+ companion object {
+ val plugin = Eco.getHandler().ecoPlugin!!
+
+ val allowMovingItem: BiConsumer = BiConsumer { event, _ ->
+ event.isCancelled = false
+ }
+ }
+}
\ No newline at end of file
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 d5146fc4..a5a82054 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
@@ -9,7 +9,7 @@ import java.util.function.BiConsumer
import java.util.function.Function
open class EcoSlot(
- private val provider: Function,
+ val provider: Function,
private val onLeftClick: BiConsumer,
private val onRightClick: BiConsumer,
private val onShiftLeftClick: BiConsumer,
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlotBuilder.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlotBuilder.kt
index c4db620c..75261142 100644
--- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlotBuilder.kt
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/slot/EcoSlotBuilder.kt
@@ -9,6 +9,8 @@ import java.util.function.BiConsumer
import java.util.function.Function
class EcoSlotBuilder(private val provider: Function) : SlotBuilder {
+ private var captive = false;
+
private var onLeftClick: BiConsumer = BiConsumer { _, _ -> run { } }
private var onRightClick: BiConsumer = BiConsumer { _, _ -> run { } }
private var onShiftLeftClick: BiConsumer = BiConsumer { _, _ -> run { } }
@@ -40,7 +42,16 @@ class EcoSlotBuilder(private val provider: Function) : SlotBu
return this
}
+ override fun setCaptive(): SlotBuilder {
+ captive = true
+ return this
+ }
+
override fun build(): Slot {
- return EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick)
+ return if (captive) {
+ EcoCaptivatorSlot(provider)
+ } else {
+ EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick)
+ }
}
}
\ No newline at end of file
diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/gui/GUIListener.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/gui/GUIListener.kt
index 1cbc6ab9..55c3a83e 100644
--- a/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/gui/GUIListener.kt
+++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/eco/spigot/gui/GUIListener.kt
@@ -2,13 +2,16 @@ package com.willfp.eco.spigot.gui
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
+import com.willfp.eco.core.drops.DropQueue
import com.willfp.eco.internal.gui.menu.EcoMenu
import com.willfp.eco.internal.gui.menu.MenuHandler
import com.willfp.eco.internal.gui.slot.EcoSlot
import com.willfp.eco.util.MenuUtils
import org.apache.commons.lang.Validate
+import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
+import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent
@@ -16,13 +19,11 @@ import org.bukkit.event.inventory.InventoryCloseEvent
class GUIListener(plugin: EcoPlugin) : PluginDependent(plugin), Listener {
@EventHandler
fun handleSlotClick(event: InventoryClickEvent) {
- if (event.whoClicked !is Player) {
+ val player = event.whoClicked
+ if (player !is Player) {
return
}
- if (event.clickedInventory == null) {
- return
- }
- val menu = MenuHandler.getMenu(event.clickedInventory!!) ?: return
+ val menu = MenuHandler.getMenu(event.clickedInventory ?: return) ?: return
val rowColumn = MenuUtils.convertSlotToRowColumn(event.slot)
val row = rowColumn.first!!
val column = rowColumn.second!!
@@ -31,17 +32,40 @@ class GUIListener(plugin: EcoPlugin) : PluginDependent(plugin), Liste
val ecoSlot = menu.getSlot(row, column) as EcoSlot
event.isCancelled = true
ecoSlot.handleInventoryClick(event)
+
+ plugin.scheduler.run{ MenuHandler.getExtendedInventory(event.clickedInventory!!).refresh(player) }
}
@EventHandler
+ fun handleCaptivatorSlots(event: InventoryClickEvent) {
+ val player = event.whoClicked
+ if (player !is Player) {
+ return
+ }
+
+ val menu = MenuHandler.getMenu(player.openInventory.topInventory) ?: return
+
+ plugin.scheduler.run{ MenuHandler.getExtendedInventory(player.openInventory.topInventory).refresh(player) }
+ plugin.scheduler.runLater({ Bukkit.getLogger().info(menu.getCaptiveItems(player).toString()) }, 1)
+ }
+
+ @EventHandler(priority = EventPriority.HIGH)
fun handleClose(event: InventoryCloseEvent) {
- if (event.player !is Player) {
+ val player = event.player
+ if (player !is Player) {
return
}
val menu = MenuHandler.getMenu(event.inventory) ?: return
Validate.isTrue(menu is EcoMenu, "Menu not instance of EcoMenu!")
val ecoMenu = menu as EcoMenu
ecoMenu.handleClose(event)
+
+ DropQueue(player)
+ .addItems(ecoMenu.getCaptiveItems(player))
+ .setLocation(player.location)
+ .forceTelekinesis()
+ .push()
+
plugin.scheduler.run { MenuHandler.unregisterMenu(event.inventory) }
}
}
\ No newline at end of file