Вопрос Не выбирается предмет в гуи

Версия Minecraft
1.20.X

paingocry

Пользователь
Сообщения
46
Решения
1
Веб-сайт
paingocry.tb.ru
Я понятия не имею почему, но при открытом гуи игрок не может выбрать броню для перекраски, вся логика уже прописана и работает

Код:
public class GuiManager implements Listener, CommandExecutor {

    private final Main plugin;

    private static final String GUI_TITLE = Util.color("&0Покраска предмета");

    private static final int SLOT_CURRENT = 10;
    private static final int SLOT_NEW     = 19;
    private static final int SLOT_ACTION  = 41;
    private static final int SLOT_CANCEL  = 39;

    private static final int[] PALETTE_SLOTS = {12, 13, 14, 15, 16, 21, 22, 23, 24, 25};

    private final Map<UUID, Session> sessions = new HashMap<>();

    public GuiManager(Main plugin) {
        this.plugin = plugin;
    }

    private static final List<ColorChoice> COLORS = Arrays.asList(
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)14), Color.RED, "§4Красная краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)5), Color.LIME, "§aЗеленая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)11), Color.AQUA, "§bСиняя краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)4), Color.YELLOW, "§eЖелтая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)1), Color.ORANGE, "§6Оранжевая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)10), Color.PURPLE, "§5Фиолетовая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)6), Color.FUCHSIA, "§cРозовая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)12), Color.fromRGB(102, 51, 0), "§7Коричневая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)0), Color.WHITE, "§fБелая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)15), Color.BLACK, "§8Черная краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false)
    );
    
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("Эта команда доступна только игрокам!");
            return true;
        }
        Player player = (Player) sender;
        openGui(player);
        return true;
    }

    private void openGui(Player p) {
        Inventory inv = Bukkit.createInventory(p, 54, GUI_TITLE);

        inv.setItem(SLOT_CURRENT, Util.namedPane((short)7, "&8Слот текущего состояния предмета"));
        inv.setItem(SLOT_NEW, Util.namedPane((short)7, "&8Слот нового состояния предмета"));
        inv.setItem(SLOT_CANCEL, Util.namedConcrete((short)14, "&cОтмена"));
        inv.setItem(SLOT_ACTION, Util.namedConcrete((short)7, "&7Покраска не возможна"));

        for (int i = 0; i < COLORS.size() && i < PALETTE_SLOTS.length; i++) {
            inv.setItem(PALETTE_SLOTS[i], COLORS.get(i).icon);
        }

        sessions.put(p.getUniqueId(), new Session());
        p.openInventory(inv);
    }

    @EventHandler
    public void onClick(InventoryClickEvent e) {
        if (!(e.getWhoClicked() instanceof Player)) return;
        Player p = (Player) e.getWhoClicked();
        if (!GUI_TITLE.equals(e.getView().getTitle())) return;

        e.setCancelled(true);

        Session s = sessions.get(p.getUniqueId());
        if (s == null) return;

        Inventory clickedInv = e.getClickedInventory();
        ItemStack clicked = e.getCurrentItem();

        if (clickedInv != null && clickedInv.equals(e.getView().getBottomInventory())) {
            if (clicked != null && isLeatherArmor(clicked) && s.current == null) {
                s.current = clicked.clone();
                s.current.setAmount(1);

                e.getView().getTopInventory().setItem(SLOT_CURRENT, s.current);

                ItemStack toRemove = clicked.clone();
                toRemove.setAmount(1);
                p.getInventory().removeItem(toRemove);

                p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1.2f);
            }
            return;
        }

        int slot = e.getRawSlot();

        if (slot == SLOT_CANCEL) {
            if (s.current != null) giveOrDrop(p, s.current);
            p.closeInventory();
            sessions.remove(p.getUniqueId());
            return;
        }

        if (slot == SLOT_CURRENT && s.current != null) {
            giveOrDrop(p, s.current);
            e.getView().getTopInventory().setItem(SLOT_CURRENT, Util.namedPane((short)7, "&8Слот текущего состояния предмета"));
            e.getView().getTopInventory().setItem(SLOT_NEW, Util.namedPane((short)7, "&8Слот нового состояния предмета"));
            e.getView().getTopInventory().setItem(SLOT_ACTION, Util.namedConcrete((short)7, "&7Покраска невозможна"));
            s.current = null;
            s.chosenColor = null;
            s.additive = false;
            return;
        }

        for (int i = 0; i < PALETTE_SLOTS.length && i < COLORS.size(); i++) {
            if (slot == PALETTE_SLOTS[i] && s.current != null) {
                ColorChoice choice = COLORS.get(i);
                s.chosenColor = choice.color;
                s.additive = choice.additive;

                ItemStack preview = s.current.clone();
                LeatherArmorMeta meta = (LeatherArmorMeta) preview.getItemMeta();
                if (s.additive) meta.setColor(additiveColor(meta.getColor(), choice.color));
                else meta.setColor(choice.color);
                preview.setItemMeta(meta);

                e.getView().getTopInventory().setItem(SLOT_NEW, preview);
                e.getView().getTopInventory().setItem(SLOT_ACTION, Util.namedConcrete((short)5, "&aПокрасить предмет"));
                p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1.6f);
                return;
            }
        }

        if (slot == SLOT_ACTION && s.current != null && s.chosenColor != null) {
            ItemStack newItem = s.current.clone();
            paintLeather(newItem, s.chosenColor, s.additive);

            giveOrDrop(p, newItem);
            p.sendMessage(Util.color("&aДоспехи окрашены"));
            p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1.8f);

            s.current = null;
            s.chosenColor = null;
            s.additive = false;
            p.closeInventory();
            sessions.remove(p.getUniqueId());
        }
    }

    @EventHandler
    public void onDrag(InventoryDragEvent e) {
        if (GUI_TITLE.equals(e.getView().getTitle())) e.setCancelled(true);
    }

    @EventHandler
    public void onClose(InventoryCloseEvent e) {
        sessions.remove(e.getPlayer().getUniqueId());
    }

    private boolean isLeatherArmor(ItemStack it) {
        if (it == null) return false;
        Material m = it.getType();
        return m == Material.LEATHER_HELMET || m == Material.LEATHER_CHESTPLATE
                || m == Material.LEATHER_LEGGINGS || m == Material.LEATHER_BOOTS;
    }

    private void paintLeather(ItemStack stack, Color c, boolean additive) {
        if (!isLeatherArmor(stack)) return;
        LeatherArmorMeta meta = (LeatherArmorMeta) stack.getItemMeta();
        if (additive) meta.setColor(additiveColor(meta.getColor(), c));
        else meta.setColor(c);
        stack.setItemMeta(meta);
    }

    private Color additiveColor(Color original, Color added) {
        int r = Math.min(255, (int)(original.getRed() + added.getRed() * 0.15));
        int g = Math.min(255, (int)(original.getGreen() + added.getGreen() * 0.15));
        int b = Math.min(255, (int)(original.getBlue() + added.getBlue() * 0.15));
        return Color.fromRGB(r, g, b);
    }

    private void giveOrDrop(Player p, ItemStack item) {
        HashMap<Integer, ItemStack> left = p.getInventory().addItem(item);
        for (ItemStack rem : left.values()) p.getWorld().dropItemNaturally(p.getLocation(), rem);
    }

    private static class Session {
        ItemStack current = null;
        Color chosenColor = null;
        boolean additive = false;
    }

    private static class ColorChoice {
        final ItemStack icon;
        final Color color;
        final String name;
        final List<String> lore;
        final boolean additive;

        ColorChoice(ItemStack icon, Color color, String name, List<String> lore, boolean additive) {
            this.icon = Util.named(icon, name, lore);
            this.color = color;
            this.name = name;
            this.lore = lore;
            this.additive = additive;
        }
    }
}

Прошу вас помочь!
 
Мне кажется или это гпт код? Вложенные статические классы внутри класса, это его паттерн
Скорее всего так и есть)

А автору советую поучиться использовать режим отладки. Очень полезная штука, кстати. Поставил точку останова и пошагово смотришь как выполняется код и с какими наборами данных)
 
Я понятия не имею почему, но при открытом гуи игрок не может выбрать броню для перекраски, вся логика уже прописана и работает

Код:
public class GuiManager implements Listener, CommandExecutor {

    private final Main plugin;

    private static final String GUI_TITLE = Util.color("&0Покраска предмета");

    private static final int SLOT_CURRENT = 10;
    private static final int SLOT_NEW     = 19;
    private static final int SLOT_ACTION  = 41;
    private static final int SLOT_CANCEL  = 39;

    private static final int[] PALETTE_SLOTS = {12, 13, 14, 15, 16, 21, 22, 23, 24, 25};

    private final Map<UUID, Session> sessions = new HashMap<>();

    public GuiManager(Main plugin) {
        this.plugin = plugin;
    }

    private static final List<ColorChoice> COLORS = Arrays.asList(
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)14), Color.RED, "§4Красная краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)5), Color.LIME, "§aЗеленая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)11), Color.AQUA, "§bСиняя краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)4), Color.YELLOW, "§eЖелтая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)1), Color.ORANGE, "§6Оранжевая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)10), Color.PURPLE, "§5Фиолетовая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)6), Color.FUCHSIA, "§cРозовая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)12), Color.fromRGB(102, 51, 0), "§7Коричневая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)0), Color.WHITE, "§fБелая краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false),
            new ColorChoice(ru.paingocry.msopaint.Util.glass((short)15), Color.BLACK, "§8Черная краска", Arrays.asList("§7Окрасит предмет в этот цвет.", "§e  §e", "§eНажмите, чтобы окрасить!"), false)
    );
   
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("Эта команда доступна только игрокам!");
            return true;
        }
        Player player = (Player) sender;
        openGui(player);
        return true;
    }

    private void openGui(Player p) {
        Inventory inv = Bukkit.createInventory(p, 54, GUI_TITLE);

        inv.setItem(SLOT_CURRENT, Util.namedPane((short)7, "&8Слот текущего состояния предмета"));
        inv.setItem(SLOT_NEW, Util.namedPane((short)7, "&8Слот нового состояния предмета"));
        inv.setItem(SLOT_CANCEL, Util.namedConcrete((short)14, "&cОтмена"));
        inv.setItem(SLOT_ACTION, Util.namedConcrete((short)7, "&7Покраска не возможна"));

        for (int i = 0; i < COLORS.size() && i < PALETTE_SLOTS.length; i++) {
            inv.setItem(PALETTE_SLOTS[i], COLORS.get(i).icon);
        }

        sessions.put(p.getUniqueId(), new Session());
        p.openInventory(inv);
    }

    @EventHandler
    public void onClick(InventoryClickEvent e) {
        if (!(e.getWhoClicked() instanceof Player)) return;
        Player p = (Player) e.getWhoClicked();
        if (!GUI_TITLE.equals(e.getView().getTitle())) return;

        e.setCancelled(true);

        Session s = sessions.get(p.getUniqueId());
        if (s == null) return;

        Inventory clickedInv = e.getClickedInventory();
        ItemStack clicked = e.getCurrentItem();

        if (clickedInv != null && clickedInv.equals(e.getView().getBottomInventory())) {
            if (clicked != null && isLeatherArmor(clicked) && s.current == null) {
                s.current = clicked.clone();
                s.current.setAmount(1);

                e.getView().getTopInventory().setItem(SLOT_CURRENT, s.current);

                ItemStack toRemove = clicked.clone();
                toRemove.setAmount(1);
                p.getInventory().removeItem(toRemove);

                p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1.2f);
            }
            return;
        }

        int slot = e.getRawSlot();

        if (slot == SLOT_CANCEL) {
            if (s.current != null) giveOrDrop(p, s.current);
            p.closeInventory();
            sessions.remove(p.getUniqueId());
            return;
        }

        if (slot == SLOT_CURRENT && s.current != null) {
            giveOrDrop(p, s.current);
            e.getView().getTopInventory().setItem(SLOT_CURRENT, Util.namedPane((short)7, "&8Слот текущего состояния предмета"));
            e.getView().getTopInventory().setItem(SLOT_NEW, Util.namedPane((short)7, "&8Слот нового состояния предмета"));
            e.getView().getTopInventory().setItem(SLOT_ACTION, Util.namedConcrete((short)7, "&7Покраска невозможна"));
            s.current = null;
            s.chosenColor = null;
            s.additive = false;
            return;
        }

        for (int i = 0; i < PALETTE_SLOTS.length && i < COLORS.size(); i++) {
            if (slot == PALETTE_SLOTS[i] && s.current != null) {
                ColorChoice choice = COLORS.get(i);
                s.chosenColor = choice.color;
                s.additive = choice.additive;

                ItemStack preview = s.current.clone();
                LeatherArmorMeta meta = (LeatherArmorMeta) preview.getItemMeta();
                if (s.additive) meta.setColor(additiveColor(meta.getColor(), choice.color));
                else meta.setColor(choice.color);
                preview.setItemMeta(meta);

                e.getView().getTopInventory().setItem(SLOT_NEW, preview);
                e.getView().getTopInventory().setItem(SLOT_ACTION, Util.namedConcrete((short)5, "&aПокрасить предмет"));
                p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1f, 1.6f);
                return;
            }
        }

        if (slot == SLOT_ACTION && s.current != null && s.chosenColor != null) {
            ItemStack newItem = s.current.clone();
            paintLeather(newItem, s.chosenColor, s.additive);

            giveOrDrop(p, newItem);
            p.sendMessage(Util.color("&aДоспехи окрашены"));
            p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1.8f);

            s.current = null;
            s.chosenColor = null;
            s.additive = false;
            p.closeInventory();
            sessions.remove(p.getUniqueId());
        }
    }

    @EventHandler
    public void onDrag(InventoryDragEvent e) {
        if (GUI_TITLE.equals(e.getView().getTitle())) e.setCancelled(true);
    }

    @EventHandler
    public void onClose(InventoryCloseEvent e) {
        sessions.remove(e.getPlayer().getUniqueId());
    }

    private boolean isLeatherArmor(ItemStack it) {
        if (it == null) return false;
        Material m = it.getType();
        return m == Material.LEATHER_HELMET || m == Material.LEATHER_CHESTPLATE
                || m == Material.LEATHER_LEGGINGS || m == Material.LEATHER_BOOTS;
    }

    private void paintLeather(ItemStack stack, Color c, boolean additive) {
        if (!isLeatherArmor(stack)) return;
        LeatherArmorMeta meta = (LeatherArmorMeta) stack.getItemMeta();
        if (additive) meta.setColor(additiveColor(meta.getColor(), c));
        else meta.setColor(c);
        stack.setItemMeta(meta);
    }

    private Color additiveColor(Color original, Color added) {
        int r = Math.min(255, (int)(original.getRed() + added.getRed() * 0.15));
        int g = Math.min(255, (int)(original.getGreen() + added.getGreen() * 0.15));
        int b = Math.min(255, (int)(original.getBlue() + added.getBlue() * 0.15));
        return Color.fromRGB(r, g, b);
    }

    private void giveOrDrop(Player p, ItemStack item) {
        HashMap<Integer, ItemStack> left = p.getInventory().addItem(item);
        for (ItemStack rem : left.values()) p.getWorld().dropItemNaturally(p.getLocation(), rem);
    }

    private static class Session {
        ItemStack current = null;
        Color chosenColor = null;
        boolean additive = false;
    }

    private static class ColorChoice {
        final ItemStack icon;
        final Color color;
        final String name;
        final List<String> lore;
        final boolean additive;

        ColorChoice(ItemStack icon, Color color, String name, List<String> lore, boolean additive) {
            this.icon = Util.named(icon, name, lore);
            this.color = color;
            this.name = name;
            this.lore = lore;
            this.additive = additive;
        }
    }
}

Прошу вас помочь!
Менеджер не должен заниматься двумя вещами сразу, он не должен слушать ивенты и слушать команду.
 
Назад
Сверху Снизу