I'm having an issue where I have a ScheduledTask within a method, I've used scheduled tasks before so I'm pretty used to them, I just can't seem to get this one to work properly. The following is a part of an if statement within a PlayerInteractEvent. The statement is valid because the for loop above it works perfectly fine. I will say this though, I'm not sure exactly what final does to a variable, but the scheduled task wanted player to be final so I did so. I'm not sure if that could cause an issue or not, although I'm pretty sure it wouldn't because I've tested just broadcasting a message to the server. Here it is... Code: else if(e.getMaterial()== Material.REDSTONE_TORCH_OFF){ long time = Bukkit.getServer().getWorld("world").getTime(); final Player player = e.getPlayer(); if(time <= 20000){ e.getPlayer().sendMessage(ChatColor.YELLOW + "You only need this when affected by blindness."); }else{//night if (e.getPlayer().getLevel()==0){ e.getPlayer().sendMessage(ChatColor.RED + " I should probably get some batteries..."); }else{ //Get location where redstone torch off is, swap with ON, start scheduledTask, store in Hashmap for other uses. //LOOP WORKS FINE for (ItemStack item : player.getInventory()) { if(item.getTypeId() == 75) { item.setTypeId(76); } } //HERE IS WHERE THE ISSUE IS int id = this.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() { public void run() { player.setLevel(player.getLevel()-1);; }}, 4L, 1000L); threads.put(e.getPlayer().getName(), id); } } } If you guys need any more information I'd be happy to do so. Thanks so much! Also, my ItemStack loop is only grabbing items from a player's hot-bar, and not from their full inventory if anyone knows a quick fix for that, thanks in advance!
Sorry about that. Here Code: else{ //Get location where redstone torch off is, swap with ON, start scheduledTask, store in Hashmap for other uses. for (ItemStack item : player.getInventory()) { if(item.getTypeId() == 75) { item.setTypeId(76); } } int id = this.getServer().getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() { public void run() { Bukkit.getServer().broadcastMessage("THIS IS A TEST"); player.setLevel(player.getLevel()-1);; }}, 4L, 1000L); threads.put(e.getPlayer().getName(), id); }
You should use sync task, not async task. The modifier "final" tells Java that the value of a variable cannot change once it is set. Code:java //now "num5" ALWAYS represents 5...//forever...//you cannot set it againfinal int num5 = 5; //in this case, the "variable" is a pointer to an objectfinal Player creator = Bukkit.getPlayerExact("Notch");//now "creator" will always refer to the player object//you just got//aka it is always Notch//you cannot reassign the variableplayer = Bukkit.getPlayerExact("jeb_"); //THIS WILL NOT COMPILE//but you can still call the methods and change fields//of the object, since that doesn't reassign to your variablecreator.setGameMode(GameMode.CREATIVE); //this is fine You need to declare variables as final to access them from an anonymous inner class. When an anonymous inner class's object is instantiated, all variables which are declared "final" are copied to it. Code:java new Runnable(){ //THIS IS AN ANONYMOUS INNER CLASS}
Thanks, I understand that now, but how about switching async to sync. Does that explain why it doesn't run at all?
It doesn't work because you are using id before it exists... I would do something like this. Code:java final MutableInt id = new MutableInt(-1);id.value = Bukkit.scheduleSyncDelayedTask(new Runnable(){ Bukkit.broadcastMessage("the scheduled ID is: " + id.value);}); ... class MutableInt{ public int value; public MutableInt(int value) {this.value = value;}}
I did all of the following and still it changed nothing. Here it is now... Code: final MutableInt id = new MutableInt(-1); id.value = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){ public void run() { Bukkit.getServer().broadcastMessage("THIS IS A TEST"); e.getPlayer().setLevel(player.getLevel()-1);; }},60L); //threads.put(e.getPlayer().getName(), id); ...and the class Code: class MutableInt { public int value; public MutableInt(int value) {this.value = value;} }