Skip to content

Commit

Permalink
reduced blockstates of storage blocks to 10 unique states
Browse files Browse the repository at this point in the history
  • Loading branch information
JR1811 committed Sep 4, 2024
1 parent 45fe8d1 commit fc2b73e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,29 +28,23 @@
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<MayorProperties.Position> 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)
);
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(NORTH, EAST, SOUTH, WEST, Properties.WATERLOGGED);
builder.add(POSITION, Properties.WATERLOGGED);
}

@Nullable
Expand All @@ -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
Expand All @@ -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<Direction> 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<Direction, BlockState> getConnectedBlockStates(WorldAccess world, BlockPos pos) {
Map<Direction, BlockState> connectedBlockStates = new HashMap<>();
for (Direction entry : Direction.Type.HORIZONTAL) {
connectedBlockStates.put(entry, world.getBlockState(pos.offset(entry)));
}
return connectedBlockStates;
}

public static HashSet<Direction> getValidConnectedDirections(WorldAccess world, BlockPos pos) {
HashSet<Direction> 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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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> 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<Direction> connectedDirections;

Position(String name, Direction... involvedPositions) {
this.name = name;
this.connectedDirections = new HashSet<>(Arrays.asList(involvedPositions));
}

@Override
public String asString() {
return name;
}

public HashSet<Direction> getConnectedDirections() {
return connectedDirections;
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
Expand Down

0 comments on commit fc2b73e

Please sign in to comment.