Repeating a task then stopping it after X amount of times

Discussion in 'Plugin Development' started by InfamousSheep, Jun 1, 2013.

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

    InfamousSheep

    Hello, so I want to repeat a task (which I know how to do) then stop the task after X amount of times. I previously made an integer and every time the task repeat, it would plus 1 to the number. Then is would check if the number was equal to 5, for example if would cancel the task. Only trouble with this is if multiple people would activate this task, it would be adding 2 or more to the number at one time, therefore skipping over the 5, so it would just continuously repeat until the server was restarted/reloaded.

    If anyone has an alternative way of doing this please respond!
    Thanks in advance.
     
  2. Offline

    CubieX

    Where/when do you start this task? (event handler, other method?)
    Should this task run 5 times for each individual player? Or just 5 times total?
     
  3. Offline

    InfamousSheep

    When when an item is right clicked, so yes an Event Handler. It repeats the task X amount of times, its not just 5 times.
     
  4. Offline

    Rocoty

    You could check if the number is greater than or equal to 5, rather than just equal to 5. But I think what you really want is a task for each individual player
     
  5. Offline

    CubieX

    Even if multiple players click this item, the event will be called for each player individually one after another.
    So it will not add 2 or more at a time.

    Showing us this piece of code (the handler and where you increase the variable) would be helpful.
    I'm also still not fully understanding when the task may run x times.
    Whether for every individual player or x times total and when the counter will be reset.
    To help you, this is necessary to know.
    Your implementation will probably clarify this.
     
  6. Offline

    InfamousSheep

    When the sugar is right clicked, the player is given a speed boost for 5 seconds. Every tick, a fake sugar item is dropped from the location. That's what I'm using the repeating task for.

    Heres my code:
    Code:
    @SuppressWarnings("deprecation")
    @EventHandler
    public void onSpeedBoost(PlayerInteractEvent event) {
    final Player player = event.getPlayer();
    ItemStack item = player.getItemInHand();
    final World world = player.getWorld();
    // Location location = damaged.getLocation();
    final Location location = player.getLocation();
    if (item == null) {
    return;
    } else if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
    if (!(player.getInventory().getItemInHand().getType() == Material.SUGAR)) {
    return;
    } else if (player.getItemInHand().getType() == Material.SUGAR) {
    if (item.hasItemMeta()) {
    if (item.getItemMeta().getDisplayName().equals(ChatColor.AQUA + "Speed Boost")) {
    if (Cooldown.tryCooldown(player, "SpeedBoost", 60000)) {
    player.getWorld().playSound(location, Sound.WOLF_HOWL, 1.2F, 1.0F);
    player.playEffect(player.getLocation(), Effect.SMOKE, 0);
    player.sendMessage(ChatColor.AQUA + "Speed Boost has been activated!");
    player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 100, 3));
    player.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 100, 10));
     
    final ItemStack drop = new ItemStack(Material.SUGAR, 1);
     
    task = this.plugin.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) plugin, new Runnable() {
       @Override
       public void run() {
       if(num == 75) {
       Bukkit.getScheduler().cancelTask(task);
       num = 0;
         } else {
         if(player.isDead() == false && player.isOnline() == true) {
         player.getWorld().playSound(location, Sound.FIZZ, 1.2F, 1.0F);
         world.dropItem(player.getLocation(), drop);
         num += 1;
         } else {
         Bukkit.getScheduler().cancelTask(task);
         num = 0;
         }
         }
         }
         },0L, 1L);
     
    Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() {
    public void run() {
    player.updateInventory();
    }
    }, 01L);
     
    } else {
    // Cooldown hasn't expired yet
    player.sendMessage(ChatColor.DARK_AQUA + "Speed Boost on cooldown (" + (Cooldown.getCooldown(player, "SpeedBoost") / 1000) + " seconds left).");
    }
    }
    }
    }
    }
    }
     
  7. Offline

    CubieX

    OK. So first problem is, you are sharing the global "num" counter for each player that uses this speed boost.
    What you need to do is, save the players name in a HashMap to mark him as "boosted".
    The value will then be the counter variable.
    So each player will have it's own counter.

    Also, every time a player clicks with the "boost sugar", a new task will be created.
    But you only want 1 running scheduler per boosted player at a time.
    So again, use a second HashMap to store the player name along with the running schedulers BukkitTask - TaskID.
    This way you can block multiple schedulers for a single player (by canceling the event and not calling the scheduler method again if the player is already on the Map) and delete him from both Maps when the max counter value is reached.

    Of course this is only one slution of many.
     
  8. Offline

    InfamousSheep

    How would I go about doing this?
    I previously added a cool down for the whole event
     
  9. Offline

    MehrPvM

    Also i would suggest indenting it a little bit better, it helps a lot when trying to find what's wrong
     
Thread Status:
Not open for further replies.

Share This Page