Resource [Tutorial] Easier cooldown method

Discussion in 'Spigot Plugin Development' started by RestrictedPower, May 1, 2016.

  1. Hey guys! Today I will be showing you a cool cooldown method. Many of you probably know and use this method but I'm sure this is going to help some other people who don't know it. So lets begin :)

    Advantages of this method:
    1)Easy to use/understand.
    2)Easy to edit cooldowns.
    3)Easily get the remaining time.
    4)It never gets canceled so we don't have to mess with some hard stuff.
    Disadvantage of this method:
    1)It is a little more laggy than the other methods.

    So lets say you wanna make a combat log plugin...
    Every time a player hits an other one you have to put him on a ArrayList and remove him after some time .You would probably do this like this:
    Code (Text):
    ArrayList<Player> inCombat = new ArrayList<>();
    public void setincombat(final Player player){
    getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
                public void run() {
            }, 20*10L);
    What is the problem with this method?
    Lets say that a player hits another. So the method adds the player to the arraylist and it is ready to remove him in 10 seconds.After five seconds the player hits the other guy again.So the time to remove him should be updated again to 10 seconds right? Well, except the task we added now, don't forget the other one running at the background which ends in 5 seconds so the player will be out of combat in five seconds which is wrong...

    Lets move to the better method now :)
    Firstly I will give you some code i made and then I will explain how this works...
    Code (Text):

    public void onEnable(){
        HashMap<Player, Integer> timer = new HashMap();

        public void decrease() {
            getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
                public void run() {
                    for (Entry<Player, Integer> e : timer.entrySet()) {
                        if (e.getValue() != 0) {
                            int fixed = e.getValue() - 1;
                            timer.put(e.getKey(), fixed);
                        } else {
            }, 0L, 20L);

        public void onHit(EntityDamageByEntityEvent e) {
            if (!(e.getEntity() instanceof Player)) {
            if (!(e.getDamager() instanceof Player)) {
            Player player = (Player) e.getDamager();
            timer.put(player, 10);
        public Boolean isInCombat(Player player) {
            if (timer.containsKey(player)) {
                return true;
            return false;
        public int getRemainingTime(Player player){
                return timer.get(player);
            return 0;
    So now I will explain what this method does...
    Firstly we have a hashmap containing the player and the time left.
    We decrease the hashmap's values per second by 1.
    If a value from the hashmap reaches 0 then we completely remove it from the hashmap.
    So we can simply update the value to 10 seconds for each of the player's hits.
    Nothing gets canceled so we don't have the problem we had at the other method...
    And we can always get the remaining time from the map :)

    That's it Thank you guys for checking this out and I hope you understood what these methods do... I tried to explain them as well as I could... If you have any questions do not hesitate to ask me.

    - RestrictedPower
    #1 RestrictedPower, May 1, 2016
    Last edited: May 1, 2016
    • Informative Informative x 1
    • Friendly Friendly x 1
  2. s/new Runnable() {/() -> {
    • Like Like x 1
    • Agree Agree x 1
  3. You shouldn't store a Player object anywhere in memory for some obvious reasons...
    • Optimistic Optimistic x 2
    • Funny Funny x 1
  4. @RestrictedPower aside that you should type the field Map rather than HashMap, storing an Integer is as inefficient as it gets. Why not just store the timestamp? Saves you the whole decrementing task... (also, if you want a collection for add/contains/remove, go with Sets, not Lists)

    In the case that you are not going to mention memory leaks, elaborate.
  5. Well that's just it: memory leaks. Storing something like that is asking for it.
  6. Better not store UUIDs then... or Strings... or ints/Integers...

    If there's a memory leak, the developer is to blame, not the fact that you stored a variable of a specific type.
    • Agree Agree x 4
    • Like Like x 1
  7. I never really understood that syntax. What is it?

    Why is storing an Integer inefficient?
    • Like Like x 2
  8. That's not what I'm trying to convey :p. What I'm saying is that anything can be considered a memory leak, even the most used and 'natural' data types are not immune to it.
    • Like Like x 2
  9. Dude I just showed an example... Obviously anyone can change the player value to anything he wants.. Like player name or uuid...
  10. That will happen if you forget to remove the player when the player logs out or is invalid. (facepalm)
    • Agree Agree x 1
  11. It counts 0 as a second too...
    Example if i have 4 it will count it as 5
  12. This post is a couple months old, the last reply was on May 1st, did you seriously have to reply to it?
  13. Yes, do u have a problem with that?
  14. I don't know what this is for ;-;
  15. Its for searching threads.. Example, like this. and i do not know why you are making this a big deal.
  16. You started it vvv
  17. Yes, we do, as your comment was not actually useful to the resource.
    Don't necro when you don't have to.
  18. If this really bugs u guys.
    Then i can delete my posts if u want to.
  19. That won't help. It's brought back to life now, and now we'll let it die again, okay?
    /no replies