/* * 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 */ 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.List; import java.util.Map; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.InsideBlockEffectApplier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Items; 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.CrossCollisionBlock; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.PipeBlock; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.TripWireHookBlock; 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.gameevent.GameEvent; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; public class TripWireBlock extends Block { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group((App)BuiltInRegistries.BLOCK.byNameCodec().fieldOf("hook").forGetter(b -> b.hook), TripWireBlock.propertiesCodec()).apply((Applicative)i, TripWireBlock::new)); public static final BooleanProperty POWERED = BlockStateProperties.POWERED; public static final BooleanProperty ATTACHED = BlockStateProperties.ATTACHED; public static final BooleanProperty DISARMED = BlockStateProperties.DISARMED; public static final BooleanProperty NORTH = PipeBlock.NORTH; public static final BooleanProperty EAST = PipeBlock.EAST; public static final BooleanProperty SOUTH = PipeBlock.SOUTH; public static final BooleanProperty WEST = PipeBlock.WEST; private static final Map PROPERTY_BY_DIRECTION = CrossCollisionBlock.PROPERTY_BY_DIRECTION; private static final VoxelShape SHAPE_ATTACHED = Block.column(16.0, 1.0, 2.5); private static final VoxelShape SHAPE_NOT_ATTACHED = Block.column(16.0, 0.0, 8.0); private static final int RECHECK_PERIOD = 10; private final Block hook; public MapCodec codec() { return CODEC; } public TripWireBlock(Block hook, BlockBehaviour.Properties properties) { super(properties); this.registerDefaultState((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)((BlockState)this.stateDefinition.any()).setValue(POWERED, false)).setValue(ATTACHED, false)).setValue(DISARMED, false)).setValue(NORTH, false)).setValue(EAST, false)).setValue(SOUTH, false)).setValue(WEST, false)); this.hook = hook; } @Override protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { return state.getValue(ATTACHED) != false ? SHAPE_ATTACHED : SHAPE_NOT_ATTACHED; } @Override public BlockState getStateForPlacement(BlockPlaceContext context) { Level level = context.getLevel(); BlockPos pos = context.getClickedPos(); return (BlockState)((BlockState)((BlockState)((BlockState)this.defaultBlockState().setValue(NORTH, this.shouldConnectTo(level.getBlockState(pos.north()), Direction.NORTH))).setValue(EAST, this.shouldConnectTo(level.getBlockState(pos.east()), Direction.EAST))).setValue(SOUTH, this.shouldConnectTo(level.getBlockState(pos.south()), Direction.SOUTH))).setValue(WEST, this.shouldConnectTo(level.getBlockState(pos.west()), Direction.WEST)); } @Override protected BlockState updateShape(BlockState state, LevelReader level, ScheduledTickAccess ticks, BlockPos pos, Direction directionToNeighbour, BlockPos neighbourPos, BlockState neighbourState, RandomSource random) { if (directionToNeighbour.getAxis().isHorizontal()) { return (BlockState)state.setValue(PROPERTY_BY_DIRECTION.get(directionToNeighbour), this.shouldConnectTo(neighbourState, directionToNeighbour)); } return super.updateShape(state, level, ticks, pos, directionToNeighbour, neighbourPos, neighbourState, random); } @Override protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) { if (oldState.is(state.getBlock())) { return; } this.updateSource(level, pos, state); } @Override protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) { if (!movedByPiston) { this.updateSource(level, pos, (BlockState)state.setValue(POWERED, true)); } } @Override public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) { if (!level.isClientSide() && !player.getMainHandItem().isEmpty() && player.getMainHandItem().is(Items.SHEARS)) { level.setBlock(pos, (BlockState)state.setValue(DISARMED, true), 260); level.gameEvent((Entity)player, GameEvent.SHEAR, pos); } return super.playerWillDestroy(level, pos, state, player); } private void updateSource(Level level, BlockPos pos, BlockState state) { block0: for (Direction direction : new Direction[]{Direction.SOUTH, Direction.WEST}) { for (int i = 1; i < 42; ++i) { BlockPos testPos = pos.relative(direction, i); BlockState block = level.getBlockState(testPos); if (block.is(this.hook)) { if (block.getValue(TripWireHookBlock.FACING) != direction.getOpposite()) continue block0; TripWireHookBlock.calculateState(level, testPos, block, false, true, i, state); continue block0; } if (!block.is(this)) continue block0; } } } @Override protected VoxelShape getEntityInsideCollisionShape(BlockState state, BlockGetter level, BlockPos pos, Entity entity) { return state.getShape(level, pos); } @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier, boolean isPrecise) { if (level.isClientSide()) { return; } if (state.getValue(POWERED).booleanValue()) { return; } this.checkPressed(level, pos, List.of(entity)); } @Override protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { if (!level.getBlockState(pos).getValue(POWERED).booleanValue()) { return; } this.checkPressed(level, pos); } private void checkPressed(Level level, BlockPos pos) { BlockState state = level.getBlockState(pos); List entities = level.getEntities(null, state.getShape(level, pos).bounds().move(pos)); this.checkPressed(level, pos, entities); } private void checkPressed(Level level, BlockPos pos, List entities) { BlockState state = level.getBlockState(pos); boolean wasPressed = state.getValue(POWERED); boolean shouldBePressed = false; if (!entities.isEmpty()) { for (Entity entity : entities) { if (entity.isIgnoringBlockTriggers()) continue; shouldBePressed = true; break; } } if (shouldBePressed != wasPressed) { state = (BlockState)state.setValue(POWERED, shouldBePressed); level.setBlock(pos, state, 3); this.updateSource(level, pos, state); } if (shouldBePressed) { level.scheduleTick(new BlockPos(pos), this, 10); } } public boolean shouldConnectTo(BlockState blockState, Direction direction) { if (blockState.is(this.hook)) { return blockState.getValue(TripWireHookBlock.FACING) == direction.getOpposite(); } return blockState.is(this); } @Override protected BlockState rotate(BlockState state, Rotation rotation) { switch (rotation) { case CLOCKWISE_180: { return (BlockState)((BlockState)((BlockState)((BlockState)state.setValue(NORTH, state.getValue(SOUTH))).setValue(EAST, state.getValue(WEST))).setValue(SOUTH, state.getValue(NORTH))).setValue(WEST, state.getValue(EAST)); } case COUNTERCLOCKWISE_90: { return (BlockState)((BlockState)((BlockState)((BlockState)state.setValue(NORTH, state.getValue(EAST))).setValue(EAST, state.getValue(SOUTH))).setValue(SOUTH, state.getValue(WEST))).setValue(WEST, state.getValue(NORTH)); } case CLOCKWISE_90: { return (BlockState)((BlockState)((BlockState)((BlockState)state.setValue(NORTH, state.getValue(WEST))).setValue(EAST, state.getValue(NORTH))).setValue(SOUTH, state.getValue(EAST))).setValue(WEST, state.getValue(SOUTH)); } } return state; } @Override protected BlockState mirror(BlockState state, Mirror mirror) { switch (mirror) { case LEFT_RIGHT: { return (BlockState)((BlockState)state.setValue(NORTH, state.getValue(SOUTH))).setValue(SOUTH, state.getValue(NORTH)); } case FRONT_BACK: { return (BlockState)((BlockState)state.setValue(EAST, state.getValue(WEST))).setValue(WEST, state.getValue(EAST)); } } return super.mirror(state, mirror); } @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(POWERED, ATTACHED, DISARMED, NORTH, EAST, WEST, SOUTH); } }