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?
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()); } }
Thank you so much! It worked perfectly! 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; }
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; }
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Tag.html#BEDS Replace this.material.getMaterial().name().endsWith("_BED") with Tag.BEDS.isTagged(this.material.getMaterial())
Thanks! 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. 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): Oops, it shouldn't be called "Bedwars"... XD