property based block data implementation

This commit is contained in:
dfsek
2021-06-26 02:17:31 -07:00
parent 43307b737c
commit bce7a181bd
45 changed files with 288 additions and 1542 deletions

View File

@@ -1,133 +0,0 @@
package com.dfsek.terra.api.block;
import org.jetbrains.annotations.NotNull;
public enum BlockFace {
NORTH(0, 0, -1),
EAST(1, 0, 0),
SOUTH(0, 0, 1),
WEST(-1, 0, 0),
UP(0, 1, 0),
DOWN(0, -1, 0),
NORTH_EAST(NORTH, EAST),
NORTH_WEST(NORTH, WEST),
SOUTH_EAST(SOUTH, EAST),
SOUTH_WEST(SOUTH, WEST),
WEST_NORTH_WEST(WEST, NORTH_WEST),
NORTH_NORTH_WEST(NORTH, NORTH_WEST),
NORTH_NORTH_EAST(NORTH, NORTH_EAST),
EAST_NORTH_EAST(EAST, NORTH_EAST),
EAST_SOUTH_EAST(EAST, SOUTH_EAST),
SOUTH_SOUTH_EAST(SOUTH, SOUTH_EAST),
SOUTH_SOUTH_WEST(SOUTH, SOUTH_WEST),
WEST_SOUTH_WEST(WEST, SOUTH_WEST),
SELF(0, 0, 0);
private final int modX;
private final int modY;
private final int modZ;
BlockFace(final int modX, final int modY, final int modZ) {
this.modX = modX;
this.modY = modY;
this.modZ = modZ;
}
BlockFace(final BlockFace face1, final BlockFace face2) {
this.modX = face1.getModX() + face2.getModX();
this.modY = face1.getModY() + face2.getModY();
this.modZ = face1.getModZ() + face2.getModZ();
}
/**
* Get the amount of X-coordinates to modify to get the represented block
*
* @return Amount of X-coordinates to modify
*/
public int getModX() {
return modX;
}
/**
* Get the amount of Y-coordinates to modify to get the represented block
*
* @return Amount of Y-coordinates to modify
*/
public int getModY() {
return modY;
}
/**
* Get the amount of Z-coordinates to modify to get the represented block
*
* @return Amount of Z-coordinates to modify
*/
public int getModZ() {
return modZ;
}
@NotNull
public BlockFace getOppositeFace() {
switch(this) {
case NORTH:
return BlockFace.SOUTH;
case SOUTH:
return BlockFace.NORTH;
case EAST:
return BlockFace.WEST;
case WEST:
return BlockFace.EAST;
case UP:
return BlockFace.DOWN;
case DOWN:
return BlockFace.UP;
case NORTH_EAST:
return BlockFace.SOUTH_WEST;
case NORTH_WEST:
return BlockFace.SOUTH_EAST;
case SOUTH_EAST:
return BlockFace.NORTH_WEST;
case SOUTH_WEST:
return BlockFace.NORTH_EAST;
case WEST_NORTH_WEST:
return BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_WEST:
return BlockFace.SOUTH_SOUTH_EAST;
case NORTH_NORTH_EAST:
return BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST:
return BlockFace.WEST_SOUTH_WEST;
case EAST_SOUTH_EAST:
return BlockFace.WEST_NORTH_WEST;
case SOUTH_SOUTH_EAST:
return BlockFace.NORTH_NORTH_WEST;
case SOUTH_SOUTH_WEST:
return BlockFace.NORTH_NORTH_EAST;
case WEST_SOUTH_WEST:
return BlockFace.EAST_NORTH_EAST;
case SELF:
return BlockFace.SELF;
}
return BlockFace.SELF;
}
}

View File

@@ -1,11 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
public interface AnaloguePowerable extends BlockState {
int getMaximumPower();
int getPower();
void setPower(int power);
}

View File

@@ -1,20 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
public interface Bisected extends BlockState {
Half getHalf();
void setHalf(Half half);
enum Half {
/**
* The top half of the block, normally with the higher y coordinate.
*/
TOP,
/**
* The bottom half of the block, normally with the lower y coordinate.
*/
BOTTOM
}
}

View File

@@ -1,10 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.BlockFace;
public interface Directional extends BlockState {
BlockFace getFacing();
void setFacing(BlockFace facing);
}

View File

@@ -1,16 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.BlockFace;
import java.util.Set;
public interface MultipleFacing extends BlockState {
Set<BlockFace> getFaces();
void setFace(BlockFace face, boolean facing);
Set<BlockFace> getAllowedFaces();
boolean hasFace(BlockFace f);
}

View File

@@ -1,14 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.properties.enums.Axis;
import com.dfsek.terra.api.block.state.BlockState;
import java.util.Set;
public interface Orientable extends BlockState {
Set<Axis> getAxes();
Axis getAxis();
void setAxis(Axis axis);
}

View File

@@ -1,11 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.state.properties.enums.RailShape;
public interface Rail extends BlockState {
RailShape getShape();
void setShape(RailShape newShape);
}

View File

@@ -1,18 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.BlockFace;
import java.util.Set;
public interface RedstoneWire extends BlockState, AnaloguePowerable {
Set<BlockFace> getAllowedFaces();
Connection getFace(BlockFace face);
void setFace(BlockFace face, Connection connection);
enum Connection {
NONE, SIDE, UP
}
}

View File

@@ -1,10 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.BlockFace;
public interface Rotatable extends BlockState {
BlockFace getRotation();
void setRotation(BlockFace face);
}

View File

@@ -1,11 +0,0 @@
package com.dfsek.terra.api.block.data;
public interface Slab extends Waterlogged {
Type getType();
void setType(Type type);
enum Type {
TOP, BOTTOM, DOUBLE
}
}

View File

@@ -1,30 +0,0 @@
package com.dfsek.terra.api.block.data;
public interface Stairs extends Waterlogged, Directional, Bisected {
Shape getShape();
void setShape(Shape shape);
enum Shape {
/**
* Regular stair block.
*/
STRAIGHT,
/**
* Inner corner stair block with higher left side.
*/
INNER_LEFT,
/**
* Inner corner stair block with higher right side.
*/
INNER_RIGHT,
/**
* Outer corner stair block with higher left side.
*/
OUTER_LEFT,
/**
* Outer corner stair block with higher right side.
*/
OUTER_RIGHT
}
}

View File

@@ -1,18 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.block.BlockFace;
public interface Wall extends BlockState, Waterlogged {
boolean isUp();
void setHeight(BlockFace face, Height height);
Height getHeight(BlockFace face);
void setUp(boolean up);
enum Height {
LOW, NONE, TALL
}
}

View File

@@ -1,9 +0,0 @@
package com.dfsek.terra.api.block.data;
import com.dfsek.terra.api.block.state.BlockState;
public interface Waterlogged extends BlockState {
boolean isWaterlogged();
void setWaterlogged(boolean waterlogged);
}

View File

@@ -4,6 +4,8 @@ import com.dfsek.terra.api.Handle;
import com.dfsek.terra.api.block.BlockType;
import com.dfsek.terra.api.block.state.properties.Property;
import java.util.function.Consumer;
public interface BlockState extends Cloneable, Handle {
BlockType getBlockType();
@@ -22,5 +24,15 @@ public interface BlockState extends Cloneable, Handle {
<T> T get(Property<T> property);
<T> BlockState set(Property<T> property);
<T> BlockState set(Property<T> property, T value);
default <T> BlockState setIfPresent(Property<T> property, T value) {
if(has(property)) set(property, value);
return this;
}
default <T> BlockState ifProperty(Property<T> property, Consumer<BlockState> action) {
if(has(property)) action.accept(this);
return this;
}
}

View File

@@ -1,17 +1,36 @@
package com.dfsek.terra.api.block.state.properties.base;
import com.dfsek.terra.api.block.state.properties.enums.Axis;
import com.dfsek.terra.api.block.state.properties.enums.Direction;
import com.dfsek.terra.api.block.state.properties.enums.Half;
import com.dfsek.terra.api.block.state.properties.enums.RailShape;
import com.dfsek.terra.api.block.state.properties.enums.RedstoneConnection;
import com.dfsek.terra.api.block.state.properties.enums.WallHeight;
public final class Properties {
public static final EnumProperty<Direction> DIRECTION = EnumProperty.of("facing", Direction.class);
public static final EnumProperty<Axis> AXIS = EnumProperty.of("axis", Axis.class);
public static final BooleanProperty NORTH = BooleanProperty.of("north");
public static final BooleanProperty SOUTH = BooleanProperty.of("south");
public static final BooleanProperty EAST = BooleanProperty.of("east");
public static final BooleanProperty WEST = BooleanProperty.of("west");
public static final EnumProperty<WallHeight> NORTH_HEIGHT = EnumProperty.of("north", WallHeight.class);
public static final EnumProperty<WallHeight> SOUTH_HEIGHT = EnumProperty.of("south", WallHeight.class);
public static final EnumProperty<WallHeight> EAST_HEIGHT = EnumProperty.of("east", WallHeight.class);
public static final EnumProperty<WallHeight> WEST_HEIGHT = EnumProperty.of("west", WallHeight.class);
public static final EnumProperty<RedstoneConnection> NORTH_CONNECTION = EnumProperty.of("north", RedstoneConnection.class);
public static final EnumProperty<RedstoneConnection> SOUTH_CONNECTION = EnumProperty.of("south", RedstoneConnection.class);
public static final EnumProperty<RedstoneConnection> EAST_CONNECTION = EnumProperty.of("east", RedstoneConnection.class);
public static final EnumProperty<RedstoneConnection> WEST_CONNECTION = EnumProperty.of("west", RedstoneConnection.class);
public static final EnumProperty<RailShape> RAIL_SHAPE = EnumProperty.of("shape", RailShape.class);
public static final EnumProperty<Half> HALF = EnumProperty.of("half", Half.class);
public static final IntProperty ROTATION = IntProperty.of("rotation", 0, 15);
public static final BooleanProperty WATERLOGGED = BooleanProperty.of("waterlogged");
}

View File

@@ -1,5 +1,69 @@
package com.dfsek.terra.api.block.state.properties.enums;
import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.util.generic.Construct;
public enum Direction {
NORTH,SOUTH,EAST,WEST,UP,DOWN
NORTH(0, 0, 0, -1),
EAST(1, 1, 0, 0),
SOUTH(2, 0, 0, 1),
WEST(3, -1, 0, 0),
UP(-1, 0, 1, 0),
DOWN(-1, 0, -1, 0);
private static final Direction[] rotations = Construct.construct(() -> new Direction[] {NORTH, SOUTH, EAST, WEST});
private final int rotation;
private final int modX;
private final int modY;
private final int modZ;
Direction(int rotation, int modX, int modY, int modZ) {
this.rotation = rotation;
this.modX = modX;
this.modY = modY;
this.modZ = modZ;
}
public Direction rotate(Rotation rotation) {
switch(this) {
case UP:
case DOWN:
return this;
default:
return rotations[(this.rotation + rotation.getDegrees()/90) % 4];
}
}
public int getModX() {
return modX;
}
public int getModY() {
return modY;
}
public int getModZ() {
return modZ;
}
public Direction opposite() {
switch(this) {
case DOWN:
return UP;
case UP:
return DOWN;
case EAST:
return WEST;
case WEST:
return EAST;
case NORTH:
return SOUTH;
case SOUTH:
return NORTH;
}
throw new IllegalStateException();
}
}

View File

@@ -0,0 +1,17 @@
package com.dfsek.terra.api.block.state.properties.enums;
public enum Half {
/**
* The top half of the block, normally with the higher y coordinate.
*/
TOP,
/**
* The bottom half of the block, normally with the lower y coordinate.
*/
BOTTOM,
/**
* Some blocks, e.g. slabs, can occupy both halves.
*/
DOUBLE
}

View File

@@ -0,0 +1,5 @@
package com.dfsek.terra.api.block.state.properties.enums;
public enum RedstoneConnection {
NONE, SIDE, UP
}

View File

@@ -0,0 +1,5 @@
package com.dfsek.terra.api.block.state.properties.enums;
public enum WallHeight {
LOW, NONE, TALL
}