From cd3c5443bb3227c4bc3393fbfd75d937a55fd089 Mon Sep 17 00:00:00 2001 From: Rubix327 Date: Fri, 7 Oct 2022 23:16:38 +0300 Subject: [PATCH] A big update on menu system. --- .../java/org/mineacademy/fo/PlayerUtil.java | 3 +- .../fo/conversation/SimpleConversation.java | 35 ++-- .../fo/conversation/SimplePrompt.java | 23 +-- .../org/mineacademy/fo/menu/AdvancedMenu.java | 168 ++++++++++-------- .../fo/menu/AdvancedMenuPagged.java | 57 +++--- .../fo/menu/LockedSlotsFigure.java | 68 ------- .../java/org/mineacademy/fo/menu/Menu.java | 22 +-- .../org/mineacademy/fo/menu/MenuPagged.java | 3 + .../org/mineacademy/fo/menu/MenuSlots.java | 96 ++++++++++ .../org/mineacademy/fo/menu/MenuTools.java | 3 + .../org/mineacademy/fo/menu/MenuUtil.java | 2 +- .../mineacademy/fo/menu/button/Button.java | 4 +- .../fo/menu/tool/ToolsListener.java | 4 +- .../mineacademy/fo/plugin/SimplePlugin.java | 4 +- 14 files changed, 259 insertions(+), 233 deletions(-) delete mode 100644 src/main/java/org/mineacademy/fo/menu/LockedSlotsFigure.java create mode 100644 src/main/java/org/mineacademy/fo/menu/MenuSlots.java diff --git a/src/main/java/org/mineacademy/fo/PlayerUtil.java b/src/main/java/org/mineacademy/fo/PlayerUtil.java index e2565059d..83a8bddc6 100644 --- a/src/main/java/org/mineacademy/fo/PlayerUtil.java +++ b/src/main/java/org/mineacademy/fo/PlayerUtil.java @@ -23,6 +23,7 @@ import org.mineacademy.fo.exception.FoException; import org.mineacademy.fo.jsonsimple.JSONObject; import org.mineacademy.fo.jsonsimple.JSONParser; +import org.mineacademy.fo.menu.AdvancedMenu; import org.mineacademy.fo.menu.Menu; import org.mineacademy.fo.model.HookManager; import org.mineacademy.fo.plugin.SimplePlugin; @@ -837,7 +838,7 @@ public static void updateInventoryTitle(final Menu menu, final Player player, fi pending.cancel(); pending = Common.runLater(duration, () -> { - final Menu futureMenu = Menu.getMenu(player); + final AdvancedMenu futureMenu = AdvancedMenu.getMenu(player); if (futureMenu != null && futureMenu.getClass().getName().equals(menu.getClass().getName())) updateInventoryTitle(player, oldTitle); diff --git a/src/main/java/org/mineacademy/fo/conversation/SimpleConversation.java b/src/main/java/org/mineacademy/fo/conversation/SimpleConversation.java index c0088106e..04536ecdf 100644 --- a/src/main/java/org/mineacademy/fo/conversation/SimpleConversation.java +++ b/src/main/java/org/mineacademy/fo/conversation/SimpleConversation.java @@ -1,30 +1,21 @@ package org.mineacademy.fo.conversation; -import java.util.concurrent.TimeUnit; - -import org.bukkit.conversations.Conversable; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.conversations.ConversationAbandonedListener; -import org.bukkit.conversations.ConversationCanceller; -import org.bukkit.conversations.ConversationContext; -import org.bukkit.conversations.ConversationPrefix; -import org.bukkit.conversations.InactivityConversationCanceller; -import org.bukkit.conversations.Prompt; +import lombok.AccessLevel; +import lombok.Getter; +import org.bukkit.conversations.*; import org.bukkit.entity.Player; import org.mineacademy.fo.Common; import org.mineacademy.fo.Messenger; import org.mineacademy.fo.Valid; import org.mineacademy.fo.collection.expiringmap.ExpiringMap; -import org.mineacademy.fo.menu.Menu; +import org.mineacademy.fo.menu.AdvancedMenu; import org.mineacademy.fo.model.BoxedMessage; import org.mineacademy.fo.model.Variables; import org.mineacademy.fo.plugin.SimplePlugin; import org.mineacademy.fo.remain.CompSound; import org.mineacademy.fo.settings.SimpleLocalization; -import lombok.AccessLevel; -import lombok.Getter; +import java.util.concurrent.TimeUnit; /** * A simple way to communicate with the player @@ -36,7 +27,7 @@ public abstract class SimpleConversation implements ConversationAbandonedListene /** * The menu to return to, if any */ - private Menu menuToReturnTo; + private AdvancedMenu menuToReturnTo; /** * Creates a simple conversation @@ -48,10 +39,8 @@ protected SimpleConversation() { /** * Creates a simple conversation that opens the * menu when finished - * - * @param menuToReturnTo */ - protected SimpleConversation(final Menu menuToReturnTo) { + protected SimpleConversation(final AdvancedMenu menuToReturnTo) { this.menuToReturnTo = menuToReturnTo; } @@ -116,14 +105,14 @@ public final void conversationAbandoned(final ConversationAbandonedEvent event) (event.gracefulExit() ? CompSound.SUCCESSFUL_HIT : CompSound.NOTE_BASS).play(player, 1F, 1F); if (this.menuToReturnTo != null && this.reopenMenu()) { - final Menu newMenu = this.menuToReturnTo.newInstance(); + final AdvancedMenu menu = AdvancedMenu.newInstanceOf(menuToReturnTo.getClass(), player); - newMenu.displayTo(player); + menu.display(); final String title = this.getMenuAnimatedTitle(); if (title != null) - Common.runLater(2, () -> newMenu.animateTitle(title)); + Common.runLater(2, () -> menu.animateTitle(title)); } } } @@ -220,10 +209,8 @@ protected boolean isModal() { /** * Sets the menu to return to after the end of this conversation - * - * @param menu */ - public final void setMenuToReturnTo(final Menu menu) { + public final void setMenuToReturnTo(final AdvancedMenu menu) { this.menuToReturnTo = menu; } diff --git a/src/main/java/org/mineacademy/fo/conversation/SimplePrompt.java b/src/main/java/org/mineacademy/fo/conversation/SimplePrompt.java index e6a1247be..789e15d32 100644 --- a/src/main/java/org/mineacademy/fo/conversation/SimplePrompt.java +++ b/src/main/java/org/mineacademy/fo/conversation/SimplePrompt.java @@ -1,17 +1,12 @@ package org.mineacademy.fo.conversation; -import org.bukkit.conversations.Conversable; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.conversations.ConversationContext; -import org.bukkit.conversations.ConversationPrefix; -import org.bukkit.conversations.Prompt; -import org.bukkit.conversations.ValidatingPrompt; +import org.bukkit.conversations.*; import org.bukkit.entity.Player; import org.mineacademy.fo.Common; import org.mineacademy.fo.Messenger; import org.mineacademy.fo.Valid; import org.mineacademy.fo.exception.FoException; -import org.mineacademy.fo.menu.Menu; +import org.mineacademy.fo.menu.AdvancedMenu; import org.mineacademy.fo.model.Variables; import org.mineacademy.fo.settings.SimpleLocalization; @@ -48,25 +43,20 @@ protected SimplePrompt(final boolean openMenu) { /** * Return the prefix before tell messages - * - * @param ctx - * @return */ protected String getCustomPrefix() { return null; } /** - * @see {@link SimpleConversation#isModal()} - * - * @return + * @see SimpleConversation#isModal() */ protected boolean isModal() { return true; } /** - * @see SimpleConversation#setMenuAnimatedTitle(String) + * @see SimpleConversation#getMenuAnimatedTitle() * * @return */ @@ -137,9 +127,6 @@ protected final Player getPlayer(final ConversationContext ctx) { /** * Send the player (in case any) the given message - * - * @param ctx - * @param message */ protected final void tell(final String message) { Valid.checkNotNull(this.player, "Cannot use tell() when player not yet set!"); @@ -265,7 +252,7 @@ protected void onConversationEnd(ConversationAbandonedEvent event, boolean cance }; if (this.openMenu) { - final Menu menu = Menu.getMenu(player); + final AdvancedMenu menu = AdvancedMenu.getMenu(player); if (menu != null) conversation.setMenuToReturnTo(menu); diff --git a/src/main/java/org/mineacademy/fo/menu/AdvancedMenu.java b/src/main/java/org/mineacademy/fo/menu/AdvancedMenu.java index 3a76c4028..df3153d14 100644 --- a/src/main/java/org/mineacademy/fo/menu/AdvancedMenu.java +++ b/src/main/java/org/mineacademy/fo/menu/AdvancedMenu.java @@ -5,15 +5,14 @@ import org.bukkit.event.inventory.InventoryAction; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import org.mineacademy.fo.Common; -import org.mineacademy.fo.ItemUtil; -import org.mineacademy.fo.Messenger; -import org.mineacademy.fo.SoundUtil; +import org.mineacademy.fo.*; +import org.mineacademy.fo.constants.FoConstants; import org.mineacademy.fo.menu.button.Button; import org.mineacademy.fo.menu.model.ItemCreator; import org.mineacademy.fo.menu.tool.Tool; import org.mineacademy.fo.remain.CompMaterial; +import javax.annotation.Nullable; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; @@ -49,13 +48,9 @@ public abstract class AdvancedMenu extends Menu { * are filled with {@link #getWrapperItem()}. */ private List lockedSlots = new ArrayList<>(); - /** - * The menu which is opened from {@link #getReturnBackButton}. - */ - private Class parentMenu = getClass(); /** * Convenient item that you can use to close some menu slots.
- * By default, displays on empty locked slots in MenuPaginated.
+ * By default, displays on empty locked slots in AdvancedMenuPagged.
* Default item is gray stained-glass. * Set this item to whether you want by {@link #setWrapper}. * To disable item set it to null. @@ -132,20 +127,20 @@ protected final void setLockedSlots(Integer... slots){ /** * See {@link #setLockedSlots(Integer...)} for the detailed description.

- * Figures available: {@link LockedSlotsFigure}. + * Figures available: {@link MenuSlots.SizedShape}. */ - protected final void setLockedSlots(LockedSlotsFigure figure){ + protected final void setLockedSlots(MenuSlots.SizedShape figure){ setLockedSlots(figure.getSlots()); } /** * Set the automated slots locking depending on the figure and the size.
- * Figures available: {@link LockedSlotsFigure.Raw}. - * @param rawFigure the figure + * Figures available: {@link MenuSlots.Shape}. + * @param shape the shape you want to use * @param size the size of the menu */ - protected final void setLockedSlots(LockedSlotsFigure.Raw rawFigure, int size){ - setLockedSlots(LockedSlotsFigure.AUTO(rawFigure, size)); + protected final void setLockedSlots(MenuSlots.Shape shape, int size){ + setLockedSlots(MenuSlots.AUTO(shape, size)); } /** @@ -159,20 +154,6 @@ protected final void setUnlockedSlots(Integer... slots){ setLockedSlots(IntStream.rangeClosed(0, getSize() - 1).filter(i -> !slotsList.contains(i)).boxed().toArray(Integer[]::new)); } - /** - * Get the {@link #parentMenu}. - */ - protected final Class getParentMenu(){ - return this.parentMenu; - } - - /** - * Set the {@link #parentMenu}. - */ - protected final void setParent(Class parent){ - this.parentMenu = parent; - } - /** * Get the {@link #wrapperItem} */ @@ -180,10 +161,16 @@ protected final ItemStack getWrapperItem(){ return wrapperItem; } + /** + * Set the material of {@link #wrapperItem} + */ protected final void setWrapper(CompMaterial material){ wrapperItem = ItemCreator.of(material, "").make(); } + /** + * Set the item of {@link #wrapperItem} + */ protected final void setWrapper(ItemStack item){ wrapperItem = item; } @@ -196,27 +183,18 @@ public void display(){ displayTo(getPlayer()); } - /** - * Does the same as {@link #getReturnBackButton(ItemStack)}. - * Uses the default button from {@link MenuUtil#defaultReturnBackItem}. - */ - protected final Button getReturnBackButton(){ - return getReturnBackButton(MenuUtil.defaultReturnBackItem); + protected final Button getBackButton(){ + return getBackButton(MenuUtil.defaultBackItem); } - /** - * Get the button that returns player to the parent menu given in the constructor. - * If the parent is not given it will return player to the same menu. - * If item is not given, it will get its item from {@link MenuUtil#defaultReturnBackItem}.

- * NOTE that this button returns player to the non-personalized menu. - * To use personalized menus, use {@link #getMenuButton}.

- * @return the return button - */ - protected final Button getReturnBackButton(@NotNull ItemStack item){ + protected final Button getBackButton(ItemStack item){ return new Button() { @Override public void onClickedInMenu(Player player, AdvancedMenu menu, ClickType click) { - newInstanceOf(player, parentMenu).display(); + AdvancedMenu previous = getPreviousMenu(player); + if (previous != null){ + getPreviousMenu(player).display(); + } } @Override @@ -307,7 +285,7 @@ protected final Button getMenuButton(Class to, ItemStack return new Button() { @Override public void onClickedInMenu(Player player, AdvancedMenu menu, ClickType click) { - newInstanceOf(player, to).display(); + newInstanceOf(to, player).display(); } @Override @@ -317,22 +295,6 @@ public ItemStack getItem() { }; } - /** - * Create a new instance of the menu from the given class. - */ - private AdvancedMenu newInstanceOf(Player player, Class menu){ - try{ - AdvancedMenu am = menu.getDeclaredConstructor(Player.class).newInstance(player); - am.setParent(menu); - return am; - } - catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e){ - e.printStackTrace(); - } - throw new NullPointerException("Could not create a new instance of " + menu.getName() + " class. " + - "Please create a constructor with only Player argument."); - } - /** * Make the button from the tool. It gives player one piece of this tool.
* This button gets its additional lore depending on if player has the tool @@ -418,7 +380,7 @@ protected final Button getInfoButton(){ */ protected final Button getInfoButton(ItemStack item){ return Button.makeDummy(ItemCreator.of(item).name(getInfoName()) - .lore(Arrays.asList(getInfoLore())).hideTags(true)); + .lore(getInfoLore()).hideTags(true)); } /** @@ -435,12 +397,10 @@ protected String getInfoName(){ * Override it to set your own lore (info). * @see #getInfoButton(ItemStack) */ - protected String[] getInfoLore() { - return new String[]{ - "", + protected List getInfoLore() { + return Arrays.asList("", "&7Override &fgetInfoName() &7and &fgetInfoLore()", - "&7in " + getClass().getSimpleName() + " &7to set your own menu description." - }; + "&7in " + getClass().getSimpleName() + " &7to set your own menu description."); } @Override @@ -454,7 +414,7 @@ protected void onMenuClick(Player player, int slot, InventoryAction action, Clic * Override this method and customize your menu here. * This method is automatically started just before displaying a menu to a player. */ - protected void setup(){} + protected abstract void setup(); protected final boolean isButton(int slot){ return getButtons().containsKey(slot); @@ -483,8 +443,74 @@ public ItemStack getItemAt(int slot) { } @Override - public AdvancedMenu newInstance() { - return this; + public final AdvancedMenu newInstance() { + return newInstanceOf(this.getClass(), this.player); + } + + /** + * Create a new instance of the menu from the given class. + */ + public static AdvancedMenu newInstanceOf(Class menu, Player player){ + try{ + AdvancedMenu am = menu.getDeclaredConstructor(Player.class).newInstance(player); + return am; + } + catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e){ + e.printStackTrace(); + } + throw new NullPointerException("Could not create a new instance of " + menu.getName() + " class. " + + "Please create a constructor with only Player argument."); + } + + /** + * Returns the current menu for player + * + * @param player the player + * @return the menu, or null if none + */ + public static AdvancedMenu getMenu(final Player player) { + return getMenu0(player, FoConstants.NBT.TAG_MENU_CURRENT); + } + + /** + * Returns the previous menu for player + * + * @param player the player + * @return the menu, or none + */ + public static AdvancedMenu getPreviousMenu(final Player player) { + return getMenu0(player, FoConstants.NBT.TAG_MENU_PREVIOUS); + } + + /** + * Returns the last closed menu, null if it exists. + */ + @Nullable + public static AdvancedMenu getLastClosedMenu(final Player player) { + if (player.hasMetadata(FoConstants.NBT.TAG_MENU_LAST_CLOSED)) { + return (AdvancedMenu) player.getMetadata(FoConstants.NBT.TAG_MENU_LAST_CLOSED).get(0).value(); + } + + return null; + } + + /** + * Returns the menu associated with the player's metadata, or null + */ + private static AdvancedMenu getMenu0(final Player player, final String tag) { + if (player.hasMetadata(tag)) { + final AdvancedMenu menu = (AdvancedMenu) player.getMetadata(tag).get(0).value(); + Valid.checkNotNull(menu, "Menu missing from " + player.getName() + "'s metadata '" + tag + "' tag!"); + + return menu; + } + + return null; + } + + @Override + protected final void finalize() throws Throwable { + super.finalize(); } /** diff --git a/src/main/java/org/mineacademy/fo/menu/AdvancedMenuPagged.java b/src/main/java/org/mineacademy/fo/menu/AdvancedMenuPagged.java index d3984a424..e617bd975 100644 --- a/src/main/java/org/mineacademy/fo/menu/AdvancedMenuPagged.java +++ b/src/main/java/org/mineacademy/fo/menu/AdvancedMenuPagged.java @@ -42,9 +42,9 @@ public abstract class AdvancedMenuPagged extends AdvancedMenu { */ private List elementsItems; /** - * Position of cursor in {@link #elementsItems} map that is being displayed now. + * Position at which the item setter is now. */ - private int cursorAt = 0; + private int currentSlot = 0; /** * Current page opened in the player's menu. */ @@ -80,7 +80,6 @@ protected final TreeMap getElementsSlots(){ * It automatically runs when the menu opens. */ private void updateElements(){ - resetCursorAt(); setElements(); setElementsItems(); setElementsSlots(); @@ -157,7 +156,6 @@ public void onClickedInMenu(Player player, AdvancedMenu menu, ClickType click) { return; } currentPage -= 1; - resetCursorAt(); redraw(); SoundUtil.Play.CLICK_LOW(player); } @@ -181,7 +179,6 @@ public void onClickedInMenu(Player player, AdvancedMenu menu, ClickType click) { return; } currentPage += 1; - resetCursorAt(); redraw(); SoundUtil.Play.CLICK_HIGH(player); } @@ -216,35 +213,31 @@ public final int getMaxPage(){ private void setElementsSlots(){ elementsSlots.clear(); for (T element : elements){ - loopSlots(element); + putElementOnFreeSlot(element); } } /** - * Internal implementation of {@link #setElementsSlots()}. + * Put the element on the first found free slot. + * @param element */ - private void loopSlots(T element){ - for (int page = 1; page <= getMaxPage(); page++){ - for (int slot = 0; slot < getSize(); slot++){ - int finalSlot = (page - 1) * getSize() + slot; - - if (getItems().containsKey(slot)) continue; - if (getLockedSlots().contains(slot)) continue; - if (getPreviousButtonSlot() == slot) continue; - if (getNextButtonSlot() == slot) continue; - if (getElementsSlots().containsKey(finalSlot)) continue; - - elementsSlots.put(finalSlot, element); - return; - } + private void putElementOnFreeSlot(T element){ + int slot = currentSlot % 54; + for (int i = 0; i < 1; i++){ + if (getButtons().containsKey(slot)) continue; + if (getItems().containsKey(slot)) continue; + if (getLockedSlots().contains(slot)) continue; + if (getPreviousButtonSlot() == slot) continue; + if (getNextButtonSlot() == slot) continue; + if (getElementsSlots().containsKey(this.currentSlot)) continue; + + elementsSlots.put(currentSlot, element); + currentSlot++; + return; } - } - /** - * Resets the {@link #cursorAt} to the first slot of this page. - */ - private void resetCursorAt() { - this.cursorAt = (currentPage - 1) * getAvailableSlotsSize(); + currentSlot++; + putElementOnFreeSlot(element); } /** @@ -280,12 +273,12 @@ public ItemStack getItemAt(int slot){ if (super.getItemAt(slot) != null){ return super.getItemAt(slot); } - else{ - if (cursorAt >= elementsItems.size()) return null; - ItemStack item = elementsItems.get(cursorAt); - cursorAt += 1; - return item; + + slot = slot + (currentPage - 1) * getSize(); + if (elementsSlots.containsKey(slot)){ + return convertToItemStack(elementsSlots.get(slot)); } + return null; } @Override diff --git a/src/main/java/org/mineacademy/fo/menu/LockedSlotsFigure.java b/src/main/java/org/mineacademy/fo/menu/LockedSlotsFigure.java deleted file mode 100644 index 9a47482f7..000000000 --- a/src/main/java/org/mineacademy/fo/menu/LockedSlotsFigure.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.mineacademy.fo.menu; - -import lombok.Getter; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -/** - * Represents locked slots of menus. - */ -public enum LockedSlotsFigure { - - BOUNDS_9X3(true, 10, 11, 12, 13, 14, 15, 16), - BOUNDS_9X4(true, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25), - BOUNDS_9X5(true, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34), - - BOUNDS_9X6(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53), - CIRCLE_9X6(true, 12, 13, 14, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 39, 40, 41), - ROWS_9X6(0, 1, 2, 3, 4, 5, 6, 7, 8, 45, 46, 47, 48, 49, 50, 51, 52, 53), - COLUMNS_9X6(0, 8, 9, 18, 27, 36, 45, 17, 26, 35, 44, 53), - SIX_SLOTS_9X6(true, 21, 22, 23, 30, 31, 32), - TWO_SLOTS_9X6(true, 22, 31), - ONE_SLOT_9X3(true, 13), - ONE_SLOT_9X1(true, 4), - NONE(-1); - - public enum Raw{ - BOUNDS(NONE, NONE, BOUNDS_9X3, BOUNDS_9X4, BOUNDS_9X5, BOUNDS_9X6), - CIRCLE(NONE, NONE, NONE, NONE, NONE, CIRCLE_9X6), - COLUMNS(NONE, NONE, NONE, NONE, NONE, COLUMNS_9X6), - SIX_SLOTS(NONE, NONE, NONE, NONE, NONE, SIX_SLOTS_9X6), - TWO_SLOTS(NONE, NONE, NONE, NONE, NONE, TWO_SLOTS_9X6), - ONE_SLOT(ONE_SLOT_9X1, NONE, ONE_SLOT_9X3, NONE, NONE, NONE); - - private final LockedSlotsFigure[] mod; - - Raw(LockedSlotsFigure... modification){ - this.mod = modification; - } - - } - - @Getter - private final Integer[] slots; - - LockedSlotsFigure(Integer... slots){ - this(false, slots); - } - - LockedSlotsFigure(boolean reversed, Integer... slots){ - if (!reversed) { - this.slots = slots; - return; - } - List lockedSlots = IntStream.rangeClosed(0, 53).boxed().collect(Collectors.toList()); - for (Integer slot : slots){ - lockedSlots.remove(Integer.valueOf(slot)); - } - this.slots = lockedSlots.toArray(new Integer[0]); - } - - public static LockedSlotsFigure AUTO(LockedSlotsFigure.Raw rawFigure, int size){ - if (size == 0 || size % 9 != 0) throw new IllegalArgumentException("Menu size must be a multiple of 9."); - return rawFigure.mod[size / 9 - 1]; - } - -} diff --git a/src/main/java/org/mineacademy/fo/menu/Menu.java b/src/main/java/org/mineacademy/fo/menu/Menu.java index b4124bcf8..c8db609c9 100644 --- a/src/main/java/org/mineacademy/fo/menu/Menu.java +++ b/src/main/java/org/mineacademy/fo/menu/Menu.java @@ -212,7 +212,7 @@ protected Menu(final Menu parent, final boolean returnMakesNewInstance) { * @param player the player * @return the menu, or null if none */ - public static Menu getMenu(final Player player) { + protected static Menu getMenu(final Player player) { return getMenu0(player, FoConstants.NBT.TAG_MENU_CURRENT); } @@ -222,16 +222,12 @@ public static Menu getMenu(final Player player) { * @param player the player * @return the menu, or none */ - @Deprecated public static Menu getPreviousMenu(final Player player) { return getMenu0(player, FoConstants.NBT.TAG_MENU_PREVIOUS); } /** * Returns the last closed menu, null if does not exist. - * - * @param player - * @return */ @Nullable public static Menu getLastClosedMenu(final Player player) { @@ -313,6 +309,8 @@ private void registerButtonsIfHasnt() { * * @param fromItem the itemstack to compare to * @return the button or null if not found + * + * @deprecated Do not use, internal only */ @Deprecated protected final Button getButton(final ItemStack fromItem) { @@ -366,14 +364,12 @@ public Menu newInstance() { // -------------------------------------------------------------------------------- /** - * Display this menu to the player + * Display this menu to the player.
+ * Internal use only. Use {@link AdvancedMenu#display()} to display the menu. * * @param player the player - * - * @deprecated use {@link AdvancedMenu#display()} to display the menu. */ - @Deprecated - public final void displayTo(final Player player) { + protected final void displayTo(final Player player) { Valid.checkNotNull(this.size, "Size not set in " + this + " (call setSize in your constructor)"); Valid.checkNotNull(this.title, "Title not set in " + this + " (call setTitle in your constructor)"); @@ -709,10 +705,10 @@ protected final void setTitle(final String title) { /** * Return the parent menu or null * - * @deprecated use {@link AdvancedMenu#getParentMenu()} instead. + * @deprecated */ @Deprecated - public final Menu getParent() { + private final Menu getParent() { return this.parent; } @@ -857,7 +853,7 @@ protected void onMenuClick(final Player player, final int slot, final ItemStack * Called automatically when a registered button is clicked * *

- * By default this method parses the click into + * By default, this method parses the click into * {@link Button#onClickedInMenu(Player, AdvancedMenu, ClickType)} * * @param player the player diff --git a/src/main/java/org/mineacademy/fo/menu/MenuPagged.java b/src/main/java/org/mineacademy/fo/menu/MenuPagged.java index 2ac8689e5..1c345812c 100644 --- a/src/main/java/org/mineacademy/fo/menu/MenuPagged.java +++ b/src/main/java/org/mineacademy/fo/menu/MenuPagged.java @@ -25,7 +25,10 @@ * An advanced menu listing items with automatic page support * * @param the item that each page consists of + * + * @deprecated Use {@link AdvancedMenuPagged} */ +@Deprecated public abstract class MenuPagged extends Menu { /** diff --git a/src/main/java/org/mineacademy/fo/menu/MenuSlots.java b/src/main/java/org/mineacademy/fo/menu/MenuSlots.java new file mode 100644 index 000000000..17ed38814 --- /dev/null +++ b/src/main/java/org/mineacademy/fo/menu/MenuSlots.java @@ -0,0 +1,96 @@ +package org.mineacademy.fo.menu; + +import lombok.Getter; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * Represents slots in menus. + */ +public enum MenuSlots { +; + public enum SizedShape { + BOUNDS_3(true, 10, 11, 12, 13, 14, 15, 16), + BOUNDS_4(true, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25), + BOUNDS_5(true, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34), + BOUNDS_6(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53), + + CIRCLE_5(true, 11, 12, 13, 14, 15, 19, 20, 21, 22, 23, 24, 25, 29, 30, 31, 32, 33), + CIRCLE_6(true, 12, 13, 14, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 39, 40, 41), + + ROWS_3(0, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 26), + ROWS_4(0, 1, 2, 3, 4, 5, 6, 7, 8, 27, 28, 29, 30, 31, 32, 33, 34, 35), + ROWS_5(0, 1, 2, 3, 4, 5, 6, 7, 8, 36, 37, 38, 39, 40, 41, 42, 43, 44), + ROWS_6(0, 1, 2, 3, 4, 5, 6, 7, 8, 45, 46, 47, 48, 49, 50, 51, 52, 53), + + COLUMNS_1(0, 8), + COLUMNS_2(0, 8, 9, 17), + COLUMNS_3(0, 8, 9, 17, 18, 26), + COLUMNS_4(0, 8, 9, 17, 18, 26, 27, 35), + COLUMNS_5(0, 8, 9, 17, 18, 26, 27, 35, 36, 44), + COLUMNS_6(0, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 53), + + SIX_SLOTS_2(true, 3, 4, 5, 12, 13, 14), + SIX_SLOTS_4(true, 12, 13, 14, 21, 22, 23), + SIX_SLOTS_6(true, 21, 22, 23, 30, 31, 32), + + TWO_SLOTS_1(true, 3, 5), + TWO_SLOTS_2(true, 4, 13), + TWO_SLOTS_3(true, 12, 14), + TWO_SLOTS_4(true, 13, 22), + TWO_SLOTS_5(true, 21, 23), + TWO_SLOTS_6(true, 22, 31), + + ONE_SLOT_1(true, 4), + ONE_SLOT_2(true, 4), + ONE_SLOT_3(true, 13), + ONE_SLOT_4(true, 13), + ONE_SLOT_5(true, 22), + ONE_SLOT_6(true, 22), + + NONE(-1); + + @Getter + private final Integer[] slots; + + SizedShape(Integer... slots) { + this(false, slots); + } + + SizedShape(boolean reversed, Integer... slots) { + if (!reversed) { + this.slots = slots; + return; + } + List lockedSlots = IntStream.rangeClosed(0, 53).boxed().collect(Collectors.toList()); + for (Integer slot : slots) { + lockedSlots.remove(Integer.valueOf(slot)); + } + this.slots = lockedSlots.toArray(new Integer[0]); + } + } + + public enum Shape { + BOUNDS(SizedShape.NONE, SizedShape.NONE, SizedShape.BOUNDS_3, SizedShape.BOUNDS_4, SizedShape.BOUNDS_5, SizedShape.BOUNDS_6), + CIRCLE(SizedShape.NONE, SizedShape.NONE, SizedShape.NONE, SizedShape.NONE, SizedShape.CIRCLE_5, SizedShape.CIRCLE_6), + COLUMNS(SizedShape.COLUMNS_1, SizedShape.COLUMNS_2, SizedShape.COLUMNS_3, SizedShape.COLUMNS_4, SizedShape.COLUMNS_5, SizedShape.COLUMNS_6), + ROWS(SizedShape.NONE, SizedShape.NONE, SizedShape.ROWS_3, SizedShape.ROWS_4, SizedShape.ROWS_5, SizedShape.ROWS_6), + SIX_SLOTS(SizedShape.NONE, SizedShape.SIX_SLOTS_2, SizedShape.NONE, SizedShape.SIX_SLOTS_4, SizedShape.NONE, SizedShape.SIX_SLOTS_6), + TWO_SLOTS(SizedShape.TWO_SLOTS_1, SizedShape.TWO_SLOTS_2, SizedShape.TWO_SLOTS_3, SizedShape.TWO_SLOTS_4, SizedShape.TWO_SLOTS_5, SizedShape.TWO_SLOTS_6), + ONE_SLOT(SizedShape.ONE_SLOT_1, SizedShape.ONE_SLOT_2, SizedShape.ONE_SLOT_3, SizedShape.ONE_SLOT_4, SizedShape.ONE_SLOT_5, SizedShape.ONE_SLOT_6); + + private final SizedShape[] mod; + + Shape(SizedShape... modification){ + this.mod = modification; + } + } + + public static SizedShape AUTO(Shape shape, int size){ + if (size == 0 || size % 9 != 0) throw new IllegalArgumentException("Menu size must be a multiple of 9."); + return shape.mod[size / 9 - 1]; + } + +} diff --git a/src/main/java/org/mineacademy/fo/menu/MenuTools.java b/src/main/java/org/mineacademy/fo/menu/MenuTools.java index ba3c73527..4f8f5a8c5 100644 --- a/src/main/java/org/mineacademy/fo/menu/MenuTools.java +++ b/src/main/java/org/mineacademy/fo/menu/MenuTools.java @@ -19,7 +19,10 @@ /** * A standardized menu to display a list of tools player can toggle to get in * his inventory + * + * @deprecated Use {@link AdvancedMenuTools} */ +@Deprecated public abstract class MenuTools extends Menu { /** diff --git a/src/main/java/org/mineacademy/fo/menu/MenuUtil.java b/src/main/java/org/mineacademy/fo/menu/MenuUtil.java index 66af0caf0..77136bf24 100644 --- a/src/main/java/org/mineacademy/fo/menu/MenuUtil.java +++ b/src/main/java/org/mineacademy/fo/menu/MenuUtil.java @@ -11,7 +11,7 @@ public class MenuUtil { public static ItemStack defaultPreviousPageButtonItem = ItemCreator.of(CompMaterial.SPECTRAL_ARROW, "&7Previous page").make(); public static ItemStack defaultNextPageButtonItem = ItemCreator.of(CompMaterial.TIPPED_ARROW, "&7Next page").make(); - public static ItemStack defaultReturnBackItem = ItemCreator.of(CompMaterial.OAK_DOOR, "&7Go back").make(); + public static ItemStack defaultBackItem = ItemCreator.of(CompMaterial.OAK_TRAPDOOR, "&7Go back").make(); public static ItemStack defaultRefreshItem = ItemCreator.of(CompMaterial.REDSTONE, "&7Refresh menu").make(); public static ItemStack defaultInfoItem = ItemCreator.of(CompMaterial.BOOK).make(); public static ItemStack defaultMenuItem = ItemCreator.of(CompMaterial.APPLE).make(); diff --git a/src/main/java/org/mineacademy/fo/menu/button/Button.java b/src/main/java/org/mineacademy/fo/menu/button/Button.java index 1f025ae18..e096967cc 100644 --- a/src/main/java/org/mineacademy/fo/menu/button/Button.java +++ b/src/main/java/org/mineacademy/fo/menu/button/Button.java @@ -234,9 +234,9 @@ public void onClickedInMenu(Player player, AdvancedMenu menu, ClickType click) { setter.accept(!has); - final Menu newMenu = menu.newInstance(); + final AdvancedMenu newMenu = menu.newInstance(); - newMenu.displayTo(player); + newMenu.display(); newMenu.restartMenu((has ? "&4Disabled" : "&2Enabled") + " " + menuTitle + "!"); } diff --git a/src/main/java/org/mineacademy/fo/menu/tool/ToolsListener.java b/src/main/java/org/mineacademy/fo/menu/tool/ToolsListener.java index ce0fc8283..bcddb4b44 100644 --- a/src/main/java/org/mineacademy/fo/menu/tool/ToolsListener.java +++ b/src/main/java/org/mineacademy/fo/menu/tool/ToolsListener.java @@ -113,7 +113,9 @@ public void onToolPlaceBlock(final BlockPlaceEvent event) { } catch (final Throwable t) { if (initialAmount < finalAmount){ - player.getInventory().addItem(tool.getItem()); + for (int i = initialAmount; i < finalAmount; i++){ + player.getInventory().addItem(tool.getItem()); + } } event.setCancelled(true); diff --git a/src/main/java/org/mineacademy/fo/plugin/SimplePlugin.java b/src/main/java/org/mineacademy/fo/plugin/SimplePlugin.java index 5b8ac8584..7797bb789 100644 --- a/src/main/java/org/mineacademy/fo/plugin/SimplePlugin.java +++ b/src/main/java/org/mineacademy/fo/plugin/SimplePlugin.java @@ -34,7 +34,7 @@ import org.mineacademy.fo.debug.Debugger; import org.mineacademy.fo.event.SimpleListener; import org.mineacademy.fo.exception.FoException; -import org.mineacademy.fo.menu.Menu; +import org.mineacademy.fo.menu.AdvancedMenu; import org.mineacademy.fo.menu.MenuListener; import org.mineacademy.fo.menu.tool.ToolsListener; import org.mineacademy.fo.metrics.Metrics; @@ -693,7 +693,7 @@ public final void onDisable() { try { for (final Player online : Remain.getOnlinePlayers()) { - final Menu menu = Menu.getMenu(online); + final AdvancedMenu menu = AdvancedMenu.getMenu(online); if (menu != null) online.closeInventory();