/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.mojang.datafixers.kinds.App * com.mojang.datafixers.kinds.Applicative * com.mojang.serialization.MapCodec * com.mojang.serialization.codecs.RecordCodecBuilder * org.jspecify.annotations.Nullable */ package net.minecraft.world.level.block; import com.mojang.datafixers.kinds.App; import com.mojang.datafixers.kinds.Applicative; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.tags.BlockTags; import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.HangingSignItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.ScheduledTickAccess; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.SignBlock; import net.minecraft.world.level.block.SupportType; import net.minecraft.world.level.block.WallHangingSignBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.HangingSignBlockEntity; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.block.state.properties.RotationSegment; import net.minecraft.world.level.block.state.properties.WoodType; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import org.jspecify.annotations.Nullable; public class CeilingHangingSignBlock extends SignBlock { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group((App)WoodType.CODEC.fieldOf("wood_type").forGetter(SignBlock::type), CeilingHangingSignBlock.propertiesCodec()).apply((Applicative)i, CeilingHangingSignBlock::new)); public static final IntegerProperty ROTATION = BlockStateProperties.ROTATION_16; public static final BooleanProperty ATTACHED = BlockStateProperties.ATTACHED; private static final VoxelShape SHAPE_DEFAULT = Block.column(10.0, 0.0, 16.0); private static final Map SHAPES = Shapes.rotateHorizontal(Block.column(14.0, 2.0, 0.0, 10.0)).entrySet().stream().collect(Collectors.toMap(e -> RotationSegment.convertToSegment((Direction)e.getKey()), Map.Entry::getValue)); public MapCodec codec() { return CODEC; } public CeilingHangingSignBlock(WoodType type, BlockBehaviour.Properties properties) { super(type, properties.sound(type.hangingSignSoundType())); this.registerDefaultState((BlockState)((BlockState)((BlockState)((BlockState)this.stateDefinition.any()).setValue(ROTATION, 0)).setValue(ATTACHED, false)).setValue(WATERLOGGED, false)); } @Override protected InteractionResult useItemOn(ItemStack itemStack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult) { SignBlockEntity signEntity; BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof SignBlockEntity && this.shouldTryToChainAnotherHangingSign(player, hitResult, signEntity = (SignBlockEntity)blockEntity, itemStack)) { return InteractionResult.PASS; } return super.useItemOn(itemStack, state, level, pos, player, hand, hitResult); } private boolean shouldTryToChainAnotherHangingSign(Player player, BlockHitResult hitResult, SignBlockEntity signEntity, ItemStack itemStack) { return !signEntity.canExecuteClickCommands(signEntity.isFacingFrontText(player), player) && itemStack.getItem() instanceof HangingSignItem && hitResult.getDirection().equals(Direction.DOWN); } @Override protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { return level.getBlockState(pos.above()).isFaceSturdy(level, pos.above(), Direction.DOWN, SupportType.CENTER); } @Override public BlockState getStateForPlacement(BlockPlaceContext context) { boolean attachedToMiddle; Level level = context.getLevel(); FluidState replacedFluidState = level.getFluidState(context.getClickedPos()); BlockPos above = context.getClickedPos().above(); BlockState stateAbove = level.getBlockState(above); boolean isBelowHangingSign = stateAbove.is(BlockTags.ALL_HANGING_SIGNS); Direction direction = Direction.fromYRot(context.getRotation()); boolean bl = attachedToMiddle = !Block.isFaceFull(stateAbove.getCollisionShape(level, above), Direction.DOWN) || context.isSecondaryUseActive(); if (isBelowHangingSign && !context.isSecondaryUseActive()) { Object aboveDirection; if (stateAbove.hasProperty(WallHangingSignBlock.FACING)) { aboveDirection = stateAbove.getValue(WallHangingSignBlock.FACING); if (((Direction)aboveDirection).getAxis().test(direction)) { attachedToMiddle = false; } } else if (stateAbove.hasProperty(ROTATION) && ((Optional)(aboveDirection = RotationSegment.convertToDirection(stateAbove.getValue(ROTATION)))).isPresent() && ((Direction)((Optional)aboveDirection).get()).getAxis().test(direction)) { attachedToMiddle = false; } } int rotationSegment = !attachedToMiddle ? RotationSegment.convertToSegment(direction.getOpposite()) : RotationSegment.convertToSegment(context.getRotation() + 180.0f); return (BlockState)((BlockState)((BlockState)this.defaultBlockState().setValue(ATTACHED, attachedToMiddle)).setValue(ROTATION, rotationSegment)).setValue(WATERLOGGED, replacedFluidState.getType() == Fluids.WATER); } @Override protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { return SHAPES.getOrDefault(state.getValue(ROTATION), SHAPE_DEFAULT); } @Override protected VoxelShape getBlockSupportShape(BlockState state, BlockGetter level, BlockPos pos) { return this.getShape(state, level, pos, CollisionContext.empty()); } @Override protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticks, BlockPos pos, Direction directionToNeighbour, BlockPos neighbourPos, BlockState neighbourState, RandomSource random) { if (directionToNeighbour == Direction.UP && !this.canSurvive(state, level, pos)) { return Blocks.AIR.defaultBlockState(); } return super.updateShape(state, level, ticks, pos, directionToNeighbour, neighbourPos, neighbourState, random); } @Override public float getYRotationDegrees(BlockState state) { return RotationSegment.convertToDegrees(state.getValue(ROTATION)); } @Override protected BlockState rotate(BlockState state, Rotation rotation) { return (BlockState)state.setValue(ROTATION, rotation.rotate(state.getValue(ROTATION), 16)); } @Override protected BlockState mirror(BlockState state, Mirror mirror) { return (BlockState)state.setValue(ROTATION, mirror.mirror(state.getValue(ROTATION), 16)); } @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(ROTATION, ATTACHED, WATERLOGGED); } @Override public BlockEntity newBlockEntity(BlockPos worldPosition, BlockState blockState) { return new HangingSignBlockEntity(worldPosition, blockState); } @Override public @Nullable BlockEntityTicker getTicker(Level level, BlockState blockState, BlockEntityType type) { return CeilingHangingSignBlock.createTickerHelper(type, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick); } }