Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

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

niheev

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

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

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

 
Код:
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;
    }
}
Ну раз любому, то пжалста ¯\_(ツ)_/¯
 
Последнее редактирование:
Код:
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() {
    leftClick.run();
  }

  public void executeRightClick() {
    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;
    }
}
Ну раз любому, то пжалста ¯\_(ツ)_/¯
Что за дичь? Уже давно придумали InventoryHolder, ТС на правильном пути. В этом случае, при нажатии на слот будет срабатывать в ЛЮБОМ инвентаре.

Из решений:
Для своего инвентаря создай класс и унаследуйся от InventoryHolder
В этом классе сделай методы для обработки события с ПКМ\ЛКМ.
Так-же сделай мапу, которая принимает в себе слот и Consumer, её заполняй когда добавляешь предметы в инвентарь.
При клике из этой мапы ищи консумер по слоту, если такой есть, значит выполняй его.
 
Что за дичь? Уже давно придумали InventoryHolder, ТС на правильном пути. В этом случае, при нажатии на слот будет срабатывать в ЛЮБОМ инвентаре.
При чем тут "будет срабатывать в любом инвентаре"? У меня не было цели показать, как правильно обрабатывать ивент и как отличать инвентари. Ну а имплементировать InventoryHolder не лучшая практика.
 
Последнее редактирование:
Класс меню

Код:
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());
        }
    }
}
 
Создали меню
Код:
 Menu menu = new Menu(количество слотов, "название");
Добавили кнопки в переопределении метода онКлик твоя логика
Код:
menu.addButton(new Button(айтам стак,слот для предмета) {

 
@Override
    public void onClick(Player player, int slot, ClickType clickType) {

///Твой код
    }
}));


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

                });
 
Последнее редактирование:
Под себя переделай, я пыталась найти именно то что ты хочешь в своих исходниках, но только такая шляпа есть
 
Последнее редактирование:
Класс меню

Код:
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());
        }
    }
}
Уже давно придумали InventoryHolder для этого. То что ты скинул выше - извращение, мало того, что при закрытии инвентаря он не убирается с листа, так пока найдёшь конкретный инвентарь надо перебрать ещё мильён игроков.
 
Уже давно придумали InventoryHolder для этого. То что ты скинул выше - извращение, мало того, что при закрытии инвентаря он не убирается с листа, так пока найдёшь конкретный инвентарь надо перебрать ещё мильён игроков.


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

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

Назад
Верх