Instantly share code, notes, and snippets.
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save Sxtanna/5ec752663c4fa8ee1d27b9a312b849bc to your computer and use it in GitHub Desktop.
Spigot Menu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.bukkit.ChatColor; | |
import org.bukkit.Material; | |
import org.bukkit.entity.Player; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.EventPriority; | |
import org.bukkit.event.HandlerList; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.inventory.InventoryClickEvent; | |
import org.bukkit.event.inventory.InventoryCloseEvent; | |
import org.bukkit.event.inventory.InventoryType; | |
import org.bukkit.inventory.Inventory; | |
import org.bukkit.inventory.InventoryHolder; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.inventory.meta.ItemMeta; | |
import org.bukkit.plugin.Plugin; | |
import org.jetbrains.annotations.Contract; | |
import org.jetbrains.annotations.NotNull; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.function.Consumer; | |
public abstract class Menu implements InventoryHolder, Listener | |
{ | |
private boolean loaded; | |
protected final Plugin plugin; | |
protected final Inventory inventory; | |
protected final Map<Integer, Consumer<InventoryClickEvent>> consumers = new HashMap<>(); | |
protected Menu(@NotNull final Plugin plugin, @NotNull final String title, @NotNull final Size size) | |
{ | |
this.plugin = plugin; | |
this.inventory = plugin.getServer().createInventory(this, (size.ordinal() + 1) * 9, color(title)); | |
} | |
@NotNull | |
@Override | |
public final Inventory getInventory() | |
{ | |
return inventory; | |
} | |
@NotNull | |
public final Map<Integer, Consumer<InventoryClickEvent>> getConsumers() | |
{ | |
return consumers; | |
} | |
private void load() | |
{ | |
if (loaded) | |
{ | |
return; | |
} | |
loaded = true; | |
plugin.getServer().getPluginManager().registerEvents(this, plugin); | |
} | |
private void kill() | |
{ | |
if (!loaded) | |
{ | |
return; | |
} | |
loaded = false; | |
HandlerList.unregisterAll(this); | |
getConsumers().clear(); | |
getInventory().clear(); | |
} | |
public final void open(@NotNull final Player player) | |
{ | |
if (!loaded) | |
{ | |
load(); | |
make(); | |
} | |
player.openInventory(getInventory()); | |
opened(player); | |
} | |
protected void make() | |
{ | |
} | |
protected void redo() | |
{ | |
consumers.clear(); | |
getInventory().clear(); | |
make(); | |
} | |
protected void opened(@NotNull final Player player) | |
{ | |
} | |
protected void closed(@NotNull final Player player) | |
{ | |
} | |
protected final void slot(final int slot, @NotNull final ItemStack item) | |
{ | |
getInventory().setItem(slot, item); | |
} | |
protected final void slot(final int slot, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
consumers.put(slot, consumer); | |
} | |
protected final void slot(final int slot, @NotNull final ItemStack item, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
slot(slot, item); | |
slot(slot, consumer); | |
} | |
protected final void grid(@NotNull final Rows row, @NotNull final Cols col, @NotNull final ItemStack item) | |
{ | |
slot(Grid.from(row, col), item); | |
} | |
protected final void grid(@NotNull final Rows row, @NotNull final Cols col, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
slot(Grid.from(row, col), consumer); | |
} | |
protected final void grid(@NotNull final Rows row, @NotNull final Cols col, @NotNull final ItemStack item, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
grid(row, col, item); | |
grid(row, col, consumer); | |
} | |
protected final void grid(@NotNull final Rows row, @NotNull final ItemStack item) | |
{ | |
for (final Cols col : Cols.COLS) | |
{ | |
final int slot = Grid.from(row, col); | |
if (slot > getInventory().getSize()) | |
{ | |
break; | |
} | |
if (getInventory().getItem(slot) != null) | |
{ | |
continue; | |
} | |
slot(slot, item); | |
} | |
} | |
protected final void grid(@NotNull final Rows row, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
for (final Cols col : Cols.COLS) | |
{ | |
final int slot = Grid.from(row, col); | |
if (slot > getInventory().getSize()) | |
{ | |
break; | |
} | |
if (consumers.containsKey(slot)) | |
{ | |
continue; | |
} | |
slot(slot, consumer); | |
} | |
} | |
protected final void grid(@NotNull final Rows row, @NotNull final ItemStack item, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
for (final Cols col : Cols.COLS) | |
{ | |
final int slot = Grid.from(row, col); | |
if (slot > getInventory().getSize()) | |
{ | |
break; | |
} | |
if (consumers.containsKey(slot) || getInventory().getItem(slot) != null) | |
{ | |
continue; | |
} | |
slot(slot, item); | |
slot(slot, consumer); | |
} | |
} | |
protected final void grid(@NotNull final Cols col, @NotNull final ItemStack item) | |
{ | |
for (final Rows row : Rows.ROWS) | |
{ | |
final int slot = Grid.from(row, col); | |
if (slot > getInventory().getSize()) | |
{ | |
break; | |
} | |
if (getInventory().getItem(slot) != null) | |
{ | |
continue; | |
} | |
slot(slot, item); | |
} | |
} | |
protected final void grid(@NotNull final Cols col, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
for (final Rows row : Rows.ROWS) | |
{ | |
final int slot = Grid.from(row, col); | |
if (slot > getInventory().getSize()) | |
{ | |
break; | |
} | |
if (consumers.containsKey(slot)) | |
{ | |
continue; | |
} | |
slot(slot, consumer); | |
} | |
} | |
protected final void grid(@NotNull final Cols col, @NotNull final ItemStack item, @NotNull final Consumer<InventoryClickEvent> consumer) | |
{ | |
for (final Rows row : Rows.ROWS) | |
{ | |
final int slot = Grid.from(row, col); | |
if (slot > getInventory().getSize()) | |
{ | |
break; | |
} | |
if (consumers.containsKey(slot) || getInventory().getItem(slot) != null) | |
{ | |
continue; | |
} | |
slot(slot, item); | |
slot(slot, consumer); | |
} | |
} | |
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) | |
public final void onClick(@NotNull final InventoryClickEvent event) | |
{ | |
if (event.getView().getTopInventory().getHolder() != this) | |
{ | |
// if we aren't the holder, do nothing | |
return; | |
} | |
if (event.getSlotType() == InventoryType.SlotType.OUTSIDE || event.getRawSlot() > getInventory().getSize()) | |
{ | |
// if they click outside of the inventory, or the slot the click isn't in this inventory, do nothing | |
return; | |
} | |
final Consumer<InventoryClickEvent> consumer = consumers.get(event.getRawSlot()); | |
if (consumer == null) | |
{ | |
// if there is no consumer for this slot, do nothing | |
return; | |
} | |
consumer.accept(event); | |
} | |
@EventHandler | |
public final void onClose(@NotNull final InventoryCloseEvent event) | |
{ | |
if (event.getView().getTopInventory().getHolder() != this) | |
{ | |
// if we aren't the holder, do nothing | |
return; | |
} | |
if (event.getPlayer() instanceof Player) | |
{ | |
closed(((Player) event.getPlayer())); | |
} | |
if (getInventory().getViewers().size() > 1) | |
{ | |
// if there is more than one player viewing this inventory, do nothing | |
return; | |
} | |
kill(); | |
} | |
@NotNull | |
public static String color(@NotNull final String text) | |
{ | |
return ChatColor.translateAlternateColorCodes('&', text); | |
} | |
@NotNull | |
public static ItemStack item(@NotNull final Material type) | |
{ | |
return item(type, 1); | |
} | |
@NotNull | |
public static ItemStack item(@NotNull final Material type, final int amount) | |
{ | |
return new ItemStack(type, amount); | |
} | |
@NotNull | |
public static ItemStack item(@NotNull final Material type, final int amount, @NotNull final Consumer<ItemMeta> consumer) | |
{ | |
return meta(item(type, amount), consumer); | |
} | |
@NotNull | |
@Contract("_, _ -> param1") | |
public static ItemStack meta(@NotNull final ItemStack item, @NotNull final Consumer<ItemMeta> consumer) | |
{ | |
final ItemMeta meta = item.getItemMeta(); | |
consumer.accept(meta); | |
item.setItemMeta(meta); | |
return item; | |
} | |
public enum Size | |
{ | |
ROWS_1, | |
ROWS_2, | |
ROWS_3, | |
ROWS_4, | |
ROWS_5, | |
ROWS_6, | |
} | |
/** | |
* C_1 C_2 C_3 C_4 C_5 C_6 C_7 C_8 C_9 | |
* ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗ | |
* R_1║ 0║ 1║ 2║ 3║ 4║ 5║ 6║ 7║ 8║ | |
* ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ | |
* R_2║ 9║ 10║ 11║ 12║ 13║ 14║ 15║ 16║ 17║ | |
* ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ | |
* R_3║ 18║ 19║ 20║ 21║ 22║ 23║ 24║ 25║ 26║ | |
* ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ | |
* R_4║ 27║ 28║ 29║ 30║ 31║ 32║ 33║ 34║ 35║ | |
* ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ | |
* R_5║ 36║ 37║ 38║ 39║ 40║ 41║ 42║ 43║ 44║ | |
* ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣ | |
* R_6║ 45║ 46║ 47║ 48║ 49║ 50║ 51║ 52║ 53║ | |
* ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝ | |
*/ | |
public enum Grid | |
{ | |
; | |
public static int from(@NotNull final Rows row, @NotNull final Cols col) | |
{ | |
return (row.ordinal() * 9) + col.ordinal(); | |
} | |
@NotNull | |
@Contract(value = "_ -> new", pure = true) | |
public static RaC into(final int slot) | |
{ | |
final int row = slot / 9; | |
final int col = slot - row * 9; | |
return new RaC(Rows.ROWS[row], Cols.COLS[col]); | |
} | |
public static final class RaC | |
{ | |
public final Rows row; | |
public final Cols col; | |
private RaC(final Rows row, final Cols col) | |
{ | |
this.row = row; | |
this.col = col; | |
} | |
} | |
} | |
public enum Rows | |
{ | |
R_1, | |
R_2, | |
R_3, | |
R_4, | |
R_5, | |
R_6; | |
public static final Rows[] ROWS = values(); | |
} | |
public enum Cols | |
{ | |
C_1, | |
C_2, | |
C_3, | |
C_4, | |
C_5, | |
C_6, | |
C_7, | |
C_8, | |
C_9; | |
public static final Cols[] COLS = values(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment