Merge pull request #210 from alexwith/master

StairsPlacementRule (not perfect yet)
This commit is contained in:
TheMode 2021-04-02 15:51:15 +02:00 committed by GitHub
commit 773b90e16a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,166 @@
package net.minestom.server.instance.block.rule.vanilla;
import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockAlternative;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.instance.block.rule.BlockPlacementRule;
import net.minestom.server.utils.BlockPosition;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class StairsPlacementRule extends BlockPlacementRule {
public StairsPlacementRule(@NotNull Block block) {
super(block);
}
@Override
public short blockUpdate(@NotNull Instance instance, @NotNull BlockPosition blockPosition, short currentStateID) {
return currentStateID;
}
@Override
public short blockPlace(@NotNull Instance instance, @NotNull Block block, @NotNull BlockFace blockFace, @NotNull BlockPosition blockPosition, @NotNull Player player) {
Facing facing = this.getFacing(player);
Shape shape = this.getShape(instance, blockPosition, facing);
BlockFace half = BlockFace.BOTTOM; // waiting for new block faces to be implemented
boolean waterlogged = false; // waiting for water to be implemented
return block.withProperties(
"facing=" + facing.toString().toLowerCase(),
"half=" + half.toString().toLowerCase(),
"shape=" + shape.toString().toLowerCase(),
"waterlogged=" + waterlogged
);
}
private enum Shape {
STRAIGHT,
OUTER_LEFT,
OUTER_RIGHT,
INNER_LEFT,
INNER_RIGHT;
}
private enum Facing {
NORTH(
new BlockPosition(0, 0, 1),
new BlockPosition(0, 0, -1)
),
EAST(
new BlockPosition(-1, 0, 0),
new BlockPosition(1, 0, 0)
),
SOUTH(
new BlockPosition(0, 0, -1),
new BlockPosition(0, 0, 1)
),
WEST(
new BlockPosition(1, 0, 0),
new BlockPosition(-1, 0, 0)
);
private final BlockPosition front;
private final BlockPosition back;
Facing(@NotNull BlockPosition front, @NotNull BlockPosition back) {
this.front = front;
this.back = back;
}
@NotNull
public Pair<@Nullable Shape, @Nullable Facing> getFront(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
return this.getProperties(instance, blockPosition.clone().add(this.front));
}
@NotNull
public Pair<@Nullable Shape, @Nullable Facing> getBack(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
return this.getProperties(instance, blockPosition.clone().add(this.back));
}
@NotNull
private Pair<@Nullable Shape, @Nullable Facing> getProperties(@NotNull Instance instance, @NotNull BlockPosition blockPosition) {
Block block = instance.getBlock(blockPosition);
if (block == null) {
return Pair.of(null, null);
}
short stateId = instance.getBlockStateId(blockPosition);
BlockAlternative alternative = block.getAlternative(stateId);
try {
Shape shape = Shape.valueOf(alternative.getProperty("shape").toUpperCase());
Facing facing = Facing.valueOf(alternative.getProperty("facing").toUpperCase());
return Pair.of(shape, facing);
} catch (Exception ex) {
return Pair.of(null, null);
}
}
}
@NotNull
private Shape getShape(@NotNull Instance instance, @NotNull BlockPosition blockPosition, @NotNull Facing facing) {
Pair<Shape, Facing> front = facing.getFront(instance, blockPosition);
Pair<Shape, Facing> back = facing.getBack(instance, blockPosition);
Shape shape = this.getShapeFromSide(front, facing, Shape.INNER_RIGHT, Shape.INNER_LEFT);
if (shape == null) {
shape = this.getShapeFromSide(back, facing, Shape.OUTER_RIGHT, Shape.OUTER_LEFT);
}
return shape == null ? Shape.STRAIGHT : shape;
}
@Nullable
private Shape getShapeFromSide(@NotNull Pair<Shape, Facing> side, @NotNull Facing facing, @NotNull Shape right, @NotNull Shape left) {
if (side.getLeft() == null) {
return null;
}
Facing sideFacing = side.getRight();
if (facing.equals(Facing.NORTH)) {
if (sideFacing.equals(Facing.EAST)) {
return right;
} else if (sideFacing.equals(Facing.WEST)) {
return left;
}
} else if (facing.equals(Facing.SOUTH)) {
if (sideFacing.equals(Facing.EAST)) {
return left;
} else if (sideFacing.equals(Facing.WEST)) {
return right;
}
} else if (facing.equals(Facing.EAST)) {
if (sideFacing.equals(Facing.SOUTH)) {
return right;
} else if (sideFacing.equals(Facing.NORTH)) {
return left;
}
} else if (facing.equals(Facing.WEST)) {
if (sideFacing.equals(Facing.SOUTH)) {
return left;
} else if (sideFacing.equals(Facing.NORTH)) {
return right;
}
}
return null;
}
@NotNull
private Facing getFacing(@NotNull Player player) {
float degrees = (player.getPosition().getYaw() - 90) % 360;
if (degrees < 0) {
degrees += 360;
}
if (0 <= degrees && degrees < 45) {
return Facing.WEST;
} else if (45 <= degrees && degrees < 135) {
return Facing.NORTH;
} else if (135 <= degrees && degrees < 225) {
return Facing.EAST;
} else if (225 <= degrees && degrees < 315) {
return Facing.SOUTH;
} else { // 315 <= degrees && degrees < 360
return Facing.WEST;
}
}
}