存储块以备后用
Storing Blocks for Replace Later
这是我的代码片段。我有积木和播放器的列表。我所需要的只是在可运行的五秒后,它将替换之前替换的块,分配一个玩家来获取块。
@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);
}
}
}
您可以像从 painters
列表中删除 Player
一样进行操作。找到第一个实体块 (hitBlock
) 后,创建一个新的最终引用,以便您可以在 Runnable
中访问它,例如:
final Block solidBlock = hitBlock;
为了 return 将块恢复到更改其类型和数据之前的状态,您可以跟踪这些属性:
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
任务在此处编写的方式而变成了染色粘土块,要解决此问题,您需要完全不同地编写它并跟踪更多内容)。
这是我的代码片段。我有积木和播放器的列表。我所需要的只是在可运行的五秒后,它将替换之前替换的块,分配一个玩家来获取块。
@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);
}
}
}
您可以像从 painters
列表中删除 Player
一样进行操作。找到第一个实体块 (hitBlock
) 后,创建一个新的最终引用,以便您可以在 Runnable
中访问它,例如:
final Block solidBlock = hitBlock;
为了 return 将块恢复到更改其类型和数据之前的状态,您可以跟踪这些属性:
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
任务在此处编写的方式而变成了染色粘土块,要解决此问题,您需要完全不同地编写它并跟踪更多内容)。