352 lines
9 KiB
Java
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;
|
|
}
|
|
}
|