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

297 lines
13 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 java.util.List;
import java.util.function.Predicate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.Container;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.InsideBlockEffectApplier;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.entity.vehicle.MinecartCommandBlock;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
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.EnumProperty;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.state.properties.RailShape;
import net.minecraft.world.phys.AABB;
public class DetectorRailBlock extends BaseRailBlock {
public static final MapCodec<DetectorRailBlock> CODEC = simpleCodec(DetectorRailBlock::new);
public static final EnumProperty<RailShape> SHAPE = BlockStateProperties.RAIL_SHAPE_STRAIGHT;
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
private static final int PRESSED_CHECK_PERIOD = 20;
@Override
public MapCodec<DetectorRailBlock> codec() {
return CODEC;
}
public DetectorRailBlock(BlockBehaviour.Properties p_52431_) {
super(true, p_52431_);
this.registerDefaultState(this.stateDefinition.any().setValue(POWERED, false).setValue(SHAPE, RailShape.NORTH_SOUTH).setValue(WATERLOGGED, false));
}
@Override
protected boolean isSignalSource(BlockState p_52489_) {
return true;
}
@Override
protected void entityInside(BlockState p_52458_, Level p_52459_, BlockPos p_52460_, Entity p_52461_, InsideBlockEffectApplier p_395259_) {
if (!p_52459_.isClientSide) {
if (!p_52458_.getValue(POWERED)) {
this.checkPressed(p_52459_, p_52460_, p_52458_);
}
}
}
@Override
protected void tick(BlockState p_221060_, ServerLevel p_221061_, BlockPos p_221062_, RandomSource p_221063_) {
if (p_221060_.getValue(POWERED)) {
this.checkPressed(p_221061_, p_221062_, p_221060_);
}
}
@Override
protected int getSignal(BlockState p_52449_, BlockGetter p_52450_, BlockPos p_52451_, Direction p_52452_) {
return p_52449_.getValue(POWERED) ? 15 : 0;
}
@Override
protected int getDirectSignal(BlockState p_52478_, BlockGetter p_52479_, BlockPos p_52480_, Direction p_52481_) {
if (!p_52478_.getValue(POWERED)) {
return 0;
} else {
return p_52481_ == Direction.UP ? 15 : 0;
}
}
private void checkPressed(Level p_52433_, BlockPos p_52434_, BlockState p_52435_) {
if (this.canSurvive(p_52435_, p_52433_, p_52434_)) {
boolean flag = p_52435_.getValue(POWERED);
boolean flag1 = false;
List<AbstractMinecart> list = this.getInteractingMinecartOfType(p_52433_, p_52434_, AbstractMinecart.class, p_153125_ -> true);
if (!list.isEmpty()) {
flag1 = true;
}
if (flag1 && !flag) {
BlockState blockstate = p_52435_.setValue(POWERED, true);
p_52433_.setBlock(p_52434_, blockstate, 3);
this.updatePowerToConnected(p_52433_, p_52434_, blockstate, true);
p_52433_.updateNeighborsAt(p_52434_, this);
p_52433_.updateNeighborsAt(p_52434_.below(), this);
p_52433_.setBlocksDirty(p_52434_, p_52435_, blockstate);
}
if (!flag1 && flag) {
BlockState blockstate1 = p_52435_.setValue(POWERED, false);
p_52433_.setBlock(p_52434_, blockstate1, 3);
this.updatePowerToConnected(p_52433_, p_52434_, blockstate1, false);
p_52433_.updateNeighborsAt(p_52434_, this);
p_52433_.updateNeighborsAt(p_52434_.below(), this);
p_52433_.setBlocksDirty(p_52434_, p_52435_, blockstate1);
}
if (flag1) {
p_52433_.scheduleTick(p_52434_, this, 20);
}
p_52433_.updateNeighbourForOutputSignal(p_52434_, this);
}
}
protected void updatePowerToConnected(Level p_52473_, BlockPos p_52474_, BlockState p_52475_, boolean p_52476_) {
RailState railstate = new RailState(p_52473_, p_52474_, p_52475_);
for (BlockPos blockpos : railstate.getConnections()) {
BlockState blockstate = p_52473_.getBlockState(blockpos);
p_52473_.neighborChanged(blockstate, blockpos, blockstate.getBlock(), null, false);
}
}
@Override
protected void onPlace(BlockState p_52483_, Level p_52484_, BlockPos p_52485_, BlockState p_52486_, boolean p_52487_) {
if (!p_52486_.is(p_52483_.getBlock())) {
BlockState blockstate = this.updateState(p_52483_, p_52484_, p_52485_, p_52487_);
this.checkPressed(p_52484_, p_52485_, blockstate);
}
}
@Override
public Property<RailShape> getShapeProperty() {
return SHAPE;
}
@Override
protected boolean hasAnalogOutputSignal(BlockState p_52442_) {
return true;
}
@Override
protected int getAnalogOutputSignal(BlockState p_52454_, Level p_52455_, BlockPos p_52456_) {
if (p_52454_.getValue(POWERED)) {
List<MinecartCommandBlock> list = this.getInteractingMinecartOfType(p_52455_, p_52456_, MinecartCommandBlock.class, p_153123_ -> true);
if (!list.isEmpty()) {
return list.get(0).getCommandBlock().getSuccessCount();
}
List<AbstractMinecart> list1 = this.getInteractingMinecartOfType(p_52455_, p_52456_, AbstractMinecart.class, EntitySelector.CONTAINER_ENTITY_SELECTOR);
if (!list1.isEmpty()) {
return AbstractContainerMenu.getRedstoneSignalFromContainer((Container)list1.get(0));
}
}
return 0;
}
private <T extends AbstractMinecart> List<T> getInteractingMinecartOfType(Level p_52437_, BlockPos p_52438_, Class<T> p_52439_, Predicate<Entity> p_52440_) {
return p_52437_.getEntitiesOfClass(p_52439_, this.getSearchBB(p_52438_), p_52440_);
}
private AABB getSearchBB(BlockPos p_52471_) {
double d0 = 0.2;
return new AABB(
p_52471_.getX() + 0.2,
p_52471_.getY(),
p_52471_.getZ() + 0.2,
p_52471_.getX() + 1 - 0.2,
p_52471_.getY() + 1 - 0.2,
p_52471_.getZ() + 1 - 0.2
);
}
@Override
protected BlockState rotate(BlockState p_52466_, Rotation p_52467_) {
switch (p_52467_) {
case CLOCKWISE_180:
switch ((RailShape)p_52466_.getValue(SHAPE)) {
case ASCENDING_EAST:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_WEST);
case ASCENDING_WEST:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_EAST);
case ASCENDING_NORTH:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
case ASCENDING_SOUTH:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_NORTH);
case SOUTH_EAST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_WEST);
case SOUTH_WEST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_EAST);
case NORTH_WEST:
return p_52466_.setValue(SHAPE, RailShape.SOUTH_EAST);
case NORTH_EAST:
return p_52466_.setValue(SHAPE, RailShape.SOUTH_WEST);
}
case COUNTERCLOCKWISE_90:
switch ((RailShape)p_52466_.getValue(SHAPE)) {
case ASCENDING_EAST:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_NORTH);
case ASCENDING_WEST:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
case ASCENDING_NORTH:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_WEST);
case ASCENDING_SOUTH:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_EAST);
case SOUTH_EAST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_EAST);
case SOUTH_WEST:
return p_52466_.setValue(SHAPE, RailShape.SOUTH_EAST);
case NORTH_WEST:
return p_52466_.setValue(SHAPE, RailShape.SOUTH_WEST);
case NORTH_EAST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_WEST);
case NORTH_SOUTH:
return p_52466_.setValue(SHAPE, RailShape.EAST_WEST);
case EAST_WEST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_SOUTH);
}
case CLOCKWISE_90:
switch ((RailShape)p_52466_.getValue(SHAPE)) {
case ASCENDING_EAST:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
case ASCENDING_WEST:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_NORTH);
case ASCENDING_NORTH:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_EAST);
case ASCENDING_SOUTH:
return p_52466_.setValue(SHAPE, RailShape.ASCENDING_WEST);
case SOUTH_EAST:
return p_52466_.setValue(SHAPE, RailShape.SOUTH_WEST);
case SOUTH_WEST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_WEST);
case NORTH_WEST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_EAST);
case NORTH_EAST:
return p_52466_.setValue(SHAPE, RailShape.SOUTH_EAST);
case NORTH_SOUTH:
return p_52466_.setValue(SHAPE, RailShape.EAST_WEST);
case EAST_WEST:
return p_52466_.setValue(SHAPE, RailShape.NORTH_SOUTH);
}
default:
return p_52466_;
}
}
@Override
protected BlockState mirror(BlockState p_52463_, Mirror p_52464_) {
RailShape railshape = p_52463_.getValue(SHAPE);
switch (p_52464_) {
case LEFT_RIGHT:
switch (railshape) {
case ASCENDING_NORTH:
return p_52463_.setValue(SHAPE, RailShape.ASCENDING_SOUTH);
case ASCENDING_SOUTH:
return p_52463_.setValue(SHAPE, RailShape.ASCENDING_NORTH);
case SOUTH_EAST:
return p_52463_.setValue(SHAPE, RailShape.NORTH_EAST);
case SOUTH_WEST:
return p_52463_.setValue(SHAPE, RailShape.NORTH_WEST);
case NORTH_WEST:
return p_52463_.setValue(SHAPE, RailShape.SOUTH_WEST);
case NORTH_EAST:
return p_52463_.setValue(SHAPE, RailShape.SOUTH_EAST);
default:
return super.mirror(p_52463_, p_52464_);
}
case FRONT_BACK:
switch (railshape) {
case ASCENDING_EAST:
return p_52463_.setValue(SHAPE, RailShape.ASCENDING_WEST);
case ASCENDING_WEST:
return p_52463_.setValue(SHAPE, RailShape.ASCENDING_EAST);
case ASCENDING_NORTH:
case ASCENDING_SOUTH:
default:
break;
case SOUTH_EAST:
return p_52463_.setValue(SHAPE, RailShape.SOUTH_WEST);
case SOUTH_WEST:
return p_52463_.setValue(SHAPE, RailShape.SOUTH_EAST);
case NORTH_WEST:
return p_52463_.setValue(SHAPE, RailShape.NORTH_EAST);
case NORTH_EAST:
return p_52463_.setValue(SHAPE, RailShape.NORTH_WEST);
}
}
return super.mirror(p_52463_, p_52464_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_52469_) {
p_52469_.add(SHAPE, POWERED, WATERLOGGED);
}
}