这是我的代码片段。我有块和玩家的列表。我需要的只是在运行中的五秒钟之后,它将替换之前被替换的块,分配一个玩家来获取块。
@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);
}
}
}
答案 0 :(得分:0)
您可以按照从Player
列表中删除painters
的方式执行此操作。找到第一个固体块(hitBlock
)后,创建一个新的最终引用,以便您可以在Runnable
中访问它,例如:
final Block solidBlock = hitBlock;
要将块恢复到更改其类型和数据之前的状态,您可以跟踪这些属性:
final byte previousData = solidBlock.getData();
final Material previousType = solidBlock.getType();
然后在你的run()
方法中,如果它仍然处于不同的位置,你可以简单地改变它:
if (solidBlock.getType() != previousType) {
solidBlock.setType(previousType);
}
if (solidBlock.getData() != previousType) {
solidBlock.setData(previousData);
}
我确信有一种更清洁,更好的方法可以做到这一点但这对你的目的来说可能已经足够了(我确实发现了一个小故障,如果你在同一个区块扔两个雪球,它将不会恢复到真实由于未来Runnable
任务写在这里的方式,原始块但是染色的粘土块,为了解决这个问题,你需要完全不同地编写它并跟踪更多的事情。