1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Задержка на использование жемчуга и плодов хоруса

Тема в разделе "Разработка плагинов для новичков", создана пользователем WhileInside, 31 окт 2020.

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

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

    Баллы:
    66
    Имя в Minecraft:
    WhileInside
    Как можно сделать задержку на жемчуг эндера и плодов хоруса при определённом условии?

    Сделал вот такой метод

    Код:
        private void useItem(ItemStack item, Player player) {
            if (item.getType() != Material.CHORUS_FRUIT && item.getType() != Material.ENDER_PEARL) {
                return;
            }
    
            //if (!combatManager.isFighting(player)) {
            //    return;
            //}
    
            player.setCooldown(item.getType(), 15 * 20);
        }
    Вызываю его во время PlayerLaunchProjectileEvent и PlayerItemConsumeEvent, вроде бы .setCooldown вызывается (выводил сообщение в чат), но никакое кд не ставиться.

    P.S Делать тасками или в мапе хранить время не особо хочется, но если не будет других вариантов, то похоже придётся.
     
  2. Exception_Prototype

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

    Баллы:
    96
    У меня никогда не возникало проблем с этим методом. Какая версия сервера и ядро?
     
  3. Автор темы
    WhileInside

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

    Баллы:
    66
    Имя в Minecraft:
    WhileInside
    1.16.3, пробовал paper и tuinity
     
  4. Exception_Prototype

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

    Баллы:
    96
    На всякий случай спрошу, у тебя установка cd в основном потоке выполняется? Никаких async не кидаешь?
     
  5. Автор темы
    WhileInside

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

    Баллы:
    66
    Имя в Minecraft:
    WhileInside
    Метод вызывается в двух обработчиках эвентов, эвенты вроде бы синхронные, так что да, в основном
     
  6. Fairwol

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

    Баллы:
    61
    С "Хорусом" можно вот так сделать, а с "Жемчугом эндера" аналогично, но будет ивент PlayerInteractEvent;

    Код:
        private HashMap<String, Long> chorusItems = new HashMap<>();
        private long timeChorus = 40000;
    
        @EventHandler
        public void onConsumItem(PlayerItemConsumeEvent event) {
            Player player = event.getPlayer();
    
            if (event.getItem().getType() == Material.CHORUS_FRUIT) {
                if (cdChorus(player.getName())) {
                    player.sendMessage("§7Использовал §f\"Плод хоруса\"§7.");
                    return;
                }
                long message = chorusItems.get(player.getName()) - System.currentTimeMillis();
                player.sendMessage("§7У вас кд, ждите§f " + String.valueOf(message / 1000L) + " §7секунд.");
                event.setCancelled(true);
            }
        }
    
    public boolean cdChorus(String player) {
            if (!chorusItems.keySet().contains(player) || chorusItems.get(player) < System.currentTimeMillis()) {
                chorusItems.put(player, System.currentTimeMillis() + timeChorus);
                return true;
            }
            return false;
        }
     
    Последнее редактирование: 3 ноя 2020
  7. Автор темы
    WhileInside

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

    Баллы:
    66
    Имя в Minecraft:
    WhileInside
    Смотри постскриптум:
    Ладно, я так понял, Bukkit почему-то не хочет ставить кд

    Я уже сделал мапой, так что всем спасибо, вот примерно такой код получился:

    Код:
        private final TObjectLongMap<Player> cooldowns
                = new TObjectLongHashMap<>();
    
        @EventHandler(priority = LOWEST)
        public void onQuit(PlayerQuitEvent event) {
            cooldowns.remove(event.getPlayer());
        }
    
        @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
        public void onProjectile(PlayerLaunchProjectileEvent event) {
            boolean result = useItem(event.getItemStack(), event.getPlayer());
    
            if (result) {
                event.setCancelled(true);
            }
        }
    
        @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
        public void onConsume(PlayerItemConsumeEvent event) {
            boolean result = useItem(event.getItem(), event.getPlayer());
    
            if (result) {
                event.setCancelled(true);
            }
        }
    
        private boolean useItem(ItemStack item, Player player) {
            if (item.getType() != Material.CHORUS_FRUIT && item.getType() != Material.ENDER_PEARL) {
                return false;
            }
    
            long now = System.currentTimeMillis();
            long usageAvailableAt = cooldowns.get(player);
    
            if (now < usageAvailableAt) {
                // todo send message
                return true;
            }
    
            if (!combatManager.isFighting(player)) {
                return false;
            }
    
            cooldowns.put(player, now + 15_000);
    
            return false;
        }
     
Статус темы:
Закрыта.

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