Scheduler on Special items

Discussion in 'Spigot Plugin Development' started by KricoGamer, May 12, 2016.

  1. I wanted to create a special item that launches arrows and i try to add a cooldown. But it does not work.
    Code (Text):

    @EventHandler
        public void inter(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            Action action = e.getAction();
            ArrayList<Player> cooldown = new ArrayList<Player>();

            if (p.getItemInHand().getType() == Material.DIAMOND_AXE) {
                if (action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) {
                    Arrow arrow = p.getWorld().spawn(p.getEyeLocation(), Arrow.class);
                    arrow.setVelocity(p.getLocation().getDirection().multiply(3.0));
                    arrow.setShooter(p);
                    cooldown.add(p);
                    Bukkit.getServer().getScheduler().scheduleSyncDelayedTask((Plugin) this, new Runnable() {
                        public void run() { cooldown.remove(p);}}, 20L);
                    if (cooldown.contains(p)) {
                                    p.sendMessage(ChatColor.RED + "You can't use now");
                    }
                }

            }
        }
     
  2. The code there makes the list as a variable in the method not a local variable, you need it as a local variable instead so it doesn't get cleared each interact event.
     
    • Like Like x 1
  3. Aka move the list outside of the event
     
    • Agree Agree x 1
  4. why are you casting "this" ? didn't you provide your Javaplugin instance?
    oh, btw you should use player's name or UUID for checking cooldown, sometimes event.getPlayer() does not return the same instance, and cooldowns.contains(p) will not work as you expected
     
    • Agree Agree x 1
  5. This my class

    Code (Text):

    public class Archer implements Listener {

        public Archer(Plugin p) {
            Bukkit.getServer().getPluginManager().registerEvents(this, p);
        }

        ArrayList<Player> cooldown = new ArrayList<Player>();

     
        @EventHandler
        public void inter(PlayerInteractEvent e) {
            Player p = e.getPlayer();
            Action action = e.getAction();

            if (p.getItemInHand().getType() == Material.DIAMOND_AXE) {
                if (action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) {
                    Arrow arrow = p.getWorld().spawn(p.getEyeLocation(), Arrow.class);
                    arrow.setVelocity(p.getLocation().getDirection().multiply(3.0));
                    arrow.setShooter(p);
                    cooldown.add(p);
                    Bukkit.getServer().getScheduler().scheduleSyncDelayedTask((Plugin) this, new Runnable() {
                        public void run() { cooldown.remove(p);}}, 20L);
                    if (cooldown.contains(p)) {
                                    p.sendMessage(ChatColor.RED + "You can't use now");
                    }
                }

            }
        }

    }
    This is my main
    Code (Text):

    public class kitcore extends JavaPlugin {

        @Override
        public void onEnable() {

            System.out.println("---------------------");
            System.out.println("SUPER KIT PVP ENABLED");
            System.out.println("-----CREATED BY------");
            System.out.println("-----KRICOGAMER------");

       
            getServer().getPluginManager().registerEvents(new Archer(this), this);
    }
     
     
  6. put the if cooldowns contains check before the shooting of the arrow so it doesn't shoot anyway, and put return; after it so it doesn't continue running the code.
     
  7. So:

    Code (Text):
    if (p.getItemInHand().getType() == Material.DIAMOND_AXE) {
                if (action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) {
                    Arrow arrow = p.getWorld().spawn(p.getEyeLocation(), Arrow.class);
                    arrow.setVelocity(p.getLocation().getDirection().multiply(3.0));
                    arrow.setShooter(p);
                    cooldown.add(p);
                    Bukkit.getServer().getScheduler().scheduleSyncDelayedTask((Plugin) this, new Runnable() {
                        public void run() { cooldown.remove(p);}}, 20L);
                  ---->  if(arrow.getShooter() == p){
                        if (cooldown.contains(p)) {
                                    p.sendMessage(ChatColor.RED + "You can't use now");
                    }
                    }
                }
     
  8. No, just don't create the arrow entity in the class if cooldowns contain that player
     
  9. "this" means the instance, or the context of which your code is lexically sitting at.

    for your code, the "this" in
    is really pointing to the Archer instance, you should instead use your JavaPlugin's instance instead.
    I see that you are passing a instance of your java plugin to Archer class though the constructor, you can save it in a local field, and pass it that way.