mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2025-12-26 10:29:16 +00:00
2.0-backup-3
This commit is contained in:
@@ -1,189 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Represents an element in a gui that will query all it's data when drawn.
|
||||
*/
|
||||
public class DynamicGuiElement extends GuiElement {
|
||||
private Function<HumanEntity, GuiElement> query;
|
||||
|
||||
private Map<UUID, CacheEntry> cachedElements = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Represents an element in a gui that will query all it's data when drawn.
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param query Query the element data, this should return an element with the information
|
||||
*/
|
||||
public DynamicGuiElement(char slotChar, Supplier<GuiElement> query) {
|
||||
this(slotChar, (h) -> query.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element in a gui that will query all it's data when drawn.
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param query Query the element data, this should return an element with the information and handle null players properly
|
||||
*/
|
||||
public DynamicGuiElement(char slotChar, Function<HumanEntity, GuiElement> query) {
|
||||
super(slotChar);
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query this element's state for every player who had it cached
|
||||
*/
|
||||
public void update() {
|
||||
for (UUID playerId : new ArrayList<>(cachedElements.keySet())) {
|
||||
Player p = gui.getPlugin().getServer().getPlayer(playerId);
|
||||
if (p != null && p.isOnline()) {
|
||||
update(p);
|
||||
} else {
|
||||
cachedElements.remove(playerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query this element's state for a certain player
|
||||
* @param player The player for whom to update the element
|
||||
*/
|
||||
public CacheEntry update(HumanEntity player) {
|
||||
CacheEntry cacheEntry = new CacheEntry(queryElement(player));
|
||||
if (cacheEntry.element instanceof DynamicGuiElement) {
|
||||
((DynamicGuiElement) cacheEntry.element).update(player);
|
||||
} else if (cacheEntry.element instanceof GuiElementGroup) {
|
||||
InventoryGui.updateElements(player, ((GuiElementGroup) cacheEntry.element).getElements());
|
||||
}
|
||||
cachedElements.put(player.getUniqueId(), cacheEntry);
|
||||
return cacheEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGui(InventoryGui gui) {
|
||||
super.setGui(gui);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
GuiElement element = getCachedElement(who);
|
||||
return element != null ? element.getItem(who, slot) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action getAction(HumanEntity who) {
|
||||
GuiElement element = getCachedElement(who);
|
||||
return element != null ? element.getAction(who) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the supplier for this element's content
|
||||
* @return The supplier query
|
||||
*/
|
||||
public Function<HumanEntity, GuiElement> getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the supplier for this element's content
|
||||
* @param query The supplier query to set
|
||||
*/
|
||||
public void setQuery(Function<HumanEntity, GuiElement> query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the element for a player
|
||||
* @param who The player
|
||||
* @return The GuiElement or null
|
||||
*/
|
||||
public GuiElement queryElement(HumanEntity who) {
|
||||
GuiElement element = getQuery().apply(who);
|
||||
if (element != null) {
|
||||
element.setGui(gui);
|
||||
element.setSlots(slots);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cached element, creates a new one if there is none for that player.
|
||||
* Use {@link #getLastCached(HumanEntity)} to check if a player has something cached.
|
||||
* @param who The player to get the element for
|
||||
* @return The element that is currently cached
|
||||
*/
|
||||
public GuiElement getCachedElement(HumanEntity who) {
|
||||
CacheEntry cached = cachedElements.get(who.getUniqueId());
|
||||
if (cached == null) {
|
||||
cached = update(who);
|
||||
}
|
||||
return cached.getElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the cached element if the player has one.
|
||||
* @param who The player to remove the cached element for
|
||||
* @return The element that was cached or null if none was cached
|
||||
*/
|
||||
public GuiElement removeCachedElement(HumanEntity who) {
|
||||
CacheEntry cached = cachedElements.remove(who.getUniqueId());
|
||||
return cached != null ? cached.getElement() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time at which this element was last cached for a certain player
|
||||
* @param who The player to get the last cache time for
|
||||
* @return The timestamp from when it was last cached or -1 if it wasn't cached
|
||||
*/
|
||||
public long getLastCached(HumanEntity who) {
|
||||
CacheEntry cached = cachedElements.get(who.getUniqueId());
|
||||
return cached != null ? cached.getCreated() : -1;
|
||||
}
|
||||
|
||||
public class CacheEntry {
|
||||
private final GuiElement element;
|
||||
private final long created = System.currentTimeMillis();
|
||||
|
||||
CacheEntry(GuiElement element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public GuiElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public long getCreated() {
|
||||
return created;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* An element that will not appear if there is no previous history,
|
||||
* but will go back one step if there is
|
||||
*/
|
||||
public class GuiBackElement extends StaticGuiElement {
|
||||
|
||||
private boolean close;
|
||||
|
||||
/**
|
||||
* An element used to go back in history of the gui if there is something to go back to.
|
||||
* Will not display when there is nothing to go back to.
|
||||
*
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param item The {@link ItemStack} representing this element
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public GuiBackElement(char slotChar, ItemStack item, String... text) {
|
||||
this(slotChar, item, false, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* An element used to go back in history of the gui
|
||||
*
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param item The {@link ItemStack} representing this element
|
||||
* @param close Whether to close the GUI if there is nothing to go back to.
|
||||
* Will not display item if set to false and nothing to go back to.
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public GuiBackElement(char slotChar, ItemStack item, boolean close, String... text) {
|
||||
super(slotChar, item, text);
|
||||
this.close = close;
|
||||
|
||||
setAction(click -> {
|
||||
if (canGoBack(click.getWhoClicked())) {
|
||||
InventoryGui.goBack(click.getWhoClicked());
|
||||
} else if (close) {
|
||||
click.getGui().close();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
if (!canGoBack(who) && !close) {
|
||||
return gui.getFiller() != null ? gui.getFiller().getItem(who, slot) : null;
|
||||
}
|
||||
|
||||
return super.getItem(who, slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this element can close the GUI when nothing to go back to
|
||||
* @return Close the GUI when nothing to go back
|
||||
*/
|
||||
public boolean canClose() {
|
||||
return close;
|
||||
}
|
||||
|
||||
private boolean canGoBack(HumanEntity who) {
|
||||
return InventoryGui.getHistory(who).size() > 1 || (InventoryGui.getHistory(who).size() == 1 && InventoryGui.getHistory(who).peekLast() != gui);
|
||||
}
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Represents an element in a gui
|
||||
*/
|
||||
public abstract class GuiElement {
|
||||
private final char slotChar;
|
||||
private Action action;
|
||||
protected int[] slots = new int[0];
|
||||
protected InventoryGui gui;
|
||||
|
||||
/**
|
||||
* Represents an element in a gui
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param action The action to run when the player clicks on this element
|
||||
*/
|
||||
public GuiElement(char slotChar, Action action) {
|
||||
this.slotChar = slotChar;
|
||||
setAction(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element in a gui that doesn't have any action when clicked
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
*/
|
||||
public GuiElement(char slotChar) {
|
||||
this(slotChar, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the character in the gui setup that corresponds with this element
|
||||
* @return The character
|
||||
*/
|
||||
public char getSlotChar() {
|
||||
return slotChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item that is displayed by this element on a certain page
|
||||
* @param who The player who views the page
|
||||
* @param slot The slot to get the item for
|
||||
* @return The ItemStack that is displayed as this element
|
||||
*/
|
||||
public abstract ItemStack getItem(HumanEntity who, int slot);
|
||||
|
||||
/**
|
||||
* Get the action that is executed when clicking on this element
|
||||
* @param who The player who views the page
|
||||
* @return The action to run
|
||||
*/
|
||||
public Action getAction(HumanEntity who) {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action that is executed when clicking on this element
|
||||
* @param action The action to run. The {@link Action#onClick} method should
|
||||
* return whether or not the click event should be cancelled
|
||||
*/
|
||||
public void setAction(Action action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the indexes of the lots that this element is displayed in
|
||||
* @return An array of the lost indexes
|
||||
*/
|
||||
public int[] getSlots() {
|
||||
return slots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ids of the slots where this element is assigned to
|
||||
* @param slots An array of the slot ids where this element is displayed
|
||||
*/
|
||||
public void setSlots(int[] slots) {
|
||||
this.slots = slots;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index that this slot has in the list of slots that this element is displayed in
|
||||
* @param slot The id of the slot
|
||||
* @return The index in the list of slots that this id has or <code>-1</code> if it isn't in that list
|
||||
*/
|
||||
public int getSlotIndex(int slot) {
|
||||
return getSlotIndex(slot, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index that this slot has in the list of slots that this element is displayed in
|
||||
* @param slot The id of the slot
|
||||
* @param pageNumber The number of the page that the gui is on
|
||||
* @return The index in the list of slots that this id has or <code>-1</code> if it isn't in that list
|
||||
*/
|
||||
public int getSlotIndex(int slot, int pageNumber) {
|
||||
for (int i = 0; i < slots.length; i++) {
|
||||
if (slots[i] == slot) {
|
||||
return i + slots.length * pageNumber;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the gui this element belongs to
|
||||
* @param gui The GUI that this element is in
|
||||
*/
|
||||
public void setGui(InventoryGui gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the gui this element belongs to
|
||||
* @return The GUI that this element is in
|
||||
*/
|
||||
public InventoryGui getGui() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public static interface Action {
|
||||
|
||||
/**
|
||||
* Executed when a player clicks on an element
|
||||
* @param click The Click class containing information about the click
|
||||
* @return Whether or not the click event should be cancelled
|
||||
*/
|
||||
boolean onClick(Click click);
|
||||
|
||||
}
|
||||
|
||||
public static class Click {
|
||||
private final InventoryGui gui;
|
||||
private final int slot;
|
||||
private final ClickType clickType;
|
||||
private ItemStack cursor;
|
||||
private final GuiElement element;
|
||||
private final InventoryInteractEvent event;
|
||||
|
||||
public Click(InventoryGui gui, int slot, ClickType clickType, ItemStack cursor, GuiElement element, InventoryInteractEvent event) {
|
||||
this.gui = gui;
|
||||
this.slot = slot;
|
||||
this.clickType = clickType;
|
||||
this.cursor = cursor;
|
||||
this.element = element;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot of the GUI that was clicked
|
||||
* @return The clicked slot
|
||||
*/
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element that was clicked
|
||||
* @return The clicked GuiElement
|
||||
*/
|
||||
public GuiElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the click
|
||||
* @return The type of the click
|
||||
*/
|
||||
public ClickType getType() {
|
||||
return clickType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item on the cursor
|
||||
* @return The item on the cursor when this click occurred
|
||||
*/
|
||||
public ItemStack getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item on the cursor after the click
|
||||
* @param cursor The new item on the cursor
|
||||
*/
|
||||
public void setCursor(ItemStack cursor) {
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get who clicked the element
|
||||
* @return The player that clicked
|
||||
*/
|
||||
public HumanEntity getWhoClicked() {
|
||||
return event.getWhoClicked();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the event of the inventory interaction
|
||||
* @return The InventoryInteractEvent associated with this Click
|
||||
*/
|
||||
public InventoryInteractEvent getRawEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public InventoryGui getGui() {
|
||||
return gui;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a group of multiple elements. Will be left-aligned by default.
|
||||
*/
|
||||
public class GuiElementGroup extends GuiElement {
|
||||
private List<GuiElement> elements = new ArrayList<>();
|
||||
private GuiElement filler = null;
|
||||
private Alignment alignment = Alignment.LEFT;
|
||||
|
||||
/**
|
||||
* A group of elements
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param elements The elements in this group
|
||||
*/
|
||||
public GuiElementGroup(char slotChar, GuiElement... elements) {
|
||||
super(slotChar, null);
|
||||
setAction(click -> {
|
||||
GuiElement element = getElement(click.getSlot(), click.getGui().getPageNumber(click.getWhoClicked()));
|
||||
if (element != null && element.getAction(click.getRawEvent().getWhoClicked()) != null) {
|
||||
return element.getAction(click.getWhoClicked()).onClick(click);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
Collections.addAll(this.elements, elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
GuiElement element = getElement(slot, gui.getPageNumber(who));
|
||||
if (element != null) {
|
||||
return element.getItem(who, slot);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGui(InventoryGui gui) {
|
||||
super.setGui(gui);
|
||||
for (GuiElement element : elements) {
|
||||
if (element != null) {
|
||||
element.setGui(gui);
|
||||
}
|
||||
}
|
||||
if (filler != null) {
|
||||
filler.setGui(gui);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSlots(int[] slots) {
|
||||
super.setSlots(slots);
|
||||
for (GuiElement element : elements) {
|
||||
if (element != null) {
|
||||
element.setSlots(slots);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to this group
|
||||
* @param element The element to add
|
||||
*/
|
||||
public void addElement(GuiElement element){
|
||||
elements.add(element);
|
||||
if (element != null) {
|
||||
element.setGui(gui);
|
||||
element.setSlots(slots);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add elements to this group
|
||||
* @param elements The elements to add
|
||||
*/
|
||||
public void addElements(GuiElement... elements){
|
||||
for (GuiElement element : elements) {
|
||||
addElement(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add elements to this group
|
||||
* @param elements The elements to add
|
||||
*/
|
||||
public void addElements(Collection<GuiElement> elements){
|
||||
for (GuiElement element : elements) {
|
||||
addElement(element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element in a certain slot
|
||||
* @param slot The slot to get the element for
|
||||
* @return The GuiElement in that slot or <code>null</code>
|
||||
*/
|
||||
public GuiElement getElement(int slot) {
|
||||
return getElement(slot, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element in a certain slot on a certain page
|
||||
* @param slot The slot to get the element for
|
||||
* @param pageNumber The number of the page that the gui is on
|
||||
* @return The GuiElement in that slot or <code>null</code>
|
||||
*/
|
||||
public GuiElement getElement(int slot, int pageNumber) {
|
||||
if (elements.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
int index = getSlotIndex(slot, slots.length < elements.size() ? pageNumber : 0);
|
||||
if (index > -1) {
|
||||
if (alignment == Alignment.LEFT) {
|
||||
if (index < elements.size()) {
|
||||
return elements.get(index);
|
||||
}
|
||||
} else {
|
||||
int lineWidth = getLineWidth(slot);
|
||||
int linePosition = getLinePosition(slot);
|
||||
if (elements.size() - index > lineWidth - linePosition) {
|
||||
return elements.get(index);
|
||||
}
|
||||
int rest = elements.size() - (index - linePosition);
|
||||
int blankBefore = alignment == Alignment.CENTER ? (lineWidth - rest) / 2 : lineWidth - rest;
|
||||
if (linePosition < blankBefore || index - blankBefore >= elements.size()) {
|
||||
return filler;
|
||||
}
|
||||
return elements.get(index - blankBefore);
|
||||
}
|
||||
}
|
||||
return filler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the line the slot is in
|
||||
* @param slot The slot
|
||||
* @return The width of the line in the GUI setup of this group
|
||||
*/
|
||||
private int getLineWidth(int slot) {
|
||||
int width = gui.getWidth();
|
||||
int row = slot / width;
|
||||
|
||||
int amount = 0;
|
||||
for (int s : slots) {
|
||||
if (s >= row * width && s < (row + 1) * width) {
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position of the slot in its line
|
||||
* @param slot The slot ID
|
||||
* @return The line position or -1 if not in its line. wat
|
||||
*/
|
||||
private int getLinePosition(int slot) {
|
||||
int width = gui.getWidth();
|
||||
int row = slot / width;
|
||||
|
||||
int position = -1;
|
||||
for (int s : slots) {
|
||||
if (s >= row * width && s < (row + 1) * width) {
|
||||
position++;
|
||||
if (s == slot) {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all elements of this group. This list is immutable, use {@link #addElement(GuiElement)}
|
||||
* and {@link #clearElements()} to modify the elements in this group.
|
||||
* @return An immutable list of all elements in this group
|
||||
*/
|
||||
public List<GuiElement> getElements() {
|
||||
return Collections.unmodifiableList(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements in the group
|
||||
*/
|
||||
public void clearElements() {
|
||||
elements.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filler element for empty slots
|
||||
* @param item The item for the filler element
|
||||
*/
|
||||
public void setFiller(ItemStack item) {
|
||||
filler = new StaticGuiElement(' ', item, " ");
|
||||
filler.setGui(gui);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filler element for empty slots
|
||||
* @param filler The item for the filler element
|
||||
*/
|
||||
public void setFiller(GuiElement filler) {
|
||||
this.filler = filler;
|
||||
if (filler != null) {
|
||||
filler.setGui(gui);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filler element
|
||||
* @return The filler element
|
||||
*/
|
||||
public GuiElement getFiller() {
|
||||
return filler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of this group
|
||||
* @return The amount of elements that this group has
|
||||
*/
|
||||
public int size() {
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alignment of the elements in this group
|
||||
* @param alignment The alignment
|
||||
*/
|
||||
public void setAlignment(Alignment alignment) {
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alignment of the elements in this group
|
||||
* @return The alignment
|
||||
*/
|
||||
public Alignment getAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
public enum Alignment {
|
||||
LEFT,
|
||||
CENTER,
|
||||
RIGHT;
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* This is an element that allows for controlling the pagination of the gui.
|
||||
* <b>Untested und potentially unfinished.</b>
|
||||
*/
|
||||
public class GuiPageElement extends StaticGuiElement {
|
||||
private PageAction pageAction;
|
||||
private boolean silent = false;
|
||||
|
||||
/**
|
||||
* An element that allows for controlling the pagination of the gui.
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param item The {@link ItemStack} representing this element
|
||||
* @param pageAction What kind of page action you want to happen when interacting with the element.
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public GuiPageElement(char slotChar, ItemStack item, PageAction pageAction, String... text) {
|
||||
super(slotChar, item, text);
|
||||
setAction(click -> {
|
||||
switch (pageAction) {
|
||||
case NEXT:
|
||||
if (click.getGui().getPageNumber(click.getWhoClicked()) + 1 < click.getGui().getPageAmount(click.getWhoClicked())) {
|
||||
if (!isSilent()) {
|
||||
click.getGui().playClickSound();
|
||||
}
|
||||
click.getGui().setPageNumber(click.getWhoClicked(), click.getGui().getPageNumber(click.getWhoClicked()) + 1);
|
||||
}
|
||||
break;
|
||||
case PREVIOUS:
|
||||
if (click.getGui().getPageNumber(click.getWhoClicked()) > 0) {
|
||||
if (!isSilent()) {
|
||||
click.getGui().playClickSound();
|
||||
}
|
||||
click.getGui().setPageNumber(click.getWhoClicked(), click.getGui().getPageNumber(click.getWhoClicked()) - 1);
|
||||
}
|
||||
break;
|
||||
case FIRST:
|
||||
if (!isSilent()) {
|
||||
click.getGui().playClickSound();
|
||||
}
|
||||
click.getGui().setPageNumber(click.getWhoClicked(), 0);
|
||||
break;
|
||||
case LAST:
|
||||
if (!isSilent()) {
|
||||
click.getGui().playClickSound();
|
||||
}
|
||||
click.getGui().setPageNumber(click.getWhoClicked(), click.getGui().getPageAmount(click.getWhoClicked()) - 1);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
this.pageAction = pageAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not this element should make a sound when interacted with
|
||||
* @return Whether or not to make a sound when interacted with
|
||||
*/
|
||||
public boolean isSilent() {
|
||||
return silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not this element should make a sound when interacted with
|
||||
* @param silent Whether or not to make a sound when interacted with
|
||||
*/
|
||||
public void setSilent(boolean silent) {
|
||||
this.silent = silent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
if (((pageAction == PageAction.FIRST || pageAction == PageAction.LAST) && gui.getPageAmount(who) < 3)
|
||||
|| (pageAction == PageAction.NEXT && gui.getPageNumber(who) + 1 >= gui.getPageAmount(who))
|
||||
|| (pageAction == PageAction.PREVIOUS && gui.getPageNumber(who) == 0)) {
|
||||
return gui.getFiller() != null ? gui.getFiller().getItem(who, slot) : null;
|
||||
}
|
||||
if (pageAction == PageAction.PREVIOUS) {
|
||||
setNumber(gui.getPageNumber(who));
|
||||
} else if (pageAction == PageAction.NEXT) {
|
||||
setNumber(gui.getPageNumber(who) + 2);
|
||||
} else if (pageAction == PageAction.LAST) {
|
||||
setNumber(gui.getPageAmount(who));
|
||||
}
|
||||
return super.getItem(who, slot).clone();
|
||||
}
|
||||
|
||||
public enum PageAction {
|
||||
NEXT,
|
||||
PREVIOUS,
|
||||
FIRST,
|
||||
LAST;
|
||||
}
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* An element that can switch between certain states. It automatically handles the switching
|
||||
* of the item in the slot that corresponds to the state that the element is in.
|
||||
*/
|
||||
public class GuiStateElement extends GuiElement {
|
||||
private Supplier<Integer> queryState = null;
|
||||
private boolean silent = false;
|
||||
private int currentState;
|
||||
private final State[] states;
|
||||
|
||||
/**
|
||||
* An element that can switch between certain states.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param defaultState The index of the default state.
|
||||
* @param states The list of different {@link State}s that this element can have.
|
||||
*/
|
||||
public GuiStateElement(char slotChar, int defaultState, State... states) {
|
||||
super(slotChar, null);
|
||||
if (states.length == 0) {
|
||||
throw new IllegalArgumentException("You need to add at least one State!");
|
||||
}
|
||||
this.currentState = defaultState;
|
||||
this.states = states;
|
||||
|
||||
setAction(click -> {
|
||||
State next = nextState();
|
||||
next.change.onChange(click);
|
||||
if (!isSilent()) {
|
||||
click.getGui().playClickSound();
|
||||
}
|
||||
gui.draw(click.getWhoClicked(), false);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* An element that can switch between certain states.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param defaultState The key of the default state.
|
||||
* @param states The list of different {@link State}s that this element can have.
|
||||
*/
|
||||
public GuiStateElement(char slotChar, String defaultState, State... states) {
|
||||
this(slotChar, getStateIndex(defaultState, states), states);
|
||||
}
|
||||
|
||||
/**
|
||||
* An element that can switch between certain states.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param queryState Supplier for the current state.
|
||||
* @param states The list of different {@link State}s that this element can have.
|
||||
*/
|
||||
public GuiStateElement(char slotChar, Supplier<String> queryState, State... states) {
|
||||
this(slotChar, queryState.get(), states);
|
||||
this.queryState = () -> getStateIndex(queryState.get(), states);
|
||||
}
|
||||
|
||||
/**
|
||||
* An element that can switch between certain states. The first state will be the default one.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param states The list of different {@link State}s that this element can have.
|
||||
*/
|
||||
public GuiStateElement(char slotChar, State... states) {
|
||||
this(slotChar, 0, states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through the states of this element
|
||||
* @return The new state (next one to the old)
|
||||
*/
|
||||
public State nextState() {
|
||||
queryCurrentState();
|
||||
currentState = states.length > currentState + 1 ? currentState + 1 : 0;
|
||||
return states[currentState];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through the states of this element backwards
|
||||
* @return The new state (previous one to the old)
|
||||
*/
|
||||
public State previousState() {
|
||||
queryCurrentState();
|
||||
currentState = currentState > 0 ? currentState - 1 : states.length - 1;
|
||||
return states[currentState];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
return getState().getItem(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGui(InventoryGui gui) {
|
||||
super.setGui(gui);
|
||||
for (State state : states) {
|
||||
state.setGui(gui);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current state of this element
|
||||
* @return The current state of this element
|
||||
*/
|
||||
public State getState() {
|
||||
queryCurrentState();
|
||||
return states[currentState];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not this element should make a sound when interacted with
|
||||
* @return Whether or not to make a sound when interacted with
|
||||
*/
|
||||
public boolean isSilent() {
|
||||
return silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not this element should make a sound when interacted with
|
||||
* @param silent Whether or not to make a sound when interacted with
|
||||
*/
|
||||
public void setSilent(boolean silent) {
|
||||
this.silent = silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to query the current state if there is a query
|
||||
*/
|
||||
private void queryCurrentState() {
|
||||
if (queryState != null) {
|
||||
currentState = queryState.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current state with the state's key. Does not trigger the state's change.
|
||||
* @param key The key to search for.
|
||||
* @throws IllegalArgumentException Thrown if there is no state with the provided key.
|
||||
*/
|
||||
public void setState(String key) throws IllegalArgumentException {
|
||||
currentState = getStateIndex(key, states);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of a state from a key
|
||||
* @param key The key to search for.
|
||||
* @param states The states to search in.
|
||||
* @return The index of that key in the state array.
|
||||
* @throws IllegalArgumentException Thrown if there is no state with the provided key.
|
||||
*/
|
||||
private static int getStateIndex(String key, State[] states) throws IllegalArgumentException {
|
||||
for (int i = 0; i < states.length; i++) {
|
||||
if (states[i].getKey().equals(key)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("This element does not have the state " + key);
|
||||
}
|
||||
|
||||
/**
|
||||
* A state that the {@link GuiStateElement} can have.
|
||||
*/
|
||||
public static class State {
|
||||
private final Change change;
|
||||
private final String key;
|
||||
private final ItemStack item;
|
||||
private String[] text;
|
||||
private InventoryGui gui;
|
||||
|
||||
/**
|
||||
* A state that the {@link GuiStateElement} can have.
|
||||
* @param change What to do when the state changes
|
||||
* @param key The state's string key
|
||||
* @param item The {@link ItemStack} to represent this state
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public State(Change change, String key, ItemStack item, String... text) {
|
||||
this.change = change;
|
||||
this.key = key;
|
||||
this.item = item;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this element's display text. If this is an empty array the item's name will be displayed
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public void setText(String... text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ItemStack} that represents this state.
|
||||
* @return The {@link ItemStack} that represents this state
|
||||
* @deprecated Use {@link #getItem(HumanEntity)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ItemStack getItem() {
|
||||
return getItem(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ItemStack} that represents this state.
|
||||
* @param who The player viewing the GUI
|
||||
* @return The {@link ItemStack} that represents this state
|
||||
*/
|
||||
public ItemStack getItem(HumanEntity who) {
|
||||
ItemStack clone = item.clone();
|
||||
gui.setItemText(who, clone, getText());
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string key of the state.
|
||||
* @return The state's string key
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text lines that describe this state.
|
||||
* @return The text lines for this state
|
||||
*/
|
||||
public String[] getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
private void setGui(InventoryGui gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define what should happen when the state of the element' state changes to this state
|
||||
*/
|
||||
public interface Change {
|
||||
|
||||
/**
|
||||
* What should happen when the element's state changes to this state
|
||||
* @param click The click that triggered this change
|
||||
*/
|
||||
void onChange(Click click);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,368 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* This element is used to access an {@link Inventory}. The slots in the inventory are selected
|
||||
* by searching through the whole gui the element is in and getting the number of the spot
|
||||
* in the character group that this element is in. <br>
|
||||
* E.g. if you have five characters called "s" in the gui setup and the second element is
|
||||
* accessed by the player then it will translate to the second slot in the inventory.
|
||||
*/
|
||||
public class GuiStorageElement extends GuiElement {
|
||||
private final Inventory storage;
|
||||
private final int invSlot;
|
||||
private Runnable applyStorage;
|
||||
private Function<ValidatorInfo, Boolean> itemValidator;
|
||||
|
||||
/**
|
||||
* An element used to access an {@link Inventory}.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param storage The {@link Inventory} that this element is linked to.
|
||||
*/
|
||||
public GuiStorageElement(char slotChar, Inventory storage) {
|
||||
this(slotChar, storage, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* An element used to access a specific slot in an {@link Inventory}.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param storage The {@link Inventory} that this element is linked to.
|
||||
* @param invSlot The index of the slot to access in the {@link Inventory}.
|
||||
*/
|
||||
public GuiStorageElement(char slotChar, Inventory storage, int invSlot) {
|
||||
this(slotChar, storage, invSlot, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* An element used to access a specific slot in an {@link Inventory}.
|
||||
* @param slotChar The character to replace in the gui setup string.
|
||||
* @param storage The {@link Inventory} that this element is linked to.
|
||||
* @param invSlot The index of the slot to access in the {@link Inventory}.
|
||||
* @param applyStorage Apply the storage that this element represents.
|
||||
* @param itemValidator Should return <code>false</code> for items that should not work in that slot
|
||||
* Can be null if the storage is directly linked.
|
||||
*/
|
||||
public GuiStorageElement(char slotChar, Inventory storage, int invSlot, Runnable applyStorage, Function<ValidatorInfo, Boolean> itemValidator) {
|
||||
super(slotChar, null);
|
||||
this.invSlot = invSlot;
|
||||
this.applyStorage = applyStorage;
|
||||
this.itemValidator = itemValidator;
|
||||
setAction(click -> {
|
||||
if (getStorageSlot(click.getWhoClicked(), click.getSlot()) < 0) {
|
||||
return true;
|
||||
}
|
||||
ItemStack storageItem = getStorageItem(click.getWhoClicked(), click.getSlot());
|
||||
ItemStack slotItem = click.getRawEvent().getView().getTopInventory().getItem(click.getSlot());
|
||||
if (slotItem == null && storageItem != null && storageItem.getType() != Material.AIR
|
||||
|| storageItem == null && slotItem != null && slotItem.getType() != Material.AIR
|
||||
|| storageItem != null && !storageItem.equals(slotItem)) {
|
||||
gui.draw(click.getWhoClicked(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(click.getRawEvent() instanceof InventoryClickEvent)) {
|
||||
// Only the click event will be handled here, drag event is handled separately
|
||||
return true;
|
||||
}
|
||||
|
||||
InventoryClickEvent event = (InventoryClickEvent) click.getRawEvent();
|
||||
|
||||
ItemStack movedItem = null;
|
||||
switch (event.getAction()) {
|
||||
case NOTHING:
|
||||
case CLONE_STACK:
|
||||
return false;
|
||||
case MOVE_TO_OTHER_INVENTORY:
|
||||
if (event.getRawSlot() < click.getRawEvent().getView().getTopInventory().getSize()) {
|
||||
// Moved from storage
|
||||
|
||||
// Check if there is actually space (more advanced checks can unfortunately not be supported right now)
|
||||
if (click.getRawEvent().getView().getBottomInventory().firstEmpty() == -1) {
|
||||
// No empty slot, cancel
|
||||
return true;
|
||||
}
|
||||
movedItem = null;
|
||||
} else {
|
||||
// Moved to storage
|
||||
|
||||
// Check if there is actually space (more advanced checks can unfortunately not be supported right now)
|
||||
if (click.getRawEvent().getView().getTopInventory().firstEmpty() == -1) {
|
||||
// No empty slot, cancel
|
||||
return true;
|
||||
}
|
||||
movedItem = event.getCurrentItem();
|
||||
}
|
||||
// Update GUI to avoid display glitches
|
||||
gui.runTask(gui::draw);
|
||||
break;
|
||||
case HOTBAR_MOVE_AND_READD:
|
||||
case HOTBAR_SWAP:
|
||||
int button = event.getHotbarButton();
|
||||
if (button < 0) {
|
||||
return true;
|
||||
}
|
||||
ItemStack hotbarItem = click.getRawEvent().getView().getBottomInventory().getItem(button);
|
||||
if (hotbarItem != null) {
|
||||
movedItem = hotbarItem.clone();
|
||||
}
|
||||
break;
|
||||
case PICKUP_ONE:
|
||||
case DROP_ONE_SLOT:
|
||||
if (event.getCurrentItem() != null) {
|
||||
movedItem = event.getCurrentItem().clone();
|
||||
movedItem.setAmount(movedItem.getAmount() - 1);
|
||||
}
|
||||
break;
|
||||
case DROP_ALL_SLOT:
|
||||
movedItem = null;
|
||||
break;
|
||||
case PICKUP_HALF:
|
||||
if (event.getCurrentItem() != null) {
|
||||
movedItem = event.getCurrentItem().clone();
|
||||
movedItem.setAmount(movedItem.getAmount() / 2);
|
||||
}
|
||||
break;
|
||||
case PLACE_SOME:
|
||||
if (event.getCurrentItem() == null) {
|
||||
if (event.getCursor() != null) {
|
||||
movedItem = event.getCursor().clone();
|
||||
}
|
||||
} else {
|
||||
movedItem = event.getCurrentItem().clone();
|
||||
int newAmount = movedItem.getAmount() + (event.getCursor() != null ? event.getCursor().getAmount() : 0);
|
||||
if (newAmount < movedItem.getMaxStackSize()) {
|
||||
movedItem.setAmount(newAmount);
|
||||
} else {
|
||||
movedItem.setAmount(movedItem.getMaxStackSize());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PLACE_ONE:
|
||||
if (event.getCursor() != null) {
|
||||
if (event.getCurrentItem() == null) {
|
||||
movedItem = event.getCursor().clone();
|
||||
movedItem.setAmount(1);
|
||||
} else {
|
||||
movedItem = event.getCursor().clone();
|
||||
movedItem.setAmount(event.getCurrentItem().getAmount() + 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PLACE_ALL:
|
||||
if (event.getCursor() != null) {
|
||||
movedItem = event.getCursor().clone();
|
||||
if (event.getCurrentItem() != null && event.getCurrentItem().getAmount() > 0) {
|
||||
movedItem.setAmount(event.getCurrentItem().getAmount() + movedItem.getAmount());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PICKUP_ALL:
|
||||
case SWAP_WITH_CURSOR:
|
||||
if (event.getCursor() != null) {
|
||||
movedItem = event.getCursor().clone();
|
||||
};
|
||||
break;
|
||||
case COLLECT_TO_CURSOR:
|
||||
if (event.getCursor() == null
|
||||
|| event.getCurrentItem() != null && event.getCurrentItem().getType() != Material.AIR) {
|
||||
return true;
|
||||
}
|
||||
gui.simulateCollectToCursor(click);
|
||||
return false;
|
||||
default:
|
||||
click.getRawEvent().getWhoClicked().sendMessage(ChatColor.RED + "The action " + event.getAction() + " is not supported! Sorry about that :(");
|
||||
return true;
|
||||
}
|
||||
return !setStorageItem(click.getWhoClicked(), click.getSlot(), movedItem);
|
||||
});
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
int index = getStorageSlot(who, slot);
|
||||
if (index > -1 && index < storage.getSize()) {
|
||||
return storage.getItem(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Inventory} that this element is linked to.
|
||||
* @return The {@link Inventory} that this element is linked to.
|
||||
*/
|
||||
public Inventory getStorage() {
|
||||
return storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the storage slot index that corresponds to the InventoryGui slot
|
||||
* @param player The player which is using the GUI view
|
||||
* @param slot The slot in the GUI
|
||||
* @return The index of the storage slot or <code>-1</code> if it's outside the storage
|
||||
*/
|
||||
private int getStorageSlot(HumanEntity player, int slot) {
|
||||
int index = invSlot != -1 ? invSlot : getSlotIndex(slot, gui.getPageNumber(player));
|
||||
if (index < 0 || index >= storage.getSize()) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item in the storage that corresponds to the InventoryGui slot
|
||||
* @param slot The slot in the GUI
|
||||
* @return The {@link ItemStack} or <code>null</code> if the slot is outside of the item's size
|
||||
* @deprecated Use {@link #getStorageItem(HumanEntity, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ItemStack getStorageItem(int slot) {
|
||||
return getStorageItem(null, slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item in the storage that corresponds to the InventoryGui slot
|
||||
* @param player The player which is using the GUI view
|
||||
* @param slot The slot in the GUI
|
||||
* @return The {@link ItemStack} or <code>null</code> if the slot is outside of the item's size
|
||||
*/
|
||||
public ItemStack getStorageItem(HumanEntity player, int slot) {
|
||||
int index = getStorageSlot(player, slot);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
return storage.getItem(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item in the storage that corresponds to the InventoryGui slot.
|
||||
* @param slot The slot in the GUI
|
||||
* @param item The {@link ItemStack} to set
|
||||
* @return <code>true</code> if the item was set; <code>false</code> if the slot was outside of this storage
|
||||
* @deprecated Use {@link #setStorageItem(HumanEntity, int, ItemStack)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setStorageItem(int slot, ItemStack item) {
|
||||
return setStorageItem(null, slot, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item in the storage that corresponds to the InventoryGui slot.
|
||||
* @param player The player using the GUI view
|
||||
* @param slot The slot in the GUI
|
||||
* @param item The {@link ItemStack} to set
|
||||
* @return <code>true</code> if the item was set; <code>false</code> if the slot was outside of this storage
|
||||
*/
|
||||
public boolean setStorageItem(HumanEntity player, int slot, ItemStack item) {
|
||||
int index = getStorageSlot(player, slot);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
if (!validateItem(slot, item)) {
|
||||
return false;
|
||||
}
|
||||
storage.setItem(index, item);
|
||||
if (applyStorage != null) {
|
||||
applyStorage.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the runnable that applies the storage
|
||||
* @return The storage applying runnable; might be null
|
||||
*/
|
||||
public Runnable getApplyStorage() {
|
||||
return applyStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set what should be done to apply the storage.
|
||||
* Not necessary if the storage is directly backed by a real inventory.
|
||||
* @param applyStorage How to apply the storage; can be null if nothing should be done
|
||||
*/
|
||||
public void setApplyStorage(Runnable applyStorage) {
|
||||
this.applyStorage = applyStorage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item validator
|
||||
* @return The item validator
|
||||
*/
|
||||
public Function<ValidatorInfo, Boolean> getItemValidator() {
|
||||
return itemValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a function that can validate whether or not an item can fit in the slot
|
||||
* @param itemValidator The item validator that takes a {@link ValidatorInfo} and returns <code>true</code> for items that
|
||||
* should and <code>false</code> for items that should not work in that slot
|
||||
*/
|
||||
public void setItemValidator(Function<ValidatorInfo, Boolean> itemValidator) {
|
||||
this.itemValidator = itemValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate whether or not an item can be put in a slot with the item validator set in {@link #setItemValidator(Function)}
|
||||
* @param slot The slot the item should be tested for
|
||||
* @param item The item to test
|
||||
* @return <code>true</code> for items that should and <code>false</code> for items that should not work in that slot
|
||||
*/
|
||||
public boolean validateItem(int slot, ItemStack item) {
|
||||
return itemValidator == null || itemValidator.apply(new ValidatorInfo(this, slot, item));
|
||||
}
|
||||
|
||||
public static class ValidatorInfo {
|
||||
private final GuiElement element;
|
||||
private final int slot;
|
||||
private final ItemStack item;
|
||||
|
||||
public ValidatorInfo(GuiElement element, int slot, ItemStack item) {
|
||||
this.item = item;
|
||||
this.slot = slot;
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public GuiElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,159 +0,0 @@
|
||||
package net.momirealms.customfishing.libraries.inventorygui;
|
||||
|
||||
/*
|
||||
* Copyright 2017 Max Lee (https://github.com/Phoenix616)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Represents a simple element in a gui to which an action can be assigned.
|
||||
* If you want the item to change on click you have to do that yourself.
|
||||
*/
|
||||
public class StaticGuiElement extends GuiElement {
|
||||
private ItemStack item;
|
||||
private int number;
|
||||
private String[] text;
|
||||
|
||||
/**
|
||||
* Represents an element in a gui
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param item The item this element displays
|
||||
* @param number The number, 1 will not display the number
|
||||
* @param action The action to run when the player clicks on this element
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
* @throws IllegalArgumentException If the number is below 1 or above the max stack count (currently 64)
|
||||
*/
|
||||
public StaticGuiElement(char slotChar, ItemStack item, int number, Action action, String... text) throws IllegalArgumentException {
|
||||
super(slotChar, action);
|
||||
this.item = item;
|
||||
this.text = text;
|
||||
setNumber(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element in a gui
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param item The item this element displays
|
||||
* @param action The action to run when the player clicks on this element
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public StaticGuiElement(char slotChar, ItemStack item, Action action, String... text) {
|
||||
this(slotChar, item, item != null ? item.getAmount() : 1, action, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element in a gui that doesn't have any action when clicked
|
||||
* @param slotChar The character to replace in the gui setup string
|
||||
* @param item The item this element displays
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public StaticGuiElement(char slotChar, ItemStack item, String... text) {
|
||||
this(slotChar, item, item != null ? item.getAmount() : 1, null, text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the item that is displayed by this element
|
||||
* @param item The item that should be displayed by this element
|
||||
*/
|
||||
public void setItem(ItemStack item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw item displayed by this element which was passed to the constructor or set with {@link #setItem(ItemStack)}.
|
||||
* This item will not have the amount or text applied! Use {@link #getItem(HumanEntity, int)} for that!
|
||||
* @return The raw item
|
||||
*/
|
||||
public ItemStack getRawItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(HumanEntity who, int slot) {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
ItemStack clone = item.clone();
|
||||
gui.setItemText(who, clone, getText());
|
||||
if (number > 0 && number <= 64) {
|
||||
clone.setAmount(number);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this element's display text. If this is an empty array the item's name will be displayed
|
||||
* @param text The text to display on this element, placeholders are automatically
|
||||
* replaced, see {@link InventoryGui#replaceVars} for a list of the
|
||||
* placeholder variables. Empty text strings are also filter out, use
|
||||
* a single space if you want to add an empty line!<br>
|
||||
* If it's not set/empty the item's default name will be used
|
||||
*/
|
||||
public void setText(String... text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text that this element displays
|
||||
* @return The text that is displayed on this element
|
||||
*/
|
||||
public String[] getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number that this element should display (via the Item's amount)
|
||||
* @param number The number, 1 will not display the number
|
||||
* @return <code>true</code> if the number was set; <code>false</code> if it was below 1 or above 64
|
||||
*/
|
||||
public boolean setNumber(int number) {
|
||||
if (number < 1 || number > 64) {
|
||||
this.number = 1;
|
||||
return false;
|
||||
}
|
||||
this.number = number;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number that this element should display
|
||||
* @return The number (item amount) that this element currently has
|
||||
*/
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
@@ -43,6 +44,8 @@ public class ActionManagerImpl implements ActionManager {
|
||||
this.registerPluginExpAction();
|
||||
this.registerTitleAction();
|
||||
this.registerActionBarAction();
|
||||
this.registerCloseInvAction();
|
||||
this.registerDelayedAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,6 +156,13 @@ public class ActionManagerImpl implements ActionManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerCloseInvAction() {
|
||||
registerAction("close-inv", (args, chance) -> condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
condition.getPlayer().closeInventory();
|
||||
});
|
||||
}
|
||||
|
||||
private void registerActionBarAction() {
|
||||
registerAction("actionbar", (args, chance) -> {
|
||||
String text = (String) args;
|
||||
@@ -217,6 +227,34 @@ public class ActionManagerImpl implements ActionManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerDelayedAction() {
|
||||
registerAction("delay", (args, chance) -> {
|
||||
List<Action> actions = new ArrayList<>();
|
||||
int delay;
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
delay = section.getInt("delay", 1);
|
||||
ConfigurationSection actionSection = section.getConfigurationSection("action");
|
||||
if (actionSection != null) {
|
||||
for (Map.Entry<String, Object> entry : actionSection.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection innerSection) {
|
||||
actions.add(getAction(innerSection));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delay = 1;
|
||||
}
|
||||
return condition -> {
|
||||
if (Math.random() > chance) return;
|
||||
plugin.getScheduler().runTaskSyncLater(() -> {
|
||||
for (Action action : actions) {
|
||||
action.trigger(condition);
|
||||
}
|
||||
}, condition.getLocation(), delay * 50L, TimeUnit.MILLISECONDS);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void registerTitleAction() {
|
||||
registerAction("title", (args, chance) -> {
|
||||
if (args instanceof ConfigurationSection section) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.customfishing.mechanic.fishing;
|
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerJumpEvent;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||
import net.momirealms.customfishing.CustomFishingPluginImpl;
|
||||
import net.momirealms.customfishing.api.common.Pair;
|
||||
import net.momirealms.customfishing.api.event.LavaFishingEvent;
|
||||
@@ -33,16 +34,14 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerAttemptPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -174,6 +173,16 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChat(AsyncPlayerChatEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
GamingPlayer gamingPlayer = gamingPlayerMap.get(event.getPlayer().getUniqueId());
|
||||
if (gamingPlayer != null) {
|
||||
if (gamingPlayer.onChat(event.getMessage()))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeHook(UUID uuid) {
|
||||
FishHook hook = hookCacheMap.remove(uuid);
|
||||
@@ -185,6 +194,11 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<FishHook> getHook(UUID uuid) {
|
||||
return Optional.ofNullable(hookCacheMap.get(uuid));
|
||||
}
|
||||
|
||||
public void selectState(PlayerFishEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
switch (event.getState()) {
|
||||
|
||||
@@ -341,11 +341,9 @@ public class GameManagerImpl implements GameManager {
|
||||
+ FontUtils.surroundWithFont(fishImage, font)
|
||||
+ OffsetUtils.getOffsetChars((int) (barEffectiveWidth - fish_position - fishIconWidth + 1))
|
||||
;
|
||||
|
||||
AdventureManagerImpl.getInstance().sendTitle(
|
||||
player,
|
||||
tip != null && !played ? tip :
|
||||
title.replace("{progress}", progress[(int) ((hold_time / time_requirement) * progress.length)])
|
||||
tip != null && !played ? tip : title.replace("{progress}", progress[(int) ((hold_time / time_requirement) * progress.length)])
|
||||
,
|
||||
bar,
|
||||
0,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.momirealms.customfishing.mechanic.market;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class MarketDynamicGUIElement extends MarketGUIElement {
|
||||
|
||||
public MarketDynamicGUIElement(char symbol, ItemStack itemStack) {
|
||||
super(symbol, itemStack);
|
||||
}
|
||||
|
||||
public void setItemStack(ItemStack itemStack) {
|
||||
super.itemStack = itemStack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package net.momirealms.customfishing.mechanic.market;
|
||||
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.mechanic.market.MarketGUIHolder;
|
||||
import net.momirealms.customfishing.api.util.InventoryUtils;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MarketGUI {
|
||||
|
||||
private final HashMap<Character, MarketGUIElement> itemsCharMap;
|
||||
private final HashMap<Integer, MarketGUIElement> itemsSlotMap;
|
||||
private final Inventory inventory;
|
||||
private final MarketManagerImpl manager;
|
||||
private final Player owner;
|
||||
|
||||
public MarketGUI(MarketManagerImpl manager, Player player) {
|
||||
this.manager = manager;
|
||||
this.owner = player;
|
||||
this.itemsCharMap = new HashMap<>();
|
||||
this.itemsSlotMap = new HashMap<>();
|
||||
var holder = new MarketGUIHolder();
|
||||
this.inventory = InventoryUtils.createInventory(
|
||||
holder,
|
||||
manager.getLayout().length * 9,
|
||||
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(manager.getTitle())
|
||||
);
|
||||
holder.setInventory(this.inventory);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
int line = 0;
|
||||
for (String content : manager.getLayout()) {
|
||||
if (content.length() != 9) {
|
||||
LogUtils.warn("Please make sure that GUI layout has 9 elements in each row");
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < 9; index++) {
|
||||
char symbol = content.charAt(index);
|
||||
MarketGUIElement element = itemsCharMap.get(symbol);
|
||||
element.addSlot(index + line * 9);
|
||||
itemsSlotMap.put(index + line * 9, element);
|
||||
}
|
||||
line++;
|
||||
}
|
||||
for (Map.Entry<Integer, MarketGUIElement> entry : itemsSlotMap.entrySet()) {
|
||||
this.inventory.setItem(entry.getKey(), entry.getValue().getItemStack().clone());
|
||||
}
|
||||
}
|
||||
|
||||
public MarketGUI addElement(MarketGUIElement... elements) {
|
||||
for (MarketGUIElement element : elements) {
|
||||
itemsCharMap.put(element.getSymbol(), element);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MarketGUI build() {
|
||||
init();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void show(Player player) {
|
||||
if (player != owner) return;
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MarketGUIElement getElement(int slot) {
|
||||
return itemsSlotMap.get(slot);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MarketGUIElement getElement(char slot) {
|
||||
return itemsCharMap.get(slot);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
double totalWorth = getTotalWorth();
|
||||
if (totalWorth <= 0) {
|
||||
addElement(new MarketDynamicGUIElement(
|
||||
manager.getFunctionSlot(),
|
||||
manager.getFunctionIconDenyBuilder().build(owner,
|
||||
Map.of("{worth}", String.format("%.2f", totalWorth)
|
||||
,"{player}", owner.getName())
|
||||
)
|
||||
));
|
||||
} else {
|
||||
addElement(new MarketDynamicGUIElement(
|
||||
manager.getFunctionSlot(),
|
||||
manager.getFunctionIconAllowBuilder().build(owner,
|
||||
Map.of("{worth}", String.format("%.2f", totalWorth)
|
||||
,"{player}", owner.getName())
|
||||
)
|
||||
));
|
||||
}
|
||||
for (Map.Entry<Integer, MarketGUIElement> entry : itemsSlotMap.entrySet()) {
|
||||
if (entry.getValue() instanceof MarketDynamicGUIElement dynamicGUIElement) {
|
||||
this.inventory.setItem(entry.getKey(), dynamicGUIElement.getItemStack().clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double getTotalWorth() {
|
||||
double money = 0d;
|
||||
MarketGUIElement itemElement = getElement(manager.getItemSlot());
|
||||
if (itemElement == null) {
|
||||
LogUtils.warn("No item slot available. Please check if GUI layout contains the item slot symbol.");
|
||||
return money;
|
||||
}
|
||||
for (int slot : itemElement.getSlots()) {
|
||||
money += manager.getItemPrice(this.inventory.getItem(slot));
|
||||
}
|
||||
return money;
|
||||
}
|
||||
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void clearWorthyItems() {
|
||||
MarketGUIElement itemElement = getElement(manager.getItemSlot());
|
||||
if (itemElement == null) {
|
||||
return;
|
||||
}
|
||||
for (int slot : itemElement.getSlots()) {
|
||||
double money = manager.getItemPrice(inventory.getItem(slot));
|
||||
if (money != 0) {
|
||||
inventory.setItem(slot, new ItemStack(Material.AIR));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.momirealms.customfishing.mechanic.market;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MarketGUIElement {
|
||||
|
||||
private final char symbol;
|
||||
private final List<Integer> slots;
|
||||
protected ItemStack itemStack;
|
||||
|
||||
public MarketGUIElement(char symbol, ItemStack itemStack) {
|
||||
this.symbol = symbol;
|
||||
this.itemStack = itemStack;
|
||||
this.slots = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addSlot(int slot) {
|
||||
slots.add(slot);
|
||||
}
|
||||
|
||||
public char getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public List<Integer> getSlots() {
|
||||
return slots;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,33 @@
|
||||
package net.momirealms.customfishing.mechanic.market;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.data.user.OnlineUser;
|
||||
import net.momirealms.customfishing.api.manager.MarketManager;
|
||||
import net.momirealms.customfishing.api.mechanic.item.BuildableItem;
|
||||
import net.momirealms.customfishing.api.mechanic.item.ItemBuilder;
|
||||
import net.momirealms.customfishing.api.mechanic.market.MarketGUI;
|
||||
import net.momirealms.customfishing.libraries.inventorygui.InventoryGui;
|
||||
import net.momirealms.customfishing.libraries.inventorygui.StaticGuiElement;
|
||||
import net.momirealms.customfishing.mechanic.item.ItemManagerImpl;
|
||||
import net.momirealms.customfishing.api.mechanic.market.MarketGUIHolder;
|
||||
import net.momirealms.customfishing.util.ConfigUtils;
|
||||
import net.objecthunter.exp4j.Expression;
|
||||
import net.objecthunter.exp4j.ExpressionBuilder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MarketManagerImpl implements MarketManager {
|
||||
public class MarketManagerImpl implements MarketManager, Listener {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
private final HashMap<String, Double> priceMap;
|
||||
@@ -32,14 +36,36 @@ public class MarketManagerImpl implements MarketManager {
|
||||
private String formula;
|
||||
private final HashMap<Character, ItemBuilder> decorativeIcons;
|
||||
private char itemSlot;
|
||||
private char functionSlot;
|
||||
private BuildableItem functionIconAllowBuilder;
|
||||
private BuildableItem functionIconDenyBuilder;
|
||||
private double earningLimit;
|
||||
private ConcurrentHashMap<UUID, MarketGUI> marketGUIMap;
|
||||
|
||||
public MarketManagerImpl(CustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.priceMap = new HashMap<>();
|
||||
this.decorativeIcons = new HashMap<>();
|
||||
this.marketGUIMap = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.loadConfig();
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
|
||||
public void unload() {
|
||||
HandlerList.unregisterAll(this);
|
||||
this.priceMap.clear();
|
||||
this.decorativeIcons.clear();
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
unload();
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
YamlConfiguration config = plugin.getConfig("market.yml");
|
||||
this.layout = config.getStringList("layout").toArray(new String[0]);
|
||||
this.title = config.getString("title", "market.title");
|
||||
@@ -62,38 +88,74 @@ public class MarketManagerImpl implements MarketManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
this.priceMap.clear();
|
||||
this.decorativeIcons.clear();
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
unload();
|
||||
}
|
||||
|
||||
public void openMarketGUI(Player player) {
|
||||
player.closeInventory();
|
||||
MarketGUI gui = new MarketGUI(this, player);
|
||||
|
||||
InventoryGui gui = new InventoryGui(
|
||||
plugin,
|
||||
new MarketGUI(),
|
||||
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(title),
|
||||
layout
|
||||
);
|
||||
}
|
||||
|
||||
gui.setCloseAction(close -> {
|
||||
var elements = gui.getElement(itemSlot);
|
||||
@EventHandler
|
||||
public void onClickInv(InventoryClickEvent event) {
|
||||
if (event.isCancelled())
|
||||
return;
|
||||
Inventory clickedInv = event.getClickedInventory();
|
||||
if (clickedInv == null)
|
||||
return;
|
||||
HumanEntity human = event.getWhoClicked();
|
||||
if (!(clickedInv.getHolder() instanceof MarketGUIHolder holder))
|
||||
return;
|
||||
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
for (Map.Entry<Character, ItemBuilder> entry : decorativeIcons.entrySet()) {
|
||||
gui.addElement(new StaticGuiElement(
|
||||
entry.getKey(),
|
||||
((ItemManagerImpl.CFBuilder) entry.getValue()).build()
|
||||
));
|
||||
MarketGUI gui = marketGUIMap.get(human.getUniqueId());
|
||||
if (gui == null) {
|
||||
event.setCancelled(true);
|
||||
human.closeInventory();
|
||||
return;
|
||||
}
|
||||
|
||||
int slot = event.getSlot();
|
||||
MarketGUIElement element = gui.getElement(slot);
|
||||
if (element == null) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.getSymbol() == itemSlot) {
|
||||
plugin.getScheduler().runTaskSyncLater(gui::refresh, human.getLocation(), 50, TimeUnit.MILLISECONDS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.getSymbol() == functionSlot) {
|
||||
event.setCancelled(true);
|
||||
double worth = gui.getTotalWorth();
|
||||
if (worth > 0) {
|
||||
double remainingToEarn = getRemainingMoneyToEarn(human.getUniqueId());
|
||||
if (remainingToEarn < worth) {
|
||||
|
||||
} else {
|
||||
gui.clearWorthyItems();
|
||||
this.setRemainMoneyToEarn(human.getUniqueId(), remainingToEarn + worth);
|
||||
}
|
||||
}
|
||||
plugin.getScheduler().runTaskSyncLater(gui::refresh, human.getLocation(), 50, TimeUnit.MILLISECONDS);
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public double getRemainingMoneyToEarn(UUID uuid) {
|
||||
OnlineUser user = plugin.getStorageManager().getOnlineUser(uuid);
|
||||
if (user == null) {
|
||||
return -1;
|
||||
}
|
||||
return earningLimit - user.getEarningData().earnings;
|
||||
}
|
||||
|
||||
public void setRemainMoneyToEarn(UUID uuid, double remaining) {
|
||||
OnlineUser user = plugin.getStorageManager().getOnlineUser(uuid);
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
user.getEarningData().earnings = remaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,4 +195,28 @@ public class MarketManagerImpl implements MarketManager {
|
||||
.setVariable("size", size);
|
||||
return expression.evaluate();
|
||||
}
|
||||
|
||||
public char getItemSlot() {
|
||||
return itemSlot;
|
||||
}
|
||||
|
||||
public char getFunctionSlot() {
|
||||
return functionSlot;
|
||||
}
|
||||
|
||||
public String[] getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public BuildableItem getFunctionIconAllowBuilder() {
|
||||
return functionIconAllowBuilder;
|
||||
}
|
||||
|
||||
public BuildableItem getFunctionIconDenyBuilder() {
|
||||
return functionIconDenyBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ layout:
|
||||
- 'AIIIIIIIA'
|
||||
- 'AAAABAAAA'
|
||||
|
||||
# Price formula (For customfishing loots)
|
||||
# Price formula (For CustomFishing loots)
|
||||
price-formula: '{base} + {bonus} * {size}'
|
||||
|
||||
# Item price (For vanilla items & other plugin items)
|
||||
# Item price (For vanilla items & other plugin items that have CustomModelData)
|
||||
item-price:
|
||||
# Vanilla Items
|
||||
COD: 10
|
||||
@@ -22,30 +22,39 @@ item-price:
|
||||
# PAPER (CustomModelData: 999)
|
||||
PAPER:999: 5
|
||||
|
||||
# Functional icons
|
||||
# Slots to put items in
|
||||
item-slot:
|
||||
symbol: 'I'
|
||||
|
||||
# Functional icon
|
||||
functional-icons:
|
||||
symbol: 'B'
|
||||
sell-icon:
|
||||
symbol: 'B'
|
||||
material: IRON_BLOCK
|
||||
display:
|
||||
name: '<#00CED1><bold>● <bold:false>Sell the fish'
|
||||
name: '<#00CED1><b>● <!b>Ship the fish'
|
||||
lore:
|
||||
- '<font:uniform><gradient:#E6E6FA:#48D1CC:#E6E6FA>You will gain {money}$</gradient></font>'
|
||||
- '<font:uniform><gradient:#E6E6FA:#48D1CC:#E6E6FA>You will get <green>{money}$</green> by selling the fish</gradient></font>'
|
||||
action:
|
||||
message:
|
||||
sound_action:
|
||||
type: sound
|
||||
message_action:
|
||||
type: message
|
||||
text: 'You earned {money}$ from selling the fish! You can still gain {remains}$ from selling fish today'
|
||||
chance: 1.0
|
||||
value: 'You earned {money}$ by selling the fish! You can still get {remains}$ from market today'
|
||||
command_action:
|
||||
type: command
|
||||
value: 'money give {player} {money}'
|
||||
deny-icon:
|
||||
symbol: 'B'
|
||||
material: REDSTONE_BLOCK
|
||||
display:
|
||||
name: '<red><bold>● <bold:false>Denied'
|
||||
name: '<red><b>● <!b>Denied trade'
|
||||
lore:
|
||||
- '<font:uniform><gradient:#E6E6FA:red:#E6E6FA>Nothing to sell!</gradient></font>'
|
||||
item-slot:
|
||||
symbol: 'I'
|
||||
action:
|
||||
sound_action:
|
||||
type: sound
|
||||
|
||||
# Decorative icons
|
||||
decorative-icons:
|
||||
glass-pane:
|
||||
symbol: 'A'
|
||||
|
||||
Reference in New Issue
Block a user