Solved "Unbreakable" fake glass

Discussion in 'Spigot Plugin Development' started by Incrementing, Jan 31, 2017.

  1. So I'm creating a plugin that spawns glass walls around a certain region up to a certain height when a player, who's in combat, tries to enter the region. I'm using sendBlockChange() to spawn the walls just for that player and I've had no problem creating them and cleaning up afterward.

    The issue I'm having is that the glass block isn't a real block so players could just break the block or simply even click it and their client updates the block and removes it. I can't find a way to make these blocks unbreakable while the wall is visible because (as mentioned above) the blocks aren't real so when the player interacts with them they don't fire any events.

    If anyone has an idea of how to overcome this issue and make the glass blocks unbreakable I'd really appreciate your help.

    James out! :)
     
  2. Does the event BlockBreakEvent not work on this?
     
  3. Nope, there isn't a block being broken.
    "Send a block change. This fakes a block change packet for a user at a certain location. This will not actually change the world in any way." - Spigot JavaDocs
     
  4. JanTuck

    Supporter

    You could do this in a hacky way, by listening to PlayerInteractEvent and seeing if hes close to your blocks and then assume he tried to destroy one and resend it.
     
  5. Why are you trying to make "fake" blocks, why not just make real ones?
     
  6. That would prevent the people that are not in combat from entering and/or exiting the region.
     
  7. Does fake glass allow you to walk through it? (Never tried it sorry :p)
     
  8. All you have to do is use PlayerMoveEvent and check if they're in lets say 5 blocks to the outside of your region then select that part of the region and make the fake blocks around that block with #sendBlockChange().

    Edit: Then as they move set the blocks to air if they are glass, I'd suggest adding locations to a list of where the glass is if you can.
     
  9. No, you would only send the glass to people in combat
     
    • Like Like x 1
  10. FG_

    FG_

    Maybe he should try making Alternative Blocks.
     
  11. Oh ok.
     
  12. Thanks for all the help I think I've found a solution.
     
  13. JanTuck

    Supporter

    Mind sharing to help others?
     
  14. Will do once I've tested it out :)
     
  15. It's very messy and needs to be cleaned up but oh well... I'll do that later (maybe..)
    When the combat ends you loop the wallLocations HashMap and send the player a block update of air at the locations in the Map.

    Code (Text):
    public class PlayerMoveEventHandler implements Listener {

        static HashMap<UUID, ArrayList<Location>> wallLocations = new HashMap<>();

        private Main instance;
        public PlayerMoveEventHandler(Main instance) {
            this.instance = instance;
        }

        @EventHandler
        public void onMove(PlayerMoveEvent e) {
    if (e.getPlayer().getWorld().getName().equalsIgnoreCase("world")) {
                RegionManager region = Utils.getWorldGuard().getRegionManager(e.getPlayer().getWorld());
                CombatTag tag = new CombatTag(e.getPlayer().getUniqueId(), instance);
                if (tag.isTagged()) {
                    ProtectedRegion spawn = region.getRegion("spawn");
                    Location min = new Location(Bukkit.getWorld("world"), spawn.getMinimumPoint().getBlockX(), e.getPlayer().getLocation().getBlockY(), spawn.getMinimumPoint().getBlockZ());
                    Location max = new Location(Bukkit.getWorld("world"), spawn.getMaximumPoint().getBlockX(), e.getPlayer().getLocation().getBlockY(), spawn.getMaximumPoint().getBlockZ());
                    List<Block> blocks = Utils.blocksBetweenPoints(min, max);
                    List<Location> locs = new ArrayList<>();

                    for (Block block : blocks) {
                        if (e.getTo().distance(block.getLocation()) <= 5.0) {
                            if (block.getRelative(BlockFace.DOWN).getType() == Material.BEDROCK) { //Only spawn glass on the bedrock blocks around spawn claim
                                for (int i = 0; i < 25; i++) {
                                    locs.add(block.getLocation().add(0, i, 0));
                                }
                            }
                        }
                    }

                        if (!locs.isEmpty()) {
                            for (Location loc : locs) {
                                e.getPlayer().sendBlockChange(loc, Material.STAINED_GLASS, (byte) 14);
                                ArrayList<Location> list = new ArrayList<>();
                                if (wallLocations.containsKey(e.getPlayer().getUniqueId())) {
                                    list.addAll(wallLocations.get(e.getPlayer().getUniqueId()));
                                }
                                list.add(loc);
                                wallLocations.put(e.getPlayer().getUniqueId(), list);
                            }
                        }
         
                }
            }
        }