diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/GUIFactory.java b/eco-api/src/main/java/com/willfp/eco/core/gui/GUIFactory.java
index d98c3868..bb858d30 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/GUIFactory.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/GUIFactory.java
@@ -3,6 +3,7 @@ package com.willfp.eco.core.gui;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuBuilder;
+import com.willfp.eco.core.gui.menu.MenuType;
import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.inventory.ItemStack;
@@ -29,10 +30,12 @@ public interface GUIFactory {
* Create menu builder.
*
* @param rows The amount of rows.
+ * @param type The type.
* @return The builder.
*/
@NotNull
- MenuBuilder createMenuBuilder(int rows);
+ MenuBuilder createMenuBuilder(int rows,
+ @NotNull MenuType type);
/**
* Combine the state of two menus together.
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 cd0ed51c..f4ca2a33 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
@@ -27,6 +27,15 @@ public interface Menu {
*/
int getRows();
+ /**
+ * Get the amount of columns.
+ *
+ * @return The amount of columns.
+ */
+ default int getColumns() {
+ return 9;
+ }
+
/**
* Get a static slot at a given row and column.
*
@@ -81,6 +90,21 @@ public interface Menu {
*/
List getCaptiveItems(@NotNull Player player);
+ /**
+ * Get a captive item at a specific position.
+ *
+ * @param player The player.
+ * @param row The row.
+ * @param column The column.
+ * @return The captive item.
+ */
+ @Nullable
+ default ItemStack getCaptiveItem(@NotNull final Player player,
+ final int row,
+ final int column) {
+ return null;
+ }
+
/**
* Add state for a player.
*
@@ -196,6 +220,19 @@ public interface Menu {
* @return The builder.
*/
static MenuBuilder builder(final int rows) {
- return Eco.getHandler().getGUIFactory().createMenuBuilder(rows);
+ return Eco.getHandler().getGUIFactory().createMenuBuilder(
+ rows,
+ MenuType.NORMAL
+ );
+ }
+
+ /**
+ * Create a builder with a given type.
+ *
+ * @param type The menu type.
+ * @return The builder.
+ */
+ static MenuBuilder builder(@NotNull final MenuType type) {
+ return Eco.getHandler().getGUIFactory().createMenuBuilder(type.getDefaultRows(), type);
}
}
diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java
index 6b68afa1..c96d4821 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuBuilder.java
@@ -101,6 +101,22 @@ public interface MenuBuilder extends PageBuilder {
return this.addComponent(MenuLayer.TOP, 1, 1, page);
}
+ /**
+ * Add a page.
+ *
+ * @param pageNumber The page number.
+ * @param pageBuilder The page builder.
+ * @return The builder.
+ */
+ default MenuBuilder addPage(final int pageNumber,
+ @NotNull final Consumer pageBuilder) {
+ MenuBuilder builder = Menu.builder(this.getRows());
+ pageBuilder.accept(builder);
+
+ Page page = new Page(pageNumber, builder.build());
+ return this.addPage(page);
+ }
+
/**
* Set the max pages.
*
diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuType.java b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuType.java
new file mode 100644
index 00000000..a47d208d
--- /dev/null
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/menu/MenuType.java
@@ -0,0 +1,56 @@
+package com.willfp.eco.core.gui.menu;
+
+/**
+ * The type of menu.
+ */
+public enum MenuType {
+ /**
+ * Normal menu (1x9, 2x9, 3x9, etc).
+ */
+ NORMAL(9, 6),
+
+ /**
+ * Dispenser menu (3x3).
+ */
+ DISPENSER(3, 3);
+
+ /**
+ * The amount of columns.
+ */
+ private final int columns;
+
+ /**
+ * The default amount of rows.
+ */
+ private final int defaultRows;
+
+ /**
+ * Create a new menu type.
+ *
+ * @param columns The number of columns.
+ * @param defaultRows The default number of rows.
+ */
+ MenuType(final int columns,
+ final int defaultRows) {
+ this.columns = columns;
+ this.defaultRows = defaultRows;
+ }
+
+ /**
+ * Get the amount of columns.
+ *
+ * @return The columns.
+ */
+ public int getColumns() {
+ return columns;
+ }
+
+ /**
+ * Get the default amount of rows.
+ *
+ * @return The default amount of rows.
+ */
+ public int getDefaultRows() {
+ return defaultRows;
+ }
+}
diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java b/eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
index 8cbfc18b..8f402b86 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
@@ -3,14 +3,12 @@ package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
-import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
-import java.util.function.Consumer;
/**
* A page is a component representing another menu.
@@ -42,6 +40,16 @@ public final class Page implements GUIComponent {
*/
private Menu delegate = null;
+ /**
+ * The rows for the page to have.
+ */
+ private int rows = 6;
+
+ /**
+ * The columns for the page to have.
+ */
+ private int columns = 9;
+
/**
* Create a new page.
*
@@ -54,20 +62,6 @@ public final class Page implements GUIComponent {
this.page = page;
}
- /**
- * Create a new page.
- *
- * @param pageNumber The page number.
- * @param page The base menu.
- */
- public Page(final int pageNumber,
- @NotNull final Consumer page) {
- this.pageNumber = pageNumber;
- MenuBuilder builder = Menu.builder(6);
- page.accept(builder);
- this.page = builder.build();
- }
-
/**
* Get the current page number.
*
@@ -93,14 +87,21 @@ public final class Page implements GUIComponent {
return page.getSlot(row, column, player, delegate);
}
+ @Override
+ public void init(final int maxRows,
+ final int maxColumns) {
+ this.rows = maxRows;
+ this.columns = maxColumns;
+ }
+
@Override
public int getRows() {
- return page.getRows();
+ return rows;
}
@Override
public int getColumns() {
- return 9;
+ return columns;
}
/**
diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageBuilder.java b/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageBuilder.java
index f82fb462..7a6c5383 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageBuilder.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/page/PageBuilder.java
@@ -1,19 +1,14 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.gui.component.GUIComponent;
-import com.willfp.eco.core.gui.menu.CloseHandler;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuLayer;
-import com.willfp.eco.core.gui.menu.OpenHandler;
import com.willfp.eco.core.gui.slot.FillerMask;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
-import org.bukkit.event.inventory.InventoryCloseEvent;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
/**
* Builder to create pages.
@@ -26,6 +21,13 @@ public interface PageBuilder {
*/
int getRows();
+ /**
+ * Get the amount of columns.
+ *
+ * @return The amount of columns.
+ */
+ int getColumns();
+
/**
* Set a slot.
*
diff --git a/eco-api/src/main/java/com/willfp/eco/core/gui/slot/FillerMask.java b/eco-api/src/main/java/com/willfp/eco/core/gui/slot/FillerMask.java
index 6c9bb84a..3e2f1aa0 100644
--- a/eco-api/src/main/java/com/willfp/eco/core/gui/slot/FillerMask.java
+++ b/eco-api/src/main/java/com/willfp/eco/core/gui/slot/FillerMask.java
@@ -90,9 +90,6 @@ public class FillerMask implements GUIComponent {
for (String patternRow : pattern) {
int column = 0;
- if (patternRow.length() != 9) {
- throw new IllegalArgumentException("Invalid amount of columns in pattern!");
- }
for (char c : patternRow.toCharArray()) {
if (c == '0') {
mask.get(row).set(column, null);
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 f60d45c8..0294991c 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
@@ -9,6 +9,7 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
diff --git a/eco-api/src/main/java/com/willfp/eco/util/MenuUtils.java b/eco-api/src/main/java/com/willfp/eco/util/MenuUtils.java
index 98165f8d..b57a776f 100644
--- a/eco-api/src/main/java/com/willfp/eco/util/MenuUtils.java
+++ b/eco-api/src/main/java/com/willfp/eco/util/MenuUtils.java
@@ -3,14 +3,10 @@ package com.willfp.eco.util;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.tuples.Pair;
-import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
-import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.function.Function;
-
/**
* Utilities / API methods for menus.
*/
@@ -23,9 +19,7 @@ public final class MenuUtils {
*/
@NotNull
public static Pair convertSlotToRowColumn(final int slot) {
- int row = Math.floorDiv(slot, 9);
- int column = slot - row * 9;
- return new Pair<>(row + 1, column + 1);
+ return convertSlotToRowColumn(slot, 9);
}
/**
@@ -36,7 +30,36 @@ public final class MenuUtils {
* @return The slot.
*/
public static int rowColumnToSlot(final int row, final int column) {
- return (column - 1) + ((row - 1) * 9);
+ return rowColumnToSlot(row, column, 9);
+ }
+
+ /**
+ * Convert 0-53 slot to row and column pair.
+ *
+ * @param slot The slot.
+ * @param columns The columns.
+ * @return The pair of row and columns.
+ */
+ @NotNull
+ public static Pair convertSlotToRowColumn(final int slot,
+ final int columns) {
+ int row = Math.floorDiv(slot, columns);
+ int column = slot - row * columns;
+ return new Pair<>(row + 1, column + 1);
+ }
+
+ /**
+ * Convert row and column to 0-53 slot.
+ *
+ * @param row The row.
+ * @param column The column.
+ * @param columns The columns in the menu.
+ * @return The slot.
+ */
+ public static int rowColumnToSlot(final int row,
+ final int column,
+ final int columns) {
+ return (column - 1) + ((row - 1) * columns);
}
/**
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/EcoGUIFactory.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/EcoGUIFactory.kt
index f6aff538..fdfca628 100644
--- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/EcoGUIFactory.kt
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/EcoGUIFactory.kt
@@ -3,6 +3,7 @@ package com.willfp.eco.internal.gui
import com.willfp.eco.core.gui.GUIFactory
import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.menu.MenuBuilder
+import com.willfp.eco.core.gui.menu.MenuType
import com.willfp.eco.core.gui.slot.functional.SlotProvider
import com.willfp.eco.internal.gui.menu.EcoMenuBuilder
import com.willfp.eco.internal.gui.page.MergedStateMenu
@@ -12,8 +13,8 @@ object EcoGUIFactory : GUIFactory {
override fun createSlotBuilder(provider: SlotProvider) =
EcoSlotBuilder(provider)
- override fun createMenuBuilder(rows: Int): MenuBuilder =
- EcoMenuBuilder(rows)
+ override fun createMenuBuilder(rows: Int, type: MenuType): MenuBuilder =
+ EcoMenuBuilder(rows, type.columns)
override fun blendMenuState(base: Menu, additional: Menu): Menu =
MergedStateMenu(base, additional)
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 675aad1c..257c8274 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
@@ -14,6 +14,7 @@ import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryCloseEvent
+import org.bukkit.event.inventory.InventoryType
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType
@@ -21,7 +22,8 @@ import org.bukkit.persistence.PersistentDataType
@Suppress("UNCHECKED_CAST")
class EcoMenu(
private val rows: Int,
- private val componentsAtPoints: Map>,
+ private val columns: Int,
+ private val componentsAtPoints: Map>,
private val title: String,
private val onClose: List,
private val onRender: List<(Player, Menu) -> Unit>,
@@ -29,12 +31,12 @@ class EcoMenu(
private val signalHandlers: List>
) : Menu {
private fun getPossiblyReactiveSlot(row: Int, column: Int, player: Player?, menu: Menu?): Slot {
- if (row < 1 || row > this.rows || column < 1 || column > 9) {
+ if (row < 1 || row > this.rows || column < 1 || column > this.columns) {
return emptyFillerSlot
}
- val anchor = Anchor(row, column)
- val components = componentsAtPoints[anchor] ?: return emptyFillerSlot
+ val guiPosition = GUIPosition(row, column)
+ val components = componentsAtPoints[guiPosition] ?: return emptyFillerSlot
for (component in components) {
val found = if (player != null && menu != null) component.component.getSlotAt(
@@ -62,7 +64,12 @@ class EcoMenu(
getPossiblyReactiveSlot(row, column, player, menu)
override fun open(player: Player): Inventory {
- val inventory = Bukkit.createInventory(null, rows * 9, title)
+ val inventory = if (columns == 9) {
+ Bukkit.createInventory(null, rows * columns, title)
+ } else {
+ Bukkit.createInventory(null, InventoryType.DISPENSER, title)
+ }
+
player.forceMenuOpen(this)
MenuHandler.registerInventory(inventory, this, player)
@@ -83,17 +90,24 @@ class EcoMenu(
MenuHandler.unregisterInventory(event.inventory)
}
- override fun getRows(): Int {
- return rows
- }
+ override fun getRows() = rows
- override fun getTitle(): String {
- return title
- }
+ override fun getColumns() = columns
+
+ override fun getTitle() = title
override fun getCaptiveItems(player: Player): List {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return emptyList()
- return inventory.captiveItems
+ return inventory.captiveItems.values.toList()
+ }
+
+ override fun getCaptiveItem(player: Player, row: Int, column: Int): ItemStack? {
+ if (row < 1 || row > this.rows || column < 1 || column > this.columns) {
+ return null
+ }
+
+ val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return null
+ return inventory.captiveItems[GUIPosition(row, column)]
}
override fun sendSignal(player: Player, signal: Signal) {
@@ -165,7 +179,7 @@ data class OffsetComponent(
val columnOffset: Int
)
-data class Anchor(
+data class GUIPosition(
val row: Int,
val column: Int
)
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 c8b153ba..e36e7717 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
@@ -12,15 +12,19 @@ import org.bukkit.entity.Player
import java.util.function.BiConsumer
import java.util.function.Consumer
-class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
+class EcoMenuBuilder(
+ private val rows: Int,
+ private val columns: Int
+) : MenuBuilder {
private var title = "Menu"
- private val components = mutableMapOf>>()
+ private val components = mutableMapOf>>()
private val onClose = mutableListOf()
private val onOpen = mutableListOf()
private val onRender = mutableListOf<(Player, Menu) -> Unit>()
private val signalHandlers = mutableListOf>()
override fun getRows() = rows
+ override fun getColumns() = columns
override fun setTitle(title: String): MenuBuilder {
this.title = StringUtils.format(title)
@@ -29,19 +33,19 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
override fun addComponent(layer: MenuLayer, row: Int, column: Int, component: GUIComponent): MenuBuilder {
require(row in 1..rows) { "Invalid row number!" }
- require(column in 1..9) { "Invalid column number!" }
+ require(column in 1..columns) { "Invalid column number!" }
val maxRows = 1 + rows - row
val maxColumns = 10 - column
component.init(maxRows, maxColumns)
- require(column + component.columns - 1 <= 9) { "Component is too large to be placed here!" }
- require(row + component.rows - 1 <= getRows()) { "Component is too large to be placed here!" }
+ require(column + component.columns - 1 <= columns) { "Component is too large to be placed here!" }
+ require(row + component.rows - 1 <= rows) { "Component is too large to be placed here!" }
- val anchor = Anchor(row, column)
+ val guiPosition = GUIPosition(row, column)
components.computeIfAbsent(layer) { mutableMapOf() }
- .computeIfAbsent(anchor) { mutableListOf() } += component
+ .computeIfAbsent(guiPosition) { mutableListOf() } += component
return this
}
@@ -72,12 +76,12 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
}
override fun build(): Menu {
- val layeredComponents = mutableMapOf>>()
+ val layeredComponents = mutableMapOf>>()
// 5 nested for loops? Shut up. Silence. Quiet.
for (layer in MenuLayer.values()) {
for (row in (1..rows)) {
- for (column in (1..9)) {
+ for (column in (1..columns)) {
for ((anchor, availableComponents) in components.computeIfAbsent(layer) { mutableMapOf() }) {
for (component in availableComponents) {
val rowOffset = 1 + row - anchor.row
@@ -91,7 +95,7 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
continue
}
- val point = Anchor(row, column)
+ val point = GUIPosition(row, column)
layeredComponents.computeIfAbsent(layer) { mutableMapOf() }
.computeIfAbsent(point) { mutableListOf() } += OffsetComponent(
@@ -105,7 +109,7 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
}
}
- val componentsAtPoints = mutableMapOf>()
+ val componentsAtPoints = mutableMapOf>()
for (menuLayer in MenuLayer.values()) {
for ((anchor, offsetComponents) in layeredComponents[menuLayer] ?: emptyMap()) {
@@ -113,6 +117,6 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
}
}
- return EcoMenu(rows, componentsAtPoints, title, onClose, onRender, onOpen, signalHandlers)
+ return EcoMenu(rows, columns, componentsAtPoints, title, onClose, onRender, onOpen, signalHandlers)
}
}
diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuRenderedInventory.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuRenderedInventory.kt
index 9a65b00b..ad8d0b4e 100644
--- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuRenderedInventory.kt
+++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/gui/menu/MenuRenderedInventory.kt
@@ -26,13 +26,15 @@ class MenuRenderedInventory(
val inventory: Inventory,
val player: Player
) {
- val captiveItems = mutableListOf()
+ val captiveItems = mutableMapOf()
val state = mutableMapOf()
fun render() {
+ captiveItems.clear()
+
for (row in (1..menu.rows)) {
- for (column in (1..9)) {
- val bukkit = MenuUtils.rowColumnToSlot(row, column)
+ for (column in (1..menu.columns)) {
+ val bukkit = MenuUtils.rowColumnToSlot(row, column, menu.columns)
val slot = menu.getSlot(row, column, player, menu)
val renderedItem = slot.getItemStack(player)
@@ -50,7 +52,7 @@ class MenuRenderedInventory(
continue
}
- captiveItems.add(itemStack)
+ captiveItems[GUIPosition(row, column)] = itemStack
} else {
inventory.setItem(bukkit, renderedItem)
}
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 1784beb6..1801fc07 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
@@ -54,7 +54,7 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
val menu = rendered.menu
- val (row, column) = MenuUtils.convertSlotToRowColumn(event.slot)
+ val (row, column) = MenuUtils.convertSlotToRowColumn(event.slot, menu.columns)
menu.getSlot(row, column, player, menu).handle(player, event, menu)
@@ -77,7 +77,7 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
val menu = inv.getMenu() ?: return
- val (row, column) = MenuUtils.convertSlotToRowColumn(inv.firstEmpty())
+ val (row, column) = MenuUtils.convertSlotToRowColumn(inv.firstEmpty(), menu.columns)
val slot = menu.getSlot(row, column, player, menu)