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

Помогите Какой способ отслеживания InventoryClickEvent будет лучше?

Ken12345

Активный участник
Пользователь
Баллы
61
У меня есть класс слушателя ивентов, который отслеживает: на какой предмет нажал игрок в магазине (предметов довольно много).
Какой способ реализации будет лучше и оптимизированнее?
1)Для каждого айтема делать свой @EventHandler;
2)Сделать один @EventHandler и дальше if->else if->...else if->else;
3)Сделать один @EventHandler и дальше if, if, if, if;
Заранее спасибо.
//Свои варианты тоже приветствуются
 
Если ты идентифицируешь предметы по одному значению, например имени предмета, то привычный switch-case должен подойти. Из тобой предложных я бы выбрал второй, т.к. его легче читать. Первый способ будет потре****ь больше ресурсов.
 
Самое лучшее, это научиться делать кастомные инвентари, и тогда всего этого можно лишиться.
Могу дать пример, по желанию - можно улучшить или переделать под себя:

Код:
public abstract class CustomInventory implements InventoryHolder {

    protected Inventory inventory;
    private final HashMap<Integer, Consumer<Player>> handlers;
    public CustomInventory(String name, int rows) {
        this.inventory = Bukkit.createInventory(this, rows * 9, Component.text(name));
        this.handlers = new HashMap<>();

        drawInventory();
    }

    public abstract void drawInventory();

    @Override
    public @NotNull Inventory getInventory() {
        return this.inventory;
    }

    public void addItem(int slot, ItemStack item, Consumer<Player> action) {
        this.inventory.setItem(slot, item);
        this.handlers.put(slot, action);
    }

    public void clear() {
        this.inventory.clear();
        this.handlers.clear();
    }

    public void execute(int slot, Player player) {
        Optional.ofNullable(handlers.get(slot)).ifPresent(consumer -> consumer.accept(player));
    }

    public void open(Player player) {
        player.openInventory(this.inventory);
    }

}

Этот класс мы регаем как слушатель
Код:
public class InventoryListener implements Listener {

    @EventHandler
    public void onClick(InventoryClickEvent e) {
        if (e.getClickedInventory() == null) return;
        if (e.getClickedInventory().getHolder() instanceof CustomInventory inv) {
            e.setCancelled(true);
            inv.execute(e.getSlot(), (Player) e.getWhoClicked());
        }
    }

    @EventHandler
    public void onDrag(InventoryDragEvent e) {
        e.setCancelled(e.getInventory().getHolder() instanceof CustomInventory);
    }

}

Теперь, как создавать инвентари и открывать их игроку:
1. Создаем класс, в котором прописываем всё нужное и рисуем инвентарь, пример:
Код:
public class ExampleInventory extends CustomInventory {


    public ExampleInventory() {
        super("Имя инвентаря", 6);
    }
  
    public void drawInventory() {
      
        addItem(0, new ItemStack(Material.APPLE), player -> {
            player.sendMessage(Component.text("Вы нажали на этот предмет, который находится на нулевом слоту"));
        });
      
    }
}
2. Открываем инвентарь игроку:
Код:
new ExampleInventory().open(player);
 
Если ты идентифицируешь предметы по одному значению, например имени предмета, то привычный switch-case должен подойти. Из тобой предложных я бы выбрал второй, т.к. его легче читать. Первый способ будет потре****ь больше ресурсов.
Не будет первый способ кушать больше.
 

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

Назад
Верх