Skip to content

Commit

Permalink
Rewrite blocks in Java
Browse files Browse the repository at this point in the history
Fixed bugs / code adjusted to match vanilla:
- BenchBlock.rotate: not working for CLOCKWISE_90
- ChimneyBlock.onUse, SofaBlock.onUse, TableLampBlock.onUse:
    returning ActionResult.SUCCESS on the server
  • Loading branch information
Juuxel committed Jul 29, 2024
1 parent 4fd7fa7 commit 21db9db
Show file tree
Hide file tree
Showing 77 changed files with 3,574 additions and 3,130 deletions.
90 changes: 90 additions & 0 deletions common/src/main/java/juuxel/adorn/block/AbstractChimneyBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package juuxel.adorn.block;

import juuxel.adorn.lib.AdornTags;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.MapColor;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.Waterloggable;
import net.minecraft.entity.ai.pathing.NavigationType;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldAccess;

public abstract class AbstractChimneyBlock extends Block implements Waterloggable {
public static final BooleanProperty CONNECTED = BooleanProperty.of("connected");
public static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED;
private static final VoxelShape TOP_SHAPE = createCuboidShape(4.0, 0.0, 4.0, 12.0, 12.0, 12.0);
private static final VoxelShape MIDDLE_SHAPE = createCuboidShape(5.0, 0.0, 5.0, 11.0, 16.0, 11.0);

public AbstractChimneyBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState()
.with(CONNECTED, false)
.with(WATERLOGGED, false));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(CONNECTED, WATERLOGGED);
}

@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return updateConnections(
getDefaultState().with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER),
ctx.getWorld().getBlockState(ctx.getBlockPos().up())
);
}

private BlockState updateConnections(BlockState state, BlockState neighborState) {
return state.with(CONNECTED, neighborState.isIn(AdornTags.CHIMNEYS.block()));
}

@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
if (state.get(WATERLOGGED)) {
world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
}

return direction == Direction.UP ? updateConnections(state, neighborState) : state;
}

@Override
public FluidState getFluidState(BlockState state) {
return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
}

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return state.get(CONNECTED) ? MIDDLE_SHAPE : TOP_SHAPE;
}

@Override
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
return false;
}

public static Settings createBlockSettings(MapColor color) {
return createBlockSettings(color, 2f);
}

public static Settings createBlockSettings(MapColor color, float hardness) {
return Settings.create()
.mapColor(color)
.solid()
.requiresTool()
.strength(hardness, 6f)
.ticksRandomly()
.nonOpaque();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package juuxel.adorn.block;

import juuxel.adorn.block.variant.BlockVariant;
import juuxel.adorn.util.Shapes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundEvents;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.DirectionProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;

import java.util.Map;

public abstract class AbstractKitchenCounterBlock extends Block {
public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING;
public static final BlockSoundGroup SOUND_GROUP = new BlockSoundGroup(
1.0F, 1.0F,
SoundEvents.BLOCK_WOOD_BREAK,
SoundEvents.BLOCK_STONE_STEP,
SoundEvents.BLOCK_WOOD_PLACE,
SoundEvents.BLOCK_WOOD_HIT,
SoundEvents.BLOCK_STONE_FALL
);
protected static final Map<Direction, VoxelShape> SHAPES = Shapes.mergeIntoShapeMap(
Shapes.buildShapeRotationsFromNorth(
0, 0, 2,
16, 12, 16
),
createCuboidShape(
0.0, 12.0, 0.0,
16.0, 16.0, 16.0
)
);

public AbstractKitchenCounterBlock(Settings settings) {
super(settings);
}

public AbstractKitchenCounterBlock(BlockVariant variant) {
this(variant.createSettings().sounds(SOUND_GROUP));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);
}

@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite());
}

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPES.get(state.get(FACING));
}

@Override
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.rotate(mirror.getRotation(state.get(FACING)));
}

@Override
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(FACING, rotation.rotate(state.get(FACING)));
}
}
87 changes: 87 additions & 0 deletions common/src/main/java/juuxel/adorn/block/AbstractTableBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package juuxel.adorn.block;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.Waterloggable;
import net.minecraft.entity.ai.pathing.NavigationType;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldAccess;

public abstract class AbstractTableBlock extends CarpetedBlock implements Waterloggable {
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 BooleanProperty WATERLOGGED = Properties.WATERLOGGED;

public AbstractTableBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(WATERLOGGED, false));
}

protected abstract boolean canConnectTo(BlockState state, Direction sideOfSelf);

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

@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return updateConnections(
super.getPlacementState(ctx)
.with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER),
ctx.getWorld(),
ctx.getBlockPos()
);
}

@Override
public FluidState getFluidState(BlockState state) {
return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state);
}

@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
if (state.get(WATERLOGGED)) {
world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
}

return updateConnections(super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos), world, pos);
}

private BlockState updateConnections(BlockState state, WorldAccess world, BlockPos pos) {
return state.with(NORTH, canConnectTo(world.getBlockState(pos.offset(Direction.NORTH)), Direction.NORTH))
.with(EAST, canConnectTo(world.getBlockState(pos.offset(Direction.EAST)), Direction.EAST))
.with(SOUTH, canConnectTo(world.getBlockState(pos.offset(Direction.SOUTH)), Direction.SOUTH))
.with(WEST, canConnectTo(world.getBlockState(pos.offset(Direction.WEST)), Direction.WEST));
}

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return getShapeForKey(
Bits.buildTableState(
state.get(NORTH), state.get(EAST), state.get(SOUTH), state.get(WEST),
isCarpetingEnabled() && state.get(CARPET).isPresent()
)
);
}

protected abstract VoxelShape getShapeForKey(byte key);

@Override
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
return false;
}
}
Loading

0 comments on commit 21db9db

Please sign in to comment.