3

So I want to check when a player right clicks with a book in their hand after first executing a command. I've tried to make Runnable running as a timer and in that scheduler checking if the player right clicks with a book in their hand. The Runnable forced me to Override the 'run' method.

This is what I've tried:

@Override
public void onEnable() {

this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {

    @Override
    public void run() {
        //Here I want to check if the player right clicked with a book in their hand.
    }
}
Jake F.
  • 141
  • 1
  • 3
  • 17
  • Why do you want to register an event listener inside a task that will be run multiple times? For each event you'd like to listen to, you only need to implement one method inside a listener (the method will be called every time the event fires, no need for a repeating task). – Adrian Sohn Apr 09 '16 at 23:15
  • If they run this command I want to check if they are right clicking a book until they do right click a book – Jake F. Apr 09 '16 at 23:16
  • Okay, that would need to be done differently though. Events can only be registered once. I would register the PlayerInteractEvent and whenever a player right clicks a book, insert the time they clicked and their names into a list. Then, whenever the player executes the command, you can check whether they recently right clicked with the book. – Adrian Sohn Apr 09 '16 at 23:28

1 Answers1

1

In order to know if the player ran the command, you have to store the player's UUID somewhere. First of all you create a Set<UUID> which temporarily stores all the Unique ID's of all players that have executed the command, so when you see a player stored in this set, you know they executed the command. A UUID is a 36-character string that is unique for every player and is the same on every server. You make the Set like this:

final Set<UUID> players = new HashSet<>();

Next you need to make your command. I would do that like this:

@Override
public boolean onCommand(CommandSender sender, Command cmd, String cl, String[] args) {
    //Check if your command was executed
    if(cmd.getName().equalsIgnorecase("yourCommand")){
        //Check if the executor of the command is a player and not a commandblock or console
        if(sender instanceof Player){

            Player player = (Player) sender;

            //Add the player's unique ID to the set
            players.add(player.getUniqueId());
        } 
    }
}

Now what you do next is listen for the PlayerInteractEvent to see when a player clicks the book. If you see the player is in the Set, you know they have executed the command. Here is how I would make that EventHandler:

@EventHandler
public void onInteract(PlayerInteractEvent event){
    //Check if the player right clicked.
    if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK){
        //Check if the Set contains this player
        if(players.contains(event.getPlayer().getUniqueId()){
            //Check if the player had an item in their hand
            if(event.getPlayer().getItemInHand().getType() == Material.BOOK){
                //Remove player from the set so they have to execute the command again before right clicking the book again
                players.remove(event.getPlayer().getUniqueId());
                //Here you can do whatever you want to do when the player executed the command and right clicks a book.
            }
        }
    }
}

So what I've done is when the player executes the command, store them in a Set. Next listen for the PlayerInteractEvent. This is basicly a callback method called every time a player interacts. This could be when a player steps a pressureplate, when a player right or left clicks on a block or in the air etc.

In that PlayerInteractEvent, I check if the player is stored in that Set, if the player right clicked in the air or right clicked a block and check if the player has a book in their hand. If that's all correct, I remove the player from the Set so they have to execute the command once again to perform the same action.

Also don't forget to register events and implement Listener.

In case you wanna learn more about the Set, the Javadocs can be found here.