// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers // // SPDX-License-Identifier: MPL-2.0 package dan200.computercraft.shared.common; import net.minecraft.core.BlockPos; import net.minecraft.world.Containers; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.phys.BlockHitResult; /** * A block which has a container and can be placed in a horizontal direction. * * @see AbstractContainerBlockEntity The container class which should be used on the block entity. */ public abstract class HorizontalContainerBlock extends BaseEntityBlock { public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public HorizontalContainerBlock(Properties properties) { super(properties); } @Override public final BlockState getStateForPlacement(BlockPlaceContext placement) { return defaultBlockState().setValue(FACING, placement.getHorizontalDirection().getOpposite()); } @Override protected final BlockState mirror(BlockState state, Mirror mirrorIn) { return state.rotate(mirrorIn.getRotation(state.getValue(FACING))); } @Override protected final BlockState rotate(BlockState state, Rotation rot) { return state.setValue(FACING, rot.rotate(state.getValue(FACING))); } @Override protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) { if (level.isClientSide) return InteractionResult.SUCCESS; if (level.getBlockEntity(pos) instanceof BaseContainerBlockEntity container) { player.openMenu(container); } return InteractionResult.CONSUME; } @Override protected final void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { if (state.is(newState.getBlock())) return; if (level.getBlockEntity(pos) instanceof BaseContainerBlockEntity container) { Containers.dropContents(level, pos, container); level.updateNeighbourForOutputSignal(pos, this); } super.onRemove(state, level, pos, newState, isMoving); } @Override protected final boolean hasAnalogOutputSignal(BlockState pState) { return true; } @Override protected final int getAnalogOutputSignal(BlockState pBlockState, Level pLevel, BlockPos pPos) { return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(pLevel.getBlockEntity(pPos)); } @Override protected RenderShape getRenderShape(BlockState state) { return RenderShape.MODEL; } }