1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Реализация обработки ЛКМ и ПКМ в инвентаре

Тема в разделе "Разработка плагинов для новичков", создана пользователем niheev, 7 фев 2024.

  1. Автор темы
    niheev

    niheev Активный участник Пользователь

    Баллы:
    61
    Имя в Minecraft:
    slivachuu
    Приветствую! Хотел реализовать для каждого добавляемого предмета в инвентарь функцию на ЛКМ и ПКМ.

    А-ля, menu.addItems(itemStack, leftClick(собственный передаваемый аргумент в цикле), rightClick(собственный передаваемый аргумент в цикле).

    Буду рад, и безумно благодарен любому примеру реализации данного функционала. Заранее спасибо!

     
  2. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    Код:
    public class ButtonsHandler {
    
      private Runnable leftClick;
      private Runnable rightClick;
    
      public ButtonsHandler onLeftClick(Runnable leftClick) {
        this.leftClick = leftClick;
        return this;
      }
    
      public ButtonsHandler onRightClick(Runnable rightClick) {
        this.rightClick = rightClick;
        return this;
      }
    
      // other variants with shift ...
    
      public void executeLeftClick() {
        if (leftClick != null)
            leftClick.run();
      }
    
      public void executeRightClick() {
        if (rightClick != null)
            rightClick.run();
      }
    
    }
    Код:
    // Item slot number <-> bounded actions
    private final HashMap<Integer, ButtonsHandler> buttonsHandlers = new HashMap<>();
    
    public void setItem(int slot, ItemStack item, ButtonsHandler handler) {
        // ...
        buttonsHandlers.put(slot, handler);
    }
    
    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        // ...
        final ButtonsHandler handler = buttonsHandlers.get(event.getRawSlot());
        if (handler == null) return;
    
        if (event.isLeftClick()) {
            handler.executeLeftClick();
            return;
        }
    
        if (event.isRightClick()) {
            handler.executeRightClick();
            return;
        }
    }
    Ну раз любому, то пжалста ¯\_(ツ)_/¯
     
    Последнее редактирование: 8 фев 2024
  3. OJIEKCAHDP

    OJIEKCAHDP Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    OJIEKCAHDP
    Что за дичь? Уже давно придумали InventoryHolder, ТС на правильном пути. В этом случае, при нажатии на слот будет срабатывать в ЛЮБОМ инвентаре.

    Из решений:
    Для своего инвентаря создай класс и унаследуйся от InventoryHolder
    В этом классе сделай методы для обработки события с ПКМ\ЛКМ.
    Так-же сделай мапу, которая принимает в себе слот и Consumer, её заполняй когда добавляешь предметы в инвентарь.
    При клике из этой мапы ищи консумер по слоту, если такой есть, значит выполняй его.
     
  4. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    При чем тут "будет срабатывать в любом инвентаре"? У меня не было цели показать, как правильно обрабатывать ивент и как отличать инвентари. Ну а имплементировать InventoryHolder не лучшая практика.
     
    Последнее редактирование: 8 фев 2024
  5. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Сразу видно нуба в java
     
  6. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    Единственное, что видно сразу – неспособность в конструктивную критику.
     
  7. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Как скажешь.
     
  8. Karamazik

    Karamazik Новичок

    Баллы:
    6
    Имя в Minecraft:
    Karamazik
    Класс меню

    Код:
    public class Menu  {
    
        public static List<Menu> menus = new ArrayList<>();
        @Getter
        private Consumer<Menu> onClose;
    
    
        public static Menu getMenuOf(Player player){
            for(Menu menu: menus){
                if (menu.viewers.contains(player)) {
                    return menu;
                }
            }
            return null;
        }
    
        @Getter
        private int size;
        @Getter
        private final  String name;
        @Getter
        private  final Inventory inventory;
    
        private final List<Button> buttons = new ArrayList<>();
        private final  List<Player>viewers = new ArrayList<>();
    
    
    
        public Menu(int size, String name) {
            this.size = size;
            this.name = name;
    
            inventory = Bukkit.createInventory(null, size, Util.colored(name));
            menus.add(this);
        }
    
    
        public  void openMenu(Player player){
            player.openInventory(inventory);
            viewers.add(player);
        }
    
        public void onClose(Player player){
            viewers.remove(player);
        }
    
        public void addButton(Button button){
            buttons.add(button);
            inventory.setItem(button.getSlot(),button.getItemStack());
        }
        public void refreshInventory(Player viewer) {
            if(viewers.contains(viewer)){
                viewer.getOpenInventory().getTopInventory().setContents(inventory.getContents());
            }
    
    
        }
    
        public void setOnClose(Consumer<Menu> onClose) {
            this.onClose = onClose;
        }
    
        public Button getButtonIn(int slot){
            for(Button button: buttons){
                if(button.getSlot()==slot){
                    return button;
                }
            }
            return null;
        }
    
    
    }
    


    Класс кнопки

    Код:
    public abstract class Button {
    
        @Getter
        private  final int slot;
    
        @Getter
        private final ItemStack itemStack;
    
        public Button(int slot, ItemStack itemStack) {
            this.slot = slot;
            this.itemStack = itemStack;
        }
    
        public abstract void onClick(Player player, int slot, ClickType clickType);
    
    }

    Обработчик



    Код:
    public class GuiEvents implements Listener {
    
        @EventHandler
        public void onClick(InventoryClickEvent event){
            Menu menu = Menu.getMenuOf((Player) event.getWhoClicked());
            if(menu!=null){
                Button button = menu.getButtonIn(event.getSlot());
    
                if(button!=null){
                    button.onClick(((Player) event.getWhoClicked()),event.getSlot(),event.getClick());
                    event.setCancelled(true);
                }
            }
        }
    
        @EventHandler
        public void onClose(InventoryCloseEvent event){
            Menu menu = Menu.getMenuOf((Player) event.getPlayer());
            if(menu!=null){
            menu.getOnClose().accept(menu);
            menu.onClose((Player)event.getPlayer());
            }
        }
    }
     
  9. Karamazik

    Karamazik Новичок

    Баллы:
    6
    Имя в Minecraft:
    Karamazik
    Создали меню
    Код:
     Menu menu = new Menu(количество слотов, "название");
    Добавили кнопки в переопределении метода онКлик твоя логика
    Код:
    menu.addButton(new Button(айтам стак,слот для предмета) {
    
     
    @Override
        public void onClick(Player player, int slot, ClickType clickType) {
    
    ///Твой код
        }
    }));

    Так можно выполнять код при закрытии кастомног меню
    Код:
    menu.setOnClose(inventory -> {
                       //Твой код
    
                    });
     
    Последнее редактирование: 4 май 2024
  10. Karamazik

    Karamazik Новичок

    Баллы:
    6
    Имя в Minecraft:
    Karamazik
    Под себя переделай, я пыталась найти именно то что ты хочешь в своих исходниках, но только такая шляпа есть
     
    Последнее редактирование: 4 май 2024
  11. OJIEKCAHDP

    OJIEKCAHDP Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    OJIEKCAHDP
    Уже давно придумали InventoryHolder для этого. То что ты скинул выше - извращение, мало того, что при закрытии инвентаря он не убирается с листа, так пока найдёшь конкретный инвентарь надо перебрать ещё мильён игроков.
     
  12. Karamazik

    Karamazik Новичок

    Баллы:
    6
    Имя в Minecraft:
    Karamazik

    Я же сказала что шляпа.
     
    Последнее редактирование: 4 май 2024

Поделиться этой страницей