Solved Why isn't this working?

Discussion in 'Plugin Development' started by Zach_1919, Jun 6, 2013.

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

    Zach_1919

    So, I am working on a mini game, so when you right click with a block, it throws the block. I need it to do something when it hits the ground, so I decided to do a repeating task to check if the block below the item is not air. I got it working with a regular Runnable (as opposed to a BukkitRunnable) but there was a bug. If I threw another block while one was still in the air, it started bugging out and the first one would repeat whatever it was supposed to do over and over again. I decided to see if I could use a BukkitRunnable, because you can do this.cancel(), but that was giving me errors because my class wasn't extending BukkitRunnable. I couldn't make it extend BukkitRunnable because it was in my main class, so I had to make it extend JavaPlugin. I moved it to a different class that extends BukkitRunnable, but as stated before, the repeating task checks if the thrown item has hit the ground yet, and the variable for the thrown item is back in the main class. I need to know how I can get the variable from the main class, because I tried and it gave me errors.

    Main class:
    Code:
    package me.Zach_1919.BattleBlocks;
     
    import java.util.HashMap;
    import java.util.Map;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.entity.Item;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitTask;
     
    public class Main extends JavaPlugin implements Listener
    { 
        public Item di;
        public Map<String, String> status = new HashMap<String, String>();
        public void onEnable()
        {
            getServer().getPluginManager().registerEvents(this, this);
            this.saveDefaultConfig();
        }
        public void onDisable()
        {
         
        }
        @EventHandler
        public void onInteract(PlayerInteractEvent event)
        {
            Player player = event.getPlayer();
            Action action = event.getAction();
            World world = player.getWorld();
            if(!(player.getItemInHand().getType().equals(Material.AIR)))
            {
                if(action.equals(Action.RIGHT_CLICK_AIR) || action.equals(Action.RIGHT_CLICK_BLOCK))
                {
                    Item di = world.dropItem(player.getEyeLocation(), new ItemStack(player.getItemInHand().getType()));
                    di.setVelocity(player.getEyeLocation().getDirection());
                    if(player.getItemInHand().getAmount() == 1)
                    {
                        player.setItemInHand(null);
                    }
                    else
                    {
                        player.getItemInHand().setAmount(player.getItemInHand().getAmount()-1);
                    }
                    BukkitTask task = new ItemCheckRunnable().runTaskTimer(this, 0L, 4L);
                }
            }
        }
    }
    Runnable class:
    Code:
    package me.Zach_1919.BattleBlocks;
     
    import org.bukkit.Material;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.EntityType;
    import org.bukkit.entity.Item;
    import org.bukkit.entity.Player;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
    import org.bukkit.scheduler.BukkitRunnable;
    import org.bukkit.util.Vector;
     
    public class ItemCheckRunnable extends BukkitRunnable
    {
        private Main main;
        private Item di;
        public ItemCheckRunnable()
        {
            main = new Main();
            di = main.di;
        }
        public void run()
        {
            di.setPickupDelay(100);
            if(!(di.getLocation().subtract(0,1,0).getBlock().getType().equals(Material.AIR)))
            {
                if(di.getItemStack().getType().equals(Material.TNT))
                {
                    di.getWorld().createExplosion(di.getLocation(), 1);
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.GLOWSTONE))
                {
                    for(Entity e : di.getNearbyEntities(2, 2, 2))
                    {
                        if(e instanceof Player)
                        {
                            Player p = (Player) e;
                            p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 300, 1));
                        }
                    }
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.SOUL_SAND))
                {
                    for(Entity e : di.getNearbyEntities(2, 2, 2))
                    {
                        if(e instanceof Player)
                        {
                            Player p = (Player) e;
                            p.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 300, 1));
                        }
                    }
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.GOLD_BLOCK))
                {
                    for(Entity e : di.getNearbyEntities(2, 2, 2))
                    {
                        if(e instanceof Player)
                        {
                            Player p = (Player) e;
                            p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 10, 1));
                        }
                    }
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.WORKBENCH))
                {
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(1,1,0), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(-1,1,0), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(0,1,1), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(0,1,-1), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(1,1,1), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(1,1,-1), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(-1,1,1), 1, 1);
                    di.getWorld().spawnArrow(di.getLocation(), new Vector(-1,1,-1), 1, 1);
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.NETHERRACK))
                {
                    for(Entity e : di.getNearbyEntities(2, 2, 2))
                    {
                        if(e instanceof Player)
                        {
                            Player p = (Player) e;
                            p.setFireTicks(100);
                        }
                    }
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.OBSIDIAN))
                {
                    for(int x = -4; x <= 4; x++)
                    {
                        for(int z = -4; z <= 4; z++)
                        {
                            di.getWorld().spawnEntity(di.getLocation().getBlock().getRelative(x, 10, z).getLocation(), EntityType.PRIMED_TNT);
                        }
                    }
                    di.remove();
                }
                else if(di.getItemStack().getType().equals(Material.WOOL))
                {
                    for(Entity e : di.getNearbyEntities(2, 2, 2))
                    {
                        if(e instanceof Player)
                        {
                            Player p = (Player) e;
                            p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 300, 1));
                        }
                    }
                    di.remove();
                }
                else
                {
                    di.remove();
                }
                this.cancel();
            }
        }
    }
    
    Sorry for the long post. I have heard that I should never make an instance of my main class... Does that mean I should make a separate listener class, too? If so, how do I get the variable from that???

    Come on guys I need help!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  2. Offline

    CluelessDev

    Zach_1919

    If we go back to the method I showed you a bit ago we can solve this.

    This problem stems from the plugin "forgetting" the task id and never being able to cancel the task. Using normal runnables is a bit confusing because you can't directly pass the task id into it. You can get around that though.

    So with how we did it before, we simply declared an outside variable to the task ID and then used that when cancelling it. But with this, multiple tasks can be running and that breaks everything.

    So we add an extra step, and pass the taskID into the runnable.

    We need a class field to temporarily hold the taskId while it is being passed into the runnable.
    Code:
        int taskID;
    
    Now we need a method that allows us to pass the taskID into the runnable after the task has been created.
    Code:
        private int getTaskID()
        {
            return taskID;
        }
    And then the task itself.
    Code:
    taskID = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable()
    {
            int taskID = -1;//some value that isn't normally used to show the task id hasn't been set yet.
            int count;
            @Override
        public void run()
            {
            if(taskID == -1)
            {
                taskID = getTaskID();
            }
                   
            count++;
            if(count == 5)//example cancel condition
            {
                plugin.getServer().getScheduler().cancelTask(taskID);
            }
                   
            plugin.getLogger().info(taskID + "," + count);//Watching the progress in console for testing purposes
        }
               
    }, 0, 20);
     
  3. Offline

    Zach_1919

    CluelessDev So let me ask you a question... WHY ARE YOU SO FRICKEN AMAZING
     
  4. Offline

    microgeek

    Use BukkitRunnables.

    Code:
            //Kinda pointless
            new BukkitRunnable() {
             
                @Override
                public void run() {
                  this.cancel();
                }
            }.runTaskTimer(instance, 0, 10);
    A lot simpler and easy to manage.
     
Thread Status:
Not open for further replies.

Share This Page