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

  • Автор темы Автор темы iD3LSY
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

iD3LSY

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

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

Буду рад любой идеи/коду. Если у вас есть предложения на счет "погугли", советую сразу нажать Alt+←.
 
гет контейнс и там в for()
Ну я проверял просто for(int t = 0; t < player.getInventory().getSize(); t++) {}, но один хрен. Окей, contains. Он как я понял может проверять на наличие материала/itemstack. Материал - не проверим лор; itemstack - не проверим количеством.
Конечно, можно их свести к одному количеству.
Java:
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)) {
            // код
        }
    }
}
Но при этом, это либо нужно записывать слот + материал + количество. Тогда я уже не получу удаление предметов по всем слотам. (ну... Или я так думаю)
 
Java:
    public void checkItem(ItemStack item, ItemStack itemOther, Player p) {
        if(item.getType()==itemOther.getType()) {
            p.getInventory().remove(item);
        }
    }
 
Java:
    public void checkItem(ItemStack item, ItemStack itemOther, Player p) {
        if(item.getType()==itemOther.getType()) {
            p.getInventory().remove(item);
        }
    }
Чувааак, ну в том то и дело) Тут у тебя нету никакой проверки: материала, даты, количества, лора. Ну ладно, это не так уж и сложно, но думаю найду себе еще проблем со слотами.
Кстати, самое важное. Проверка идет не на 1 предмет. Пишу я некие задания, которые заключаются в добыче ресурсов, поэтому количество предметов установленное для задачи не-из-вест-но
 
Чувааак, ну в том то и дело) Тут у тебя нету никакой проверки: материала, даты, количества, лора. Ну ладно, это не так уж и сложно, но думаю найду себе еще проблем со слотами.
Кстати, самое важное. Проверка идет не на 1 предмет. Пишу я некие задания, которые заключаются в добыче ресурсов, поэтому количество предметов установленное для задачи не-из-вест-но
Ну так допиши и будет остальное чекать.
 
Ну вот мне и нужно понять, как сделать проверку на несколько предметов с учетом того, что будет работать, если 2 слота положить...
Ну вот твоя же форка тут уместна, найдет везде.

Java:
    @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);
            }
        }
    }
 
Я не понимаю, ты рофлишь? Чувак, я тебе уже несколько раз написал. В нескольких слотах лежат предметы разных типов, с разным количеством, с лором и без. В конфиге у меня есть надпись
YAML:
- STONE:0 15
- WOOD:0 5 lore:Привет!
Проверяется каждый предмет, делаю проверку на наличие, потом снимаю предметы, потом делаю выводы, все ли предметы удалось удалить, с учетом, что предметы одного типа могли лежать в разных слотах. Все! Я не знаю как это реализовать без говнокода...
 
Я не понимаю, ты рофлишь? Чувак, я тебе уже несколько раз написал. В нескольких слотах лежат предметы разных типов, с разным количеством, с лором и без. В конфиге у меня есть надпись
YAML:
- STONE:0 15
- WOOD:0 5 lore:Привет!
Проверяется каждый предмет, делаю проверку на наличие, потом снимаю предметы, потом делаю выводы, все ли предметы удалось удалить, с учетом, что предметы одного типа могли лежать в разных слотах. Все! Я не знаю как это реализовать без говнокода...
Ну так допиши item.getItemMeta().getLore(), сложно?
 
Последнее редактирование:
Чего человека мучать? Вот тебе код.
Java:
    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 - минимальное и максимальное количество предметов.
Вот пример использования:
Java:
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. Надеюсь, это именно тот код, который тебе был нужен)
 
Чего человека мучать? Вот тебе код.
Java:
    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 - минимальное и максимальное количество предметов.
Вот пример использования:
Java:
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. Надеюсь, это именно тот код, который тебе был нужен)
Мдее, я хз, кто тут кого мучает, но видимо от этой темы толку ноль. Я прошу лишь ИДЕЮ. Писал уже 2 раза, что там не 1 предмет (НЕ КОЛИЧЕСТВО, АITEMSTACK НЕ 1) может быть. Впрочем, не стоило всегда рассчитывать на rubukkit.
Напишу - сам кину сюда, ибо видимо реально идею придумать никто не может (сужу по просмотрам, засчитывает ботов или нет - хз)
 
По идее твоя задачка должна решаться так. Но т.к. это баккит, то может и не сработать - мне достаточно разделить итемстак камня на 7 и 8 единиц, и оно работать не будет.

Java:
/**
* Проверяем есть ли предметы у игрока в инвентаре
* @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();
}
 
Я тебе скинул код и это был не тот код, который был тебе нужен. Я просто неправильно тебя понял, а ты уже кричишь.
Чувак, это не "крики". Я выделил текст .-.;
Твой код абсолютно неуместен. У меня он уже есть, но поменьше у меня уж будет.
По идее твоя задачка должна решаться так. Но т.к. это баккит, то может и не сработать - мне достаточно разделить итемстак камня на 7 и 8 единиц, и оно работать не будет.

Java:
/**
* Проверяем есть ли предметы у игрока в инвентаре
* @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();
}
containsAtLeast - выполняет как раз все те функции, о которых я говорил выше. Конечно, моя формулировка убивает, но все же, спасибо. Тему закрываю.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх