0

thanks for all that helped me! I will be more detailed now. What I want to do is a Bukkit plugin which after one minute, and if the player dropped something, the console displays an information message, like "Players are moving", but I just can make the first message appear: "Player dropped something" and I think that the error is on the boolean that I used. Please, can anyone help me with bukkit? This is my code:

public class HgCake extends JavaPlugin implements Listener{
    boolean reference = false;
    @Override
    public void onEnable() {
        Bukkit.getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onDropItem (PlayerDropItemEvent e) {
        getLogger().info("Player dropped something");
        reference = true;
    }

    public void onPlayerMove (PlayerMoveEvent e){
        if (reference = true){
            getLogger().info("Players are moving");
        }
    }
}
Tuna
  • 2,937
  • 4
  • 37
  • 61
PinguCraft
  • 39
  • 1
  • 3

3 Answers3

2

Bukkit has a built in scheduling system that you can read up on Scheduler Programming

Use this instead of normal Java timers, trust me. It'll make your life easier in the long run.

To do what you're wanting to do, you'd need a BukkitRunnable class to give to the scheduler.

This is a generic one I over-simplified for example purposes:

public class Callback extends BukkitRunnable{
        private Object targetObject;
        public Method targetMethod;
        private Object[] perameters;

        public Callback(Object targetObject, String methodName, Object[] argsOrNull){
                try {
                    this.targetMethod = targetObject.getClass().getMethod(methodName, (Class<?>[]) argsOrNull);
                } catch (Exception e){
                    e.printStackTrace();
                }
                this.targetObject = targetObject;
                this.perameters = argsOrNull;
        }

        public void run(){
                try {
                    this.targetMethod.invoke(this.targetObject,perameters);
                } catch (Exception e){
                    e.printStackTrace();
                }
        }
}

Then you create an object of that runnable, providing the callback method/props as args, and give it to the scheduler to run in 60 seconds:

For the movement part, you just watch that while the item is dropped and nobody's moved yet.

public class DropWatcher implements Listener {
    private Boolean hasAnythingMoved;
    private Boolean dropped;
    private Pwncraft plugin;
    private Player player;

    public DropWatcher(Pwncraft plugin, Player player){
        this.player = player;
        this.hasAnythingMoved = false;
        this.dropped = false;
        this.plugin = plugin;
        this.plugin.pluginManager.registerEvents(this, plugin);
    }

    //Drop event listener: When the player drops an item, it sets dropped to true, and initiates the countdown.
    @EventHandler
    public void onDropItem (PlayerDropItemEvent e) {
        if(e.getPlayer().equals(this.player) && !this.dropped){
            this.dropped = true;
            BukkitCallbackTask doInSixtySeconds = new BukkitCallbackTask(this, "timesUp" , null);
            doInSixtySeconds.runTaskLater(plugin, 1200); // time is in ticks (20 ticks +/- = 1 sec), so 1200 ticks = 1 min.
        }
    }

    //Watches for other-players' movement, and sets hasAnythingMoved to true if so.
    @EventHandler
    public void onMove (PlayerMoveEvent e){
        if(!e.getPlayer().equals(this.player) && this.dropped && !this.hasAnythingMoved){
            this.hasAnythingMoved = true;
        }
    }

    /*
    This is the method the runnable calls when the timer is up.
    It checks for movement, and if so, sends a message and explodes the player 
    (Just because it can. You're welcome to veto the explosion.) 
    */
    public void timesUp(){

        if(this.hasAnythingMoved){
            this.player.sendMessage("Someone moved! Time to party!");
            this.player.getWorld().createExplosion(this.player.getLocation(), 5F);
            this.dropped = false;
            this.hasAnythingMoved = false;
        }
    }
}
Panda
  • 6,955
  • 6
  • 40
  • 55
Sintrinsic
  • 86
  • 5
0

You forgot the @EventHandler for the PlayerMoveEvent I think.

It should be:

public class HgCake extends JavaPlugin implements Listener{
boolean reference = false;
@Override
public void onEnable() {
    Bukkit.getServer().getPluginManager().registerEvents(this, this);
}

@EventHandler
public void onDropItem (PlayerDropItemEvent e) {
    getLogger().info("Player dropped something");
    reference = true;
}

@EventHandler
public void onPlayerMove (PlayerMoveEvent e){
    if (reference = true){
        getLogger().info("Players are moving");
    }
}

}

0
    int plannedActivity = getServer().getScheduler().runTaskLaterAsynchronously(this, new Runnable() {

        public void run() {

            //whatever you want to do

        }

    }, 120L);
Jonas
  • 1
  • 2
    Please add description to your answer – Abhinav Singh Maurya Oct 05 '15 at 06:57
  • For example, you may want to explain why the `delay` parameter is 120 when the OP asked for a 60 second delay. – dcsohl Oct 05 '15 at 14:10
  • Welcome to Stack Overflow! Could you please [edit] in an explanation of why this code answers the question? Code-only answers are [discouraged](http://meta.stackexchange.com/q/148272), because they don't teach the solution. – NathanOliver Oct 05 '15 at 15:16