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

354 lines
12 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
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<BlockPos> 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<BlockPos> 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;
}
}