minecraft-src/net/minecraft/world/level/block/RailState.java
2025-07-04 01:41:11 +03:00

352 lines
9 KiB
Java

package net.minecraft.world.level.block;
import com.google.common.collect.Lists;
import java.util.List;
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;
import org.jetbrains.annotations.Nullable;
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<BlockPos> connections = Lists.<BlockPos>newArrayList();
public RailState(Level level, BlockPos pos, BlockState state) {
this.level = level;
this.pos = pos;
this.state = state;
this.block = (BaseRailBlock)state.getBlock();
RailShape railShape = state.getValue(this.block.getShapeProperty());
this.isStraight = this.block.isStraight();
this.updateConnections(railShape);
}
public List<BlockPos> getConnections() {
return this.connections;
}
private void updateConnections(RailShape shape) {
this.connections.clear();
switch (shape) {
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((BlockPos)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 pos) {
return BaseRailBlock.isRail(this.level, pos) || BaseRailBlock.isRail(this.level, pos.above()) || BaseRailBlock.isRail(this.level, pos.below());
}
@Nullable
private RailState getRail(BlockPos pos) {
BlockState blockState = this.level.getBlockState(pos);
if (BaseRailBlock.isRail(blockState)) {
return new RailState(this.level, pos, blockState);
} else {
BlockPos blockPos = pos.above();
blockState = this.level.getBlockState(blockPos);
if (BaseRailBlock.isRail(blockState)) {
return new RailState(this.level, blockPos, blockState);
} else {
blockPos = pos.below();
blockState = this.level.getBlockState(blockPos);
return BaseRailBlock.isRail(blockState) ? new RailState(this.level, blockPos, blockState) : null;
}
}
}
private boolean connectsTo(RailState state) {
return this.hasConnection(state.pos);
}
private boolean hasConnection(BlockPos pos) {
for (int i = 0; i < this.connections.size(); i++) {
BlockPos blockPos = (BlockPos)this.connections.get(i);
if (blockPos.getX() == pos.getX() && blockPos.getZ() == pos.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 state) {
return this.connectsTo(state) || this.connections.size() != 2;
}
private void connectTo(RailState state) {
this.connections.add(state.pos);
BlockPos blockPos = this.pos.north();
BlockPos blockPos2 = this.pos.south();
BlockPos blockPos3 = this.pos.west();
BlockPos blockPos4 = this.pos.east();
boolean bl = this.hasConnection(blockPos);
boolean bl2 = this.hasConnection(blockPos2);
boolean bl3 = this.hasConnection(blockPos3);
boolean bl4 = this.hasConnection(blockPos4);
RailShape railShape = null;
if (bl || bl2) {
railShape = RailShape.NORTH_SOUTH;
}
if (bl3 || bl4) {
railShape = RailShape.EAST_WEST;
}
if (!this.isStraight) {
if (bl2 && bl4 && !bl && !bl3) {
railShape = RailShape.SOUTH_EAST;
}
if (bl2 && bl3 && !bl && !bl4) {
railShape = RailShape.SOUTH_WEST;
}
if (bl && bl3 && !bl2 && !bl4) {
railShape = RailShape.NORTH_WEST;
}
if (bl && bl4 && !bl2 && !bl3) {
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, blockPos2.above())) {
railShape = RailShape.ASCENDING_SOUTH;
}
}
if (railShape == RailShape.EAST_WEST) {
if (BaseRailBlock.isRail(this.level, blockPos4.above())) {
railShape = RailShape.ASCENDING_EAST;
}
if (BaseRailBlock.isRail(this.level, blockPos3.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 pos) {
RailState railState = this.getRail(pos);
if (railState == null) {
return false;
} else {
railState.removeSoftConnections();
return railState.canConnectTo(this);
}
}
public RailState place(boolean powered, boolean alwaysPlace, RailShape shape) {
BlockPos blockPos = this.pos.north();
BlockPos blockPos2 = this.pos.south();
BlockPos blockPos3 = this.pos.west();
BlockPos blockPos4 = this.pos.east();
boolean bl = this.hasNeighborRail(blockPos);
boolean bl2 = this.hasNeighborRail(blockPos2);
boolean bl3 = this.hasNeighborRail(blockPos3);
boolean bl4 = this.hasNeighborRail(blockPos4);
RailShape railShape = null;
boolean bl5 = bl || bl2;
boolean bl6 = bl3 || bl4;
if (bl5 && !bl6) {
railShape = RailShape.NORTH_SOUTH;
}
if (bl6 && !bl5) {
railShape = RailShape.EAST_WEST;
}
boolean bl7 = bl2 && bl4;
boolean bl8 = bl2 && bl3;
boolean bl9 = bl && bl4;
boolean bl10 = bl && bl3;
if (!this.isStraight) {
if (bl7 && !bl && !bl3) {
railShape = RailShape.SOUTH_EAST;
}
if (bl8 && !bl && !bl4) {
railShape = RailShape.SOUTH_WEST;
}
if (bl10 && !bl2 && !bl4) {
railShape = RailShape.NORTH_WEST;
}
if (bl9 && !bl2 && !bl3) {
railShape = RailShape.NORTH_EAST;
}
}
if (railShape == null) {
if (bl5 && bl6) {
railShape = shape;
} else if (bl5) {
railShape = RailShape.NORTH_SOUTH;
} else if (bl6) {
railShape = RailShape.EAST_WEST;
}
if (!this.isStraight) {
if (powered) {
if (bl7) {
railShape = RailShape.SOUTH_EAST;
}
if (bl8) {
railShape = RailShape.SOUTH_WEST;
}
if (bl9) {
railShape = RailShape.NORTH_EAST;
}
if (bl10) {
railShape = RailShape.NORTH_WEST;
}
} else {
if (bl10) {
railShape = RailShape.NORTH_WEST;
}
if (bl9) {
railShape = RailShape.NORTH_EAST;
}
if (bl8) {
railShape = RailShape.SOUTH_WEST;
}
if (bl7) {
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, blockPos2.above())) {
railShape = RailShape.ASCENDING_SOUTH;
}
}
if (railShape == RailShape.EAST_WEST) {
if (BaseRailBlock.isRail(this.level, blockPos4.above())) {
railShape = RailShape.ASCENDING_EAST;
}
if (BaseRailBlock.isRail(this.level, blockPos3.above())) {
railShape = RailShape.ASCENDING_WEST;
}
}
if (railShape == null) {
railShape = shape;
}
this.updateConnections(railShape);
this.state = this.state.setValue(this.block.getShapeProperty(), railShape);
if (alwaysPlace || 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((BlockPos)this.connections.get(i));
if (railState != null) {
railState.removeSoftConnections();
if (railState.canConnectTo(this)) {
railState.connectTo(this);
}
}
}
}
return this;
}
public BlockState getState() {
return this.state;
}
}