I want to be able to create doors, which one can open and close.
In Bukkit this was a non-obvious task (see code below). What code do I need to write in order to create a door (which I and other players can open and close) at some location?
Thanks in advance
Dmitri
P. S.: Here’s the code, which does it in Bukkit:
@Override
public void putDoor(final DoorPlacementInstruction instr) {
final Block bottom = getWorld().getBlockAt(
instr.x(),
instr.y(),
instr.z()
);
final Block top = bottom.getRelative(BlockFace.UP, 1);
top.setType(instr.material());
bottom.setType(instr.material());
top.setTypeIdAndData(64, (byte) 0x8, true);
bottom.setTypeIdAndData(64, (byte) 0x4, true);
}
import org.bukkit.Material;
public class DoorPlacementInstruction implements BukkitInstruction {
private final int x;
private final int y;
private final int z;
private final Material material;
public DoorPlacementInstruction(int x, int y, int z, Material material) {
this.x = x;
this.y = y;
this.z = z;
this.material = material;
}
public int x() {
return this.x;
}
public int y() {
return this.y;
}
public int z() {
return this.z;
}
public Material material() {
return this.material;
}
}
Take a look at Keys.HINGE_POSITION, Keys.OPEN, Keys.DIRECTION, and Keys.PORTION_TYPE. You can apply those to a door’s BlockState to change all of the values that Minecraft attaches to the blocks.
There is a key to be used with the data api. I am pretty sure that you have to offer that key with true to the Location the door is standing at, because a door is a tile entity.
Edit: I complety misread your post. Sorry. @ZephireNZ seems to be right.
Recently I tried out to write a piece of code, which would put a door. Sorry it took me so long. Here’s the Kotlin code:
internal open fun createDoor(
door: Door,
coords: McCoords
) {
val loc = createSpongeLocation(
x = coords.x + door.x,
y = coords.y + door.elevation,
z = coords.z + door.z
)
setBlockType(loc, getBlockType(door.blockType))
setBlockState(loc, createDoorBlockState(door))
}
internal open fun createDoorBlockState(
door: Door
): org.spongepowered.api.block.BlockState {
var state: org.spongepowered.api.block.BlockState =
BlockTypes.SPONGE.getDefaultState()
state = state.with(Keys.OPEN, false).get() // Error
state = state.with(Keys.DIRECTION, parseDirection(door.direction)).get()
return state
}
internal open fun createSpongeLocation(
x: Int,
y: Int,
z: Int
): org.spongepowered.api.world.Location<World> {
return org.spongepowered.api.world.Location<World>(
world,
x,
y,
z)
}
Note: createDoorBlockState and createSpongeLocation are placed into separate methods purely for the purpose of easier testing.
When I run this code, I get an error at line state = state.with(Keys.OPEN, false).get():
java.util.NoSuchElementException: No value present
at java.util.Optional.get(Unknown Source) ~[?:1.8.0_66]
Update: I tried to use Keys.PORTION_TYPE, but it’s not compatible with the door’s block state (both empirically and according to lists of applicable keys by block type).
I tried to use different directions (SOUTH, WEST, EAST, NORTH, NORTHWEST), but it didn’t help.
I also tried to set the direction of the upper half of the door to Direction.DOWN and that of the lower half to Direction.UP, without any change.
Is this functionality implemente in Sponge at all? If not and if I wanted to contribute it, where should I start?