Solved How to Place A Bed In 1.15

Discussion in 'Spigot Plugin Development' started by Naptie, Jan 23, 2020.

  1. As I'm upgrading my Bedwars plugin from 1.8 to 1.15, I've noticed many things have changed. There is an individual enum for each color of bed, and org.bukkit.material.Bed is deprecated.

    Now I'm having trouble placing a bed properly. I'm using this method:
    Code (Java):
    public void spawn() {
            Set<Block> blocks = new HashSet<>();
            if (this.material.getMaterial().name().endsWith("_BED")) {
                BlockFace facing = LocationUtil.getFacing(locations.get(0), locations.get(1));
                Block bedHeadBlock = locations.get(1).getBlock(), bedFootBlock = locations.get(0).getBlock();
                BlockState bedHeadState = bedHeadBlock.getState(), bedFootState = bedFootBlock.getState();

                bedHeadState.setType(material.getMaterial());
                Bed bedHeadData = new Bed(material.getMaterial());
                bedHeadData.setHeadOfBed(true);
                bedHeadData.setFacingDirection(facing);
                bedHeadState.setData(bedHeadData);
                bedHeadState.update(true);

                bedFootState.setType(material.getMaterial());
                Bed bedFootData = new Bed(material.getMaterial());
                bedFootData.setHeadOfBed(false);
                bedFootData.setFacingDirection(facing);
                bedFootState.setData(bedFootData);
                bedFootState.update(true);

                blocks.add(bedHeadBlock);
                blocks.add(bedFootBlock);
            } else {
                for (Location location : locations) {
                    location.getBlock().setType(this.material.getMaterial());
                    //location.getBlock().setData((byte) this.material.getData());
                    blocks.add(location.getBlock());
                }
            }
            BlockInteract.blocksPlacedByPlayer.addAll(blocks);
            this.valid = true;
        }
    It will simply place a red bed even if material.getMaterial() is a bed in another color.

    Does anyone know a method that can place a bed properly in a given color and a given direction, in 1.15?
     
  2. huh, it seems like there is no Bukkit method to just set a bed (please correct me if I'm wrong). Here, take this

    Code (Java):
    public void setBed(Block start, BlockFace facing, Material material) {
    // assert material is bed
        for (Bed.Part part : Bed.Part.values()) {
            start.setType(material);
            final Bed bedState = (Bed) start.getBlockData();
            bedState.setPart(part);
            bedState.setFacing(facing);
            start.setBlockData(bedState);
            start = start.getRelative(facing.getOppositeFace());
        }
    }
    Edit: This seems more elegant imo
    Code (Java):
    public void setBed(Block start, BlockFace facing, Material material) {
        for (Bed.Part part : Bed.Part.values()) {
            start.setBlockData(Bukkit.createBlockData(material, (data) -> {
               ((Bed) data).setPart(part);
               ((Bed) data).setFacing(facing);
            }));
            start = start.getRelative(facing.getOppositeFace());
        }
    }
     
    #2 Schottky, Jan 23, 2020
    Last edited: Jan 23, 2020
    • Like Like x 1
  3. Thank you so much! It worked perfectly!
    [​IMG] [​IMG]

    Current code:
    Code (Java):
    public void spawn() {
            Set<Block> blocks = new HashSet<>();
            if (this.material.getMaterial().name().endsWith("_BED")) {
                BlockFace facing = LocationUtil.getFacing(locations.get(0), locations.get(1));
                Block bedHeadBlock = locations.get(1).getBlock(), bedFootBlock = locations.get(0).getBlock();
                setBed(bedHeadBlock, facing, material.getMaterial());

                blocks.add(bedHeadBlock);
                blocks.add(bedFootBlock);
            } else {
                for (Location location : locations) {
                    location.getBlock().setType(this.material.getMaterial());
                    //location.getBlock().setData((byte) this.material.getData());
                    blocks.add(location.getBlock());
                }
            }
            BlockInteract.blocksPlacedByPlayer.addAll(blocks);
            this.valid = true;
        }
     
  4. If you also want to add the resulting blocks to a Set, you could make it even cleaner like this:

    Code (Java):
    blocks.add(setBed(locations.get(1).getBlock(), facing, material));

    //...

    public Set<Block> setBed(Block start, BlockFace facing, Material material) {
        Set<Block> bedBlocks = new HashSet<>();
        for (Bed.Part part : Bed.Part.values()) {
            bedBlocks.add(start);
            start.setBlockData(Bukkit.createBlockData(material, (data) -> {
                ((Bed) data).setPart(part);
                ((Bed) data).setFacing(facing);
            }));
        start = start.getRelative(facing.getOppositeFace());
        }
        return bedBlocks;
    }
     
    • Like Like x 1
    • Useful Useful x 1
  5. Thanks! :D
    Code (Java):
            if (Tag.BEDS.isTagged(this.material.getMaterial())) {
                BlockFace facing = LocationUtil.getFacing(locations.get(0), locations.get(1));
                Block bedHeadBlock = locations.get(1).getBlock();
                System.out.println(material.getMaterial().name());
                blocks.addAll(setBed(bedHeadBlock, facing, material.getMaterial()));
            } else ...
    BTW, if you guys wonder why I'm checking if the material is bed, I can tell you that this plugin actually allows players to choose a random block as their bed.
    [​IMG]
    This feature makes Bedwars funnier and more creative. Also, it makes the game more challenging, as players have to prepare to break more blocks than just regular ones that protect the bed.

    Of course, admins have something special (these are only shown to ADMINs & OWNERs):
    [​IMG]

    Oops, it shouldn't be called "Bedwars"... XD
     
    #6 Naptie, Jan 24, 2020
    Last edited: Jan 24, 2020
    • Funny Funny x 1