Here's my snippet of code. I have Lists for the blocks and player. All I need is for after the five seconds in that runnable is up, it'll replace the blocks that were previously replaced, assigning a player to get the blocks.
@EventHandler
public void onSnowballHit(ProjectileHitEvent e) {
// If it's a snowball...
if (e.getEntity() instanceof Snowball) {
Snowball snowball = (Snowball) e.getEntity();
final Player p = (Player) snowball.getShooter();
// ...if a player threw it...
if (snowball.getShooter() instanceof Player) {
// Make a Player from the Entity
BlockIterator iterator = new BlockIterator(e.getEntity().getWorld(),
e.getEntity().getLocation().toVector(), e.getEntity().getVelocity().normalize(),
0.0D, 4);
// Make a block
Block hitBlock = null;
// Loop through possible blocks
while (iterator.hasNext()) {
// Set the hitBlock to the current block we're checking
hitBlock = iterator.next();
// If it's not air, STOP!
if (!hitBlock.getType().equals(Material.AIR)) {
break;
}
}
int min = 1;
int max = 15;
Random r = new Random();
byte clayBlocks = (byte) (r.nextInt(max - min + 1) + min);
paintBlockList.add(hitBlock);
painters.add(p);
// Set it to stained clay
hitBlock.setType(Material.STAINED_CLAY);
// red = 14, blue = 11 (data values)
hitBlock.setData(clayBlocks);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
public void run(){
if(painters.contains(p)){
painters.remove(p);
}
}
}, 100);
}
}
}
You could do it the same way you remove the Player
from the painters
list. Once you've found the first solid block (hitBlock
) create a new final reference so that you can access it in the Runnable
, for example like this:
final Block solidBlock = hitBlock;
To return the block to the state it was before you changed its type and data, you could keep track of those attributes:
final byte previousData = solidBlock.getData();
final Material previousType = solidBlock.getType();
Then in your run()
method you can simply change the block back if it is still at that point different like so:
if (solidBlock.getType() != previousType) {
solidBlock.setType(previousType);
}
if (solidBlock.getData() != previousType) {
solidBlock.setData(previousData);
}
I'm sure there's a cleaner, nicer way to do it but this might be good enough for your purposes (I did find a glitch where if you throw two snowballs at the same block, it won't revert to the true original block but to a stained clay block because of the way the future Runnable
tasks are written here, to fix this you'd need to write this completely differently and keep track of more things).