Tutorial A Simple Solution to Cooldowns

Discussion in 'Resources' started by 0ct0berBkkitPlgins, Dec 30, 2015.

Thread Status:
Not open for further replies.
  1. When you think of a cooldown, you might think of having to store events and schedule and halt them whenever the cooldown is refreshed again. Well here's a much simpler way to do it, with only a HashMap and a scheduled task!

    1. Create your HashMap as a global variable outside of any events or methods in your class (usually below your imports), including the object you want the cooldown to be applied to, and an integer. Most often you will want a cooldown to apply to a player, so in that case you should use a UUID, like so:
    Code:
    HashMap<UUID, Integer> cooldown = new HashMap<UUID, Integer>();[code=Java]
    
    Now let's say player Gummywich_33 uses magic spell "Fireball" in the magic plugin you are creating. You want there to be a cooldown of five seconds before Gummywich_33 can use the spell again. This is how we'd go about it:
    
    [code=Java]final Player p = e.getPlayer();
    final UUID pu = p.getUniqueId();
    int cd = 0;
    int duration = 100;
    if (cooldowns.contains(pu)) {
    cd = cooldowns.get(pu);}
    cd++;
    cooldowns.put(pu, cd);
            getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable()
            {
              public void run() {
                int cd = cooldowns.get(pu);
                cd--;
                cooldowns.put(pu, cd);
              }
            }
            , duration);
    
    This code will make it so that when the player casts their spell, they will get a point. When the task runs, they will loose a point. As long as no cooldowns are running, the player will always be at 0 points. If one, two, three, or four cooldowns are running, the player will have a value greater than zero, and will need to wait for those four cooldowns to expire. I recommend this method of using cooldowns, as you can't possibly make a mistake with it. If you want other factors to call a cooldown, maybe you want, say, standing in water to call the cooldown. That means that every time they step in water, the cooldown will run again. Without using HashMaps, you'd probably have to go and cancel existing tasks and create new ones all the time you want to update a cooldown.

    To change the time of the cooldown, simply change the integer "duration" to whatever amount of ticks you want this to be.



    So that is how you can make your cooldown. But how do we test for it? Simple. We check if the player's UUID stored in the HashMap gives us an integer greater than zero:

    Code:
    Player p = e.getPlayer();
    UUID pu = p.getUniqueId();
    if (cooldowns.contains(pu)) {
    if (cooldowns.get(pu) > 0) {
    p.sendMessage("Fireball is still on it's 5 second cooldown!");
    return;
    }}
    //... rest of your code, that will never be ran if the cooldown hasn't ended ...//
    I hope this guide was helpful.
     
    ChipDev likes this.
  2. Offline

    mcdorli

    One thing to mentions, is that when you create a tutorial, thn you should use understandable variable names, like player, uuid, message, etc.
     
  3. All of these variables happen to be easy to understand... p for player, pu for player uuid, cooldowns for the hashmap, cd for cooldown.

    They might not be your preferred variables, but I'm not you. These variables still work, so the comment is rather pointless, and was just picky to begin with.
     
  4. Offline

    teej107

    @0ct0berBkkitPlgins That is not how you do cooldowns! Cooldowns should compare the System's time to another time. This is a timer and it it uses more resources than a cooldown done right.
     
    20zinnm and Mrs. bwfctower like this.
  5. It is still a way to do it and has been the way I've used cooldowns for for a long time. I've noticed no performance drop when these tasks are running. It might not be your preferred method of doing it, but it still works fine. I made this tutorial knowing very well that cooldown tutorials using the method you presented already exist. This just happened to be my solution to it, as I had figured it out on my own without looking at some guide :cool:
     
    Last edited: Dec 31, 2015
  6. Offline

    Gorbit99

    Doing stuff like "you always did" is not the best everytime. I could never use for loops, instead I could write out every single line and it would be still wrong, but that's how I done it in the past (not actually true), so is it okay?
     
  7. Offline

    20zinnm

    Why not use Metadata? I mean, this is slightly memory inefficient.
     
  8. Offline

    Zombie_Striker

    @0ct0berBkkitPlgins
    I think you forgot to add the [/code] bracket.

    Please use descriptive names.
    Please use correct formatting.

    This will only work in the main class. Either note that or use "Bukkit.getServer"

    If you're a good enough programmer, you can merge these two lines.

    And as has been said before, this is not at all the best way to achieve this. You should compare the current time to the stored time, not make a counter.
     
Thread Status:
Not open for further replies.

Share This Page