Code/net/minecraft/world/level/block/TripWireBlock.java

239 lines
10 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
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<TripWireBlock> 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<Direction, BooleanProperty> 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<TripWireBlock> 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<? extends Entity> 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<? extends Entity> 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<Block, BlockState> p_57652_) {
p_57652_.add(POWERED, ATTACHED, DISARMED, NORTH, EAST, WEST, SOUTH);
}
}