335 lines
12 KiB
Java
335 lines
12 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* com.google.common.collect.Lists
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
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.BaseRailBlock;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.properties.RailShape;
|
|
import org.jspecify.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.newArrayList();
|
|
|
|
public RailState(Level level, BlockPos pos, BlockState state) {
|
|
this.level = level;
|
|
this.pos = pos;
|
|
this.state = state;
|
|
this.block = (BaseRailBlock)state.getBlock();
|
|
RailShape direction = state.getValue(this.block.getShapeProperty());
|
|
this.isStraight = this.block.isStraight();
|
|
this.updateConnections(direction);
|
|
}
|
|
|
|
public List<BlockPos> getConnections() {
|
|
return this.connections;
|
|
}
|
|
|
|
private void updateConnections(RailShape direction) {
|
|
this.connections.clear();
|
|
switch (direction) {
|
|
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 rail = this.getRail(this.connections.get(i));
|
|
if (rail == null || !rail.connectsTo(this)) {
|
|
this.connections.remove(i--);
|
|
continue;
|
|
}
|
|
this.connections.set(i, rail.pos);
|
|
}
|
|
}
|
|
|
|
private boolean hasRail(BlockPos pos) {
|
|
return BaseRailBlock.isRail(this.level, pos) || BaseRailBlock.isRail(this.level, pos.above()) || BaseRailBlock.isRail(this.level, pos.below());
|
|
}
|
|
|
|
private @Nullable RailState getRail(BlockPos pos) {
|
|
BlockPos testPos = pos;
|
|
BlockState testState = this.level.getBlockState(testPos);
|
|
if (BaseRailBlock.isRail(testState)) {
|
|
return new RailState(this.level, testPos, testState);
|
|
}
|
|
testPos = pos.above();
|
|
testState = this.level.getBlockState(testPos);
|
|
if (BaseRailBlock.isRail(testState)) {
|
|
return new RailState(this.level, testPos, testState);
|
|
}
|
|
testPos = pos.below();
|
|
testState = this.level.getBlockState(testPos);
|
|
if (BaseRailBlock.isRail(testState)) {
|
|
return new RailState(this.level, testPos, testState);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private boolean connectsTo(RailState rail) {
|
|
return this.hasConnection(rail.pos);
|
|
}
|
|
|
|
private boolean hasConnection(BlockPos railPos) {
|
|
for (int i = 0; i < this.connections.size(); ++i) {
|
|
BlockPos pos = this.connections.get(i);
|
|
if (pos.getX() != railPos.getX() || pos.getZ() != railPos.getZ()) continue;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected int countPotentialConnections() {
|
|
int count = 0;
|
|
for (Direction direction : Direction.Plane.HORIZONTAL) {
|
|
if (!this.hasRail(this.pos.relative(direction))) continue;
|
|
++count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
private boolean canConnectTo(RailState rail) {
|
|
return this.connectsTo(rail) || this.connections.size() != 2;
|
|
}
|
|
|
|
private void connectTo(RailState rail) {
|
|
this.connections.add(rail.pos);
|
|
BlockPos north = this.pos.north();
|
|
BlockPos south = this.pos.south();
|
|
BlockPos west = this.pos.west();
|
|
BlockPos east = this.pos.east();
|
|
boolean n = this.hasConnection(north);
|
|
boolean s = this.hasConnection(south);
|
|
boolean w = this.hasConnection(west);
|
|
boolean e = this.hasConnection(east);
|
|
RailShape shape = null;
|
|
if (n || s) {
|
|
shape = RailShape.NORTH_SOUTH;
|
|
}
|
|
if (w || e) {
|
|
shape = RailShape.EAST_WEST;
|
|
}
|
|
if (!this.isStraight) {
|
|
if (s && e && !n && !w) {
|
|
shape = RailShape.SOUTH_EAST;
|
|
}
|
|
if (s && w && !n && !e) {
|
|
shape = RailShape.SOUTH_WEST;
|
|
}
|
|
if (n && w && !s && !e) {
|
|
shape = RailShape.NORTH_WEST;
|
|
}
|
|
if (n && e && !s && !w) {
|
|
shape = RailShape.NORTH_EAST;
|
|
}
|
|
}
|
|
if (shape == RailShape.NORTH_SOUTH) {
|
|
if (BaseRailBlock.isRail(this.level, north.above())) {
|
|
shape = RailShape.ASCENDING_NORTH;
|
|
}
|
|
if (BaseRailBlock.isRail(this.level, south.above())) {
|
|
shape = RailShape.ASCENDING_SOUTH;
|
|
}
|
|
}
|
|
if (shape == RailShape.EAST_WEST) {
|
|
if (BaseRailBlock.isRail(this.level, east.above())) {
|
|
shape = RailShape.ASCENDING_EAST;
|
|
}
|
|
if (BaseRailBlock.isRail(this.level, west.above())) {
|
|
shape = RailShape.ASCENDING_WEST;
|
|
}
|
|
}
|
|
if (shape == null) {
|
|
shape = RailShape.NORTH_SOUTH;
|
|
}
|
|
this.state = (BlockState)this.state.setValue(this.block.getShapeProperty(), shape);
|
|
this.level.setBlock(this.pos, this.state, 3);
|
|
}
|
|
|
|
private boolean hasNeighborRail(BlockPos railPos) {
|
|
RailState neighbor = this.getRail(railPos);
|
|
if (neighbor == null) {
|
|
return false;
|
|
}
|
|
neighbor.removeSoftConnections();
|
|
return neighbor.canConnectTo(this);
|
|
}
|
|
|
|
public RailState place(boolean hasSignal, boolean first, RailShape defaultShape) {
|
|
boolean northAndWest;
|
|
boolean westOrEast;
|
|
BlockPos north = this.pos.north();
|
|
BlockPos south = this.pos.south();
|
|
BlockPos west = this.pos.west();
|
|
BlockPos east = this.pos.east();
|
|
boolean n = this.hasNeighborRail(north);
|
|
boolean s = this.hasNeighborRail(south);
|
|
boolean w = this.hasNeighborRail(west);
|
|
boolean e = this.hasNeighborRail(east);
|
|
RailShape shape = null;
|
|
boolean northOrSouth = n || s;
|
|
boolean bl = westOrEast = w || e;
|
|
if (northOrSouth && !westOrEast) {
|
|
shape = RailShape.NORTH_SOUTH;
|
|
}
|
|
if (westOrEast && !northOrSouth) {
|
|
shape = RailShape.EAST_WEST;
|
|
}
|
|
boolean southAndEast = s && e;
|
|
boolean southAndWest = s && w;
|
|
boolean northAndEast = n && e;
|
|
boolean bl2 = northAndWest = n && w;
|
|
if (!this.isStraight) {
|
|
if (southAndEast && !n && !w) {
|
|
shape = RailShape.SOUTH_EAST;
|
|
}
|
|
if (southAndWest && !n && !e) {
|
|
shape = RailShape.SOUTH_WEST;
|
|
}
|
|
if (northAndWest && !s && !e) {
|
|
shape = RailShape.NORTH_WEST;
|
|
}
|
|
if (northAndEast && !s && !w) {
|
|
shape = RailShape.NORTH_EAST;
|
|
}
|
|
}
|
|
if (shape == null) {
|
|
if (northOrSouth && westOrEast) {
|
|
shape = defaultShape;
|
|
} else if (northOrSouth) {
|
|
shape = RailShape.NORTH_SOUTH;
|
|
} else if (westOrEast) {
|
|
shape = RailShape.EAST_WEST;
|
|
}
|
|
if (!this.isStraight) {
|
|
if (hasSignal) {
|
|
if (southAndEast) {
|
|
shape = RailShape.SOUTH_EAST;
|
|
}
|
|
if (southAndWest) {
|
|
shape = RailShape.SOUTH_WEST;
|
|
}
|
|
if (northAndEast) {
|
|
shape = RailShape.NORTH_EAST;
|
|
}
|
|
if (northAndWest) {
|
|
shape = RailShape.NORTH_WEST;
|
|
}
|
|
} else {
|
|
if (northAndWest) {
|
|
shape = RailShape.NORTH_WEST;
|
|
}
|
|
if (northAndEast) {
|
|
shape = RailShape.NORTH_EAST;
|
|
}
|
|
if (southAndWest) {
|
|
shape = RailShape.SOUTH_WEST;
|
|
}
|
|
if (southAndEast) {
|
|
shape = RailShape.SOUTH_EAST;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (shape == RailShape.NORTH_SOUTH) {
|
|
if (BaseRailBlock.isRail(this.level, north.above())) {
|
|
shape = RailShape.ASCENDING_NORTH;
|
|
}
|
|
if (BaseRailBlock.isRail(this.level, south.above())) {
|
|
shape = RailShape.ASCENDING_SOUTH;
|
|
}
|
|
}
|
|
if (shape == RailShape.EAST_WEST) {
|
|
if (BaseRailBlock.isRail(this.level, east.above())) {
|
|
shape = RailShape.ASCENDING_EAST;
|
|
}
|
|
if (BaseRailBlock.isRail(this.level, west.above())) {
|
|
shape = RailShape.ASCENDING_WEST;
|
|
}
|
|
}
|
|
if (shape == null) {
|
|
shape = defaultShape;
|
|
}
|
|
this.updateConnections(shape);
|
|
this.state = (BlockState)this.state.setValue(this.block.getShapeProperty(), shape);
|
|
if (first || 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 neighbor = this.getRail(this.connections.get(i));
|
|
if (neighbor == null) continue;
|
|
neighbor.removeSoftConnections();
|
|
if (!neighbor.canConnectTo(this)) continue;
|
|
neighbor.connectTo(this);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public BlockState getState() {
|
|
return this.state;
|
|
}
|
|
}
|
|
|