Repeating Task Cooldown

Discussion in 'Plugin Development' started by Irantwomiles, May 2, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Irantwomiles

    I really don't understand how to do this. I've looked up countless times on how I should do this but I always get messed up at one area and that is canceling the task. I can't figure out how to cancel the task for just one player so that it doesn't do it for everyone. What I mean by this is that, lets say I do /team home and it takes 10 seconds to do that, so I have the player in a Map of some sort something like this.

    Code:
    Map<String, Integer> cooldown = .....
    
    /team home
    
    cooldown.put(player.getName(), 10);
    
    bukkit.repeatingtask.... {
    
      public void run() {
        if(cooldown.containsKey(player.getName()) {
           cooldown.put(player.getName(), cooldown.get(player.getName()) - 1);
        if(cooldown.get(player.getName()) == 0) {
    
           RIGHT HERE IS WHERE I WOULD CANCEL 
    }
    }
    }
    
    }
    
    but how would I only cancel it so that it doesn't cancel the task for everyone else but just that one player.

    I hope that made sense.

    Also I know I made a post yesterday but I didn't want to edit it because someone might have the same problem as me.
     
  2. Offline

    I Al Istannen

    @Irantwomiles
    Remove the player from the map? I have sadly no idea how you did it. Do you create a new repeating task for every player? If so, that is probably not the best idea, just use one and iterate over the map. If you want to do it however, you can use a BukkitRunnable. Inside there you can just call BukkitRunnable#cancel() which will cancel this task, and only this.
     
  3. Offline

    Irantwomiles

    I hate asking for code and I wont, but could you do,some, psudo code?
     
  4. Offline

    I Al Istannen

    @Irantwomiles
    Well you coud either:
    1. In the team home command
    2. Create a new Bukkit runnable and pass it the System time as some kind of parameter. It can be a final long outside of the BukkitRunnable, as you can access that from inside.
    3. run that as an repeating task (BukkitRunnable#run...)
    4. If the current system time is bigger than (cooldown + saved time the user executed the command)
    5. Call the cancel() method and run the desired command

    Or, probably a bit nicer if you have a lot of players:
    1. Create a BukkitRunnable that runs the whole time.
    2. Create a map<String, Long> as a !field!.
    3. In the team home command: Add the player's name to the map along with the current time
    4. Inside the Runnable just loop through the map and check for every player what I wrote in step 4 above.
    5. If the above is true, run the desired command and remove the player from the map.
    6. Just check if the player isn't online anymore (e.g. Bukkit.getPlayer(String) returns null) before executing the command.
    This is quite close to pseudocode.

    I might have missed something, or did something in a not-so-nice way, just reply and point it out!
     
  5. Offline

    Irantwomiles

    I can't imagine having the runnable always running be good. Also if I call the cancel method it cancels it for everyone, doesn't it?
     
  6. Offline

    I Al Istannen

    @Irantwomiles
    Always running (20 times a second ==> every tick) is no problem, as long as the instructions and calculations are not so heavy. Looping through a small map certainly isn't. So that should be no problem. You could also run the task every 10 ticks. That would still be good enough.

    If you create a new Runnable for every player, it will cancel just this runnable for this player. But that requires a runnable for every player. Pro is that the runnable can just be run-once and not repeating and have a delay of the cooldown. It will need a bit more memory, but should take bit less CPU, if the number of players isn't big enough. I wouldn't worry about it though, the differences are way too small.
     
  7. Offline

    Irantwomiles

  8. Offline

    Lordloss

    What, "bump"? I Al Instannen wrote you a wall of text how you can do this, and you just write bump without any information where you stuck at? Post your code, and tell us what you didnt get.
     
  9. Offline

    Irantwomiles

    Sorry didn't know i needed context. I was just hoping for some other people's opini9n/ideas. I'll post my code when I get home.
     
  10. Offline

    Lordloss

    Okay, if the permanently running task is bothering you, you could try this: Have a method which starts your task, let the task iterate over the collection as long as it has values, if it is empty cancel the task. If another entry gets in, start the task again with your method.
     
Thread Status:
Not open for further replies.

Share This Page