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

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

Discussion in 'Разработка плагинов для новичков' started by iD3LSY, Jun 24, 2017.

Thread Status:
Not open for further replies.
  1. Автор темы
    iD3LSY

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

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

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

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

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

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

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

    Trophy Points:
    46
    Имя в Minecraft:
    opy
    Ну я проверял просто for(int t = 0; t < player.getInventory().getSize(); t++) {}, но один хрен. Окей, contains. Он как я понял может проверять на наличие материала/itemstack. Материал - не проверим лор; itemstack - не проверим количеством.[DOUBLEPOST=1498301613,1498301284][/DOUBLEPOST]Конечно, можно их свести к одному количеству.
    Code:
    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 Администратор

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

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

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

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

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

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

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

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

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

    Code:
        @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 Активный участник Пользователь

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

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

    Trophy Points:
    173
    Skype:
    alexandr0116
    Ну так допиши item.getItemMeta().getLore(), сложно?
     
    Last edited: Jun 24, 2017
  12. GreenBudgie

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

    Trophy Points:
    1
    Чего человека мучать? Вот тебе код.
    Code:
        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 - минимальное и максимальное количество предметов.
    Вот пример использования:
    Code:
    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 Активный участник Пользователь

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

    Dereku Старожил

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

    Code:
    /**
    * Проверяем есть ли предметы у игрока в инвентаре
    * @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 Ньюби Пользователь

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

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

    Trophy Points:
    46
    Имя в Minecraft:
    opy
    Чувак, это не "крики". Я выделил текст .-.;
    Твой код абсолютно неуместен. У меня он уже есть, но поменьше у меня уж будет.
    containsAtLeast - выполняет как раз все те функции, о которых я говорил выше. Конечно, моя формулировка убивает, но все же, спасибо. Тему закрываю.
     
Thread Status:
Not open for further replies.

Share This Page