2020-07-19 19:12:39 +00:00
|
|
|
package com.thebrokenrail.energonrelics.structure;
|
|
|
|
|
|
|
|
import com.thebrokenrail.energonrelics.util.MissingCaseException;
|
|
|
|
import net.minecraft.block.BlockState;
|
2020-07-20 22:40:56 +00:00
|
|
|
import net.minecraft.state.property.Properties;
|
2020-07-20 21:03:17 +00:00
|
|
|
import net.minecraft.util.BlockMirror;
|
2020-07-19 19:12:39 +00:00
|
|
|
import net.minecraft.util.BlockRotation;
|
|
|
|
import net.minecraft.util.math.BlockPos;
|
2020-07-21 02:39:30 +00:00
|
|
|
import net.minecraft.util.math.Direction;
|
2020-07-19 19:12:39 +00:00
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
public abstract class StructurePart<T> {
|
2020-07-22 01:23:33 +00:00
|
|
|
public interface Transformation {
|
2020-07-20 21:03:17 +00:00
|
|
|
BlockPos transform(BlockPos pos);
|
2020-07-19 19:12:39 +00:00
|
|
|
BlockState transform(BlockState state);
|
|
|
|
}
|
|
|
|
|
|
|
|
private final T state;
|
|
|
|
|
|
|
|
protected T getState() {
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
public StructurePart(T state, List<Transformation> list) {
|
|
|
|
this.state = state;
|
|
|
|
transformations.addAll(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
private final Map<Long, BlockState> blocks = new HashMap<>();
|
|
|
|
|
|
|
|
private final List<Transformation> transformations = new ArrayList<>();
|
|
|
|
|
|
|
|
protected static final Transformation NONE = new Transformation() {
|
|
|
|
@Override
|
2020-07-20 21:03:17 +00:00
|
|
|
public BlockPos transform(BlockPos pos) {
|
|
|
|
return pos;
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BlockState transform(BlockState state) {
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
protected static final Transformation CLOCKWISE_90 = new Transformation() {
|
|
|
|
@Override
|
2020-07-20 21:03:17 +00:00
|
|
|
public BlockPos transform(BlockPos pos) {
|
|
|
|
return new BlockPos(-pos.getZ(), pos.getY(), pos.getX());
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BlockState transform(BlockState state) {
|
|
|
|
return state.rotate(BlockRotation.CLOCKWISE_90);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
protected static final Transformation CLOCKWISE_180 = new Transformation() {
|
|
|
|
@Override
|
2020-07-20 21:03:17 +00:00
|
|
|
public BlockPos transform(BlockPos pos) {
|
|
|
|
return new BlockPos(-pos.getX(), pos.getY(), -pos.getZ());
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BlockState transform(BlockState state) {
|
|
|
|
return state.rotate(BlockRotation.CLOCKWISE_180);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
protected static final Transformation COUNTERCLOCKWISE_90 = new Transformation() {
|
|
|
|
@Override
|
2020-07-20 21:03:17 +00:00
|
|
|
public BlockPos transform(BlockPos pos) {
|
|
|
|
return new BlockPos(pos.getZ(), pos.getY(), -pos.getX());
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BlockState transform(BlockState state) {
|
|
|
|
return state.rotate(BlockRotation.COUNTERCLOCKWISE_90);
|
|
|
|
}
|
|
|
|
};
|
2020-07-22 01:23:33 +00:00
|
|
|
protected static final Transformation MIRROR_DEPTH = new Transformation() {
|
2020-07-20 21:03:17 +00:00
|
|
|
@Override
|
|
|
|
public BlockPos transform(BlockPos pos) {
|
|
|
|
return new BlockPos(pos.getX(), pos.getY(), -pos.getZ());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BlockState transform(BlockState state) {
|
2020-07-20 22:40:56 +00:00
|
|
|
state = state.mirror(BlockMirror.LEFT_RIGHT);
|
|
|
|
if (state.contains(Properties.CHEST_TYPE)) {
|
|
|
|
state = state.with(Properties.CHEST_TYPE, state.get(Properties.CHEST_TYPE).getOpposite());
|
|
|
|
}
|
|
|
|
return state;
|
2020-07-20 21:03:17 +00:00
|
|
|
}
|
|
|
|
};
|
2020-07-19 19:12:39 +00:00
|
|
|
|
|
|
|
protected abstract void build(StructureContext context);
|
|
|
|
|
2020-07-20 21:03:17 +00:00
|
|
|
private BlockPos transform(BlockPos pos) {
|
2020-07-19 19:12:39 +00:00
|
|
|
for (Transformation transformation : transformations) {
|
|
|
|
pos = transformation.transform(pos);
|
|
|
|
}
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
private BlockState transform(BlockState state) {
|
|
|
|
for (Transformation transformation : transformations) {
|
|
|
|
state = transformation.transform(state);
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2020-07-20 21:03:17 +00:00
|
|
|
protected void set(BlockPos originalPos, BlockState state) {
|
|
|
|
BlockPos pos = transform(originalPos);
|
|
|
|
blocks.put(pos.asLong(), transform(state));
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
2020-07-20 21:03:17 +00:00
|
|
|
protected void rect(BlockPos pos, int width, int height, int depth, BlockState state) {
|
2020-07-19 19:12:39 +00:00
|
|
|
for (int x = 0; x < width; x++) {
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
for (int z = 0; z < depth; z++) {
|
2020-07-20 21:03:17 +00:00
|
|
|
set(pos.add(x, y, z), state);
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-20 21:03:17 +00:00
|
|
|
protected void rotate(Transformation[] functions, Runnable action) {
|
2020-07-19 19:12:39 +00:00
|
|
|
for (Transformation function : functions) {
|
|
|
|
transformations.add(function);
|
|
|
|
action.run();
|
|
|
|
transformations.remove(transformations.size() - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-20 21:03:17 +00:00
|
|
|
protected void rotate(Runnable action) {
|
|
|
|
rotate(new Transformation[]{NONE, CLOCKWISE_90, CLOCKWISE_180, COUNTERCLOCKWISE_90}, action);
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void place(World world, BlockPos pos) {
|
|
|
|
for (Map.Entry<Long, BlockState> entry : blocks.entrySet()) {
|
|
|
|
BlockState state = entry.getValue();
|
2020-07-22 01:23:33 +00:00
|
|
|
BlockPos newPos = pos.add(BlockPos.fromLong(entry.getKey()));
|
|
|
|
|
|
|
|
world.removeBlockEntity(newPos);
|
|
|
|
world.setBlockState(newPos, state);
|
|
|
|
|
|
|
|
handleBlockPlace(world, newPos, state);
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract void handleBlockPlace(World world, BlockPos pos, BlockState state);
|
|
|
|
|
2020-07-22 01:23:33 +00:00
|
|
|
public static Transformation directionToTransformation(Direction direction) {
|
2020-07-21 02:39:30 +00:00
|
|
|
switch (direction) {
|
|
|
|
case NORTH: {
|
2020-07-19 19:12:39 +00:00
|
|
|
return NONE;
|
|
|
|
}
|
2020-07-21 02:39:30 +00:00
|
|
|
case EAST: {
|
2020-07-19 19:12:39 +00:00
|
|
|
return CLOCKWISE_90;
|
|
|
|
}
|
2020-07-21 02:39:30 +00:00
|
|
|
case SOUTH: {
|
2020-07-19 19:12:39 +00:00
|
|
|
return CLOCKWISE_180;
|
|
|
|
}
|
2020-07-21 02:39:30 +00:00
|
|
|
case WEST: {
|
2020-07-19 19:12:39 +00:00
|
|
|
return COUNTERCLOCKWISE_90;
|
|
|
|
}
|
|
|
|
default: {
|
2020-07-21 02:39:30 +00:00
|
|
|
throw new MissingCaseException(direction);
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-20 21:03:17 +00:00
|
|
|
protected void part(StructureContext context, BlockPos originalPos, StructurePart<?> part) {
|
|
|
|
BlockPos pos = transform(originalPos);
|
|
|
|
context.addPart(pos.getX(), pos.getY(), pos.getZ(), part);
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected List<Transformation> getTransformations() {
|
|
|
|
return transformations;
|
|
|
|
}
|
2020-07-20 21:03:17 +00:00
|
|
|
|
|
|
|
private BlockPos pos = null;
|
|
|
|
|
|
|
|
private BlockPos getPos() {
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected BlockPos getPosFromOrigin(BlockPos pos) {
|
|
|
|
return transform(pos).add(getPos());
|
|
|
|
}
|
|
|
|
|
|
|
|
void setPos(BlockPos pos) {
|
|
|
|
this.pos = pos;
|
|
|
|
}
|
2020-07-19 19:12:39 +00:00
|
|
|
}
|