Question

I currently have a delayed task that runs whenever I click a button. Clicking the button toggles a boolean to true and after 7 seconds, the delayed task sets it to false again.

However, what happens is that if a person clicks the button multiple times, the boolean is toggled on and off, on and off, and so on since the delayed tasks are piling up. Is there a way to simply prolong the delayed task if the button is clicked multiple times instead of having all the delayed task pile up on each other?

So let's say that the delayed task would wait 7 seconds before switching the boolean from true to false once the button is clicked. How would I change the code so that if the button is pressed again while the delayed task has not executed, it cancels the previous and simply executes the next delayed task (I am using this for a server so simply cancelling the previous task may not mean that it was the actual delayed task but some other task)?

@EventHandler
public void damage (EntityDamageEvent event) {
    Entity victim = event.getEntity();
    if (event instanceof EntityDamageByEntityEvent) {
        EntityDamageByEntityEvent edbeEvent = (EntityDamageByEntityEvent) event;
        if(edbeEvent.getDamager() instanceof Player && victim instanceof Player) {
            EntityDamageByEntityEvent edbeEvent1 = (EntityDamageByEntityEvent) event;
            Entity attacker = edbeEvent1.getDamager();
            //Checks if both players are humans and not NPCS.
            final Player player = (Player) victim;
            final Player player2 = (Player) attacker;
            //Saving the players as the variable Player.
            Damagelist.add(player);

            Damagelist.add(player2);
            //Adds both players to the hashmap to be used by other classes.
            isDamaged = true;
            //Toggles the boolean to true.
            int delay = plugin.getConfig().getInt("StunDuration") * 20;
            //The above line gets the delay time from the config.yml file.
            plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
                public void run() {         

                    Damagelist.remove(player);
                    Damagelist.remove(player2);
                    //After an x amount of time, removes players from hashmap.
                    isDamaged = false;
                    playeradd = true;
                    //Toggles the booleans around.
                }
            }, delay);
        }
    }
}
Was it helpful?

Solution

In order to ensure that the event does not run subsequent times for the same damage event you can use the isDamaged variable to validate if the code should run.

Since you set isDamaged to true after validating the event you simply need to make a check against this value as high up in the event as possible and if it is true then just return out of the entire method which would stop another scheduled task being created.

If you wish to stop the player damage as well then you can also cancel the entire event before returning to pass along to other plugins that no damage should be access during the cooldown period.

// End event, add setCancelled(true), and exit method if the isDamaged modifier is set to true
if (isDamaged) {
    event.setCancelled(true);
    return;
}

Here is your code modified to show an example use.

@EventHandler
public void damage (EntityDamageEvent event) {
    // Get the victim of the damage event.
    Entity victim = event.getEntity();

    // End event, add setCancelled(true), and exit method if the isDamaged modifier is set to true
    if (isDamaged) {
        event.setCancelled(true);
        return;
    }

    if (event instanceof EntityDamageByEntityEvent) {
        // Get the attacker of the event.
        EntityDamageByEntityEvent edbeEvent = (EntityDamageByEntityEvent) event;
        Entity attacker = edbeEvent.getDamager();

        // Continue only if both players are humans and not NPCS.
        if(edbeEvent.getDamager() instanceof Player && victim instanceof Player) {

            // Saving the players as the variable Player.
            final Player player = (Player) victim;
            final Player player2 = (Player) attacker;

            // Add both players to the hashmap to be used by other classes.
            Damagelist.add(player);
            Damagelist.add(player2);

            // Toggle to true.
            isDamaged = true;

            // Get delay time from the config.yml file.
            int delay = plugin.getConfig().getInt("StunDuration") * 20;

            // Setup delayed task to end cooldown set under StunDuration.
            plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
                // Define task to be run by scheduler.
                public void run() {         
                    // After amount of time set by StunDuration, remove players from hashmap.
                    Damagelist.remove(player);
                    Damagelist.remove(player2);

                    // Toggle back to false;
                    isDamaged = false;
                    playeradd = true;
                }
            }, delay);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top