mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-08 16:56:07 +00:00
property based block data implementation
This commit is contained in:
@@ -2,7 +2,7 @@ package com.dfsek.terra.api.structures.structure.buffer.items;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.data.Waterlogged;
|
||||
import com.dfsek.terra.api.block.state.properties.base.Properties;
|
||||
import com.dfsek.terra.api.structure.buffer.BufferedItem;
|
||||
import com.dfsek.terra.api.vector.Vector3;
|
||||
import com.dfsek.terra.api.world.World;
|
||||
@@ -25,8 +25,9 @@ public class BufferedBlock implements BufferedItem {
|
||||
try {
|
||||
BlockState current = world.getBlockData(origin);
|
||||
if(overwrite || current.isAir()) {
|
||||
if(waterlog && current instanceof Waterlogged && current.getBlockType().isWater())
|
||||
((Waterlogged) current).setWaterlogged(true);
|
||||
if(waterlog && current.has(Properties.WATERLOGGED) && current.getBlockType().isWater()) {
|
||||
current.set(Properties.WATERLOGGED, true);
|
||||
}
|
||||
world.setBlockData(origin, data);
|
||||
}
|
||||
} catch(RuntimeException e) {
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import com.dfsek.terra.api.block.state.properties.enums.RailShape;
|
||||
import com.dfsek.terra.api.block.state.properties.enums.Axis;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.BlockFace;
|
||||
import com.dfsek.terra.api.block.data.Directional;
|
||||
import com.dfsek.terra.api.block.data.MultipleFacing;
|
||||
import com.dfsek.terra.api.block.data.Orientable;
|
||||
import com.dfsek.terra.api.block.data.Rail;
|
||||
import com.dfsek.terra.api.block.data.RedstoneWire;
|
||||
import com.dfsek.terra.api.block.data.Rotatable;
|
||||
import com.dfsek.terra.api.block.data.Wall;
|
||||
import com.dfsek.terra.api.block.state.properties.base.BooleanProperty;
|
||||
import com.dfsek.terra.api.block.state.properties.base.EnumProperty;
|
||||
import com.dfsek.terra.api.block.state.properties.base.Properties;
|
||||
import com.dfsek.terra.api.block.state.properties.enums.Axis;
|
||||
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;
|
||||
import com.dfsek.terra.api.structure.rotation.Rotation;
|
||||
import com.dfsek.terra.api.vector.Vector2;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RotationUtil {
|
||||
private static final Set<BlockFace> CARDINALS = Sets.newHashSet(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
||||
|
||||
/**
|
||||
* Rotate and mirror a coordinate pair.
|
||||
@@ -46,112 +36,8 @@ public class RotationUtil {
|
||||
orig.setZ(copy.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BlockFace with rotation and mirrors applied to it
|
||||
*
|
||||
* @param f BlockFace to apply rotation to
|
||||
* @param r Rotation
|
||||
* @return Rotated BlockFace
|
||||
*/
|
||||
public static BlockFace getRotatedFace(BlockFace f, Rotation r) {
|
||||
BlockFace n = f;
|
||||
int rotateNum = r.getDegrees() / 90;
|
||||
int rn = faceRotation(f);
|
||||
if(rn >= 0) {
|
||||
n = fromRotation(faceRotation(n) + 4 * rotateNum);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer representation of a BlockFace, to perform math on.
|
||||
*
|
||||
* @param f BlockFace to get integer for
|
||||
* @return integer representation of BlockFace
|
||||
*/
|
||||
public static int faceRotation(BlockFace f) {
|
||||
switch(f) {
|
||||
case NORTH:
|
||||
return 0;
|
||||
case NORTH_NORTH_EAST:
|
||||
return 1;
|
||||
case NORTH_EAST:
|
||||
return 2;
|
||||
case EAST_NORTH_EAST:
|
||||
return 3;
|
||||
case EAST:
|
||||
return 4;
|
||||
case EAST_SOUTH_EAST:
|
||||
return 5;
|
||||
case SOUTH_EAST:
|
||||
return 6;
|
||||
case SOUTH_SOUTH_EAST:
|
||||
return 7;
|
||||
case SOUTH:
|
||||
return 8;
|
||||
case SOUTH_SOUTH_WEST:
|
||||
return 9;
|
||||
case SOUTH_WEST:
|
||||
return 10;
|
||||
case WEST_SOUTH_WEST:
|
||||
return 11;
|
||||
case WEST:
|
||||
return 12;
|
||||
case WEST_NORTH_WEST:
|
||||
return 13;
|
||||
case NORTH_WEST:
|
||||
return 14;
|
||||
case NORTH_NORTH_WEST:
|
||||
return 15;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert integer to BlockFace representation
|
||||
*
|
||||
* @param r integer to get BlockFace for
|
||||
* @return BlockFace represented by integer.
|
||||
*/
|
||||
public static BlockFace fromRotation(int r) {
|
||||
switch(FastMath.floorMod(r, 16)) {
|
||||
case 0:
|
||||
return BlockFace.NORTH;
|
||||
case 1:
|
||||
return BlockFace.NORTH_NORTH_EAST;
|
||||
case 2:
|
||||
return BlockFace.NORTH_EAST;
|
||||
case 3:
|
||||
return BlockFace.EAST_NORTH_EAST;
|
||||
case 4:
|
||||
return BlockFace.EAST;
|
||||
case 5:
|
||||
return BlockFace.EAST_SOUTH_EAST;
|
||||
case 6:
|
||||
return BlockFace.SOUTH_EAST;
|
||||
case 7:
|
||||
return BlockFace.SOUTH_SOUTH_EAST;
|
||||
case 8:
|
||||
return BlockFace.SOUTH;
|
||||
case 9:
|
||||
return BlockFace.SOUTH_SOUTH_WEST;
|
||||
case 10:
|
||||
return BlockFace.SOUTH_WEST;
|
||||
case 11:
|
||||
return BlockFace.WEST_SOUTH_WEST;
|
||||
case 12:
|
||||
return BlockFace.WEST;
|
||||
case 13:
|
||||
return BlockFace.WEST_NORTH_WEST;
|
||||
case 14:
|
||||
return BlockFace.NORTH_WEST;
|
||||
case 15:
|
||||
return BlockFace.NORTH_NORTH_WEST;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Axis getRotatedAxis(Axis orig, Rotation r) {
|
||||
Axis other = orig;
|
||||
@@ -250,44 +136,100 @@ public class RotationUtil {
|
||||
return orig;
|
||||
}
|
||||
|
||||
public static void rotateBlockData(BlockState data, Rotation r) {
|
||||
if(data instanceof Rotatable) {
|
||||
BlockFace rt = getRotatedFace(((Rotatable) data).getRotation(), r);
|
||||
((Rotatable) data).setRotation(rt);
|
||||
} else if(data instanceof Directional) {
|
||||
BlockFace rt = getRotatedFace(((Directional) data).getFacing(), r);
|
||||
((Directional) data).setFacing(rt);
|
||||
} else if(data instanceof MultipleFacing) {
|
||||
MultipleFacing mfData = (MultipleFacing) data;
|
||||
Map<BlockFace, Boolean> faces = new EnumMap<>(BlockFace.class);
|
||||
for(BlockFace f : mfData.getAllowedFaces()) {
|
||||
faces.put(f, mfData.hasFace(f));
|
||||
}
|
||||
for(Map.Entry<BlockFace, Boolean> face : faces.entrySet()) {
|
||||
mfData.setFace(getRotatedFace(face.getKey(), r), face.getValue());
|
||||
}
|
||||
} else if(data instanceof Rail) {
|
||||
RailShape newShape = getRotatedRail(((Rail) data).getShape(), r);
|
||||
((Rail) data).setShape(newShape);
|
||||
} else if(data instanceof Orientable) {
|
||||
Axis newAxis = getRotatedAxis(((Orientable) data).getAxis(), r);
|
||||
((Orientable) data).setAxis(newAxis);
|
||||
} else if(data instanceof RedstoneWire) {
|
||||
Map<BlockFace, RedstoneWire.Connection> connections = new EnumMap<>(BlockFace.class);
|
||||
RedstoneWire rData = (RedstoneWire) data;
|
||||
for(BlockFace f : rData.getAllowedFaces()) {
|
||||
connections.put(f, rData.getFace(f));
|
||||
}
|
||||
for(Map.Entry<BlockFace, RedstoneWire.Connection> e : connections.entrySet()) {
|
||||
rData.setFace(getRotatedFace(e.getKey(), r), e.getValue());
|
||||
}
|
||||
} else if(data instanceof Wall) {
|
||||
Wall wallData = (Wall) data;
|
||||
Map<BlockFace, Wall.Height> faces = new EnumMap<>(BlockFace.class);
|
||||
for(BlockFace b : CARDINALS) faces.put(b, wallData.getHeight(b));
|
||||
for(Map.Entry<BlockFace, Wall.Height> face : faces.entrySet()) {
|
||||
wallData.setHeight(getRotatedFace(face.getKey(), r), face.getValue());
|
||||
}
|
||||
private static BooleanProperty rotateCardinal(BooleanProperty property, Rotation r) {
|
||||
switch(r) {
|
||||
case NONE:
|
||||
return property;
|
||||
case CW_90:
|
||||
if(property == Properties.NORTH) return Properties.EAST;
|
||||
if(property == Properties.EAST) return Properties.SOUTH;
|
||||
if(property == Properties.SOUTH) return Properties.WEST;
|
||||
if(property == Properties.WEST) return Properties.NORTH;
|
||||
throw new IllegalStateException();
|
||||
case CW_180:
|
||||
if(property == Properties.NORTH) return Properties.SOUTH;
|
||||
if(property == Properties.EAST) return Properties.WEST;
|
||||
if(property == Properties.SOUTH) return Properties.NORTH;
|
||||
if(property == Properties.WEST) return Properties.EAST;
|
||||
throw new IllegalStateException();
|
||||
case CCW_90:
|
||||
if(property == Properties.NORTH) return Properties.WEST;
|
||||
if(property == Properties.EAST) return Properties.NORTH;
|
||||
if(property == Properties.SOUTH) return Properties.EAST;
|
||||
if(property == Properties.WEST) return Properties.SOUTH;
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private static EnumProperty<RedstoneConnection> rotateRedstone(EnumProperty<RedstoneConnection> property, Rotation r) {
|
||||
switch(r) {
|
||||
case NONE:
|
||||
return property;
|
||||
case CW_90:
|
||||
if(property == Properties.NORTH_CONNECTION) return Properties.EAST_CONNECTION;
|
||||
if(property == Properties.EAST_CONNECTION) return Properties.SOUTH_CONNECTION;
|
||||
if(property == Properties.SOUTH_CONNECTION) return Properties.WEST_CONNECTION;
|
||||
if(property == Properties.WEST_CONNECTION) return Properties.NORTH_CONNECTION;
|
||||
throw new IllegalStateException();
|
||||
case CW_180:
|
||||
if(property == Properties.NORTH_CONNECTION) return Properties.SOUTH_CONNECTION;
|
||||
if(property == Properties.EAST_CONNECTION) return Properties.WEST_CONNECTION;
|
||||
if(property == Properties.SOUTH_CONNECTION) return Properties.NORTH_CONNECTION;
|
||||
if(property == Properties.WEST_CONNECTION) return Properties.EAST_CONNECTION;
|
||||
throw new IllegalStateException();
|
||||
case CCW_90:
|
||||
if(property == Properties.NORTH_CONNECTION) return Properties.WEST_CONNECTION;
|
||||
if(property == Properties.EAST_CONNECTION) return Properties.NORTH_CONNECTION;
|
||||
if(property == Properties.SOUTH_CONNECTION) return Properties.EAST_CONNECTION;
|
||||
if(property == Properties.WEST_CONNECTION) return Properties.SOUTH_CONNECTION;
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private static EnumProperty<WallHeight> rotateWall(EnumProperty<WallHeight> property, Rotation r) {
|
||||
switch(r) {
|
||||
case NONE:
|
||||
return property;
|
||||
case CW_90:
|
||||
if(property == Properties.NORTH_HEIGHT) return Properties.EAST_HEIGHT;
|
||||
if(property == Properties.EAST_HEIGHT) return Properties.SOUTH_HEIGHT;
|
||||
if(property == Properties.SOUTH_HEIGHT) return Properties.WEST_HEIGHT;
|
||||
if(property == Properties.WEST_HEIGHT) return Properties.NORTH_HEIGHT;
|
||||
throw new IllegalStateException();
|
||||
case CW_180:
|
||||
if(property == Properties.NORTH_HEIGHT) return Properties.SOUTH_HEIGHT;
|
||||
if(property == Properties.EAST_HEIGHT) return Properties.WEST_HEIGHT;
|
||||
if(property == Properties.SOUTH_HEIGHT) return Properties.NORTH_HEIGHT;
|
||||
if(property == Properties.WEST_HEIGHT) return Properties.EAST_HEIGHT;
|
||||
throw new IllegalStateException();
|
||||
case CCW_90:
|
||||
if(property == Properties.NORTH_HEIGHT) return Properties.WEST_HEIGHT;
|
||||
if(property == Properties.EAST_HEIGHT) return Properties.NORTH_HEIGHT;
|
||||
if(property == Properties.SOUTH_HEIGHT) return Properties.EAST_HEIGHT;
|
||||
if(property == Properties.WEST_HEIGHT) return Properties.SOUTH_HEIGHT;
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public static void rotateBlockData(BlockState data, Rotation r) {
|
||||
data
|
||||
.ifProperty(Properties.NORTH, state -> state.set(rotateCardinal(Properties.NORTH, r), state.get(Properties.NORTH)))
|
||||
.ifProperty(Properties.SOUTH, state -> state.set(rotateCardinal(Properties.SOUTH, r), state.get(Properties.SOUTH)))
|
||||
.ifProperty(Properties.EAST, state -> state.set(rotateCardinal(Properties.EAST, r), state.get(Properties.EAST)))
|
||||
.ifProperty(Properties.WEST, state -> state.set(rotateCardinal(Properties.WEST, r), state.get(Properties.WEST)))
|
||||
.ifProperty(Properties.DIRECTION, state -> state.set(Properties.DIRECTION, state.get(Properties.DIRECTION).rotate(r)))
|
||||
.ifProperty(Properties.AXIS, state -> state.set(Properties.AXIS, getRotatedAxis(state.get(Properties.AXIS), r)))
|
||||
.ifProperty(Properties.RAIL_SHAPE, state -> state.set(Properties.RAIL_SHAPE, getRotatedRail(state.get(Properties.RAIL_SHAPE), r)))
|
||||
.ifProperty(Properties.NORTH_CONNECTION, state -> state.set(rotateRedstone(Properties.NORTH_CONNECTION, r), state.get(Properties.NORTH_CONNECTION)))
|
||||
.ifProperty(Properties.SOUTH_CONNECTION, state -> state.set(rotateRedstone(Properties.SOUTH_CONNECTION, r), state.get(Properties.SOUTH_CONNECTION)))
|
||||
.ifProperty(Properties.EAST_CONNECTION, state -> state.set(rotateRedstone(Properties.EAST_CONNECTION, r), state.get(Properties.EAST_CONNECTION)))
|
||||
.ifProperty(Properties.WEST_CONNECTION, state -> state.set(rotateRedstone(Properties.WEST_CONNECTION, r), state.get(Properties.WEST_CONNECTION)))
|
||||
.ifProperty(Properties.NORTH_HEIGHT, state -> state.set(rotateWall(Properties.NORTH_HEIGHT, r), state.get(Properties.NORTH_HEIGHT)))
|
||||
.ifProperty(Properties.SOUTH_HEIGHT, state -> state.set(rotateWall(Properties.SOUTH_HEIGHT, r), state.get(Properties.SOUTH_HEIGHT)))
|
||||
.ifProperty(Properties.EAST_HEIGHT, state -> state.set(rotateWall(Properties.EAST_HEIGHT, r), state.get(Properties.EAST_HEIGHT)))
|
||||
.ifProperty(Properties.WEST_HEIGHT, state -> state.set(rotateWall(Properties.WEST_HEIGHT, r), state.get(Properties.WEST_HEIGHT)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.dfsek.terra.world.generation.generators;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.BlockFace;
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.data.Bisected;
|
||||
import com.dfsek.terra.api.block.data.Slab;
|
||||
import com.dfsek.terra.api.block.data.Stairs;
|
||||
import com.dfsek.terra.api.block.data.Waterlogged;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.state.properties.base.Properties;
|
||||
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.config.ConfigPack;
|
||||
import com.dfsek.terra.api.math.range.ConstantRange;
|
||||
import com.dfsek.terra.api.profiler.ProfileFrame;
|
||||
@@ -145,16 +143,16 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
|
||||
Palette stairPalette = stairs.get(down.getBlockType());
|
||||
if(stairPalette != null) {
|
||||
BlockState stair = stairPalette.get(0, block.getX(), block.getY(), block.getZ()).clone();
|
||||
if(stair instanceof Stairs) {
|
||||
Stairs stairNew = (Stairs) stair;
|
||||
if(stair.has(Properties.DIRECTION)) {
|
||||
BlockState stairNew = stair.clone();
|
||||
if(placeStair(orig, chunk, block, thresh, sampler, stairNew)) return; // Successfully placed part.
|
||||
}
|
||||
}
|
||||
}
|
||||
BlockState slab = slabs.getOrDefault(down.getBlockType(), blank).get(0, block.getX(), block.getY(), block.getZ());
|
||||
if(slab instanceof Waterlogged) {
|
||||
((Waterlogged) slab).setWaterlogged(orig.getBlockType().equals(water));
|
||||
} else if(orig.getBlockType().equals(water)) return;
|
||||
BlockState slab = slabs.getOrDefault(down.getBlockType(), blank).get(0, block.getX(), block.getY(), block.getZ())
|
||||
.setIfPresent(Properties.WATERLOGGED, orig.getBlockType().equals(water));
|
||||
|
||||
if(orig.getBlockType().equals(water)) return;
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab);
|
||||
}
|
||||
}
|
||||
@@ -166,37 +164,36 @@ public class DefaultChunkGenerator3D implements TerraChunkGenerator {
|
||||
Palette stairPalette = stairs.get(up.getBlockType());
|
||||
if(stairPalette != null) {
|
||||
BlockState stair = stairPalette.get(0, block.getX(), block.getY(), block.getZ()).clone();
|
||||
if(stair instanceof Stairs) {
|
||||
Stairs stairNew = (Stairs) stair.clone();
|
||||
stairNew.setHalf(Bisected.Half.TOP);
|
||||
stair.setIfPresent(Properties.HALF, Half.TOP);
|
||||
if(stair.has(Properties.DIRECTION)) {
|
||||
BlockState stairNew = stair.clone();
|
||||
if(placeStair(orig, chunk, block, thresh, sampler, stairNew)) return; // Successfully placed part.
|
||||
}
|
||||
}
|
||||
}
|
||||
BlockState slab = slabs.getOrDefault(up.getBlockType(), blank).get(0, block.getX(), block.getY(), block.getZ()).clone();
|
||||
if(slab instanceof Bisected) ((Bisected) slab).setHalf(Bisected.Half.TOP);
|
||||
if(slab instanceof Slab) ((Slab) slab).setType(Slab.Type.TOP);
|
||||
if(slab instanceof Waterlogged) {
|
||||
((Waterlogged) slab).setWaterlogged(orig.getBlockType().equals(water));
|
||||
} else if(orig.getBlockType().equals(water)) return; // Only replace water if waterlogged.
|
||||
slab.setIfPresent(Properties.HALF, Half.TOP);
|
||||
|
||||
slab.setIfPresent(Properties.WATERLOGGED, orig.getBlockType().isWater());
|
||||
if(orig.getBlockType().equals(water)) return;
|
||||
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), slab);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean placeStair(BlockState orig, ChunkData chunk, Vector3 block, double thresh, Sampler sampler, Stairs stairNew) {
|
||||
private boolean placeStair(BlockState orig, ChunkData chunk, Vector3 block, double thresh, Sampler sampler, BlockState stairNew) {
|
||||
|
||||
if(sampler.sample(block.getBlockX() - 0.55, block.getY(), block.getZ()) > thresh) {
|
||||
|
||||
stairNew.setFacing(BlockFace.WEST);
|
||||
stairNew.set(Properties.DIRECTION, Direction.WEST);
|
||||
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() - 0.55) > thresh) {
|
||||
stairNew.setFacing(BlockFace.NORTH);
|
||||
stairNew.set(Properties.DIRECTION, Direction.NORTH);
|
||||
} else if(sampler.sample(block.getBlockX(), block.getY(), block.getZ() + 0.55) > thresh) {
|
||||
stairNew.setFacing(BlockFace.SOUTH);
|
||||
stairNew.set(Properties.DIRECTION, Direction.SOUTH);
|
||||
} else if(sampler.sample(block.getX() + 0.55, block.getY(), block.getZ()) > thresh) {
|
||||
stairNew.setFacing(BlockFace.EAST);
|
||||
stairNew.set(Properties.DIRECTION, Direction.EAST);
|
||||
} else stairNew = null;
|
||||
if(stairNew != null) {
|
||||
if(orig.getBlockType().equals(water)) stairNew.setWaterlogged(orig.getBlockType().equals(water));
|
||||
stairNew.setIfPresent(Properties.WATERLOGGED, orig.getBlockType().equals(water));
|
||||
chunk.setBlock(block.getBlockX(), block.getBlockY(), block.getBlockZ(), stairNew);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,9 @@ package com.dfsek.terra.world.population.items.flora;
|
||||
|
||||
import com.dfsek.terra.api.TerraPlugin;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.BlockFace;
|
||||
import com.dfsek.terra.api.block.data.Directional;
|
||||
import com.dfsek.terra.api.block.data.MultipleFacing;
|
||||
import com.dfsek.terra.api.block.data.Rotatable;
|
||||
import com.dfsek.terra.api.block.state.properties.base.Properties;
|
||||
import com.dfsek.terra.api.block.state.properties.enums.Direction;
|
||||
import com.dfsek.terra.api.util.FastRandom;
|
||||
import com.dfsek.terra.api.util.GlueList;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collections.MaterialSet;
|
||||
import com.dfsek.terra.api.vector.Vector3;
|
||||
@@ -19,6 +16,7 @@ import com.dfsek.terra.vector.Vector3Impl;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class TerraFlora implements Flora {
|
||||
@@ -100,39 +98,36 @@ public class TerraFlora implements Flora {
|
||||
int size = floraPalette.getSize();
|
||||
int c = ceiling ? -1 : 1;
|
||||
|
||||
List<BlockFace> faces = doRotation ? getFaces(location.clone().add(0, c, 0), world) : new GlueList<>();
|
||||
EnumSet<Direction> faces = doRotation ? getFaces(location.clone().add(0, c, 0), world) : EnumSet.noneOf(Direction.class);
|
||||
if(doRotation && faces.size() == 0) return false; // Don't plant if no faces are valid.
|
||||
|
||||
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
|
||||
int lvl = (FastMath.abs(i));
|
||||
BlockState data = floraPalette.get((ceiling ? lvl : size - lvl - 1), location.getX(), location.getY(), location.getZ()).clone();
|
||||
if(doRotation) {
|
||||
BlockFace oneFace = faces.get(new FastRandom(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face.
|
||||
if(data instanceof Directional) {
|
||||
((Directional) data).setFacing(oneFace.getOppositeFace());
|
||||
} else if(data instanceof MultipleFacing) {
|
||||
MultipleFacing o = (MultipleFacing) data;
|
||||
for(BlockFace face : o.getFaces()) o.setFace(face, false);
|
||||
for(BlockFace face : faces) o.setFace(face, true);
|
||||
} else if(data instanceof Rotatable) {
|
||||
((Rotatable) data).setRotation(oneFace);
|
||||
}
|
||||
Direction oneFace = new ArrayList<>(faces).get(new FastRandom(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face.
|
||||
|
||||
data.setIfPresent(Properties.DIRECTION, oneFace.opposite())
|
||||
.setIfPresent(Properties.NORTH, faces.contains(Direction.NORTH))
|
||||
.setIfPresent(Properties.SOUTH, faces.contains(Direction.SOUTH))
|
||||
.setIfPresent(Properties.EAST, faces.contains(Direction.EAST))
|
||||
.setIfPresent(Properties.WEST, faces.contains(Direction.WEST));
|
||||
}
|
||||
world.setBlockData(location.clone().add(0, i + c, 0), data, physics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<BlockFace> getFaces(Vector3 b, World world) {
|
||||
List<BlockFace> faces = new GlueList<>();
|
||||
test(faces, BlockFace.NORTH, b, world);
|
||||
test(faces, BlockFace.SOUTH, b, world);
|
||||
test(faces, BlockFace.EAST, b, world);
|
||||
test(faces, BlockFace.WEST, b, world);
|
||||
private EnumSet<Direction> getFaces(Vector3 b, World world) {
|
||||
EnumSet<Direction> faces = EnumSet.noneOf(Direction.class);
|
||||
test(faces, Direction.NORTH, b, world);
|
||||
test(faces, Direction.SOUTH, b, world);
|
||||
test(faces, Direction.EAST, b, world);
|
||||
test(faces, Direction.WEST, b, world);
|
||||
return faces;
|
||||
}
|
||||
|
||||
private void test(List<BlockFace> faces, BlockFace f, Vector3 b, World world) {
|
||||
private void test(EnumSet<Direction> faces, Direction f, Vector3 b, World world) {
|
||||
if(testRotation.contains(world.getBlockData(b.getBlockX() + f.getModX(), b.getBlockY() + f.getModY(), b.getBlockZ() + f.getModZ()).getBlockType()))
|
||||
faces.add(f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user