Build cage around player

Discussion in 'Spigot Plugin Development' started by Drawethree, Apr 26, 2017.

  1. What's the most efficient way to build iron fence cage around player ?
     
  2. NathanWolf

    Supporter

    Iterate over player location, x-1 to x+1, z-1 to z+1, y to y+2. If your x or z iterator is not 0 then place an iron fence block.

    You could also add a roof by going up to y+3 and make that layer a different material (iron bars will look weird)
     
  3. You could use plr.getLocation().getBlock()

    To get the block they're standing on,

    Then make an array of blockfaces. North,south,west etc

    Then use a loop to get the relative blocks and set them to iron bars.

    This would get a bit complicated if you tried to make the size of the cage more than 1-2 blocks in size.

    Another method would be to get the players location, specify a radius and create a list of locations.


    Set counter = 0
    While (counter < 360)
    Calculate the angle
    counter * pi / 180
    Set x = radius * math.cos(angle)
    Set z = radius * math.sin(angle)

    Clone the original location
    newLoc.add(x,0,z)
    Add this location to your list of locations.
    Add 1 to the counter variable.

    You should be able to divide the 360 / your radius to get a larger value to add to the counter variable so as a smaller radius will have more overlapping locations.

    If you get the block at the location and add it to the list you can skip re-adding it as one block can be found at multiple locations especially if you're using a small radius with 1 degree of separation




    Sent from my iPhone using Tapatalk
     
  4. Why would you use heavy sin and cos functions for such a simple thing. It doesn't even have to be circle shaped.
     
    • Agree Agree x 2
  5. I would just do what above stated, get current location and set blocks around user

    . #
    # 0 #
    # | #
    . #
     
  6. Heavy isn't super relevant here unless the cage moves with the player. Feel free to post a better solution, square, oval or triangular if you wish. OP Didn't specify the shape.


    Sent from my iPhone using Tapatalk
     
  7. NathanWolf

    Supporter

    Agreed, K.I.S.S.

    If I had wanted to over-complicate this I would've suggested the way I do it in my plugin, use a schematic... :D

    Simple solution was provided by me in the first response- I didn't spoonfeed but it should be plenty. Hollow boxes are easy enough to build!
     

  8.  
    • Like Like x 1
    • Agree Agree x 1
  9. I usually don't spoonfeed, but this got me thinking and was something quick and fun to work on. Here's some code that generates a rectangular iron cage. Would I say it's efficient? It does alright. However, the method I've provided is easy to customize and it should work with any entity. The method takes several parameters, the entity that should be enclosed, the length of one side of the cage (>=3), the height of the cage (excluding roof), and if you want a roof or not.

    Here's a cage the code built with a roof, side length of 5 blocks, and a height of two blocks.
    [​IMG]
    Code (Text):
    buildIronCageAround(player, 5, 2, true);
    Please note: This method does not take into account protected regions of any sort, so you'll have to do your own verifications before you call this method.

    Code (Text):
    /**
    * Constructs an iron cage around an entity.
    * @param Entity ent - The entity that will be surrounded by the cage.
    * @param int sideLength - The length of each side of the cage. Must be an uneven number >= 3
    * @param int height - How many blocks tall the cage is (excluding the roof, which is 1 block tall)
    * @param boolean wantRoof - If a roof should be constructed above the cage or not.
    *
    * Preconditions:
    * - sideLength is greater than or equal to 3.
    * - height is greater than 0.
    *
    * @author xMakerx | Maverick
    */

    public void buildIronCageAround(Entity ent, int sideLength, int height, boolean wantRoof) {
        Material fence = Material.IRON_FENCE;
        Material roof = Material.STONE;
        Location entLoc = ent.getLocation();
     
        // Let's make sure our preconditions were met.
        if(sideLength < 3 || sideLength % 2 == 0) {
            throw new IllegalArgumentException("You must enter an odd number greater than 3 for the side length");
        }else if(height == 0) {
            throw new IllegalArgumentException("Height must be greater than 0.");
        }
     
        int delta = (sideLength / 2);
        Location corner1 = new Location(entLoc.getWorld(), entLoc.getBlockX() + delta, entLoc.getBlockY() + 1, entLoc.getBlockZ() - delta);
        Location corner2 = new Location(entLoc.getWorld(), entLoc.getBlockX() - delta, entLoc.getBlockY() + 1, entLoc.getBlockZ() + delta);
        int minX = Math.min(corner1.getBlockX(), corner2.getBlockX());
        int maxX = Math.max(corner1.getBlockX(), corner2.getBlockX());
        int minZ = Math.min(corner1.getBlockZ(), corner2.getBlockZ());
        int maxZ = Math.max(corner1.getBlockZ(), corner2.getBlockZ());
     
        for(int x = minX; x <= maxX; x++) {
            for(int y = 0; y < height; y++) {
                for(int z = minZ; z <= maxZ; z++) {
                    if((x == minX || x == maxX) || (z == minZ || z == maxZ)) {
                        Block b = corner1.getWorld().getBlockAt(x, entLoc.getBlockY() + y, z);
                        b.setType(fence);
                    }
                 
                    if(y == height - 1 && wantRoof) {
                        Block b = corner1.getWorld().getBlockAt(x, entLoc.getBlockY() + y + 1, z);
                        b.setType(roof);
                    }
                }
            }
        }
    }
     
    • Like Like x 1