Needing Help with Cool Downs on items

Discussion in 'Spigot Plugin Development' started by _Unbannable, Jul 7, 2015.

  1. Code (Text):
     @EventHandler
        @SuppressWarnings("deprecation")
        public void onPInteract(PlayerInteractEvent e)

        {
            final Player p = e.getPlayer();

            if (p.getItemInHand().getType() == Material.NAME_TAG) {
                if (!(nametagCooldown.contains(p)))
                {
                    p.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "Kappa" + ChatColor.AQUA + ChatColor.BOLD + " >> " + ChatColor.GOLD + "This feature has been temporarily disabled!");
                    nametagCooldown.add(p);
                    Bukkit.getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {

                        public void run() {
                            nametagCooldown.remove(p);
                            p.sendMessage("ยง2You can use it now :3");

                        }
                    }, 60L);
                }else p.sendMessage(ChatColor.RED + "You need to wait 3 seconds to do that!");

            }
        }
    It sends the first msg but the time doesn't expire so it sends the second msg when ever I click on the nametag. So idk what I should do.
     
  2. Why are you using this:
    Code (Text):

     @SuppressWarnings("deprecation")
     
     
  3. Code (Text):
    Bukkit.getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
    I get the line through "scheduleAsyncDelayedTask"
     
  4. Why are you using an asyncdelayedtask, pretty sure it shouldn't be async

    Try Bukkit.getScheduler().runTaskLater(pl, new Runnable() {...}, 60L);
     
  5. The same thing is happening. Like it works but when you right click the item it shows the message. Then when I try right after that I get the message please wait 3 seconds to use this but it doesn't reset to were you can right click it after 3 seconds for it to show you the real message.
     
  6. What data type is your nametagCooldown?
     
  7. This is the updated version.
    Code (Text):
        private Plugin plugin;
        List<Player> ntCooldown = new ArrayList<Player>();
        @EventHandler
        public void onPInteract(PlayerInteractEvent e) {
            final Player p = e.getPlayer();
            if (p.getItemInHand().getType() == Material.NAME_TAG) {

                    if(!(ntCooldown.contains(p))) {
                        ntCooldown.add(p);
                        p.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "Kappa" + ChatColor.AQUA + ChatColor.BOLD + " >> " + ChatColor.GOLD + "This feature has been temporarily disabled!");

                        Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
                            @Override
                            public void run() {
                                ntCooldown.remove(p);
                                p.sendMessage("You can use it now.");

                            }
                        }, 60L);


                    }else p.sendMessage("Please wait 3 seconds to use this.");
            }
        }
    I've watched some videos about this. Some people say use Hash Maps some use ArrayList.
     
  8. That's the problem. You shouldn't use an arraylist.

    The problem with the arraylist is that when you click multiple times, it keeps adding to the list. When you remove the player from the list, it only removes the first occurrence of the player.

    A HashMap would work, but you don't have a val that you need to store with the player key.


    In these sorts of situations you want to use Sets, which are like lists, except that they are unordered and can only have unique objects.

    So change

    List<Player> ntCooldown = new ArrayList<Player>();

    into

    Set<Player> ntCooldown = new HashSet<Player>();

    I don't think that you will have to change anything else.





    EDIT
    Actually not sure if this will fix the problem, because the arraylist should never have more than one occurrence of the player in the first place...
    Change it to a set anyway because that is the appropriate type for this.

    Just not totally sure if this will fix problem.
     
  9. I prefer to use HashMaps, removes the need for scheduled tasks, is easier to update/read and allows you to send dynamic messages regarding how much time is left on the cooldown.

    Something like (quick mashup):

    Code (Text):
    import java.util.HashMap;
    import java.util.UUID;

    import org.bukkit.entity.Player;

    public class Cooldown {
     
        HashMap<UUID, Long> cooldowns = new HashMap<UUID, Long>();
     
        public void setCooldown(Player p, double seconds){
            cooldowns.put(p.getUniqueId(), (long) (System.currentTimeMillis() + (seconds*1000)));
        }
     
        public double getSecondsLeft(Player p){
            Long l = cooldowns.get(p.getUniqueId());
            if(l == null || l <= 0) return 0;
            return l/1000.0;
        }
     
        public boolean isCooldownFinished(Player p){
            return getSecondsLeft(p) <= 0;
        }

    }
     
     
  10. There is no error but same situation as before.
    I checked console and I did see this.
    Code (Text):
    07.07 15:21:10 [Server] INFO [15:21:10 ERROR]: [FinestCore] FinestCore v0.1 attempted to register an invalid EventHandler method signature "public void me.mjw.listener.AnimalGUI.animalInv(org.bukkit.entity.Player)" in class me.mjw.listener.AnimalGUI
    07.07 15:21:10 [Server] INFO [15:21:10 ERROR]: [FinestCore] FinestCore v0.1 attempted to register an invalid EventHandler method signature "public void me.mjw.listener.PlayerListener.openInv(org.bukkit.entity.Player)" in class
     
  11. Maybe try @xADudex 's suggestion of using a map with a player key and a timestamp val, not sure what's wrong with what you have now.
     
  12. So how would I implement that to this?
    Code (Text):
        @EventHandler
        public void onPInteract(PlayerInteractEvent e) {
            final Player p = e.getPlayer();
            if (p.getItemInHand().getType() == Material.NAME_TAG) {

                    p.sendMessage(ChatColor.DARK_RED + "" + ChatColor.BOLD + "Kappa" + ChatColor.AQUA + ChatColor.BOLD + " >> " + ChatColor.GOLD + "This feature has been temporarily disabled!");

                }
            }
     
     
  13. Also Thank you both for all of the help!
     
  14. Not to be rude, but you are allowed to think for yourself too....
    What on earth can be unclear about this, it has a method to check how many seconds is left on the cooldown, a method to set the amount of cooldown for players and even a idiot proof method to check if there is time left on the cooldown......

    Try implement it for your self (add the class to your project, add a Cooldown cooldown = new Cooldown(); in your main class)
    If it don't work then post the code you tried with first, then tell us why it is not working and what is happening when you test it. If you have an idea to fix it, test it out before asking us again.

    We are here to help you, not to do all the coding for you. I mean the class I gave you is way more spoon-feeding then I usually do to people...
     
  15. So sorry.