automatic grass respawn (bug)

Discussion in 'Plugin Development' started by RedZRom, Mar 11, 2017.

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

    RedZRom

    Hello, (i'am french my inglish is very bad i hope your anderstand me) the goal of my plugin, when a player break a grass like that [​IMG] after few seconde, this block respawn. I have create a loop. But then someone break this block, the loop is going infinite, and if two player break at the same moment its full bug. And i didn't find how to replace this special grass. (only a grass block).

    Code:
    @SuppressWarnings("deprecation")
        @EventHandler
        public void cassHerbe(final BlockBreakEvent e){
           
            final Player p = e.getPlayer();
            byte it = e.getBlock().getData();
                if(p.getGameMode().equals(GameMode.SURVIVAL)){
                        if(it == 1){
                                e.setCancelled(true);
                                e.getBlock().setType(Material.AIR);
                                p.playSound(p.getLocation(), Sound.BLOCK_NOTE_PLING, 8, 8);
                               
                                task = Bukkit.getScheduler().runTaskAsynchronously(ServeurMain.getIstance(), new Runnable(){
    
                                   
                                    @Override
                                    public void run() {
                                        if(timer == 0){
                                            Bukkit.getScheduler().cancelAllTasks();
                                            e.getBlock().setType(Material.GRASS);
                                            timer = 10;
                                            }
                                        else{
                                            p.sendMessage("slt" +timer);
                                        }
                                        timer--;
                                       
                                    }
    Thanks for your help, and sry for my inglish.
     
  2. Offline

    timtower Administrator Administrator Moderator

    @RedZRom Never call cancelAllTasks, that effects all plugins.
    Use runTaskLater
    Don't use a global time variable, should be per block.
     
  3. Offline

    Caderape2

    Check in the event if a material.GRASS is breack and get the location
    Call a run task later in another method with the location as parameter.
    When the delay reached, check if the block location is empty and then replace it.

    I'm not sure if it's a good idea to put a final for an event.
     
  4. Offline

    MarkehMe

    You're using an async method! Asynchronous tasks should never access any API in Bukkit. However, runTaskAsynchronously schedules it to run once on the next tick. So your countdown won't work.

    You're really close though! So maybe this will help. The first thing you want to do is create a BukkitRunnable and call it's method runTaskLater. If you want to call it repeated times (to show a countdown) you would call runTaskTimer. (to cancel a task, you have to call the cancel() method from inside the BukkitRunnable)

    PHP:
    new BukkitRunnable() {

        @
    Override
        
    public void run() {
            
    // 10 seconds has passed!
           // This method run() is ONLY called once, you don't have to cancel it
        
    }
     
    }.
    runTaskLater(ServeurMain.getIstance(), 20 10);
    // 20 ticks = 1 second. 20x10 ticks = 10 seconds
    So I'm a bit confused as to why you're using e.getBlock().getData()? Are you trying to detect if they're breaking Grass? You can do so like this:

    PHP:
    @EventHandler
    public void cassHerbe(final BlockBreakEvent e) {
        
        final 
    Player p e.getPlayer();
        
    Material blockType e.getBlock().getType();

        if (
    blockType == Material.GRASS) {
            
    // it is grass! :-)
             
    e.setCancelled(true);
             
    e.getBlock().setType(Material.AIR);
            
    // ... etc
        
    }
    }
    Everything else seems pretty OK! You can call e.getBlock().setType(Material.GRASS); inside your run() method - and whatever else

    I would never call Bukkit.getScheduler().cancelAllTasks(); - this method will cancel every task on your server.

    Good luck :)
     
Thread Status:
Not open for further replies.

Share This Page