diff --git a/src/main/java/com/slampvp/factory/FactoryServer.java b/src/main/java/com/slampvp/factory/FactoryServer.java index 7c612d2..d159e3a 100644 --- a/src/main/java/com/slampvp/factory/FactoryServer.java +++ b/src/main/java/com/slampvp/factory/FactoryServer.java @@ -1,6 +1,7 @@ package com.slampvp.factory; import com.slampvp.factory.command.FactoryCommand; +import com.slampvp.factory.common.menu.MenuListener; import com.slampvp.factory.database.DatabaseManager; import com.slampvp.factory.player.PlayerListener; import com.slampvp.factory.plot.PlotGenerator; @@ -41,6 +42,7 @@ public static void main(String[] args) { instanceContainer.setTimeRate(0); new PlayerListener(instanceContainer); + new MenuListener(); PlotManager.getInstance().init(); DatabaseManager.getInstance().init(); diff --git a/src/main/java/com/slampvp/factory/command/generic/gamemode/Menu.java b/src/main/java/com/slampvp/factory/command/generic/gamemode/Menu.java new file mode 100644 index 0000000..346bae2 --- /dev/null +++ b/src/main/java/com/slampvp/factory/command/generic/gamemode/Menu.java @@ -0,0 +1,24 @@ +package com.slampvp.factory.command.generic.gamemode; + +import com.slampvp.factory.command.Command; +import com.slampvp.factory.command.FactoryCommand; +import com.slampvp.factory.common.menu.TestMenu; +import com.slampvp.factory.player.Rank; +import net.minestom.server.entity.GameMode; +import net.minestom.server.entity.Player; + +@Command(description = "Open menu.", usage = "/menu", minimumRank = Rank.ADMIN, playerOnly = true) +public class Menu extends FactoryCommand { + public Menu() { + super("menu"); + } + + @Override + public void init() { + addSyntax((sender, context) -> { + Player player = (Player) sender; + + new TestMenu().open(player); + }); + } +} diff --git a/src/main/java/com/slampvp/factory/common/menu/Menu.java b/src/main/java/com/slampvp/factory/common/menu/Menu.java new file mode 100644 index 0000000..4456223 --- /dev/null +++ b/src/main/java/com/slampvp/factory/common/menu/Menu.java @@ -0,0 +1,46 @@ +package com.slampvp.factory.common.menu; + +import net.kyori.adventure.text.TextComponent; +import net.minestom.server.entity.Player; +import net.minestom.server.event.inventory.InventoryCloseEvent; +import net.minestom.server.event.inventory.InventoryOpenEvent; +import net.minestom.server.inventory.Inventory; +import net.minestom.server.inventory.InventoryType; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Optional; + +public interface Menu { + @NotNull + TextComponent name(); + + @NotNull + InventoryType type(); + + @NotNull + List items(); + + default Optional itemBySlot(int slot) { + return items().stream() + .filter(menuItem -> menuItem.slots().contains(slot)) + .findFirst(); + } + + default void open(Player player) { + MenuManager.getInstance().setOpenMenu(player, this); + + Inventory inventory = new Inventory(type(), name()); + + items().forEach(menuItem -> menuItem.slots().forEach(slot -> inventory.setItemStack(slot, menuItem.itemStack()))); + + player.openInventory(inventory); + } + + default void onOpen(InventoryOpenEvent event) { + } + + default void onClose(InventoryCloseEvent event) { + } + +} diff --git a/src/main/java/com/slampvp/factory/common/menu/MenuItem.java b/src/main/java/com/slampvp/factory/common/menu/MenuItem.java new file mode 100644 index 0000000..0000eb7 --- /dev/null +++ b/src/main/java/com/slampvp/factory/common/menu/MenuItem.java @@ -0,0 +1,27 @@ +package com.slampvp.factory.common.menu; + +import net.minestom.server.event.inventory.InventoryPreClickEvent; +import net.minestom.server.item.ItemStack; + +import java.util.List; + +public interface MenuItem { + + List slots(); + + ItemStack itemStack(); + + default ClickAction action() { + return new ClickAction() { + }; + } + + interface ClickAction { + default boolean canEquip() { + return false; + } + + default void onClick(InventoryPreClickEvent event) { + } + } +} diff --git a/src/main/java/com/slampvp/factory/common/menu/MenuListener.java b/src/main/java/com/slampvp/factory/common/menu/MenuListener.java new file mode 100644 index 0000000..cab6e4e --- /dev/null +++ b/src/main/java/com/slampvp/factory/common/menu/MenuListener.java @@ -0,0 +1,66 @@ +package com.slampvp.factory.common.menu; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.entity.Player; +import net.minestom.server.event.GlobalEventHandler; +import net.minestom.server.event.inventory.InventoryCloseEvent; +import net.minestom.server.event.inventory.InventoryOpenEvent; +import net.minestom.server.event.inventory.InventoryPreClickEvent; + +import java.util.Optional; + +public class MenuListener { + public MenuListener() { + GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler(); + + globalEventHandler.addListener(InventoryPreClickEvent.class, event -> { + Player player = event.getPlayer(); + Optional optionalMenu = MenuManager.getInstance().getOpenMenu(player); + + if (optionalMenu.isEmpty()) { + return; + } + + Menu menu = optionalMenu.get(); + int slot = event.getSlot(); + + Optional optionalMenuItem = menu.itemBySlot(slot); + + if (optionalMenuItem.isEmpty()) { + return; + } + + MenuItem item = optionalMenuItem.get(); + + if (!item.action().canEquip()) { + event.setCancelled(true); + } + + item.action().onClick(event); + }); + + globalEventHandler.addListener(InventoryOpenEvent.class, event -> { + Player player = event.getPlayer(); + Optional optionalMenu = MenuManager.getInstance().getOpenMenu(player); + + if (optionalMenu.isEmpty()) { + return; + } + + Menu menu = optionalMenu.get(); + menu.onOpen(event); + }); + + globalEventHandler.addListener(InventoryCloseEvent.class, event -> { + Player player = event.getPlayer(); + Optional optionalMenu = MenuManager.getInstance().getOpenMenu(player); + + if (optionalMenu.isEmpty()) { + return; + } + + Menu menu = optionalMenu.get(); + menu.onClose(event); + }); + } +} diff --git a/src/main/java/com/slampvp/factory/common/menu/MenuManager.java b/src/main/java/com/slampvp/factory/common/menu/MenuManager.java new file mode 100644 index 0000000..0e8de9c --- /dev/null +++ b/src/main/java/com/slampvp/factory/common/menu/MenuManager.java @@ -0,0 +1,36 @@ +package com.slampvp.factory.common.menu; + +import net.minestom.server.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +public final class MenuManager { + private static MenuManager instance; + private final Map openMenus; + + private MenuManager() { + this.openMenus = new HashMap<>(); + } + + public static synchronized MenuManager getInstance() { + if (instance == null) { + instance = new MenuManager(); + } + return instance; + } + + public Optional getOpenMenu(Player player) { + return Optional.ofNullable(openMenus.get(player.getUuid())); + } + + public void setOpenMenu(Player player, Menu menu) { + openMenus.put(player.getUuid(), menu); + } + + public void clearOpenMenu(Player player) { + openMenus.remove(player.getUuid()); + } +} diff --git a/src/main/java/com/slampvp/factory/common/menu/TestMenu.java b/src/main/java/com/slampvp/factory/common/menu/TestMenu.java new file mode 100644 index 0000000..79a6f4d --- /dev/null +++ b/src/main/java/com/slampvp/factory/common/menu/TestMenu.java @@ -0,0 +1,64 @@ +package com.slampvp.factory.common.menu; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.minestom.server.event.inventory.InventoryCloseEvent; +import net.minestom.server.event.inventory.InventoryOpenEvent; +import net.minestom.server.event.inventory.InventoryPreClickEvent; +import net.minestom.server.inventory.InventoryType; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class TestMenu implements Menu { + @Override + public @NotNull TextComponent name() { + return Component.text("test"); + } + + @Override + public @NotNull InventoryType type() { + return InventoryType.CHEST_4_ROW; + } + + @Override + public void onOpen(InventoryOpenEvent event) { + event.getPlayer().sendMessage("open"); + } + + @Override + public void onClose(InventoryCloseEvent event) { + event.getPlayer().sendMessage("close"); + } + + @Override + public @NotNull List items() { + return List.of( + new MenuItem() { + @Override + public List slots() { + return IntStream.range(0,9).boxed().toList(); + } + + @Override + public ItemStack itemStack() { + return ItemStack.of(Material.ACACIA_BOAT); + } + + @Override + public ClickAction action() { + return new ClickAction() { + @Override + public void onClick(InventoryPreClickEvent event) { + System.out.println("click"); + } + }; + } + } + ); + } +} diff --git a/src/main/java/com/slampvp/factory/player/PlayerListener.java b/src/main/java/com/slampvp/factory/player/PlayerListener.java index ea53210..c1d1a76 100644 --- a/src/main/java/com/slampvp/factory/player/PlayerListener.java +++ b/src/main/java/com/slampvp/factory/player/PlayerListener.java @@ -11,7 +11,6 @@ import net.minestom.server.instance.InstanceContainer; public class PlayerListener { - public PlayerListener(InstanceContainer instanceContainer) { GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();