Помогите Проблема с "getLore().contains()".

Статус
Закрыто для дальнейших ответов.

VirtualGuys

Активный участник
Пользователь
Баллы
61
Добрый день! Я пишу свой первый плагин, и у меня снова проблема. Мой плагин добавляет конфеты, и при съедании этих конфет, на игрока должны накладываться эффекты. Чтобы проверить, какую конфету съел игрок, и было ли это вообще конфетой, я проверяю lore предмета. У меня в lore везде по 4 строчки. И если я проверяю только одну, то в итоге ничего не происходит. Я попробовал убрать из lore все строчки кроме одной, и тогда всё стало работать. Я раньше не использовал проверку на lore, и не знаю, должно ли быть так, как у меня всё это происходит, или нет? Если так и должно быть, то что тогда делать, как проверять все строчки сразу, а если нет, то в чём ошибка?
Код Проверки:
Код:
ItemStack item = new ItemStack(Material.APPLE); //Создаю конфету
Код:
@EventHandler

    public void onSweetEat(PlayerItemConsumeEvent i) {
        Player r = i.getPlayer(); //Получаю игрока
        PotionEffectType heal = PotionEffectType.REGENERATION; //Список эффектов
        PotionEffectType strong = PotionEffectType.INCREASE_DAMAGE;
        PotionEffectType speed = PotionEffectType.SPEED;
        PotionEffectType jump = PotionEffectType.JUMP;
        PotionEffectType fire = PotionEffectType.FIRE_RESISTANCE;
        PotionEffectType water = PotionEffectType.WATER_BREATHING;
        if(i.getItem().isSimilar(item)) { //Проверяю, что это нужный предмет
        if(i.getItem().getItemMeta().hasLore() == true) { //Проверяю, что у него есть lore
        if(i.getItem().getItemMeta().getLore().contains(ChatColor.YELLOW + "" + ChatColor.BOLD + "Эта вкусная конфетка")) { //Проверяю, есть ли нужная строка
        if(!(r.hasMetadata("AlreadyEaten"))) { //Проверяю, не была ли конфета съедена до этого
            r.addPotionEffect(new PotionEffect(heal, 3600, 2)); //Накладываю эффекты
            r.addPotionEffect(new PotionEffect(strong, 3600, 2));
            r.addPotionEffect(new PotionEffect(speed, 3600, 1));
            r.setMetadata("AlreadyEaten", new FixedMetadataValue(plugin, true)); //Устанавливаю, что конфета теперь съедена
            return;
    } else if (r.hasMetadata("AlreadyEaten")) {
        if(!(r.hasPermission("sweets.newsweet"))) {
        r.getInventory().remove(item);
        r.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "Вы уже скушали конфету новичка!");
        r.setMetadata("AlreadyEaten", new FixedMetadataValue(plugin, true));
        return;
      } else if(r.hasPermission("sweets.newsweet")) {
            r.addPotionEffect(new PotionEffect(heal, 3600, 2));
            r.addPotionEffect(new PotionEffect(strong, 3600, 2));
            r.addPotionEffect(new PotionEffect(speed, 3600, 1));
            r.setMetadata("AlreadyEaten", new FixedMetadataValue(plugin, true));
            return;
          }
        }
      }
    } else {
        return;
    }
  }
Lore накладываю вот так:
Код:
@EventHandler
    public void join(PlayerJoinEvent e) {
        Player p = e.getPlayer(); //Получаю игрока
        Boolean s = plugin.getConfig().getBoolean("sweets.joinsweet"); //Здесь проверяю разрешение в конфиге
        if(s == true) {
        if(!(p.hasPlayedBefore())) { //Если играет в первый раз
            ItemMeta meta = item.getItemMeta(); //Получаю meta
            meta.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD + "Целебная Конфетка"); //Устанавливаю название
            ArrayList<String> lore = new ArrayList<String>(); //Создаю lore
            lore.add(ChatColor.YELLOW + "" + ChatColor.BOLD + "Эта вкусная конфетка"); 
            lore.add(ChatColor.WHITE + "" + ChatColor.BOLD + "вылечит ваше здоровье,");
            lore.add(ChatColor.YELLOW + "" + ChatColor.BOLD + "прибавит силы, и");
            lore.add(ChatColor.WHITE + "" + ChatColor.BOLD + "даст новое дыхание!");
            meta.setLore(lore); //Устанавливаю lore
            item.setItemMeta(meta); //Устанавливаю meta
            p.getInventory().addItem(item); //Выдаю предмет
        }
    }
В интернете ничего не нашёл. Заранее спасибо!
 
ItemStack i = p.getItemInHand();
if (i == null || i.getType() != Material.твой_материал || !i.hasItemMeta()) return;
ItemMeta meta = i.getItemMeta();
List<String> lore = meta.getLore();
if( !lore.get(N).equals("Тут первоя строка твоего лора"))
return;
//После return; можно зделать что-то предмету.
//Там где N количество лора, начиная от 0.
 
В главном классе плагина сделай приватное статичное поле ItemStack
private static ItemStack sweet = null;

При инициализации плагина то есть в onEnable() создай нужный ItemStack со всеми параметрами и лорами.
Потом присвой это полю sweet.

Далее создай метод
Код:
public static ItemStack getItemStackSweet() {
return sweet.clone(); // Вернет копию твоей конфеты
}

Теперь когда ты в памяти держишь конфету, можешь ее сравнивать.

В методе на проверку, получай предполагаемую конфету и сравнивай ее с той что в памяти методом
Код:
item.isSimilar(getItemStackSweet()); //Полностью сравнивает оба предмета без учета количества. Лор тоже сравнивается.

Таким образом не нужно копировать сотни раз одно и тоже для сравнивания, когда за нас уже это делает Bukkit.
 
В главном классе плагина сделай приватное статичное поле ItemStack
private static ItemStack sweet = null;

При инициализации плагина то есть в onEnable() создай нужный ItemStack со всеми параметрами и лорами.
Потом присвой это полю sweet.

Далее создай метод
Код:
public static ItemStack getItemStackSweet() {
return sweet.clone(); // Вернет копию твоей конфеты
}

Теперь когда ты в памяти держишь конфету, можешь ее сравнивать.

В методе на проверку, получай предполагаемую конфету и сравнивай ее с той что в памяти методом
Код:
item.isSimilar(getItemStackSweet()); //Полностью сравнивает оба предмета без учета количества. Лор тоже сравнивается.

Таким образом не нужно копировать сотни раз одно и тоже для сравнивания, когда за нас уже это делает Bukkit.
Всё работает, спасибо, но у меня почему-то постоянно какая-то проблема, что после перезагрузки сервера, проверка больше не работает. Т.е до перезагрузки всё хорошо, а потом выключаю, включаю, и конфеты больше ничего не делают, просто обычная еда и всё. При этом описание, название и всё остальное показывает. В чём может быть проблема?
P.S: Я раньше проверял другим способом, не очень правильным, и была та же самая проблема. Думал, что проверка описания всё исправит, но нет.
 
ItemStack i = p.getItemInHand();
if (i == null || i.getType() != Material.твой_материал || !i.hasItemMeta()) return;
ItemMeta meta = i.getItemMeta();
List<String> lore = meta.getLore();
if( !lore.get(N).equals("Тут первоя строка твоего лора"))
return;
//После return; можно зделать что-то предмету.
//Там где N количество лора, начиная от 0.
Не очень подходит потому, что у меня lore и if в разных ивентах.
 
Всё работает, спасибо, но у меня почему-то постоянно какая-то проблема, что после перезагрузки сервера, проверка больше не работает. Т.е до перезагрузки всё хорошо, а потом выключаю, включаю, и конфеты больше ничего не делают, просто обычная еда и всё. При этом описание, название и всё остальное показывает. В чём может быть проблема?
P.S: Я раньше проверял другим способом, не очень правильным, и была та же самая проблема. Думал, что проверка описания всё исправит, но нет.
Какое ядро?
Какая версия?
Какой то плагин возможно изменяет у игрока предмет, из-за чего он не сравнивается.
 
Какое ядро?
Какая версия?
Какой то плагин возможно изменяет у игрока предмет, из-за чего он не сравнивается.
Ядро Spigot
Версия: 1.8.8
Плагины стоят только EssentialsX, WorldEdit и WorldGuard.
UPDATE: Убрал все плагины кроме своего, и всё равно не сработало
 
Последнее редактирование:
Ядро Spigot
Версия: 1.8.8
Плагины стоят только EssentialsX, WorldEdit и WorldGuard.
UPDATE: Убрал все плагины кроме своего, и всё равно не сработало
Добавь дебаг сообщение, выведи в него булиан, удалось ли сравнить оба предмета.
 
Добавь дебаг сообщение, выведи в него булиан, удалось ли сравнить оба предмета.
До перезагрузки, выдаёт что предметы одинаковые (true), всё нормально. А после перезагрузки, выдаёт что они разные (false). Ещё заметил, что предметы становятся такими не только после перезагрузки, а даже после команды /reload.
 
До перезагрузки, выдаёт что предметы одинаковые (true), всё нормально. А после перезагрузки, выдаёт что они разные (false). Ещё заметил, что предметы становятся такими не только после перезагрузки, а даже после команды /reload.
Чел, метадата кажется удаляется с предмета после релоада, но эт не точно
 
До перезагрузки, выдаёт что предметы одинаковые (true), всё нормально. А после перезагрузки, выдаёт что они разные (false). Ещё заметил, что предметы становятся такими не только после перезагрузки, а даже после команды /reload.
Записывай это все в localizedname, оно сохраняется всегда.
 
Записывай это все в localizedname, оно сохраняется всегда.
А как записывать в localizedname? Просто первый раз про него слышу, и опять же в интернете ничего не нашёл.

А ещё, я кажется понял причину. Тот item который я получаю, и который я сравниваю. У него пропадает мета после перезагрузки. Визуально есть, а на самом деле нет.
Код:
@EventHandler
    public void join(PlayerJoinEvent e) {
        Player p = e.getPlayer();
        Boolean s = plugin.getConfig().getBoolean("sweets.joinsweet");
        if(s == true) {
        if((p.hasPlayedBefore())) {
            ItemMeta meta = item.getItemMeta();
            meta.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD + "Целебная Конфетка");
            ArrayList<String> lore = new ArrayList<String>();
            lore.add(ChatColor.YELLOW + "" + ChatColor.BOLD + "Эта вкусная конфетка");
            lore.add(ChatColor.WHITE + "" + ChatColor.BOLD + "вылечит ваше здоровье,");
            lore.add(ChatColor.YELLOW + "" + ChatColor.BOLD + "прибавит силы, и");
            lore.add(ChatColor.WHITE + "" + ChatColor.BOLD + "даст новое дыхание!");
            meta.setLore(lore);
            item.setItemMeta(meta);
            p.getInventory().addItem(item);
        }
    }
Если перезайти на сервер, то всё снова начинает работать. Значит нужно просто создание meta перенести куда нибудь в другое место, где оно будет создавать каждый раз при включении сервера например. А что вообще лучше, использовать localizedname или перенести этот код в другое место?
P.S: Раньше не замечал этого, из-за криво написанного кода, в котором куча проверок и в котором непонятно, что с чем проверятся вообще.
 
lore1.equals(lore2); Если порядок строк не меняется. Если меняется, то lore.contains(strins); и так с каждой строкой проделать.
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх