From fc2b73e36535f3839840c2a00653421c3b8a67f8 Mon Sep 17 00:00:00 2001 From: JR1811 Date: Wed, 4 Sep 2024 15:19:59 +0200 Subject: [PATCH] reduced blockstates of storage blocks to 10 unique states --- .../block/AbstractVillageContainerBlock.java | 92 +++++++++++-------- .../mayor/block/MayorProperties.java | 44 +++++++++ .../LumberStorageBlockEntityRenderer.java | 3 +- 3 files changed, 99 insertions(+), 40 deletions(-) create mode 100644 src/main/java/io/fabricatedatelier/mayor/block/MayorProperties.java diff --git a/src/main/java/io/fabricatedatelier/mayor/block/AbstractVillageContainerBlock.java b/src/main/java/io/fabricatedatelier/mayor/block/AbstractVillageContainerBlock.java index 6df59d4..a109ba3 100644 --- a/src/main/java/io/fabricatedatelier/mayor/block/AbstractVillageContainerBlock.java +++ b/src/main/java/io/fabricatedatelier/mayor/block/AbstractVillageContainerBlock.java @@ -8,13 +8,16 @@ import net.minecraft.block.BlockState; import net.minecraft.block.BlockWithEntity; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.MinecraftClient; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.FluidState; import net.minecraft.fluid.Fluids; import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.EnumProperty; import net.minecraft.state.property.Properties; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -25,21 +28,15 @@ import net.minecraft.world.WorldAccess; import org.jetbrains.annotations.Nullable; -import java.util.Optional; +import java.util.*; public abstract class AbstractVillageContainerBlock extends BlockWithEntity { - public static final BooleanProperty NORTH = Properties.NORTH; - public static final BooleanProperty EAST = Properties.EAST; - public static final BooleanProperty SOUTH = Properties.SOUTH; - public static final BooleanProperty WEST = Properties.WEST; + public static final EnumProperty POSITION = MayorProperties.POSITION; protected AbstractVillageContainerBlock(Settings settings) { super(settings); this.setDefaultState(this.getDefaultState() - .with(NORTH, false) - .with(EAST, false) - .with(SOUTH, false) - .with(WEST, false) + .with(POSITION, MayorProperties.Position.SINGLE) .with(Properties.WATERLOGGED, false) ); } @@ -47,7 +44,7 @@ protected AbstractVillageContainerBlock(Settings settings) { @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder); - builder.add(NORTH, EAST, SOUTH, WEST, Properties.WATERLOGGED); + builder.add(POSITION, Properties.WATERLOGGED); } @Nullable @@ -59,18 +56,28 @@ public BlockState getPlacementState(ItemPlacementContext ctx) { } @Override - public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { - if (state.get(Properties.WATERLOGGED)) { - world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { + ConnectedBlockUtil.BoundingBox box = new ConnectedBlockUtil.BoundingBox(world, pos, false); + if (!box.hasHoles() && box.isSquare()) { + state = getConnectedWallsState(world, state, pos); + world.setBlockState(pos, state); } - state = getConnectedWallsState(world, state, pos); - return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); + super.onPlaced(world, pos, state, placer, itemStack); } @Override - public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { - state = getConnectedWallsState(world, state, pos); - super.onPlaced(world, pos, state, placer, itemStack); + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + if (state.get(Properties.WATERLOGGED)) { + world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + } + BlockPos originPos = getOrigin(world, pos).orElse(pos); + ConnectedBlockUtil.BoundingBox box = new ConnectedBlockUtil.BoundingBox(world, originPos, false); + if (!box.hasHoles() && box.isSquare()) { + state = getConnectedWallsState(world, state, pos); + } else { + state = state.with(POSITION, MayorProperties.Position.SINGLE); + } + return state; } @Override @@ -95,33 +102,40 @@ protected VoxelShape getCullingShape(BlockState state, BlockView world, BlockPos @Override abstract public BlockEntity createBlockEntity(BlockPos pos, BlockState state); - public static boolean isSingle(BlockState state) { - if (state.contains(NORTH) && state.get(NORTH)) return false; - if (state.contains(EAST) && state.get(EAST)) return false; - if (state.contains(SOUTH) && state.get(SOUTH)) return false; - return !state.contains(WEST) || !state.get(WEST); + public static BlockState getConnectedWallsState(WorldAccess world, BlockState state, BlockPos pos) { + HashSet connectedBlocks = getValidConnectedDirections(world, pos); + for (var entry : MayorProperties.Position.values()) { + if (entry.getConnectedDirections().equals(connectedBlocks)) state = state.with(POSITION, entry); + } + return state; } - public static BlockState getConnectedWallsState(WorldAccess world, BlockState state, BlockPos pos) { - ConnectedBlockUtil.BoundingBox box = new ConnectedBlockUtil.BoundingBox(world, pos, false); - if (box.getConnectedPosList().size() < 2) return state; - if (!box.hasHoles() && box.isSquare()) { - if (world.getBlockState(pos.offset(Direction.NORTH)).getBlock().getClass().equals(state.getBlock().getClass())) { - state = state.with(NORTH, true); - } - if (world.getBlockState(pos.offset(Direction.EAST)).getBlock().getClass().equals(state.getBlock().getClass())) { - state = state.with(EAST, true); - } - if (world.getBlockState(pos.offset(Direction.SOUTH)).getBlock().getClass().equals(state.getBlock().getClass())) { - state = state.with(SOUTH, true); - } - if (world.getBlockState(pos.offset(Direction.WEST)).getBlock().getClass().equals(state.getBlock().getClass())) { - state = state.with(WEST, true); + private static boolean isSameBlock(BlockState stateA, BlockState stateB) { + // no instanceof check since we want to know if it's actually the same block and not any of the subclasses + // ... using the class for that still feels wrong, so change if there is a better solution + return stateA.getBlock().getClass().equals(stateB.getBlock().getClass()); + } + + public static Map getConnectedBlockStates(WorldAccess world, BlockPos pos) { + Map connectedBlockStates = new HashMap<>(); + for (Direction entry : Direction.Type.HORIZONTAL) { + connectedBlockStates.put(entry, world.getBlockState(pos.offset(entry))); + } + return connectedBlockStates; + } + + public static HashSet getValidConnectedDirections(WorldAccess world, BlockPos pos) { + HashSet validConnections = new HashSet<>(); + BlockState originState = world.getBlockState(pos); + for (var entry : getConnectedBlockStates(world, pos).entrySet()) { + if (isSameBlock(originState, world.getBlockState(pos.offset(entry.getKey())))) { + validConnections.add(entry.getKey()); } } - return state; + return validConnections; } + public static void setOrigin(WorldAccess world, BlockPos pos) { if (!(world.getBlockEntity(pos) instanceof AbstractVillageContainerBlockEntity blockEntity)) return; blockEntity.setStructureOriginPos(pos); diff --git a/src/main/java/io/fabricatedatelier/mayor/block/MayorProperties.java b/src/main/java/io/fabricatedatelier/mayor/block/MayorProperties.java new file mode 100644 index 0000000..6dbd15d --- /dev/null +++ b/src/main/java/io/fabricatedatelier/mayor/block/MayorProperties.java @@ -0,0 +1,44 @@ +package io.fabricatedatelier.mayor.block; + +import net.minecraft.state.property.EnumProperty; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.math.Direction; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +public class MayorProperties { + public static final EnumProperty POSITION = EnumProperty.of("position", Position.class); + + + public enum Position implements StringIdentifiable { + NORTH("north", Direction.EAST, Direction.SOUTH, Direction.WEST), + EAST("east", Direction.NORTH, Direction.SOUTH, Direction.WEST), + SOUTH("south", Direction.NORTH, Direction.EAST, Direction.WEST), + WEST("west", Direction.NORTH, Direction.EAST, Direction.SOUTH), + NORTH_EAST("north_east", Direction.WEST, Direction.SOUTH), + NORTH_WEST("north_west", Direction.EAST, Direction.SOUTH), + SOUTH_EAST("south_east", Direction.NORTH, Direction.WEST), + SOUTH_WEST("south_west", Direction.EAST, Direction.NORTH), + SINGLE("single"), + CENTER("center", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST); + + private final String name; + private final HashSet connectedDirections; + + Position(String name, Direction... involvedPositions) { + this.name = name; + this.connectedDirections = new HashSet<>(Arrays.asList(involvedPositions)); + } + + @Override + public String asString() { + return name; + } + + public HashSet getConnectedDirections() { + return connectedDirections; + } + } +} diff --git a/src/main/java/io/fabricatedatelier/mayor/block/entity/client/LumberStorageBlockEntityRenderer.java b/src/main/java/io/fabricatedatelier/mayor/block/entity/client/LumberStorageBlockEntityRenderer.java index 5b8d75f..0614025 100644 --- a/src/main/java/io/fabricatedatelier/mayor/block/entity/client/LumberStorageBlockEntityRenderer.java +++ b/src/main/java/io/fabricatedatelier/mayor/block/entity/client/LumberStorageBlockEntityRenderer.java @@ -1,6 +1,7 @@ package io.fabricatedatelier.mayor.block.entity.client; import io.fabricatedatelier.mayor.block.AbstractVillageContainerBlock; +import io.fabricatedatelier.mayor.block.MayorProperties; import io.fabricatedatelier.mayor.block.entity.LumberStorageBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -25,7 +26,7 @@ public void render(T blockEntity, float tickDelta, MatrixStack matrices, VertexC if (rotTick > 10) rotTick = 0; BlockState state = blockEntity.getCachedState(); - if (AbstractVillageContainerBlock.isSingle(state)) { + if (state.contains(AbstractVillageContainerBlock.POSITION) && state.get(AbstractVillageContainerBlock.POSITION).equals(MayorProperties.Position.SINGLE)) { int blockPerLog = 2; matrices.push();