Как отследить запуск фейерверка с nbt игроком?

MarinCod

Пользователь
Сообщения
81
У меня есть пуля для мушкета. Это замененный фейерверк, а мушкет - арбалет.
Мне нужно, чтобы эту пулю нельзя было запустить как фейерверк.

Я знаю как отменять действия, если, например в главной руке у тебя итем с каким-нибудь названием, но здесь ситуация немного другая.
Мне нужно отменять именно запуск фейерверка, потому что иначе я отменю и зарядку арбалета.

Скорее всего написал непонятно, так что просто напишу, что мне нужен какой-то способ отследить, что игрок запускает фейерверк. И если он с определенным названием, то отменять именно запуск фейерверка, а не все действия. Скорее всего, это PlayerInteractEvent
 
Решение
Немного не то. Проблема происходит не при выстреле, а при зарядке скажем так.
В левой руке у нас арбалет, а в правой фейерверк. Мне нужно, чтобы когда ты смотрел на землю, то не мог запустить этот фейерверк. То есть это именно как снаряд, а не обычный фейерверк.

Я сейчас пока это писал, подумал. А что если просто проверять, нажимал ли игрок правой кнопкой мыши по блоку, и если да, то отменять действие. Если же правая кнопка мыши была по воздуху, то не отменять. Пройдет такой вариант?
Если отменить, то у игрока будет может быть верное количество предметов.
Обновить предметы можно при помощи setAmount, или любой другой способ обновления предметов.

Java:
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {...
У меня есть пуля для мушкета. Это замененный фейерверк, а мушкет - арбалет.
Мне нужно, чтобы эту пулю нельзя было запустить как фейерверк.

Я знаю как отменять действия, если, например в главной руке у тебя итем с каким-нибудь названием, но здесь ситуация немного другая.
Мне нужно отменять именно запуск фейерверка, потому что иначе я отменю и зарядку арбалета.

Скорее всего написал непонятно, так что просто напишу, что мне нужен какой-то способ отследить, что игрок запускает фейерверк. И если он с определенным названием, то отменять именно запуск фейерверка, а не все действия. Скорее всего, это PlayerInteractEvent
Существует событие , которое вызывается, когда живое существо стреляет из лука или арбалета.
Получить предмет, которым стреляет живая сущность можно из лука/арбалета ((CrossbowMeta) event.getBow().getItemMeta()).getChargedProjectiles().get(0)

Не забываем проверить, что кодировка поддерживает символы с которым вы сравниваете название.

Пример (Не включает проверку на то что живая сущность является игроком):
Java:
    public void crossBowShoot(EntityShootBowEvent event) { //Событие происходит когда сущность, стреляет из арбалета

      if (event.getBow().getType() == Material.CROSSBOW) { //Проверяем что живое существо стреляет из арбалета

        ItemStack projectile = ((CrossbowMeta) event.getBow().getItemMeta()).getChargedProjectiles().get(0); //Получим предмет, которым стреляет живое существо

        if (projectile.getType().equals(Material.FIREWORK_ROCKET)) { //Проверим являться ли предмет фейерверком

          if (projectile.getItemMeta().getDisplayName().equals("Some Name")) { //Сравним название снаряда с нужным нам  названием (Я бы использовал PersistentDataContainer а не название)

            //Выполняем нужные действия
            //Например отправим сообщение живой сущности
            event.getEntity().sendMessage("You shot firework rocket with name \"Some Name\"");
            //event.getProjectile().getVelocity(); //Получить вектор фейерверка (сущности)
            //event.getProjectile().getLocation(); //Получить позицию фейерверка (сущности)
            event.getProjectile().remove(); // Удаляем фейерверк (сущность)
          }

        }
      }
    }
 
Последнее редактирование:
Немного не то. Проблема происходит не при выстреле, а при зарядке скажем так.
В левой руке у нас арбалет, а в правой фейерверк. Мне нужно, чтобы когда ты смотрел на землю, то не мог запустить этот фейерверк. То есть это именно как снаряд, а не обычный фейерверк.

Я сейчас пока это писал, подумал. А что если просто проверять, нажимал ли игрок правой кнопкой мыши по блоку, и если да, то отменять действие. Если же правая кнопка мыши была по воздуху, то не отменять. Пройдет такой вариант?
 
Немного не то. Проблема происходит не при выстреле, а при зарядке скажем так.
В левой руке у нас арбалет, а в правой фейерверк. Мне нужно, чтобы когда ты смотрел на землю, то не мог запустить этот фейерверк. То есть это именно как снаряд, а не обычный фейерверк.

Я сейчас пока это писал, подумал. А что если просто проверять, нажимал ли игрок правой кнопкой мыши по блоку, и если да, то отменять действие. Если же правая кнопка мыши была по воздуху, то не отменять. Пройдет такой вариант?
Если отменить, то у игрока будет может быть верное количество предметов.
Обновить предметы можно при помощи setAmount, или любой другой способ обновления предметов.

Java:
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
    if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
        if (event.getItem().getType() == Material.FIREWORK_ROCKET) { //Проверяем что у игрока в руке фейерверк
                event.setCancelled(true);
                if(event.getPlayer().getInventory().getItemInOffHand().getType() == Material.CROSSBOW) {
                    event.getPlayer().setCooldown(Material.FIREWORK_ROCKET, 6); //Добавляем задержку фейерверку чтобы даже когда игрок смотрит на блок смог зарядить арбалет
                } else {
                    event.getPlayer().getInventory().getItemInMainHand().setAmount(event.getPlayer().getInventory().getItemInMainHand().getAmount()); //Просто обновляем количество предметов
                }
            }
    }
}
Изменено: перенёс часть кода в else.
 
Последнее редактирование:
Спасибо, буду пробовать.
Правда не очень понял момент про обновление предметов
Я при проверке получил не обновленный предмет (Не правильное количество). Скорее всего это происходит очень редко, но я получил такую ошибку (ошибка вроде бы не происходит если в руке у игрока арбалет).
 
А, вроде понял.
Большое спасибо за ответ)
Авто объединение сообщений:

Я при проверке получил не обновленный предмет (Не правильное количество). Скорее всего это происходит очень редко, но я получил такую ошибку (ошибка вроде бы не происходит если в руке у игрока арбалет).
Java:
    if(e.getAction() == Action.RIGHT_CLICK_BLOCK) {
            if (e.getItem().getType() == Material.FIREWORK_ROCKET) {
                e.getPlayer().sendMessage("Это фейерверк");
                if (e.getPlayer().getInventory().getItemInMainHand().getItemMeta().getDisplayName().equals(ChatColor.AQUA + "Пуля для Мушкета")) {
                    e.getPlayer().sendMessage("Действие должно отменится");
                    e.setCancelled(true);
                    if(e.getPlayer().getInventory().getItemInOffHand().getType() == Material.CROSSBOW) {
                        e.getPlayer().setCooldown(Material.FIREWORK_ROCKET, 6); //Добавляем задержку фейерверку чтобы даже когда игрок смотрит на блок смог зарядить арбалет
                    } else {
                        e.getPlayer().getInventory().getItemInMainHand().setAmount(e.getPlayer().getInventory().getItemInMainHand().getAmount()); //Просто обновляем количество предметов
                    }
                }
            }
        }

Попробовал ваш код, вроде всё отлично, работает прямо как я хотел, но почему-то запуск фейерверка не отменяется. То есть я даже отправляю сообщение о том, что действие должно отменится, вроде как строка должна работать, но фейерверк всё равно запускается. Случаем не знаете в чём проблема?
 
Последнее редактирование:
А, вроде понял.
Большое спасибо за ответ)
Авто объединение сообщений:


Java:
    if(e.getAction() == Action.RIGHT_CLICK_BLOCK) {
            if (e.getItem().getType() == Material.FIREWORK_ROCKET) {
                e.getPlayer().sendMessage("Это фейерверк");
                if (e.getPlayer().getInventory().getItemInMainHand().getItemMeta().getDisplayName().equals(ChatColor.AQUA + "Пуля для Мушкета")) {
                    e.getPlayer().sendMessage("Действие должно отменится");
                    e.setCancelled(true);
                    if(e.getPlayer().getInventory().getItemInOffHand().getType() == Material.CROSSBOW) {
                        e.getPlayer().setCooldown(Material.FIREWORK_ROCKET, 6); //Добавляем задержку фейерверку чтобы даже когда игрок смотрит на блок смог зарядить арбалет
                    } else {
                        e.getPlayer().getInventory().getItemInMainHand().setAmount(e.getPlayer().getInventory().getItemInMainHand().getAmount()); //Просто обновляем количество предметов
                    }
                }
            }
        }

Попробовал ваш код, вроде всё отлично, работает прямо как я хотел, но почему-то запуск фейерверка не отменяется. То есть я даже отправляю сообщение о том, что действие должно отменится, вроде как строка должна работать, но фейерверк всё равно запускается. Случаем не знаете в чём проблема?
У меня данный вами код работает. Попробуйте заменить отмену ивента на отрицательный результат в setUseItemInHand .
 
Имеете ввиду написать:
e.setCancelled(false);

?
setCancelled вообще не использовать (setCancelled false в данном случаи не подходит, так как нам не нужно "восстанавливать" событие, которое было отменено ранние). Просто не отменяем событие.
 
Последнее редактирование:
Понял, попробую, спасибо
У вас скорее всего какой то плагин делает setCancelled(false) ("восстанавливает" событие). Попробуйте также увеличить .
 
Последнее редактирование:
Назад
Сверху Снизу