package net.minecraft.world.level.block; import com.google.common.collect.Lists; import java.util.List; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.RailShape; public class RailState { private final Level level; private final BlockPos pos; private final BaseRailBlock block; private BlockState state; private final boolean isStraight; private final List connections = Lists.newArrayList(); public RailState(Level p_55421_, BlockPos p_55422_, BlockState p_55423_) { this.level = p_55421_; this.pos = p_55422_; this.state = p_55423_; this.block = (BaseRailBlock)p_55423_.getBlock(); RailShape railshape = p_55423_.getValue(this.block.getShapeProperty()); this.isStraight = this.block.isStraight(); this.updateConnections(railshape); } public List getConnections() { return this.connections; } private void updateConnections(RailShape p_55428_) { this.connections.clear(); switch (p_55428_) { case NORTH_SOUTH: this.connections.add(this.pos.north()); this.connections.add(this.pos.south()); break; case EAST_WEST: this.connections.add(this.pos.west()); this.connections.add(this.pos.east()); break; case ASCENDING_EAST: this.connections.add(this.pos.west()); this.connections.add(this.pos.east().above()); break; case ASCENDING_WEST: this.connections.add(this.pos.west().above()); this.connections.add(this.pos.east()); break; case ASCENDING_NORTH: this.connections.add(this.pos.north().above()); this.connections.add(this.pos.south()); break; case ASCENDING_SOUTH: this.connections.add(this.pos.north()); this.connections.add(this.pos.south().above()); break; case SOUTH_EAST: this.connections.add(this.pos.east()); this.connections.add(this.pos.south()); break; case SOUTH_WEST: this.connections.add(this.pos.west()); this.connections.add(this.pos.south()); break; case NORTH_WEST: this.connections.add(this.pos.west()); this.connections.add(this.pos.north()); break; case NORTH_EAST: this.connections.add(this.pos.east()); this.connections.add(this.pos.north()); } } private void removeSoftConnections() { for (int i = 0; i < this.connections.size(); i++) { RailState railstate = this.getRail(this.connections.get(i)); if (railstate != null && railstate.connectsTo(this)) { this.connections.set(i, railstate.pos); } else { this.connections.remove(i--); } } } private boolean hasRail(BlockPos p_55430_) { return BaseRailBlock.isRail(this.level, p_55430_) || BaseRailBlock.isRail(this.level, p_55430_.above()) || BaseRailBlock.isRail(this.level, p_55430_.below()); } @Nullable private RailState getRail(BlockPos p_55439_) { BlockState blockstate = this.level.getBlockState(p_55439_); if (BaseRailBlock.isRail(blockstate)) { return new RailState(this.level, p_55439_, blockstate); } else { BlockPos $$1 = p_55439_.above(); blockstate = this.level.getBlockState($$1); if (BaseRailBlock.isRail(blockstate)) { return new RailState(this.level, $$1, blockstate); } else { $$1 = p_55439_.below(); blockstate = this.level.getBlockState($$1); return BaseRailBlock.isRail(blockstate) ? new RailState(this.level, $$1, blockstate) : null; } } } private boolean connectsTo(RailState p_55426_) { return this.hasConnection(p_55426_.pos); } private boolean hasConnection(BlockPos p_55444_) { for (int i = 0; i < this.connections.size(); i++) { BlockPos blockpos = this.connections.get(i); if (blockpos.getX() == p_55444_.getX() && blockpos.getZ() == p_55444_.getZ()) { return true; } } return false; } protected int countPotentialConnections() { int i = 0; for (Direction direction : Direction.Plane.HORIZONTAL) { if (this.hasRail(this.pos.relative(direction))) { i++; } } return i; } private boolean canConnectTo(RailState p_55437_) { return this.connectsTo(p_55437_) || this.connections.size() != 2; } private void connectTo(RailState p_55442_) { this.connections.add(p_55442_.pos); BlockPos blockpos = this.pos.north(); BlockPos blockpos1 = this.pos.south(); BlockPos blockpos2 = this.pos.west(); BlockPos blockpos3 = this.pos.east(); boolean flag = this.hasConnection(blockpos); boolean flag1 = this.hasConnection(blockpos1); boolean flag2 = this.hasConnection(blockpos2); boolean flag3 = this.hasConnection(blockpos3); RailShape railshape = null; if (flag || flag1) { railshape = RailShape.NORTH_SOUTH; } if (flag2 || flag3) { railshape = RailShape.EAST_WEST; } if (!this.isStraight) { if (flag1 && flag3 && !flag && !flag2) { railshape = RailShape.SOUTH_EAST; } if (flag1 && flag2 && !flag && !flag3) { railshape = RailShape.SOUTH_WEST; } if (flag && flag2 && !flag1 && !flag3) { railshape = RailShape.NORTH_WEST; } if (flag && flag3 && !flag1 && !flag2) { railshape = RailShape.NORTH_EAST; } } if (railshape == RailShape.NORTH_SOUTH) { if (BaseRailBlock.isRail(this.level, blockpos.above())) { railshape = RailShape.ASCENDING_NORTH; } if (BaseRailBlock.isRail(this.level, blockpos1.above())) { railshape = RailShape.ASCENDING_SOUTH; } } if (railshape == RailShape.EAST_WEST) { if (BaseRailBlock.isRail(this.level, blockpos3.above())) { railshape = RailShape.ASCENDING_EAST; } if (BaseRailBlock.isRail(this.level, blockpos2.above())) { railshape = RailShape.ASCENDING_WEST; } } if (railshape == null) { railshape = RailShape.NORTH_SOUTH; } this.state = this.state.setValue(this.block.getShapeProperty(), railshape); this.level.setBlock(this.pos, this.state, 3); } private boolean hasNeighborRail(BlockPos p_55447_) { RailState railstate = this.getRail(p_55447_); if (railstate == null) { return false; } else { railstate.removeSoftConnections(); return railstate.canConnectTo(this); } } public RailState place(boolean p_55432_, boolean p_55433_, RailShape p_55434_) { BlockPos blockpos = this.pos.north(); BlockPos blockpos1 = this.pos.south(); BlockPos blockpos2 = this.pos.west(); BlockPos blockpos3 = this.pos.east(); boolean flag = this.hasNeighborRail(blockpos); boolean flag1 = this.hasNeighborRail(blockpos1); boolean flag2 = this.hasNeighborRail(blockpos2); boolean flag3 = this.hasNeighborRail(blockpos3); RailShape railshape = null; boolean flag4 = flag || flag1; boolean flag5 = flag2 || flag3; if (flag4 && !flag5) { railshape = RailShape.NORTH_SOUTH; } if (flag5 && !flag4) { railshape = RailShape.EAST_WEST; } boolean flag6 = flag1 && flag3; boolean flag7 = flag1 && flag2; boolean flag8 = flag && flag3; boolean flag9 = flag && flag2; if (!this.isStraight) { if (flag6 && !flag && !flag2) { railshape = RailShape.SOUTH_EAST; } if (flag7 && !flag && !flag3) { railshape = RailShape.SOUTH_WEST; } if (flag9 && !flag1 && !flag3) { railshape = RailShape.NORTH_WEST; } if (flag8 && !flag1 && !flag2) { railshape = RailShape.NORTH_EAST; } } if (railshape == null) { if (flag4 && flag5) { railshape = p_55434_; } else if (flag4) { railshape = RailShape.NORTH_SOUTH; } else if (flag5) { railshape = RailShape.EAST_WEST; } if (!this.isStraight) { if (p_55432_) { if (flag6) { railshape = RailShape.SOUTH_EAST; } if (flag7) { railshape = RailShape.SOUTH_WEST; } if (flag8) { railshape = RailShape.NORTH_EAST; } if (flag9) { railshape = RailShape.NORTH_WEST; } } else { if (flag9) { railshape = RailShape.NORTH_WEST; } if (flag8) { railshape = RailShape.NORTH_EAST; } if (flag7) { railshape = RailShape.SOUTH_WEST; } if (flag6) { railshape = RailShape.SOUTH_EAST; } } } } if (railshape == RailShape.NORTH_SOUTH) { if (BaseRailBlock.isRail(this.level, blockpos.above())) { railshape = RailShape.ASCENDING_NORTH; } if (BaseRailBlock.isRail(this.level, blockpos1.above())) { railshape = RailShape.ASCENDING_SOUTH; } } if (railshape == RailShape.EAST_WEST) { if (BaseRailBlock.isRail(this.level, blockpos3.above())) { railshape = RailShape.ASCENDING_EAST; } if (BaseRailBlock.isRail(this.level, blockpos2.above())) { railshape = RailShape.ASCENDING_WEST; } } if (railshape == null) { railshape = p_55434_; } this.updateConnections(railshape); this.state = this.state.setValue(this.block.getShapeProperty(), railshape); if (p_55433_ || this.level.getBlockState(this.pos) != this.state) { this.level.setBlock(this.pos, this.state, 3); for (int i = 0; i < this.connections.size(); i++) { RailState railstate = this.getRail(this.connections.get(i)); if (railstate != null) { railstate.removeSoftConnections(); if (railstate.canConnectTo(this)) { railstate.connectTo(this); } } } } return this; } public BlockState getState() { return this.state; } }