package net.minecraft.world.level.block; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; 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.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( p_360459_ -> p_360459_.group(BuiltInRegistries.BLOCK.byNameCodec().fieldOf("hook").forGetter(p_312791_ -> p_312791_.hook), propertiesCodec()) .apply(p_360459_, 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; @Override public MapCodec codec() { return CODEC; } public TripWireBlock(Block p_310222_, BlockBehaviour.Properties p_57604_) { super(p_57604_); this.registerDefaultState( 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 = p_310222_; } @Override protected VoxelShape getShape(BlockState p_57654_, BlockGetter p_57655_, BlockPos p_57656_, CollisionContext p_57657_) { return p_57654_.getValue(ATTACHED) ? SHAPE_ATTACHED : SHAPE_NOT_ATTACHED; } @Override public BlockState getStateForPlacement(BlockPlaceContext p_57606_) { BlockGetter blockgetter = p_57606_.getLevel(); BlockPos blockpos = p_57606_.getClickedPos(); return this.defaultBlockState() .setValue(NORTH, this.shouldConnectTo(blockgetter.getBlockState(blockpos.north()), Direction.NORTH)) .setValue(EAST, this.shouldConnectTo(blockgetter.getBlockState(blockpos.east()), Direction.EAST)) .setValue(SOUTH, this.shouldConnectTo(blockgetter.getBlockState(blockpos.south()), Direction.SOUTH)) .setValue(WEST, this.shouldConnectTo(blockgetter.getBlockState(blockpos.west()), Direction.WEST)); } @Override protected BlockState updateShape( BlockState p_57645_, LevelReader p_366467_, ScheduledTickAccess p_366611_, BlockPos p_57649_, Direction p_57646_, BlockPos p_57650_, BlockState p_57647_, RandomSource p_369813_ ) { return p_57646_.getAxis().isHorizontal() ? p_57645_.setValue(PROPERTY_BY_DIRECTION.get(p_57646_), this.shouldConnectTo(p_57647_, p_57646_)) : super.updateShape(p_57645_, p_366467_, p_366611_, p_57649_, p_57646_, p_57650_, p_57647_, p_369813_); } @Override protected void onPlace(BlockState p_57659_, Level p_57660_, BlockPos p_57661_, BlockState p_57662_, boolean p_57663_) { if (!p_57662_.is(p_57659_.getBlock())) { this.updateSource(p_57660_, p_57661_, p_57659_); } } @Override protected void affectNeighborsAfterRemoval(BlockState p_393989_, ServerLevel p_396061_, BlockPos p_396839_, boolean p_392670_) { if (!p_392670_) { this.updateSource(p_396061_, p_396839_, p_393989_.setValue(POWERED, true)); } } @Override public BlockState playerWillDestroy(Level p_57615_, BlockPos p_57616_, BlockState p_57617_, Player p_57618_) { if (!p_57615_.isClientSide && !p_57618_.getMainHandItem().isEmpty() && p_57618_.getMainHandItem().is(Items.SHEARS)) { p_57615_.setBlock(p_57616_, p_57617_.setValue(DISARMED, true), 260); p_57615_.gameEvent(p_57618_, GameEvent.SHEAR, p_57616_); } return super.playerWillDestroy(p_57615_, p_57616_, p_57617_, p_57618_); } private void updateSource(Level p_57611_, BlockPos p_57612_, BlockState p_57613_) { for (Direction direction : new Direction[]{Direction.SOUTH, Direction.WEST}) { for (int i = 1; i < 42; i++) { BlockPos blockpos = p_57612_.relative(direction, i); BlockState blockstate = p_57611_.getBlockState(blockpos); if (blockstate.is(this.hook)) { if (blockstate.getValue(TripWireHookBlock.FACING) == direction.getOpposite()) { TripWireHookBlock.calculateState(p_57611_, blockpos, blockstate, false, true, i, p_57613_); } break; } if (!blockstate.is(this)) { break; } } } } @Override protected VoxelShape getEntityInsideCollisionShape(BlockState p_367024_, BlockGetter p_394181_, BlockPos p_366199_, Entity p_391633_) { return p_367024_.getShape(p_394181_, p_366199_); } @Override protected void entityInside(BlockState p_57625_, Level p_57626_, BlockPos p_57627_, Entity p_57628_, InsideBlockEffectApplier p_392144_) { if (!p_57626_.isClientSide) { if (!p_57625_.getValue(POWERED)) { this.checkPressed(p_57626_, p_57627_, List.of(p_57628_)); } } } @Override protected void tick(BlockState p_222598_, ServerLevel p_222599_, BlockPos p_222600_, RandomSource p_222601_) { if (p_222599_.getBlockState(p_222600_).getValue(POWERED)) { this.checkPressed(p_222599_, p_222600_); } } private void checkPressed(Level p_57608_, BlockPos p_57609_) { BlockState blockstate = p_57608_.getBlockState(p_57609_); List list = p_57608_.getEntities(null, blockstate.getShape(p_57608_, p_57609_).bounds().move(p_57609_)); this.checkPressed(p_57608_, p_57609_, list); } private void checkPressed(Level p_366903_, BlockPos p_365869_, List p_360972_) { BlockState blockstate = p_366903_.getBlockState(p_365869_); boolean flag = blockstate.getValue(POWERED); boolean flag1 = false; if (!p_360972_.isEmpty()) { for (Entity entity : p_360972_) { if (!entity.isIgnoringBlockTriggers()) { flag1 = true; break; } } } if (flag1 != flag) { blockstate = blockstate.setValue(POWERED, flag1); p_366903_.setBlock(p_365869_, blockstate, 3); this.updateSource(p_366903_, p_365869_, blockstate); } if (flag1) { p_366903_.scheduleTick(new BlockPos(p_365869_), this, 10); } } public boolean shouldConnectTo(BlockState p_57642_, Direction p_57643_) { return p_57642_.is(this.hook) ? p_57642_.getValue(TripWireHookBlock.FACING) == p_57643_.getOpposite() : p_57642_.is(this); } @Override protected BlockState rotate(BlockState p_57639_, Rotation p_57640_) { switch (p_57640_) { case CLOCKWISE_180: return p_57639_.setValue(NORTH, p_57639_.getValue(SOUTH)) .setValue(EAST, p_57639_.getValue(WEST)) .setValue(SOUTH, p_57639_.getValue(NORTH)) .setValue(WEST, p_57639_.getValue(EAST)); case COUNTERCLOCKWISE_90: return p_57639_.setValue(NORTH, p_57639_.getValue(EAST)) .setValue(EAST, p_57639_.getValue(SOUTH)) .setValue(SOUTH, p_57639_.getValue(WEST)) .setValue(WEST, p_57639_.getValue(NORTH)); case CLOCKWISE_90: return p_57639_.setValue(NORTH, p_57639_.getValue(WEST)) .setValue(EAST, p_57639_.getValue(NORTH)) .setValue(SOUTH, p_57639_.getValue(EAST)) .setValue(WEST, p_57639_.getValue(SOUTH)); default: return p_57639_; } } @Override protected BlockState mirror(BlockState p_57636_, Mirror p_57637_) { switch (p_57637_) { case LEFT_RIGHT: return p_57636_.setValue(NORTH, p_57636_.getValue(SOUTH)).setValue(SOUTH, p_57636_.getValue(NORTH)); case FRONT_BACK: return p_57636_.setValue(EAST, p_57636_.getValue(WEST)).setValue(WEST, p_57636_.getValue(EAST)); default: return super.mirror(p_57636_, p_57637_); } } @Override protected void createBlockStateDefinition(StateDefinition.Builder p_57652_) { p_57652_.add(POWERED, ATTACHED, DISARMED, NORTH, EAST, WEST, SOUTH); } }