Cooldowns

Discussion in 'Spigot Plugin Development' started by Exodus54, Mar 9, 2018.

  1. Hello, I am working on a simple Cooldown thing with Kits, called GKits (God Kits)
    I am trying to make it so if it is below 1 minute it says instead of "[!] You must wait 0 minutes, 59 seconds to claim your GKit"
    I want to make it say "[!] You must wait 59 seconds to claim your GKit" when it is below 1 minute.

    Code (Text):
    package gkit.chubbyduck1;
     
    import java.util.HashMap;
    import java.util.Random;
     



    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.PlayerInventory;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitRunnable;
     
    public class main extends JavaPlugin {
         
            private Random r;
            private HashMap<Player, Integer> cooldownTime;
            private HashMap<Player, BukkitRunnable> cooldownTask;
         
            public void onEnable() {
                    cooldownTime = new HashMap<Player, Integer>();
                    cooldownTask = new HashMap<Player, BukkitRunnable>();
                    r = new Random();
            }
     
            public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
                    if (!(sender instanceof Player)) {
                            sender.sendMessage(ChatColor.RED + "Only players can use the GKits.");
                            return true;
                    }
                 
                    final Player p = (Player) sender;
                    PlayerInventory pi = p.getInventory();
                 
                    if (cmd.getName().equalsIgnoreCase("gkite")) {
                            if (cooldownTime.containsKey(p)) {
                                    int seconds = (int) cooldownTime.get(p) % 60;
                                    int minutes = (int) ((cooldownTime.get(p) - seconds) / 60);
                                    p.sendMessage(ChatColor.translateAlternateColorCodes('&', "&c&l[!] &cYou must wait &4" + minutes + " &cminutes, &4" + seconds + " &cseconds to claim your GKit"));
                                    return true;
                            }
                            pi.addItem(new ItemStack(Material.EXP_BOTTLE, 128));
                            p.sendMessage(ChatColor.translateAlternateColorCodes('&', "&e&l[!] &eYou have received your GKit!"));
                         
                            cooldownTime.put(p, 70);
                            cooldownTask.put(p, new BukkitRunnable() {
                                    public void run() {
                                            cooldownTime.put(p, cooldownTime.get(p) - 1);
                                            if (cooldownTime.get(p) == 0) {
                                                    cooldownTime.remove(p);
                                                    cooldownTask.remove(p);
                                                    cancel();
                                            }
                                    }
                            });
                         
                            cooldownTask.get(p).runTaskTimer(this, 20, 20);
                            return true;
            }
            return true;
    }
            }
    }
     
  2. So if minutes == 0, print a different message- right?

    For cooldowns that don't have some kind of live countdown timer, scheduled tasks are kind of a huge waste.

    Just keep one Map but instead of storing the cooldown time remaining per player, store the last time they successfully ran the command.

    Then when they try to run the command again, calculate the cooldown time remaining on the spot. If the cooldown is up, let them do the command and update the Map- otherwise print your messages.
     
    • Agree Agree x 1
  3. Senmori

    Resource Staff Patron

    Completely agree with NathanWolf.
    I'd say look at this stackoverflow post for an idea of how to do it: StackOverflow
    If you want to convert millis to seconds/hours/days I would also look at the TimeUnit class. It's very useful.
     
    • Agree Agree x 1
  4. can anyone help me with this?
    I changed the code but now it Is saying that the hours is pretty much copying the minutes please someone help
    Picture : [​IMG]
    Code (Text):
    package gkit.chubbyduck1;

     
    import java.util.HashMap;
    import java.util.Random;
     



    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.PlayerInventory;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitRunnable;
     
    public class main extends JavaPlugin {
         
            private Random r;
            private HashMap<Player, Integer> cooldownTime;
            private HashMap<Player, BukkitRunnable> cooldownTask;
         
            public void onEnable() {
                    cooldownTime = new HashMap<Player, Integer>();
                    cooldownTask = new HashMap<Player, BukkitRunnable>();
                    r = new Random();
            }
     
            public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
                    if (!(sender instanceof Player)) {
                            sender.sendMessage(ChatColor.RED + "Only players can use the GKits.");
                            return true;
                    }
                 
                    final Player p = (Player) sender;
                    PlayerInventory pi = p.getInventory();
                 
                    if (cmd.getName().equalsIgnoreCase("gkite")) {
                            if (cooldownTime.containsKey(p)) {
                                    int seconds = (int) cooldownTime.get(p) % 60;
                                    int minutes = (int) ((cooldownTime.get(p) - seconds) / 60);
                                    int hours = (int) ((cooldownTime.get(p) - minutes) / 60);
                                    p.sendMessage(ChatColor.translateAlternateColorCodes('&', "&c&l[!] &cYou must wait &4" + hours + "&chours, " + minutes + " &cminutes, &4" + seconds + " &cseconds to claim your GKit"));
                                    if (hours == 0) {
                                        p.sendMessage(ChatColor.translateAlternateColorCodes('&', "&c&l[!] &cYou must wait &4" + minutes + " &cminutes, &4" + seconds + " &cseconds to claim your GKit"));
                                    if (minutes == 0) {
                                        p.sendMessage(ChatColor.translateAlternateColorCodes('&', "&c&l[!] &cYou must wait &4" + seconds + " &cseconds to claim your GKit"));
                                    }
                                    }
                                    return true;
                            }
                            pi.addItem(new ItemStack(Material.EXP_BOTTLE, 128));
                            p.sendMessage(ChatColor.translateAlternateColorCodes('&', "&e&l[!] &eYou have received your GKit!"));
                         
                            cooldownTime.put(p, 8000);
                            cooldownTask.put(p, new BukkitRunnable() {
                                    public void run() {
                                            cooldownTime.put(p, cooldownTime.get(p) - 1);
                                            if (cooldownTime.get(p) == 0) {
                                                    cooldownTime.remove(p);
                                                    cooldownTask.remove(p);
                                                    cancel();
                                            }
                                    }
                            });
                         
                            cooldownTask.get(p).runTaskTimer(this, 20, 20);
                            return true;
            }
            return true;
    }
    }
     
  5. Hours = seconds / 3600

    You don't want to subtract minutes from hours.
     
  6. How would I do that? just set Hours to
    "int hours = (int) (seconds / 3600);"?
     
    • Agree Agree x 1
  7. add to an array in runnable but then remove from array. set the array to e.setCancled(true); on the event
     
  8. If you want to optimize it you shouldn't be creating a runnable for this, especially for each player. That will create a huge amount of lag.

    Instead, get the current time and store it with the player in a map (you should store it either in a file or database too so it doesn't get reset on server reload/restart) and then next time they run the command subtract the first value to see if they can use it.
     
    • Agree Agree x 2

Share This Page