Помогите После Cooldown не выполняются события

Anion

Участник
Баллы
31
Здравствуйте,я начал писать плагин на способности и столкнулся с такой проблемой.
Есть код (Да-да,он говно)
Код:
package zrt.main;

import java.util.HashMap;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.*********ventory.ItemStack;
import org.*********ventory.meta.ItemMeta;
import org.bukkit.util.Vector;

public class Handler
  implements Listener
{
  private HashMap<UUID, Long> cooldown = new HashMap();
  private int cooldowntime = 40;

  @EventHandler
  public void interact(PlayerInteractEvent e)
  {
   Action a = e.getAction();
   ItemStack item = e.getPlayer().getItemInHand();
   if ((a == Action.LEFT_CLICK_AIR) && (item.getType() != Material.FEATHER)) {
     }
   if ((a == Action.LEFT_CLICK_AIR) && (item.getType() == Material.FEATHER)) {
     return;
   }
   Player p = e.getPlayer();
   Location loc = p.getLocation();
   ItemStack itemi = p.getItemInHand();
   float yaw = loc.getYaw();
   float pitch = loc.getPitch();
   if ((item.getType() == Material.FEATHER) && (itemi.getItemMeta().getDisplayName().equals(ChatColor.WHITE + "Прыжок")))
   {
     if (this.cooldown.containsKey(p.getUniqueId()))
     {
       long secondsleft = ((Long)this.cooldown.get(p.getUniqueId())).longValue() / 1000L + this.cooldowntime - (System.currentTimeMillis()/1000);
       if (secondsleft > 1) {
         p.sendMessage(ChatColor.RED + "Дождитесь отката способности("+ secondsleft+")");
       }
       e.setCancelled(true);
     }
     else
     {
       p.setVelocity(p.getLocation().getDirection().multiply(10));
       this.cooldown.put(p.getUniqueId(), Long.valueOf(System.currentTimeMillis()));
       return;
     }
     e.setCancelled(true);
   } else {
         p.sendMessage(ChatColor.RED + "Дождитесь отката способности");
     }
   e.setCancelled(true);
   if ((item.getType() == Material.BOOK) && (itemi.getItemMeta().getDisplayName().equals("Книга заклинателя стрел"))) {
     p.launchProjectile(Arrow.class);
   }
  }
}


проблема в том,что при использование способности идет cooldown 40 секунд,НО послед cooldown'a вообще ничего не происходит,те даже не пишется "Дождитесь отката способности",прошу помощи.
 
HashMap<UUID, Long> cooldown = new HashMap()
Измени на:
PHP:
Map<UUID, Long> cooldownMap = new HashMap<>();

У тебя кулдаун добавляется только когда его нет, то есть одноразовый кулдаун.
Когда время истекает, то проверка secondsleft > 1 не проходит и ничего не происходит.
Тебе нужно добавлять в мапу новое время, если оно уже истекло и выполнять действие.
Перепиши все, а то очень криво сделал.
 
Если игрок есть в мапе, код никогда не дойдёт к моменту где ты даёшь способность. Лучше бы ты переделал логику этой штуковины, но кажется, можно исправить так:
PHP:
if (secondsleft > 0) {
        p.sendMessage(ChatColor.RED + "Дождитесь отката способности("+ secondsleft+")");
} else {
    //дать способность и записать новое время
}
 
Последнее редактирование:
Если игрок есть в мапе, код никогда не дойдёт к моменту где ты даёшь способность. Лучше бы ты переделал логику этой штуковины, но кажется, можно исправить так:
PHP:
if (secondsleft > 0) {
        p.sendMessage(ChatColor.RED + "Дождитесь отката способности("+ secondsleft+")");
} else {
    //дать способность и записать новое время
}
А как новое время записывать?(Знаю,что я совсем глупый)
 
По хорошему около 6-и классов нужно для нормальной реализации Cooldown-а.
 
Написал в блокноте небольшой пример, если еще надо, могу именно с ним помочь (вроде должно работать, не тестил).
PHP:
Map<UUID, Long> cooldownMap = Maps.newHashMap();
long cooldownInterval = 40; // секунды

public void useAbility(Player player) {
    UUID uuid = player.getUniqueId();

    if(cooldownMap.containsKey(uuid) && cooldownMap.get(uuid) >= System.currentTimeMillis()) {
        cooldownMap.put(uuid, System.currentTimeMillis() + (cooldownInterval * 1000));

        player.sendMessage("Крутая способность применена!");
    } else {
        player.sendMessage("Крутая способность на откате. Осталось " + ((cooldownMap.getOrDefault(uuid, 0) - System.currentTimeMillis()) / 1000) + " секунд.");
    }
}

Минус подобных схем, это то, что все игроки всегда будут в мапе. Можно таймером каждые 5 минут аннулировать уже откатившиеся кулдауны, но это уже дело за тобой)

(ну а если пойдешь на это, то лучше кинь свой взор на Guava Caches)
 
Минус подобных схем, это то, что все игроки всегда будут в мапе. Можно таймером каждые 5 минут аннулировать уже откатившиеся кулдауны, но это уже дело за тобой)
Что-то бред, зачем, это, в мапе хранятся уже находящиеся в памяти UUID и Long-и. Обертка Long весит около 32-40 байтов и на 100 000 игроков это будет ~ 4 мбайт. Как видишь смысла самому очищать мапу нет, это будет происходить только при перезагрузках.
 
Что-то бред, зачем, это, в мапе хранятся уже находящиеся в памяти UUID и Long-и. Обертка Long весит около 32-40 байтов и на 100 000 игроков это будет ~ 4 мбайт. Как видишь смысла самому очищать мапу нет, это будет происходить только при перезагрузках.
Я о таких мелочах не думаю)

Вряд-ли бы он этим занялся, как минимум, а как максимум, докинул бы еще нагрузки. В целом, ты прав, может 5мБ и не так важны (на самом деле, там намного меньше).
 
Последнее редактирование:
Я о таких мелочах не думаю)

Вряд-ли бы он этим занялся, как минимум, а как максимум, докинул бы еще нагрузки. В целом, ты прав, может 5мБ и не так важны (на самом деле, там намного меньше).
100 000 игроков использовавших кулдаун за 1 аптайм это сильное преувеличение, я взял для наглядности, на деле будет в десятки раз меньше и очистка мапы кулдаунов шедулярами это бесполезное дело.
 
Написал в блокноте небольшой пример, если еще надо, могу именно с ним помочь (вроде должно работать, не тестил).
PHP:
Map<UUID, Long> cooldownMap = Maps.newHashMap();
long cooldownInterval = 40; // секунды

public void useAbility(Player player) {
    UUID uuid = player.getUniqueId();

    if(cooldownMap.containsKey(uuid) && cooldownMap.get(uuid) >= System.currentTimeMillis()) {
        cooldownMap.put(uuid, System.currentTimeMillis() + (cooldownInterval * 1000));

        player.sendMessage("Крутая способность применена!");
    } else {
        player.sendMessage("Крутая способность на откате. Осталось " + ((cooldownMap.getOrDefault(uuid, 0) - System.currentTimeMillis()) / 1000) + " секунд.");
    }
}

Минус подобных схем, это то, что все игроки всегда будут в мапе. Можно таймером каждые 5 минут аннулировать уже откатившиеся кулдауны, но это уже дело за тобой)

(ну а если пойдешь на это, то лучше кинь свой взор на Guava Caches)
Извиняюсь за наглость,я совсем айт
я только вчера начал этим заниматься,можете вживить код в мой?
Сам попробовал разобраться-не получилось
 
Извиняюсь за наглость,я совсем айт
я только вчера начал этим заниматься,можете вживить код в мой?
Сам попробовал разобраться-не получилось
Зачем ты начинаешь с bukkit, учи сначала java и не будешь такие глупые темы создавать.
 
Назад
Верх