Solved Setting Fake Blocks doesn't work

Discussion in 'Spigot Plugin Development' started by KonTux, Feb 16, 2020.

  1. Hi there,
    so I was trying to avoid changing the original world in some situations and make placed blocks invisible to other players. The only method seems to be calling the sendBlockChange method on all the players who should see the block. To avoid a real world change and others seeing the blocks as well I set the block to AIR rightr when the Event is fired. One tick later I send those fake blocks to the players who are supposed to see that block as it was placed. I still looks as if the event would be cancelled.

    That's the block of code:
    Code (Java):
    } else if (state == PlayerState.INMATCH || state == PlayerState.STARTINGMATCH) {
                Block block = event.getBlockPlaced();

                block.setType(Material.AIR);

                Bukkit.getScheduler().scheduleSyncDelayedTask(IcePracticePlugin.getPlugin(), new Runnable() {
                    @Override
                    public void run() {
                        MatchRegistry.getInstance().getOpponent(player).sendBlockChange(block.getLocation(), block.getType(), block.getData());
                        event.getPlayer().sendBlockChange(block.getLocation(), block.getType(), (byte) 0);
                    }
                }, 1);

            }
    I also tried just cancelling the event instead of changing the block's material to AIR.
    Is there anything I am doing wrong?
    Thanks in advance
     
  2. WAI.
    At the moment of task execution the block will be air, so you will be sending an air block change.
     
  3. In the delayed task, block.getType() will return the actual block type and not the placed and cancelled that is why it is not working. You should save the material into a variable first
     
  4. You guys are indeed right. The material would have been air. I changed it a little and also added a small message to check the material it's will use.

    Code (Java):
    else if (state == PlayerState.INMATCH || state == PlayerState.STARTINGMATCH) {
                Block block = event.getBlockPlaced();
                Material material = block.getType();

                block.getWorld().getBlockAt(block.getLocation()).setType(Material.AIR);

                Bukkit.getScheduler().scheduleSyncDelayedTask(IcePracticePlugin.getPlugin(), new Runnable() {
                    @Override
                    public void run() {

                        for (Player current : MatchRegistry.getInstance().getMatch(player).getParticipants()) {
                            current.sendMessage("Material is: " + material);
                            current.sendBlockChange(block.getLocation(), material, block.getData());
                        }
                    }
                }, 1);

            }
    The message always says the correct material (not Air) but it still gets removed immediately.
     
  5. 1 tick delay might not be enough. Try increasing it.
     
    • Useful Useful x 1
  6. Thanks a lot!
    Delaying it by 2 ticks works.
    Thanks for the tip : )