Cooldown for ClickEvent??

Discussion in 'Plugin Development' started by imfeared, Feb 3, 2017.

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

    imfeared

    So, I need to know how to have a cooldown for a clickevent on a certain slot like 11 or any...
     
  2. Offline

    Disgastings

    You could make an arraylist and add the player when the player has clicked a specific item? And if the player is in the arraylist the event would be cancelled. Use bukkit Scheduler to remove the player from the arraylist.
     
  3. Offline

    imfeared

    Well, I should have said this but I'm somewhat new to Coding Plugins... But, I do get what you are saying I just don't know how to do it.....
     
  4. @imfeared Make a Map, on InventoryClickEvent check the slot and check if they're in the map, if not, add their UUID and the current time + your delay then if they are in it, check if the current time is greater than the one in the map. If so, remove them and allow the event.
     
  5. Offline

    mehboss

    Something like this:
    Code:
    new ArrayList;
    
    onClick () {
    if (array.contains(player.getName()) {
    player.sendMessage("You're still on cool down"):
    } else if (!arraylist.contains(player.getName()) {
    //code
    arraylist.add(player.getName());
    
    new Runnable() {
    arraylist.remove(player.getName());
    } runTaskLater(this, cooldown)
    )
    
    
    

    Sent from my iPhone using Tapatalk
     
  6. Offline

    imfeared

    So, this is what I got.... I have no clue on what is right or what is wrong sooo..... I need some guidance.

    Code:

    Code:
    public class Main extends JavaPlugin implements Listener{
       
       public void onEnable() {
         Bukkit.getServer().getPluginManager().registerEvents(this, this);
       }
       
       ArrayList<Player> cooldown = new ArrayList<Player>();
       
       @Override
       public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
         
         if (label.equalsIgnoreCase("k")) {
           
           ArrayList<String> lore = new ArrayList<String>();
           final Player p = (Player) sender;
           
           ItemStack dchest = new ItemStack(Material.DIAMOND_CHESTPLATE);
           ItemMeta dchestmeta = dchest.getItemMeta();
           dchestmeta.setDisplayName(ChatColor.AQUA + ChatColor.BOLD.toString() + "Starter!");
           lore.add(ChatColor.BLUE + ChatColor.ITALIC.toString() + "Gives you the Starter Gear!!");
           lore.add(null);
           lore.add(null);
           lore.add(ChatColor.WHITE + ChatColor.BOLD.toString() + "--" +
               ChatColor.RED  + ChatColor.BOLD.toString() + "JUST LEFT/RIGHT CLICK" 
           + ChatColor.WHITE + ChatColor.BOLD.toString() + "--" );
           dchestmeta.setLore(lore);
           dchest.setItemMeta(dchestmeta);
           
           
           Inventory inv = Bukkit.createInventory(null, 27, ChatColor.RED + ChatColor.BOLD.toString() + "Kits");
           inv.setItem(0, dchest);
           
           p.openInventory(inv);
           
           }
         final Player p = (Player) sender;
         return true;
       }
       
       @EventHandler
       public void onInventoryClick(InventoryClickEvent e) {
         
         if (e.getInventory().getTitle().equals(ChatColor.RED + ChatColor.BOLD.toString() + "Kits")) {
           ItemStack ironh = new ItemStack(Material.IRON_HELMET);
           ironh.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ItemStack ironc = new ItemStack(Material.IRON_CHESTPLATE);
           ironc.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ItemStack ironl = new ItemStack(Material.IRON_LEGGINGS);
           ironl.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ItemStack ironb = new ItemStack(Material.IRON_BOOTS);
           ironb.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ironb.addEnchantment(Enchantment.PROTECTION_FALL, 1);
           ItemStack irons = new ItemStack(Material.IRON_SWORD);
           irons.addEnchantment(Enchantment.DAMAGE_ALL, 1);
           irons.addEnchantment(Enchantment.DURABILITY, 3);
           
           if (cooldown.contains(e.getWhoClicked())) {
             e.getWhoClicked().sendMessage("until next kit!");
           }
             
             if (e.getRawSlot() == 0) {
               
               e.setCancelled(true);
               e.getWhoClicked().getInventory().addItem(ironh, ironc, ironl, ironb, irons);
               e.getWhoClicked().closeInventory();
               cooldown.add((Player) e.getWhoClicked());
               Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
                 public void run() {
                   cooldown.remove(e.getWhoClicked());
                 }
                 
               
               }, 3600);
    
               e.getWhoClicked().sendMessage(ChatColor.RED + "Given Starter!");
               
             } else {
               return;
             }
         }
         
       }
    }
     
    Last edited by a moderator: Feb 4, 2017
  7. Offline

    ShaneCraftDev

    @imfeared
    You're almost correct, but do not store the player instance. You should make use of the UUID of the player, preferably the String value of it, as this value is unique per player and will never change. However, we don't know what the remaining cooldown is of the player as you did not save the time when the player clicked. So I'd suggest you use a Map with a String as key and an Long as value type and store the uuid and the timestamp as long (system time).

    Code:
    Map<String, Long> playerCooldowns = new HashMap<>();
    
     
  8. Offline

    mehboss

    @imfeared
    I will help when I get home.


    Sent from my iPhone using Tapatalk
     
  9. Offline

    imfeared

    I need a somewhat good example of how to do this.... I am sorry but I should have made it more clear but I am somewhat new to bukkit coding...... :>
     
  10. Offline

    mehboss

    @imfeared
    First, change all the cooldown.contains, cooldown.remove and cooldown.add(e.getWhoClicked()); to
    Code:
    if (cooldown.contains(e.getWhoClicked().getName()) {
    
    Code:
    cooldown.add(e.getWhoClicked().getName());
    
    Code:
    cooldown.remove(e.getWhoClicked().getName());
    
    And before you remove them from the cooldown array check:
    For Removing:
    Code:
    if (cooldown.contains(e.getWhoClicked().getName()) {
    cooldown.remove(e.getWhoClicked().getName());
    ALSO
    Code:
    else if (e.getRawSlot() == 0) {
    make the e.getRawSlot an else if statement.

    Remove this else statement at the end, it does nothing.
    Then get back to me if it doesn't work
     
    Last edited: Feb 4, 2017
  11. Offline

    imfeared

    Ok, so It works but when they try to get it again they can get the chestplate?? and I don't know how to turn ticks into days like send them a message saying how much time they have left until the kit...

    UPDATE:

    I get Half of what you are trying to say but, I will be going to bed so we can figure this out tomorrow... In the meanwhile here is what I got...

    Code:
    public class Main extends JavaPlugin implements Listener{
       
       public void onEnable() {
         Bukkit.getServer().getPluginManager().registerEvents(this, this);
       }
       
       ArrayList<Player> cooldown = new ArrayList<Player>();
       
       @Override
       public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
         
         if (label.equalsIgnoreCase("k")) {
           
           ArrayList<String> lore = new ArrayList<String>();
           final Player p = (Player) sender;
           if (!(sender instanceof Player)) {
             p.sendMessage("You need to be a Player to do this Command!");
           }
           
           ItemStack dchest = new ItemStack(Material.DIAMOND_CHESTPLATE);
           ItemMeta dchestmeta = dchest.getItemMeta();
           dchestmeta.setDisplayName(ChatColor.AQUA + ChatColor.BOLD.toString() + "Starter!");
           lore.add(ChatColor.BLUE + ChatColor.ITALIC.toString() + "Gives you the Starter Gear!!");
           lore.add(null);
           lore.add(null);
           lore.add(ChatColor.WHITE + ChatColor.BOLD.toString() + "--" +
               ChatColor.RED  + ChatColor.BOLD.toString() + "JUST LEFT/RIGHT CLICK"
           + ChatColor.WHITE + ChatColor.BOLD.toString() + "--" );
           dchestmeta.setLore(lore);
           dchest.setItemMeta(dchestmeta);
           
           
           Inventory inv = Bukkit.createInventory(null, 27, ChatColor.RED + ChatColor.BOLD.toString() + "Kits");
           inv.setItem(0, dchest);
           
           p.openInventory(inv);
           
           }
         return true;
       }
       
       @EventHandler
       public void onInventoryClick(InventoryClickEvent e) {
         
         if (e.getInventory().getTitle().equals(ChatColor.RED + ChatColor.BOLD.toString() + "Kits")) {
           int time = 20*25;
           ItemStack ironh = new ItemStack(Material.IRON_HELMET);
           ironh.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ItemStack ironc = new ItemStack(Material.IRON_CHESTPLATE);
           ironc.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ItemStack ironl = new ItemStack(Material.IRON_LEGGINGS);
           ironl.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ItemStack ironb = new ItemStack(Material.IRON_BOOTS);
           ironb.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1);
           ironb.addEnchantment(Enchantment.PROTECTION_FALL, 1);
           ItemStack irons = new ItemStack(Material.IRON_SWORD);
           irons.addEnchantment(Enchantment.DAMAGE_ALL, 1);
           irons.addEnchantment(Enchantment.DURABILITY, 3);
           
           if (cooldown.contains(e.getWhoClicked())) {
             e.getWhoClicked().sendMessage("until next kit!");
             e.setCancelled(true);
           } else if (e.getSlot() == 0) {
             
             e.setCancelled(true);
             e.getWhoClicked().getInventory().addItem(ironh, ironc, ironl, ironb, irons);
             e.getWhoClicked().closeInventory();
             cooldown.add((Player) e.getWhoClicked());
             Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
               public void run() {
                 cooldown.remove(e.getWhoClicked());
                 e.getWhoClicked().sendMessage(ChatColor.RED + "You can use kit Starter again!!");
               }
                 
               
               }, time);
    
               e.getWhoClicked().sendMessage(ChatColor.RED + "Given Starter!");
               
             }
         }
         
       }
    }
    
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited: Feb 4, 2017
  12. Offline

    mehboss

    @imfeared
    Please put this into code format by clicking the news looking thing on the top tools and clicking "Code" so we can read it better.

    UPDATE:
    Put this on the top after an instancecheck.. you need an instancecheck so console or a non-player entity does this command, need good habits man..
    This is the reason why it gives you the chestplate if you do it again. You need to check if the player is in the array and then send cooldown message for this part also.

    So basically for the ticks into seconds you want to set a variable..
    for example:​

    IDEA
    Code:
    //timer is 5 minutes...
    
    
    //timer starts
    new Runnable() {
    player.sendMessage("5 minutes remaining of cooldown");
    
    } runTaskLater
    //task is over
    player.sendMessage("Your cooldown is now over!");

    OR

    NOTE: This code is not spoonfeeding as it is set, so if you're wondering, it won't work if you copy and paste.

    1. do a timer to run every x minutes/seconds
    2. in that timer do something like:
    Code:
    int timeleft = null;
    
    //new runnable
    int timeleft = 20*60*5 \ 1200;
    
    if (timeleft == 5 && player.isOnline() && timeleft != null) {
    player.sendMessage("You have 5 minutes until your cooldown is over");
    int timeleft = 20*60*4 \ 1200;
    }
    else if (timeleft == 4 && player.isOnline() && timeleft != null) {) {
    player.sendMessage("You have 4 minutes until your cooldown is over");
    int timeleft = 20*60*3 \ 1200;
    
    //ECT
    else if (timeleft == 0 [rest code just too lazy]) {
    //cancel timer.
    
    } newTaskTimer(this, 6000)
     
    Last edited: Feb 4, 2017
  13. Offline

    Drkmaster83

    @mehboss I like the idea, and while it sometimes may not be practical, it's encouraged to use UUIDs instead of storing playernames.
    @imfeared I've put this together so you can compare the difference between the two codes, the right half should function (although something to note is that it doesn't account for players leaving) properly, but the idea is to see what I've changed and ask about what changes I've made or whatnot. A quick rundown, though:
    • Instead of creating a single task for every person who needs a cooldown, I've opted to do a global task that just checks everyone who is in the cooldown list at once.
    • The cooldown list is now a HashMap that stores the amount of seconds they have left before their cooldown is up. If you want to know why it is like this, view my post here.
    • I've permanently stored your dchest itemstack for the life of the program so that we can make sure that they're clicking the same item we put in
    • I put some nicely formatted messages in for all occurrences, even implemented the idea that @mehboss proposed (x minute(s) left until next kit)
    • Fixed up the onCommand, you were casting too soon (before you checked the instance) and using the label argument (it's just better overall to use the cmd argument and do .getName())
    • Made your onInventoryClick more reliable, returns if unnecessary and also reliably checks the item that they're clicking on (getCurrentItem() as opposed to hardcoded slot numbers)
    I know I added 30 lines, but for the functionality that's been added, it was worth it
     
Thread Status:
Not open for further replies.

Share This Page