Вопрос Баг с InventoryClickEvent

Версия Minecraft
1.16.X

1Love_Artix001

Пользователь
Сообщения
40
Разрешается выкладывание кода, файлов конфигураций, логов и т.д. только под BB-код CODE
Всем здравствуйте, у меня в плагине есть метод InventoryClickEvent который отвечает за запрет перемещения некоторых предметов (шалкеровых ящиков) в инвентаре. вот код:
if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (!isBackpack(item) || (!player.getInventory().containsAtLeast(item, 1) && !player.getInventory().getItemInOffHand().equals(item))) {
event.setCancelled(true);
player.closeInventory();
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
} else {
ItemStack clickedItem = event.getCurrentItem();
if (isShulkerBox(clickedItem) || isShulkerBox(event.getCursor())) {
event.setCancelled(true);
}

// Проверка на -1 перед тем, как пытаться получить предмет из горячей клавиши
int hotbarButton = event.getHotbarButton();
if (hotbarButton != -1) {
ItemStack hotbarItem = player.getInventory().getItem(hotbarButton);
if (isShulkerBox(hotbarItem)) {
event.setCancelled(true);
}
}
}
}
}
проблема заключается в том, что когда игрок держит во 2 руке предмет, то этот метод попросту не работает.
 
Решение
Форматирование (BB-код):
    private static final Map<UUID, Boolean> air = new HashMap<UUID, Boolean>();


Форматирование (BB-код):
    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
            handleClick(event, event.getPlayer().getInventory().getItemInHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        }
    }

    private void handleClick(PlayerInteractEvent event, ItemStack item) {
        Bukkit.getLogger().warning(event.getPlayer().getName());
        if (isBackpack(item)) {...
item.isSimilar() используй. equals не совсем правильно, ибо equals проверяет даже количество, а isSimilar именно itemStack
так шалкер можно взять в руку 1 же
Объединено

и метод же как-то запускается
Объединено

а зачем ты вызываешь метод при OFF_HAND, если ты OFF_HAND не используешь?
 
Последнее редактирование:
Разрешается выкладывание кода, файлов конфигураций, логов и т.д. только под BB-код CODE
!player.getInventory().getItemInOffHand().isSimilar(item))
package me.artix001.shulkerpacks;

import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class BackPackInventory implements Listener {

private static final Map<UUID, Inventory> backpacks = new HashMap<>();
private static final Map<UUID, ItemStack> openedShulkers = new HashMap<>();
private static final NamespacedKey BACKPACK_LEVEL_KEY = new NamespacedKey(ShulkerPacks.getInstance(), "backpackLevel");

@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
} else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
}
}

private void handleClick(PlayerInteractEvent event, ItemStack item) {
if (isBackpack(item)) {
event.setCancelled(true);
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (item.isSimilar(event.getPlayer().getInventory().getItemInMainHand())) {
openBackpack(event.getPlayer(), item);
}
}
}
}

private void openBackpack(Player player, ItemStack item) {
int level = getBackpackLevel(item);
UUID uuid = player.getUniqueId();
Inventory backpack = backpacks.computeIfAbsent(uuid, k -> Bukkit.createInventory(null, getInventorySize(level), "Рюкзак"));
loadItemsFromShulker(item, backpack);
player.openInventory(backpack);
openedShulkers.put(uuid, item); // Сохраняем ссылку на шалкеровый ящик
}

@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
UUID uuid = player.getUniqueId();

if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (isBackpack(item) && player.getInventory().containsAtLeast(item, 1)) {
saveItemsToShulker(item, backpacks.get(uuid));
}
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
}
}

@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
handleInventoryEvent(event);
}

@EventHandler
public void onInventoryDrag(InventoryDragEvent event) {
handleInventoryEvent(event);
}

private void handleInventoryEvent(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
UUID uuid = player.getUniqueId();


if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
event.setCancelled(true);
player.closeInventory();
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
} else {
ItemStack clickedItem = event.getCurrentItem();
if (isShulkerBox(clickedItem) || isShulkerBox(event.getCursor())) {
event.setCancelled(true);
}

// Проверка на -1 перед тем, как пытаться получить предмет из горячей клавиши
int hotbarButton = event.getHotbarButton();
if (hotbarButton != -1) {
ItemStack hotbarItem = player.getInventory().getItem(hotbarButton);
if (isShulkerBox(hotbarItem)) {
event.setCancelled(true);
}
}
}
}
}

private void handleInventoryEvent(InventoryDragEvent event) {
Player player = (Player) event.getWhoClicked();
UUID uuid = player.getUniqueId();

if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
event.setCancelled(true);
player.closeInventory();
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
} else {
ItemStack draggedItem = event.getOldCursor();
if (isShulkerBox(draggedItem)) {
event.setCancelled(true);
}
}
}
}

private boolean isBackpack(ItemStack item) {
return item != null && item.getType().name().endsWith("_SHULKER_BOX") && item.hasItemMeta() && item.getItemMeta().getPersistentDataContainer().has(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
}

private boolean isShulkerBox(ItemStack item) {
return item != null && (item.getType().name().endsWith("_SHULKER_BOX") || item.getType() == org.bukkit.Material.SHULKER_BOX);
}

private int getBackpackLevel(ItemStack item) {
return item.getItemMeta().getPersistentDataContainer().get(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
}

private int getInventorySize(int level) {
switch (level) {
case 1:
return 9;
case 2:
return 18;
case 3:
return 27;
default:
return 9;
}
}

private void loadItemsFromShulker(ItemStack shulker, Inventory inventory) {
BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
Inventory shulkerInventory = shulkerBox.getInventory();

for (int i = 0; i < inventory.getSize(); i++) {
inventory.setItem(i, i < shulkerInventory.getSize() ? shulkerInventory.getItem(i) : null);
}
}

private void saveItemsToShulker(ItemStack shulker, Inventory inventory) {
BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
Inventory shulkerInventory = shulkerBox.getInventory();

for (int i = 0; i < inventory.getSize(); i++) {
if (i < shulkerInventory.getSize()) {
shulkerInventory.setItem(i, inventory.getItem(i));
}
}

shulkerBox.update();
meta.setBlockState(shulkerBox);
shulker.setItemMeta(meta);
}
}
вот просто напросто полный код. возможно, я вообще что то не то скинул
 
а зачем ты вызываешь метод при OFF_HAND, если ты OFF_HAND не используешь?
package me.artix001.shulkerpacks;

import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class BackPackInventory implements Listener {

private static final Map<UUID, Inventory> backpacks = new HashMap<>();
private static final Map<UUID, ItemStack> openedShulkers = new HashMap<>();
private static final NamespacedKey BACKPACK_LEVEL_KEY = new NamespacedKey(ShulkerPacks.getInstance(), "backpackLevel");

@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
} else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
}
}

private void handleClick(PlayerInteractEvent event, ItemStack item) {
if (isBackpack(item)) {
event.setCancelled(true);
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (item.isSimilar(event.getPlayer().getInventory().getItemInMainHand())) {
openBackpack(event.getPlayer(), item);
}
}
}
}

private void openBackpack(Player player, ItemStack item) {
int level = getBackpackLevel(item);
UUID uuid = player.getUniqueId();
Inventory backpack = backpacks.computeIfAbsent(uuid, k -> Bukkit.createInventory(null, getInventorySize(level), "Рюкзак"));
loadItemsFromShulker(item, backpack);
player.openInventory(backpack);
openedShulkers.put(uuid, item); // Сохраняем ссылку на шалкеровый ящик
}

@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
UUID uuid = player.getUniqueId();

if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (isBackpack(item) && player.getInventory().containsAtLeast(item, 1)) {
saveItemsToShulker(item, backpacks.get(uuid));
}
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
}
}

@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
handleInventoryEvent(event);
}

@EventHandler
public void onInventoryDrag(InventoryDragEvent event) {
handleInventoryEvent(event);
}

private void handleInventoryEvent(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
UUID uuid = player.getUniqueId();


if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
event.setCancelled(true);
player.closeInventory();
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
} else {
ItemStack clickedItem = event.getCurrentItem();
if (isShulkerBox(clickedItem) || isShulkerBox(event.getCursor())) {
event.setCancelled(true);
}

// Проверка на -1 перед тем, как пытаться получить предмет из горячей клавиши
int hotbarButton = event.getHotbarButton();
if (hotbarButton != -1) {
ItemStack hotbarItem = player.getInventory().getItem(hotbarButton);
if (isShulkerBox(hotbarItem)) {
event.setCancelled(true);
}
}
}
}
}

private void handleInventoryEvent(InventoryDragEvent event) {
Player player = (Player) event.getWhoClicked();
UUID uuid = player.getUniqueId();

if (backpacks.containsKey(uuid)) {
ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
event.setCancelled(true);
player.closeInventory();
backpacks.remove(uuid);
openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
} else {
ItemStack draggedItem = event.getOldCursor();
if (isShulkerBox(draggedItem)) {
event.setCancelled(true);
}
}
}
}

private boolean isBackpack(ItemStack item) {
return item != null && item.getType().name().endsWith("_SHULKER_BOX") && item.hasItemMeta() && item.getItemMeta().getPersistentDataContainer().has(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
}

private boolean isShulkerBox(ItemStack item) {
return item != null && (item.getType().name().endsWith("_SHULKER_BOX") || item.getType() == org.bukkit.Material.SHULKER_BOX);
}

private int getBackpackLevel(ItemStack item) {
return item.getItemMeta().getPersistentDataContainer().get(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
}

private int getInventorySize(int level) {
switch (level) {
case 1:
return 9;
case 2:
return 18;
case 3:
return 27;
default:
return 9;
}
}

private void loadItemsFromShulker(ItemStack shulker, Inventory inventory) {
BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
Inventory shulkerInventory = shulkerBox.getInventory();

for (int i = 0; i < inventory.getSize(); i++) {
inventory.setItem(i, i < shulkerInventory.getSize() ? shulkerInventory.getItem(i) : null);
}
}

private void saveItemsToShulker(ItemStack shulker, Inventory inventory) {
BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
Inventory shulkerInventory = shulkerBox.getInventory();

for (int i = 0; i < inventory.getSize(); i++) {
if (i < shulkerInventory.getSize()) {
shulkerInventory.setItem(i, inventory.getItem(i));
}
}

shulkerBox.update();
meta.setBlockState(shulkerBox);
shulker.setItemMeta(meta);
}
}
вот просто напросто полный код. возможно, я вообще что то не то скинул
пойду протестирую наверное...
 
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
} else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
}
}

private void handleClick(PlayerInteractEvent event, ItemStack item) {
if (isBackpack(item)) {
event.setCancelled(true);
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (item.equals(event.getPlayer().getInventory().getItemInMainHand())) {
openBackpack(event.getPlayer(), item);
}
}
}
}
offtop Код размещается только в BB-тегах.
 
как его включить? первый раз здесь задаю вопросы, сори что туплю..
Возле сообщения есть форматирование там цвета и тд, справа три точки, кнопочка код в виде </> кликни и выбери там всё это
 
ой
Объединено

Java:
package me.artix001.shulkerpacks;

import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class BackPackInventory implements Listener {

    private static final Map<UUID, Inventory> backpacks = new HashMap<>();
    private static final Map<UUID, ItemStack> openedShulkers = new HashMap<>();
    private static final NamespacedKey BACKPACK_LEVEL_KEY = new NamespacedKey(ShulkerPacks.getInstance(), "backpackLevel");

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
            handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        } else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
            handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        }
    }

    private void handleClick(PlayerInteractEvent event, ItemStack item) {
        if (isBackpack(item)) {
            event.setCancelled(true);
            if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if (item.isSimilar(event.getPlayer().getInventory().getItemInMainHand())) {
                    openBackpack(event.getPlayer(), item);
                }
            }
        }
    }

    private void openBackpack(Player player, ItemStack item) {
        int level = getBackpackLevel(item);
        UUID uuid = player.getUniqueId();
        Inventory backpack = backpacks.computeIfAbsent(uuid, k -> Bukkit.createInventory(null, getInventorySize(level), "Рюкзак"));
        loadItemsFromShulker(item, backpack);
        player.openInventory(backpack);
        openedShulkers.put(uuid, item); // Сохраняем ссылку на шалкеровый ящик
    }

    @EventHandler
    public void onInventoryClose(InventoryCloseEvent event) {
        Player player = (Player) event.getPlayer();
        UUID uuid = player.getUniqueId();

        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (isBackpack(item) && player.getInventory().containsAtLeast(item, 1)) {
                saveItemsToShulker(item, backpacks.get(uuid));
            }
            backpacks.remove(uuid);
            openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
        }
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        handleInventoryEvent(event);
    }

    @EventHandler
    public void onInventoryDrag(InventoryDragEvent event) {
        handleInventoryEvent(event);
    }

    private void handleInventoryEvent(InventoryClickEvent event) {
        Player player = (Player) event.getWhoClicked();
        UUID uuid = player.getUniqueId();


        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
                event.setCancelled(true);
                player.closeInventory();
                backpacks.remove(uuid);
                openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
            } else {
                ItemStack clickedItem = event.getCurrentItem();
                if (isShulkerBox(clickedItem) || isShulkerBox(event.getCursor())) {
                    event.setCancelled(true);
                }

                // Проверка на -1 перед тем, как пытаться получить предмет из горячей клавиши
                int hotbarButton = event.getHotbarButton();
                if (hotbarButton != -1) {
                    ItemStack hotbarItem = player.getInventory().getItem(hotbarButton);
                    if (isShulkerBox(hotbarItem)) {
                        event.setCancelled(true);
                    }
                }
            }
        }
    }

    private void handleInventoryEvent(InventoryDragEvent event) {
        Player player = (Player) event.getWhoClicked();
        UUID uuid = player.getUniqueId();

        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
                event.setCancelled(true);
                player.closeInventory();
                backpacks.remove(uuid);
                openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
            } else {
                ItemStack draggedItem = event.getOldCursor();
                if (isShulkerBox(draggedItem)) {
                    event.setCancelled(true);
                }
            }
        }
    }

    private boolean isBackpack(ItemStack item) {
        return item != null && item.getType().name().endsWith("_SHULKER_BOX") && item.hasItemMeta() && item.getItemMeta().getPersistentDataContainer().has(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
    }

    private boolean isShulkerBox(ItemStack item) {
        return item != null && (item.getType().name().endsWith("_SHULKER_BOX") || item.getType() == org.bukkit.Material.SHULKER_BOX);
    }

    private int getBackpackLevel(ItemStack item) {
        return item.getItemMeta().getPersistentDataContainer().get(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
    }

    private int getInventorySize(int level) {
        switch (level) {
            case 1:
                return 9;
            case 2:
                return 18;
            case 3:
                return 27;
            default:
                return 9;
        }
    }

    private void loadItemsFromShulker(ItemStack shulker, Inventory inventory) {
        BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
        org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
        Inventory shulkerInventory = shulkerBox.getInventory();

        for (int i = 0; i < inventory.getSize(); i++) {
            inventory.setItem(i, i < shulkerInventory.getSize() ? shulkerInventory.getItem(i) : null);
        }
    }

    private void saveItemsToShulker(ItemStack shulker, Inventory inventory) {
        BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
        org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
        Inventory shulkerInventory = shulkerBox.getInventory();

        for (int i = 0; i < inventory.getSize(); i++) {
            if (i < shulkerInventory.getSize()) {
                shulkerInventory.setItem(i, inventory.getItem(i));
            }
        }

        shulkerBox.update();
        meta.setBlockState(shulkerBox);
        shulker.setItemMeta(meta);
    }
}
во
 
Последнее редактирование:
ой
Объединено

Java:
package me.artix001.shulkerpacks;

import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class BackPackInventory implements Listener {

    private static final Map<UUID, Inventory> backpacks = new HashMap<>();
    private static final Map<UUID, ItemStack> openedShulkers = new HashMap<>();
    private static final NamespacedKey BACKPACK_LEVEL_KEY = new NamespacedKey(ShulkerPacks.getInstance(), "backpackLevel");

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
            handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        } else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
            handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        }
    }

    private void handleClick(PlayerInteractEvent event, ItemStack item) {
        if (isBackpack(item)) {
            event.setCancelled(true);
            if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if (item.isSimilar(event.getPlayer().getInventory().getItemInMainHand())) {
                    openBackpack(event.getPlayer(), item);
                }
            }
        }
    }

    private void openBackpack(Player player, ItemStack item) {
        int level = getBackpackLevel(item);
        UUID uuid = player.getUniqueId();
        Inventory backpack = backpacks.computeIfAbsent(uuid, k -> Bukkit.createInventory(null, getInventorySize(level), "Рюкзак"));
        loadItemsFromShulker(item, backpack);
        player.openInventory(backpack);
        openedShulkers.put(uuid, item); // Сохраняем ссылку на шалкеровый ящик
    }

    @EventHandler
    public void onInventoryClose(InventoryCloseEvent event) {
        Player player = (Player) event.getPlayer();
        UUID uuid = player.getUniqueId();

        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (isBackpack(item) && player.getInventory().containsAtLeast(item, 1)) {
                saveItemsToShulker(item, backpacks.get(uuid));
            }
            backpacks.remove(uuid);
            openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
        }
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        handleInventoryEvent(event);
    }

    @EventHandler
    public void onInventoryDrag(InventoryDragEvent event) {
        handleInventoryEvent(event);
    }

    private void handleInventoryEvent(InventoryClickEvent event) {
        Player player = (Player) event.getWhoClicked();
        UUID uuid = player.getUniqueId();


        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
                event.setCancelled(true);
                player.closeInventory();
                backpacks.remove(uuid);
                openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
            } else {
                ItemStack clickedItem = event.getCurrentItem();
                if (isShulkerBox(clickedItem) || isShulkerBox(event.getCursor())) {
                    event.setCancelled(true);
                }

                // Проверка на -1 перед тем, как пытаться получить предмет из горячей клавиши
                int hotbarButton = event.getHotbarButton();
                if (hotbarButton != -1) {
                    ItemStack hotbarItem = player.getInventory().getItem(hotbarButton);
                    if (isShulkerBox(hotbarItem)) {
                        event.setCancelled(true);
                    }
                }
            }
        }
    }

    private void handleInventoryEvent(InventoryDragEvent event) {
        Player player = (Player) event.getWhoClicked();
        UUID uuid = player.getUniqueId();

        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
                event.setCancelled(true);
                player.closeInventory();
                backpacks.remove(uuid);
                openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
            } else {
                ItemStack draggedItem = event.getOldCursor();
                if (isShulkerBox(draggedItem)) {
                    event.setCancelled(true);
                }
            }
        }
    }

    private boolean isBackpack(ItemStack item) {
        return item != null && item.getType().name().endsWith("_SHULKER_BOX") && item.hasItemMeta() && item.getItemMeta().getPersistentDataContainer().has(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
    }

    private boolean isShulkerBox(ItemStack item) {
        return item != null && (item.getType().name().endsWith("_SHULKER_BOX") || item.getType() == org.bukkit.Material.SHULKER_BOX);
    }

    private int getBackpackLevel(ItemStack item) {
        return item.getItemMeta().getPersistentDataContainer().get(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
    }

    private int getInventorySize(int level) {
        switch (level) {
            case 1:
                return 9;
            case 2:
                return 18;
            case 3:
                return 27;
            default:
                return 9;
        }
    }

    private void loadItemsFromShulker(ItemStack shulker, Inventory inventory) {
        BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
        org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
        Inventory shulkerInventory = shulkerBox.getInventory();

        for (int i = 0; i < inventory.getSize(); i++) {
            inventory.setItem(i, i < shulkerInventory.getSize() ? shulkerInventory.getItem(i) : null);
        }
    }

    private void saveItemsToShulker(ItemStack shulker, Inventory inventory) {
        BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
        org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
        Inventory shulkerInventory = shulkerBox.getInventory();

        for (int i = 0; i < inventory.getSize(); i++) {
            if (i < shulkerInventory.getSize()) {
                shulkerInventory.setItem(i, inventory.getItem(i));
            }
        }

        shulkerBox.update();
        meta.setBlockState(shulkerBox);
        shulker.setItemMeta(meta);
    }
}
во
offtop Достаточно было бы просто изменить прошлое сообщение и все
 
offtop Достаточно было бы просто изменить прошлое сообщение и все
offtop Мистор очевидность, хватит уже мучения человеку делать

Объединено

ой
Объединено

Java:
package me.artix001.shulkerpacks;

import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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.inventory.InventoryDragEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.persistence.PersistentDataType;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class BackPackInventory implements Listener {

    private static final Map<UUID, Inventory> backpacks = new HashMap<>();
    private static final Map<UUID, ItemStack> openedShulkers = new HashMap<>();
    private static final NamespacedKey BACKPACK_LEVEL_KEY = new NamespacedKey(ShulkerPacks.getInstance(), "backpackLevel");

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
            handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        } else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
            handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
            handleClick(event, event.getPlayer().getInventory().getItemInOffHand());
        }
    }

    private void handleClick(PlayerInteractEvent event, ItemStack item) {
        if (isBackpack(item)) {
            event.setCancelled(true);
            if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if (item.isSimilar(event.getPlayer().getInventory().getItemInMainHand())) {
                    openBackpack(event.getPlayer(), item);
                }
            }
        }
    }

    private void openBackpack(Player player, ItemStack item) {
        int level = getBackpackLevel(item);
        UUID uuid = player.getUniqueId();
        Inventory backpack = backpacks.computeIfAbsent(uuid, k -> Bukkit.createInventory(null, getInventorySize(level), "Рюкзак"));
        loadItemsFromShulker(item, backpack);
        player.openInventory(backpack);
        openedShulkers.put(uuid, item); // Сохраняем ссылку на шалкеровый ящик
    }

    @EventHandler
    public void onInventoryClose(InventoryCloseEvent event) {
        Player player = (Player) event.getPlayer();
        UUID uuid = player.getUniqueId();

        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (isBackpack(item) && player.getInventory().containsAtLeast(item, 1)) {
                saveItemsToShulker(item, backpacks.get(uuid));
            }
            backpacks.remove(uuid);
            openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
        }
    }

    @EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        handleInventoryEvent(event);
    }

    @EventHandler
    public void onInventoryDrag(InventoryDragEvent event) {
        handleInventoryEvent(event);
    }

    private void handleInventoryEvent(InventoryClickEvent event) {
        Player player = (Player) event.getWhoClicked();
        UUID uuid = player.getUniqueId();


        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
                event.setCancelled(true);
                player.closeInventory();
                backpacks.remove(uuid);
                openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
            } else {
                ItemStack clickedItem = event.getCurrentItem();
                if (isShulkerBox(clickedItem) || isShulkerBox(event.getCursor())) {
                    event.setCancelled(true);
                }

                // Проверка на -1 перед тем, как пытаться получить предмет из горячей клавиши
                int hotbarButton = event.getHotbarButton();
                if (hotbarButton != -1) {
                    ItemStack hotbarItem = player.getInventory().getItem(hotbarButton);
                    if (isShulkerBox(hotbarItem)) {
                        event.setCancelled(true);
                    }
                }
            }
        }
    }

    private void handleInventoryEvent(InventoryDragEvent event) {
        Player player = (Player) event.getWhoClicked();
        UUID uuid = player.getUniqueId();

        if (backpacks.containsKey(uuid)) {
            ItemStack item = openedShulkers.get(uuid); // Получаем шалкеровый ящик, который был открыт
            if (!isBackpack(item) || !player.getInventory().containsAtLeast(item, 1)) {
                event.setCancelled(true);
                player.closeInventory();
                backpacks.remove(uuid);
                openedShulkers.remove(uuid); // Удаляем ссылку на шалкеровый ящик
            } else {
                ItemStack draggedItem = event.getOldCursor();
                if (isShulkerBox(draggedItem)) {
                    event.setCancelled(true);
                }
            }
        }
    }

    private boolean isBackpack(ItemStack item) {
        return item != null && item.getType().name().endsWith("_SHULKER_BOX") && item.hasItemMeta() && item.getItemMeta().getPersistentDataContainer().has(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
    }

    private boolean isShulkerBox(ItemStack item) {
        return item != null && (item.getType().name().endsWith("_SHULKER_BOX") || item.getType() == org.bukkit.Material.SHULKER_BOX);
    }

    private int getBackpackLevel(ItemStack item) {
        return item.getItemMeta().getPersistentDataContainer().get(BACKPACK_LEVEL_KEY, PersistentDataType.INTEGER);
    }

    private int getInventorySize(int level) {
        switch (level) {
            case 1:
                return 9;
            case 2:
                return 18;
            case 3:
                return 27;
            default:
                return 9;
        }
    }

    private void loadItemsFromShulker(ItemStack shulker, Inventory inventory) {
        BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
        org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
        Inventory shulkerInventory = shulkerBox.getInventory();

        for (int i = 0; i < inventory.getSize(); i++) {
            inventory.setItem(i, i < shulkerInventory.getSize() ? shulkerInventory.getItem(i) : null);
        }
    }

    private void saveItemsToShulker(ItemStack shulker, Inventory inventory) {
        BlockStateMeta meta = (BlockStateMeta) shulker.getItemMeta();
        org.bukkit.block.ShulkerBox shulkerBox = (org.bukkit.block.ShulkerBox) meta.getBlockState();
        Inventory shulkerInventory = shulkerBox.getInventory();

        for (int i = 0; i < inventory.getSize(); i++) {
            if (i < shulkerInventory.getSize()) {
                shulkerInventory.setItem(i, inventory.getItem(i));
            }
        }

        shulkerBox.update();
        meta.setBlockState(shulkerBox);
        shulker.setItemMeta(meta);
    }
}
во
У тебя такой баг, если ты только шалкер в правой руке держишь, верно понимаю?
 
Последнее редактирование:
Чутка переделал:

Форматирование (BB-код):
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
} else if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
handleClick(event, event.getPlayer().getInventory().getItemInMainHand());
}
}private void handleClick(PlayerInteractEvent event, ItemStack item) {
if (isBackpack(item)) {
event.setCancelled(true);
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (item.isSimilar(event.getPlayer().getInventory().getItemInMainHand())) {
openBackpack(event.getPlayer(), event.getPlayer().getInventory().getItemInMainHand());
}
}
}
}


Вот в таком варианте у меня всё работает по твоим требованиям
 
offtop Мистор очевидность, хватит уже мучения человеку делать

Объединено


У тебя такой баг, если ты только шалкер в правой руке держишь, верно понимаю?
нужно переписывать про правую и левую.
Если есть Nый предмет в левой руке отдавать левую руку, а если в правой то правую.
Объединено

нужно переписывать про правую и левую.
Если есть Nый предмет в левой руке отдавать левую руку, а если в правой то правую.
Я такое себе уже делал.
 
offtop Мистор очевидность, хватит уже мучения человеку делать

Объединено


У тебя такой баг, если ты только шалкер в правой руке держишь, верно понимаю?
неет. если я открыл рюкзак держа его в основной руке, то у меня всё хорошо, и всё работает. если я также открываю рюкзак держа его в основной руке, только ещё дополнительно держа предмет во второй руке, тогда и происходит эта проблема (то что предметы не сохраняются и inventoryclickevent не работает).
 
неет. если я открыл рюкзак держа его в основной руке, то у меня всё хорошо, и всё работает. если я также открываю рюкзак держа его в основной руке, только ещё дополнительно держа предмет во второй руке, тогда и происходит эта проблема (то что предметы не сохраняются и inventoryclickevent не работает).
Правая рука должна использоваться для открытия шалкера?
 
Правая рука должна использоваться для открытия шалкера?
если рюкзак будет во 2 руке, то его не получится открыть. только из первой
Объединено

нужно переписывать про правую и левую.
Если есть Nый предмет в левой руке отдавать левую руку, а если в правой то правую.
Объединено


Я такое себе уже делал.
прикол в том, что это уже 3 попытка написать плагин на шалкера. в прошлых была такая же проблема, ну и также куча других, поэтому и решил переписывать. здесь вроде это одна из единственных проблем.
 
Последнее редактирование:
Назад
Сверху Снизу