Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Помогите Удаление предметов из инвенторя.

Тема в разделе "Разработка плагинов для новичков", создана пользователем iD3LSY, 24 июн 2017.

Статус темы:
Закрыта.
  1. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Задача: Нужен код, который бы мог удалить определенный предмет (с учетом лора и количества) в разных айтемстаках раскиданных по всему инвенторю.

    Сделать уже давно пытался, но к результату не пришел, при том накидав уже около 5-и проверок всех слотов инвенторя. Как нагрузка - хз, но экспериментировать не очень хочется >:)

    Буду рад любой идеи/коду. Если у вас есть предложения на счет "погугли", советую сразу нажать Alt+←.
     
  2. Хостинг MineCraft
    <
  3. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    гет контейнс и там в for()
     
  4. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Ну я проверял просто for(int t = 0; t < player.getInventory().getSize(); t++) {}, но один хрен. Окей, contains. Он как я понял может проверять на наличие материала/itemstack. Материал - не проверим лор; itemstack - не проверим количеством.[DOUBLEPOST=1498301613,1498301284][/DOUBLEPOST]Конечно, можно их свести к одному количеству.
    Код:
    for(ItemStack item: needItems) {
        for(int t = 0; t < p.getInventory().getSize(); t++) {
            ItemStack a = item.clone();
    
            if(p.getInventory().getItem(t) == null) {
                continue;
            }
    
            ItemStack b = p.getInventory().getItem(t).clone();
    
            if(a.getAmount() <= b.getAmount()) {
                b.setAmount(a.getAmount());
            }
    
            if(a.equals(b)) {
                // код
            }
        }
    }
    Но при этом, это либо нужно записывать слот + материал + количество. Тогда я уже не получу удаление предметов по всем слотам. (ну... Или я так думаю)
     
  5. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Код:
        public void checkItem(ItemStack item, ItemStack itemOther, Player p) {
            if(item.getType()==itemOther.getType()) {
                p.getInventory().remove(item);
            }
        }
     
  6. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Чувааак, ну в том то и дело) Тут у тебя нету никакой проверки: материала, даты, количества, лора. Ну ладно, это не так уж и сложно, но думаю найду себе еще проблем со слотами.[DOUBLEPOST=1498302710,1498302497][/DOUBLEPOST]Кстати, самое важное. Проверка идет не на 1 предмет. Пишу я некие задания, которые заключаются в добыче ресурсов, поэтому количество предметов установленное для задачи не-из-вест-но
     
  7. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Ну так допиши и будет остальное чекать.
     
  8. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Ну вот мне и нужно понять, как сделать проверку на несколько предметов с учетом того, что будет работать, если 2 слота положить...
     
  9. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Ну вот твоя же форка тут уместна, найдет везде.

    Код:
        @EventHandler
        public void on(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            for(int i = 0; i < p.getInventory().getSize(); i++) {
                ItemStack item = p.getInventory().getItem(i);
                if(item.getType()==itemOther.getType()) {
                    p.getInventory().clear(i);
                }
            }
        }
     
  10. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Я не понимаю, ты рофлишь? Чувак, я тебе уже несколько раз написал. В нескольких слотах лежат предметы разных типов, с разным количеством, с лором и без. В конфиге у меня есть надпись
    Код:
    - STONE:0 15
    - WOOD:0 5 lore:Привет!
    Проверяется каждый предмет, делаю проверку на наличие, потом снимаю предметы, потом делаю выводы, все ли предметы удалось удалить, с учетом, что предметы одного типа могли лежать в разных слотах. Все! Я не знаю как это реализовать без говнокода...
     
  11. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Ну так допиши item.getItemMeta().getLore(), сложно?
     
    Последнее редактирование: 24 июн 2017
  12. GreenBudgie

    GreenBudgie Ньюби Пользователь

    Баллы:
    1
    Чего человека мучать? Вот тебе код.
    Код:
        public static void removeItemsExact(PlayerInventory inv, Material itemToRemove, List<String> lore, int minCount, int maxCount) {
            for(ItemStack item : inv.getStorageContents()) {
                if(item != null) {
                    if(item.getType() != itemToRemove) continue;
                    if(item.getAmount() < minCount || item.getAmount() > maxCount) continue;
                    ItemMeta meta = item.getItemMeta();
                    boolean argHasLore = lore != null && !lore.isEmpty();
                    boolean itemHasLore = meta.hasLore();
                    if(!argHasLore && !itemHasLore) {
                        item.setAmount(0);
                        continue;
                    }
                    if(lore.size() != meta.getLore().size()) continue;
                    for(int i = 0; i < lore.size(); i++) {
                        if(!meta.getLore().get(i).equals(lore.get(i))) continue;
                    }
                    item.setAmount(0);
                }
            }
        }
    По аргументам понятно. inv - сюда передаешь инвентарь (в моем случае игрока, изменишь если что); itemToRemove - материал предметов, которые надо убирать; lore - лор предмета (предмет будет убираться только если поданный сюда лор полностью соответствует лору предмета); minCount и maxCount - минимальное и максимальное количество предметов.
    Вот пример использования:
    Код:
    List<String> lore = new ArrayList<String>();
                lore.add("lore1");
                lore.add("lore2");
                InventoryHelper.removeItemsExact(e.getPlayer().getInventory(), Material.EMERALD, lore, 4, 10);
    В таком случае будут удаляться все эмеральды в количестве от 4 до 10 с определенным лором (в первой строке - lore1, во второй - lore2).
    Честно, не проверял на NullPointerException'ы, так что потесть немного добавляя и убираю лоры из аргумента или с самих айтемов в инвентаре.
    P.S. Надеюсь, это именно тот код, который тебе был нужен)
     
  13. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Мдее, я хз, кто тут кого мучает, но видимо от этой темы толку ноль. Я прошу лишь ИДЕЮ. Писал уже 2 раза, что там не 1 предмет (НЕ КОЛИЧЕСТВО, АITEMSTACK НЕ 1) может быть. Впрочем, не стоило всегда рассчитывать на rubukkit.[DOUBLEPOST=1498320783,1498320732][/DOUBLEPOST]Напишу - сам кину сюда, ибо видимо реально идею придумать никто не может (сужу по просмотрам, засчитывает ботов или нет - хз)
     
  14. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    По идее твоя задачка должна решаться так. Но т.к. это баккит, то может и не сработать - мне достаточно разделить итемстак камня на 7 и 8 единиц, и оно работать не будет.

    Код:
    /**
    * Проверяем есть ли предметы у игрока в инвентаре
    * @param who у какого игрока проверяем
    * @param items что проверяем
    * @return true если всё есть, иначе false.
    */
    private boolean hasItems(Player who, List<ItemStack> items) {
        PlayerInventory inventory = who.getInventory();
        for (ItemStack is : items) {
            //TODO: Сделать свою реализацию containsAtLeast, т.к. баккитовский
            //      полнейшее говно.
            if (!inventory.containsAtLeast(is, is.getAmount())) {
                return false;
            }
        }
        return true;
    }
    
    /**
    * Удаляем предметы из инвентаря
    * @param who у какого игрока удаляем
    * @param items какие предметы удаляем
    * @return true если предметы удалены, иначе false
    */
    public boolean removeItemsFromInventory(Player who, List<ItemStack> items) {
        if (!this.hasItems(who, items)) {
            return false;
        }
        PlayerInventory inventory = who.getInventory();
        ItemStack[] array = items.toArray(new ItemStack[items.size()]);
        //TODO: Сделать свою реализацию удаления предметов.
        return inventory.removeItem(array).isEmpty();
    }
     
  15. GreenBudgie

    GreenBudgie Ньюби Пользователь

    Баллы:
    1
    Я тебе скинул код и это был не тот код, который был тебе нужен. Я просто неправильно тебя понял, а ты уже кричишь.
     
  16. Автор темы
    iD3LSY

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

    Баллы:
    46
    Имя в Minecraft:
    opy
    Чувак, это не "крики". Я выделил текст .-.;
    Твой код абсолютно неуместен. У меня он уже есть, но поменьше у меня уж будет.
    containsAtLeast - выполняет как раз все те функции, о которых я говорил выше. Конечно, моя формулировка убивает, но все же, спасибо. Тему закрываю.
     
Статус темы:
Закрыта.

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