存储块以备后用

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 任务在此处编写的方式而变成了染色粘土块,要解决此问题,您需要完全不同地编写它并跟踪更多内容)。