package tc.oc.pgm.observers; import com.google.common.collect.Lists; import java.util.List; import net.kyori.text.Component; import net.kyori.text.TranslatableComponent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import tc.oc.pgm.api.match.Match; import tc.oc.pgm.api.match.MatchModule; import tc.oc.pgm.api.match.MatchScope; import tc.oc.pgm.api.match.factory.MatchModuleFactory; import tc.oc.pgm.api.module.exception.ModuleLoadException; import tc.oc.pgm.api.player.MatchPlayer; import tc.oc.pgm.events.ListenerScope; import tc.oc.pgm.menu.InventoryMenu; import tc.oc.pgm.menu.InventoryMenuItem; import tc.oc.pgm.observers.tools.FlySpeedTool; import tc.oc.pgm.observers.tools.GamemodeTool; import tc.oc.pgm.observers.tools.NightVisionTool; import tc.oc.pgm.observers.tools.VisibilityTool; import tc.oc.pgm.spawns.events.ObserverKitApplyEvent; import tc.oc.pgm.util.text.TextTranslations; @ListenerScope(MatchScope.LOADED) public class ObserverToolsMatchModule implements MatchModule, Listener { public static class Factory implements MatchModuleFactory<ObserverToolsMatchModule> { @Override public ObserverToolsMatchModule createMatchModule(Match match) throws ModuleLoadException { return new ObserverToolsMatchModule(match); } } // Slot where tool item is placed public static final int TOOL_BUTTON_SLOT = 8; // Material of tool item item public static final Material TOOL_MATERIAL = Material.DIAMOND; private final Match match; private ObserverToolMenu menu; public ObserverToolsMatchModule(Match match) { this.match = match; this.menu = new ObserverToolMenu(); } @EventHandler public void onObserverKitApply(ObserverKitApplyEvent event) { refreshKit(event.getPlayer()); } @EventHandler public void onToolClick(PlayerInteractEvent event) { if (isRightClick(event.getAction())) { ItemStack item = event.getPlayer().getItemInHand(); if (item.getType().equals(TOOL_MATERIAL)) { MatchPlayer player = match.getPlayer(event.getPlayer()); openMenu(player); } } } @EventHandler(priority = EventPriority.LOWEST) public void onInventoryClick(final InventoryClickEvent event) { if (event.getCurrentItem() == null || event.getCurrentItem().getItemMeta() == null || event.getCurrentItem().getItemMeta().getDisplayName() == null) return; if (event.getWhoClicked() instanceof Player) { MatchPlayer player = match.getPlayer(event.getWhoClicked()); if (menu.isViewing(player)) { ItemStack clicked = event.getCurrentItem(); menu.getTools() .forEach( tool -> { if (clicked.getType().equals(tool.getMaterial(player))) { tool.onInventoryClick(menu, player, event.getClick()); } }); } } } @EventHandler public void onInventoryClose(final InventoryCloseEvent event) { // Remove viewing of menu upon inventory close menu.remove(match.getPlayer((Player) event.getPlayer())); } public void openMenu(MatchPlayer player) { if (canUse(player)) { menu.display(player); } } private boolean canUse(MatchPlayer player) { return player.isObserving(); } private void refreshKit(MatchPlayer player) { if (canUse(player)) { player.getInventory().setItem(TOOL_BUTTON_SLOT, createToolItem(player)); } } private boolean isRightClick(Action action) { return action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK; } private ItemStack createToolItem(MatchPlayer player) { ItemStack tool = new ItemStack(TOOL_MATERIAL); ItemMeta meta = tool.getItemMeta(); Component displayName = TranslatableComponent.of("setting.displayName", TextColor.AQUA, TextDecoration.BOLD); Component lore = TranslatableComponent.of("setting.lore", TextColor.GRAY); meta.setDisplayName(TextTranslations.translateLegacy(displayName, player.getBukkit())); meta.setLore(Lists.newArrayList(TextTranslations.translateLegacy(lore, player.getBukkit()))); meta.addItemFlags(ItemFlag.values()); tool.setItemMeta(meta); return tool; } public class ObserverToolMenu extends InventoryMenu { public static final String INVENTORY_TITLE = "setting.title"; public static final int INVENTORY_ROWS = 1; private List<InventoryMenuItem> tools; public ObserverToolMenu() { super(INVENTORY_TITLE, INVENTORY_ROWS); registerTools(); } public List<InventoryMenuItem> getTools() { return tools; } // Register each of the observer tools // TODO?: Add config options to enable/disable each tool private void registerTools() { this.tools = Lists.newArrayList(); this.tools.add(new FlySpeedTool()); this.tools.add(new NightVisionTool()); this.tools.add(new VisibilityTool()); this.tools.add(new GamemodeTool()); } @Override public String getTranslatedTitle(MatchPlayer player) { return ChatColor.AQUA + super.getTranslatedTitle(player); } @Override public ItemStack[] createWindowContents(MatchPlayer player) { List<ItemStack> items = Lists.newArrayList(); items.add(null); for (InventoryMenuItem tool : tools) { items.add(tool.createItem(player)); if (items.size() < ROW_WIDTH - 1) { items.add(null); } } return items.toArray(new ItemStack[items.size()]); } } }