159 lines
6.1 KiB
Java
159 lines
6.1 KiB
Java
package fr.adrien1106.reframed.block;
|
|
|
|
import fr.adrien1106.reframed.util.VoxelHelper;
|
|
import net.minecraft.block.*;
|
|
import net.minecraft.block.enums.BlockHalf;
|
|
import net.minecraft.entity.ai.pathing.NavigationType;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
import net.minecraft.fluid.Fluids;
|
|
import net.minecraft.item.ItemPlacementContext;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.sound.SoundCategory;
|
|
import net.minecraft.state.StateManager;
|
|
import net.minecraft.util.ActionResult;
|
|
import net.minecraft.util.BlockMirror;
|
|
import net.minecraft.util.BlockRotation;
|
|
import net.minecraft.util.Hand;
|
|
import net.minecraft.util.hit.BlockHitResult;
|
|
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.World;
|
|
import net.minecraft.world.event.GameEvent;
|
|
import net.minecraft.world.explosion.Explosion;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.function.BiConsumer;
|
|
|
|
import static net.minecraft.state.property.Properties.*;
|
|
|
|
public class ReFramedTrapdoorBlock extends WaterloggableReFramedBlock {
|
|
|
|
public static final VoxelShape[] TRAPDOOR_VOXELS;
|
|
|
|
public ReFramedTrapdoorBlock(Settings settings) {
|
|
super(settings);
|
|
setDefaultState(getDefaultState()
|
|
.with(HORIZONTAL_FACING, Direction.NORTH)
|
|
.with(BLOCK_HALF, BlockHalf.BOTTOM)
|
|
.with(OPEN, false)
|
|
.with(POWERED, false)
|
|
);
|
|
}
|
|
|
|
@Override
|
|
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
|
super.appendProperties(builder.add(HORIZONTAL_FACING, BLOCK_HALF, OPEN, POWERED));
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block source, BlockPos sourcePos, boolean notify) {
|
|
if (world.isClient) return;
|
|
boolean powered = world.isReceivingRedstonePower(pos);
|
|
if (powered != state.get(POWERED)) {
|
|
if (state.get(OPEN) != powered) {
|
|
state = state.with(OPEN, powered);
|
|
playToggleSound(null, world, pos, powered);
|
|
}
|
|
|
|
world.setBlockState(pos, state.with(POWERED, powered), 2);
|
|
if (state.get(WATERLOGGED)) {
|
|
world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
|
|
BlockState state = super.getPlacementState(ctx);
|
|
World world = ctx.getWorld();
|
|
BlockPos pos = ctx.getBlockPos();
|
|
Direction side = ctx.getSide();
|
|
|
|
if (side.getAxis().isVertical()) state = state
|
|
.with(HORIZONTAL_FACING, ctx.getHorizontalPlayerFacing().getOpposite())
|
|
.with(BLOCK_HALF, side == Direction.UP ? BlockHalf.BOTTOM : BlockHalf.TOP);
|
|
else state = state
|
|
.with(HORIZONTAL_FACING, side)
|
|
.with(BLOCK_HALF, ctx.getHitPos().getY() - pos.getY() > 0.5 ? BlockHalf.TOP : BlockHalf.BOTTOM);
|
|
|
|
if (world.isReceivingRedstonePower(pos)) state = state.with(OPEN, true).with(POWERED, true);
|
|
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
|
ActionResult result = super.onUse(state, world, pos, player, hand, hit);
|
|
if (result.isAccepted()) return result;
|
|
flip(state, world, pos, player);
|
|
return ActionResult.success(world.isClient);
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
|
|
return switch (type) {
|
|
case LAND, AIR -> state.get(OPEN);
|
|
case WATER -> state.get(WATERLOGGED);
|
|
};
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
public void onExploded(BlockState state, World world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stack_merger) {
|
|
if (explosion.getDestructionType() == Explosion.DestructionType.TRIGGER_BLOCK
|
|
&& !world.isClient()
|
|
&& !state.get(POWERED)
|
|
) flip(state, world, pos, null);
|
|
|
|
super.onExploded(state, world, pos, explosion, stack_merger);
|
|
}
|
|
|
|
private void flip(BlockState state, World world, BlockPos pos, @Nullable PlayerEntity player) {
|
|
state = state.cycle(OPEN);
|
|
world.setBlockState(pos, state, 2);
|
|
|
|
this.playToggleSound(player, world, pos, state.get(OPEN));
|
|
}
|
|
|
|
protected void playToggleSound(@Nullable PlayerEntity player, World world, BlockPos pos, boolean open) {
|
|
world.playSound(player, pos, open ? BlockSetType.OAK.trapdoorOpen() : BlockSetType.OAK.trapdoorClose(), SoundCategory.BLOCKS, 1.0F, world.getRandom().nextFloat() * 0.1F + 0.9F);
|
|
world.emitGameEvent(player, open ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, pos);
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
|
int index;
|
|
if (!state.get(OPEN)) index = state.get(BLOCK_HALF) == BlockHalf.BOTTOM ? 0 : 1;
|
|
else index = state.get(HORIZONTAL_FACING).ordinal();
|
|
return TRAPDOOR_VOXELS[index];
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
public BlockState rotate(BlockState state, BlockRotation rotation) {
|
|
return state.with(HORIZONTAL_FACING, rotation.rotate(state.get(HORIZONTAL_FACING)));
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("deprecation")
|
|
public BlockState mirror(BlockState state, BlockMirror mirror) {
|
|
return state.with(HORIZONTAL_FACING, mirror.apply(state.get(HORIZONTAL_FACING)));
|
|
}
|
|
|
|
static {
|
|
VoxelShape SHAPE = createCuboidShape(0, 0, 0, 16, 3, 16);
|
|
TRAPDOOR_VOXELS = VoxelHelper.VoxelListBuilder.create(SHAPE, 6)
|
|
.add(VoxelHelper::mirrorY)
|
|
.add(VoxelHelper::rotateX)
|
|
.add(VoxelHelper::mirrorZ)
|
|
.add(VoxelHelper::rotateY)
|
|
.add(VoxelHelper::mirrorX)
|
|
.build();
|
|
}
|
|
}
|