1.15.2 Best way to do cooldowns for abilities

Discussion in 'Spigot Plugin Development' started by VivianMusic, Mar 17, 2020.

  1. I have an Ability object where I store information about the different abilities a player can have. What would be the best way to have a cooldown (with countdown) per player per ability?

    My Ability object:
    Code (Text):
    package com.squallz.nationclasses.objects;

    import com.squallz.nationclasses.enums.ClassType;

    import java.util.List;

    public class Ability {
        private Double cooldownTime;
        private Double damage;
        private ClassType classType;
        private Boolean hasStun;
        private Double stunTime;
        private String name;
        private List<String> lore;
        private int slotNum;

        public Ability(String name, int slotNum, Double cooldownTime, Double damage, Boolean hasStun, Double stunTime, ClassType classType, List<String> lore) {
            this.name = name;
            this.cooldownTime = cooldownTime;
            this.damage = damage;
            this.hasStun = hasStun;
            this.stunTime = stunTime;
            this.classType = classType;
            this.lore = lore;
            this.slotNum = slotNum;

        public String getName(){
            return name;

        public int getSlotNum() {
            return slotNum;

        public List<String> getLore (){
            return lore;

        public Boolean hasStun() {
            return hasStun;

        public Double getStunTime() {
            return stunTime;

        public Double getCooldownTime() {
            return cooldownTime;

        public Double getDamage() {
            return damage;

        public ClassType getClassType() {
            return classType;
  2. Either make a countdown timer or mark the last use's timestamp.
  3. Well, yeah. But I need to make a separate countdown for each ability, and for each player. Just trying to get the easiest/most efficient method
  4. Strahan


    I'd probably throw a Map<UUID, Long> in the ability object then make methods to handle the set/get for the map. So when a player uses an ability, you can do like if (!abilityObject.logUsage(playerObject.getUniqueId())) { tell user no }[/icode]. When you call the method, it will return negative if current time millis < Long in the map for that user and if it isn't, it logs current time + cooldown.

    Just remember to listen to the player quit event to remove entries from the map.
  5. Well, I want the timer to finish out for the player so they can't just relog to get around cooldowns
    • Like Like x 1
  6. Here's how I did it if you are interested...
    Code (Text):
    package com.squallz.nationclasses.managers;

    import com.squallz.nationclasses.ClassesMain;
    import com.squallz.nationclasses.objects.Ability;
    import com.squallz.nationclasses.objects.CPlayer;
    import org.bukkit.Bukkit;
    import org.bukkit.entity.Player;
    import org.bukkit.scheduler.BukkitRunnable;

    import java.util.HashMap;
    import java.util.UUID;

    public class CooldownHandler {

        private ClassesMain instance = ClassesMain.getInstance();

        public void runCooldownTimer() {
            new BukkitRunnable() {

                public void run() {
                    for(Ability abilities : ClassesMain.getInstance().abilityManager.getAbilityList()) {
                        if(abilities.getPlayerCooldowns() == null) return;
                        for(UUID uuids : abilities.getPlayerCooldowns().keySet()) {
                            Player player = Bukkit.getServer().getPlayer(uuids);

                            Integer currentCooldown = abilities.getPlayerCooldowns().get(uuids);

                            if(currentCooldown == 0) {

                                if(player != null && player.isOnline()) {
                                    player.getInventory().setItem(abilities.getSlotNum(), instance.classInventoryUtil.createItemForAbility(instance.classInventoryUtil.getClassAbilityItemType(abilities.getClassType()), abilities.getSlotNum(), abilities.getName(), abilities.getLore()));
                            } else {
                                if(player != null && player.isOnline()) {
                                    player.getInventory().setItem(abilities.getSlotNum(), ClassesMain.getInstance().classInventoryUtil.countdownPlaceholder(currentCooldown));

                                abilities.addPlayerCooldown(uuids, (int) (currentCooldown - 1));
            }.runTaskTimer(ClassesMain.getInstance(), 0, 20);
    Code (Text):
                    for(Ability abilities : playerCPlayer.getAbilities()) {
                        if(ChatColor.stripColor(abilities.getName()).contains("Rush!")) {
                            player.getInventory().setItem(abilities.getSlotNum(), ClassesMain.getInstance().classInventoryUtil.countdownPlaceholder(abilities.getCooldownTime()));

                            abilities.addPlayerCooldown(player.getUniqueId(), abilities.getCooldownTime());