Кулдаун у предметов

scrimers

Premium
Сообщения
37
1.12.2
Как можно сделать кулдаун после использования предмета, например накладывается эффект на игрока при каком то условии, и он не может повторить наложение сек 10

От модератора: Готовый вариант написан здесь *тык*.
 
Последнее редактирование модератором:
мне прост не понятно, я пишу вместо else и остальной код
Java:
public class Handler implements Listener{
    public static HashMap<UUID, Integer> map = new HashMap<>();
    @EventHandler
    public void use(PlayerInteractEvent e) {
        Player p = e.getPlayer();
        if(e.getAction() == Action.RIGHT_CLICK_AIR) {
         
            if (p.getInventory().getItemInMainHand().getItemMeta().getDisplayName().equals(ChatColor.DARK_AQUA +"Muramasa")) {
                if(map.containsKey(p.getUniqueId())) {
                    int cd = map.get(p.getUniqueId());
                    p.sendMessage("Вы не можете делать это ещё "+cd+" сек!");}
                    else
                        p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,3 ,40));
                        p.playSound(p.getLocation(), Sound.ENTITY_FIREWORK_LAUNCH, 10, 3);
                        map.put(p.getUniqueId(),5);
                }
            }
           
     
    }
}

Да, это он.


Java:
if(map.containsKey(p.getUniqueId())) {
    //Код, если содержится в хеше
    int cd = map.get(p.getUniqueId());
    p.sendMessage("Вы не можете делать это ещё "+cd+" сек!");
}



Но тогда у меня вообще все время шлет сообщение(точнее срабатывает один раз после перезагрузки а дальше таймер крутит
 
Последнее редактирование:
scrimers,
Java:
if(map.containsKey(p.getUniqueId())) {
    int cd = map.get(p.getUniqueId());
    p.sendMessage("Вы не можете делать это ещё "+cd+" сек!");}
} else {
    p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,3 ,40));
    p.playSound(p.getLocation(), Sound.ENTITY_FIREWORK_LAUNCH, 10, 3);
    map.put(p.getUniqueId(),5);
}
 
Класс, отвечающий за задержку
Java:
public class CooldownManager {
   private final Map<UUID, Integer> cooldowns = new HashMap();

   public void setCooldown(UUID player, int time) {
      if (time < 1) {
         this.cooldowns.remove(player);
      } else {
         this.cooldowns.put(player, time);
      }
   }
    
   public int getCooldown(UUID player) {
      return this.cooldowns.getOrDefault(player, 0);
   }
}
В том классе, где нужна задержка:

Java:
        private final CooldownManager cm = new CooldownManager();

        public void coolMethod(Player player) {
            int timeLeft = this.cm.getCooldown(player.getUniqueId());
            if (timeLeft == 0) {
                this.cm.setCooldown(player.getUniqueId(), Config.cooldown);
                (new BukkitRunnable() {
                    public void run() {
                        int timeLeft = this.cm.getCooldown(player.getUniqueId());
                        CooldownManager var10000 = this.cm;
                        UUID var10001 = player.getUniqueId();
                        --timeLeft;
                        var10000.setCooldown(var10001, timeLeft);
                        if (timeLeft == 0) {
                            this.cancel();
                        }
                    }
                }).runTaskTimer(plugin, 20L, 20L);
            } else {
                player.sendMessage("падаждите");
            }
        }
Громоздко и страшно, но это работает. Ну а еще не пугайтесь, тут последствия декомпила...
 
BuseSo, ничего не помогает, спустя час собственноручного копания я кое что смог исправить, теперь эффект выдается для нужного оружия, но таймер не сбрасывает сам себя после истечении времени, ошибка где то в таймере
Java:
public class Handler implements Listener{
    public static HashMap<UUID, Integer> map = new HashMap<>();
    @EventHandler
    public void use(PlayerInteractEvent e) {
        Player p = e.getPlayer();
        if(e.getAction() == Action.RIGHT_CLICK_AIR) {
            if (p.getInventory().getItemInMainHand() == null) return;
            p.sendMessage("1");
            if (!p.getInventory().getItemInMainHand().hasItemMeta()) return;
            p.sendMessage("2");
            if (p.getInventory().getItemInMainHand().getItemMeta().getDisplayName().equals(ChatColor.DARK_AQUA +"Muramasa")) { 
                p.sendMessage("3");
                if(map.containsKey(p.getUniqueId())) {
                   if(map.containsKey(p.getUniqueId())) {
                        int cd = map.get(p.getUniqueId());
                        p.sendMessage("Вы не можете делать это ещё "+cd+" сек!");}
                    } else {
                        p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,3 ,40));
                        p.playSound(p.getLocation(), Sound.ENTITY_FIREWORK_LAUNCH, 10, 3);
                        map.put(p.getUniqueId(),5);
                    
                    }
        }
    }
}
}
-------------- Timer
package newea.main;

import java.util.UUID;

import org.bukkit.scheduler.BukkitRunnable;

public class Timer extends BukkitRunnable {
    @Override
    public void run() {
        for(UUID uuid : Handler.map.keySet()) {
            int time =  Handler.map.get(uuid);
            
            if(time == 0) {
                 Handler.map.remove(uuid);
            } else {
                Handler.map.put(uuid, time-1);
            }
        }
    }
}
Авто объединение сообщений:

q20w26a, не могу понять как второй код использовать, мне надо как то из этого в условие превратить
 
Последнее редактирование:
Так пишу как надо делать таймер(для таких же тупых как я)
Java:
-----------Main
@Override
    public void onEnable() {
        new Timer().runTaskTimer(this, 20, 20);//понятия не имею, что эта команда делает
-----------Handler
public class Handler implements Listener{
    public static HashMap<UUID, Integer> map = new HashMap<>();
    @EventHandler
    public void use(PlayerInteractEvent e) {
        Player p = e.getPlayer();
        if(e.getAction() == Action.RIGHT_CLICK_AIR) {
            if (p.getInventory().getItemInMainHand() == null) return;//проверка обьекта
            if (!p.getInventory().getItemInMainHand().hasItemMeta()) return;//проверка обьекта
            if (p.getInventory().getItemInMainHand().getItemMeta().getDisplayName().equals("НАЗВАНЕ ПРЕДМЕТА"))//проверка обьекта
            { 
                if(map.containsKey(p.getUniqueId())) {
                   if(map.containsKey(p.getUniqueId())) {
                        int cd = map.get(p.getUniqueId());
                        p.sendMessage("Вы не можете делать это ещё "+cd+" сек!");}//сооб об ошибке
                    } else {
                    p.add// сюда ваше условие
                    map.put(p.getUniqueId(),3);//время в сек
}}}}
---------------------Timer
import java.util.UUID;

import org.bukkit.scheduler.BukkitRunnable;

public class Timer extends BukkitRunnable {
    @Override
    public void run() {
        for(UUID uuid : Handler.map.keySet()) {
            int time =  Handler.map.get(uuid);
            
            if(time == 0) {
                 Handler.map.remove(uuid);
            } else {
                Handler.map.put(uuid, time-1);//установка времени
            }
        }
    }
}
 
q20w26a,
Код:
Bukkit.getScheduler().runTaskTimerAsynchronously(this, fireworkCoolDownMap::clear, 0L, c.getFireWorkCoolDown()*20L);

Тут пример очищения мапы куллдаунов. Суть в том, что при использовании фейерверка я просто сую игрока в мапу HashMap<String, CoolDown> и запрещаю действие пока он там. Очищаю же его примером выше

P.S Чекать мапу в главном потоке вообще бред.
 
Назад
Сверху Снизу