Create Wall infront of player

Discussion in 'Spigot Plugin Development' started by NocturnalDev, May 16, 2019.

  1. Hello,

    I am looking to create a wall that's 4x4 in front of a player when they reach within a set coordinate (creating a world border).

    Here's what I've done so far, I am looking to use the sendBlockChange since that's a packet. However, how would I be able to send a block every 2 ticks to prevent someone from removing a block by right-clicking, and how could I make the blocks disappear when they leave the area?


    Code (Java):
                if ((int) player.getLocation().getX() >= xBorder - 8 && ( (int) player.getLocation().getZ() <= - 83 || (int) player.getLocation().getZ() >= -231 )) { ;
                    Location barrier = new Location(Main.getPlugin().getServer().getWorld("spawn"), 20, player.getLocation().getY(), player.getLocation().getZ());
                    player.sendBlockChange(barrier, Material.STAINED_GLASS, (byte) 14);
                }
    Thank you!
     
  2. Hello,

    According to the Javadoc, the Player#sendBlockChange() will not actually change the world in any way.

    I think you have to use World#getBlockAt(), so you can modify blocks. (And create the wall, according to the locations)

    To prevent breaking those blocks, I think you can put a Metadata on those blocks, and listen to the BlockBreakEvent: if the block contains the metadata, then cancel the event.
     
  3. Repeatable task for re-setting the block, when the player leaves, send a block change to air
     
  4. I would like it to stay as a packet so it won't change the world, b/c this is a world border. I'm trying to keep the aesthetics of the map from an insider's perspective.
     
  5. @NocturnalDev have you tried this approach? I think this would be the simplest option. You could also maybe listen to an InteractEvent and update the blocks then?
     
  6. PacketBlocks dont fire InteractEvent
     
  7. How could I send the block every few ticks to make sure that they can't remove it, and then remove it once they leave the region?
     
  8. Just put the if statement in a BukkitRunnable that runs every second or so. As for removing it, I'm pretty sure you can put an else statement after the if statement that just sends an air block packet. Haven't tried this out myself so I'm not 100% sure, but it's worth a shot.
     
  9. First let me explain packets simply so people understand what's happening.

    Basically plugin structure is plugin does code -> server does code -> sends packet to client -> client does code based off of the packet received.
    This can happen plugin->client->server as well.
    So basically to perform normal operations you don't need to use packets, the server/client will use your code to determine correct packets to send based off the code it received.

    In this case, you are doing a straight plugin sends packet -> client does code based off of packet received. This will "trick" the client into thinking there is a wall in front of them, when the server knows nothing about it.

    That means if the player simply leaves the area, their client will unload that zone, and when it needs to load a new copy, it will ask the server for the current changes in that zone. Seeing as how the server knows nothing about the wall, it is not ever there on the server, no other clients will see it other than the one you sent the packet, so it was never really there in the first place and you don't have to remove it.

    As for stopping the blocks from breaking, you could simply "trick" the client into thinking they are unbreakable blocks and they won't break.
    The events (untested) most likely won't work at all because the server doesn't know a thing about these blocks, and will think the client is clicking air or something.

    If that still doesn't do it for you have to schedule a repeating task.
    Code (Java):

    Bukkit.getScheduler().scheduleSyncRepeatingTask
     
     
    #9 ForbiddenSoul, May 18, 2019
    Last edited: May 18, 2019