Почему мой графический интерфейс для Minecraft не очищает меч и не устанавливает лук, когда он настроен на это?

Я являюсь разработчиком плагинов для сервера на Minecraft, и у меня возникает проблема с удалением алмазного меча в графическом интерфейсе и размещением лука в графическом интерфейсе, когда я нажимаю "Принять". Что мне нужно, чтобы это сделать, так это взять этот алмазный меч, очистить его, когда обмен был принят, затем добавить лук в соответствующий слот, чтобы игрок мог его взять.

private Inventory i = Bukkit.createInventory(null, 9, ChatColor.BOLD + "Trade-Up"); //Creating an inventory for everything to work around

public void onEnable() {
    getServer().getPluginManager().registerEvents(this, this);
}//Registering the event

private void openGUI(Player player) {
    player.closeInventory();

    ItemStack Anvil = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 3);
    ItemMeta AnvilMeta = Anvil.getItemMeta();

    AnvilMeta.setDisplayName(ChatColor.DARK_AQUA + "Trade Up");
    Anvil.setItemMeta(AnvilMeta);

    ItemStack AnvilAccept = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 5);
    ItemMeta AnvilAcceptMeta = AnvilAccept.getItemMeta();

    AnvilAcceptMeta.setDisplayName(ChatColor.GREEN + "Accept");
    AnvilAccept.setItemMeta(AnvilAcceptMeta);

    ItemStack AnvilFirst = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7);
    ItemMeta AnvilFirstMeta = AnvilFirst.getItemMeta();

    AnvilFirstMeta.setDisplayName(ChatColor.GRAY + "Input Items Here");
    AnvilFirst.setItemMeta(AnvilFirstMeta);

    ItemStack AnvilSecond = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7);
    ItemMeta AnvilSecondMeta = AnvilSecond.getItemMeta();

    AnvilSecondMeta.setDisplayName(ChatColor.GRAY + "Output Items Here");
    AnvilSecond.setItemMeta(AnvilSecondMeta);

    i.setItem(0, Anvil);
    i.setItem(1, Anvil);
    i.setItem(3, AnvilFirst);
    i.setItem(4, AnvilAccept);
    i.setItem(5, AnvilSecond);
    i.setItem(7, Anvil);
    i.setItem(8, Anvil);

    player.openInventory(i);
}//Opens the trade-up inventory when the player type the command

public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    if(sender instanceof Player) {
        if(cmd.getName().equalsIgnoreCase("trade-up")) {
            Player player = (Player) sender;
            openGUI(player);
        }//GUI openning command
    }
    return false;
}

@EventHandler
public void inventoryClickEvent(InventoryClickEvent e) {

    ItemStack Anvil = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 3);
    ItemMeta AnvilMeta = Anvil.getItemMeta();

    AnvilMeta.setDisplayName(ChatColor.DARK_AQUA + "Trade Up");
    Anvil.setItemMeta(AnvilMeta);

    ItemStack AnvilAccept = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 5);
    ItemMeta AnvilAcceptMeta = AnvilAccept.getItemMeta();

    AnvilAcceptMeta.setDisplayName(ChatColor.GREEN + "Accept");
    AnvilAccept.setItemMeta(AnvilAcceptMeta);

    ItemStack AnvilFirst = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7);
    ItemMeta AnvilFirstMeta = AnvilFirst.getItemMeta();

    AnvilFirstMeta.setDisplayName(ChatColor.GRAY + "Input Items Here");
    AnvilFirst.setItemMeta(AnvilFirstMeta);

    ItemStack AnvilSecond = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 7);
    ItemMeta AnvilSecondMeta = AnvilSecond.getItemMeta();

    AnvilSecondMeta.setDisplayName(ChatColor.GRAY + "Output Items Here");
    AnvilSecond.setItemMeta(AnvilSecondMeta);

    ItemStack is = e.getCurrentItem();

    if(is.equals(Anvil) || is.equals(AnvilFirst) || is.equals(AnvilSecond)) {
        e.setCancelled(true);//Making sure that the player doesn't take the glass panes
    }

    if(is.equals(AnvilAccept)) {
        Player p = (Player) e.getWhoClicked();

        ItemStack air = new ItemStack(Material.AIR);

        ItemStack chests = new ItemStack(Material.DIAMOND_SWORD);
        ItemStack chestsConvert = new ItemStack(Material.BOW);

        if(i.contains(chests, 2)) {
            i.setItem(6, chestsConvert);
            i.clear(2);
            i.setItem(0, Anvil);
            i.setItem(1, Anvil);
            i.setItem(3, AnvilFirst);
            i.setItem(4, AnvilAccept);
            i.setItem(5, AnvilSecond);
            i.setItem(7, Anvil);
            i.setItem(8, Anvil);
            p.closeInventory();
            p.openInventory(i);
            p.sendMessage(ChatColor.GREEN + "Your items have been Traded-Up!");//Removes the sword and gives them a bow instead
        }else if(i.contains(air, 2)) {
            p.sendMessage("There is no items to trade up!");
        } //Makes sure there is an item to trade-up

    e.setCancelled(true);//Makes so the player can't take the "Accept" pane.
    }
}

Плагин не регистрирует, что что-то находится в слоте, а также не удаляет и не заменяет алмазный меч луком.

1 ответ

Решение

contains(ItemStack, int) Метод не проверяет, является ли такого рода ItemStack находится в слоте int (как я вижу, вы используете его), но проверяет, содержит ли все содержимое этого инвентаря хотя бы целое количество ItemStack, Ваш код проверяет, содержит ли пользовательский инвентарь два алмазных меча (что можно сделать, если вы поместите их в слот два и шесть), вместо того, чтобы проверять, был ли один алмазный меч помещен в слот два (что я и предполагаю, что вы пытаюсь сделать).

Чтобы это исправить, используйте inventory.getItem(2).equals(chests) проверить, есть ли в слоте два меч. Обратите внимание, что метод выше не вернет ItemStack типа Material.AIR в случае пустого слота, но вместо этого вернется null,

Вот пример кода, как это может выглядеть:

ItemStack input = i.getItem(2); // Get the ItemStack at slot two

if (input == null) { // If there is nothing in that slot
    player.sendMessage("There are no items to trade up!");
} else if (input.equals(chests)) { // If it contains the sword
    // Execute the trade
}
// Optionally send message if it is the wrong item

То, как вы определяете и инициализируете Inventory а также ItemStackс можно поменять. Обратите внимание, что несколько людей могут просматривать и взаимодействовать с одним и тем же инвентарем, поэтому, как вы написали свой плагин прямо сейчас, каждый, кто использует интерфейс "обмена", увидит один и тот же инвентарь и сможет брать предметы других людей. ItemStackОднако, что вы создаете для каждого события и openGUI(Player) вызов метода не уникален и может вместо инвентаря создаваться только один раз для экономии ресурсов (другими словами, вы можете создать новый Inventory каждый раз openGUI(Player) метод вызывается, но всегда ссылается на одно и то же ItemStackс).

Другие вопросы по тегам