package net.minecraft.block; import java.util.ArrayList; import java.util.List; import net.minecraft.world.ChunkPosition; import net.minecraft.world.World; public class RailLogic { /** Reference to the World object. */ private World worldObj; private int trackX; private int trackY; private int trackZ; /** * A boolean value that is true if the rail is powered, and false if its not. */ private final boolean isPoweredRail; private List connectedTracks; final BlockRail rail; private final boolean canMakeSlopes; public RailLogic(BlockRail par1BlockRail, World par2World, int par3, int par4, int par5) { this.rail = par1BlockRail; this.connectedTracks = new ArrayList(); this.worldObj = par2World; this.trackX = par3; this.trackY = par4; this.trackZ = par5; int var6 = par2World.getBlockId(par3, par4, par5); BlockRail target = (BlockRail)Block.blocksList[var6]; int var7 = target.getBasicRailMetadata(par2World, null, par3, par4, par5); isPoweredRail = !target.isFlexibleRail(par2World, par3, par4, par5); canMakeSlopes = target.canMakeSlopes(par2World, par3, par4, par5); this.setConnections(var7); } private void setConnections(int par1) { this.connectedTracks.clear(); if (par1 == 0) { this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); } else if (par1 == 1) { this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); } else if (par1 == 2) { this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY + 1, this.trackZ)); } else if (par1 == 3) { this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY + 1, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); } else if (par1 == 4) { this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY + 1, this.trackZ - 1)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); } else if (par1 == 5) { this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY + 1, this.trackZ + 1)); } else if (par1 == 6) { this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); } else if (par1 == 7) { this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); } else if (par1 == 8) { this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); } else if (par1 == 9) { this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); } } /** * Neighboring tracks have potentially been broken, so prune the connected track list */ private void refreshConnectedTracks() { for (int var1 = 0; var1 < this.connectedTracks.size(); ++var1) { RailLogic var2 = this.getMinecartTrackLogic((ChunkPosition)this.connectedTracks.get(var1)); if (var2 != null && var2.isConnectedTo(this)) { this.connectedTracks.set(var1, new ChunkPosition(var2.trackX, var2.trackY, var2.trackZ)); } else { this.connectedTracks.remove(var1--); } } } private boolean isMinecartTrack(int par1, int par2, int par3) { return BlockRail.isRailBlockAt(this.worldObj, par1, par2, par3) ? true : (BlockRail.isRailBlockAt(this.worldObj, par1, par2 + 1, par3) ? true : BlockRail.isRailBlockAt(this.worldObj, par1, par2 - 1, par3)); } private RailLogic getMinecartTrackLogic(ChunkPosition par1ChunkPosition) { return BlockRail.isRailBlockAt(this.worldObj, par1ChunkPosition.x, par1ChunkPosition.y, par1ChunkPosition.z) ? new RailLogic(this.rail, this.worldObj, par1ChunkPosition.x, par1ChunkPosition.y, par1ChunkPosition.z) : (BlockRail.isRailBlockAt(this.worldObj, par1ChunkPosition.x, par1ChunkPosition.y + 1, par1ChunkPosition.z) ? new RailLogic(this.rail, this.worldObj, par1ChunkPosition.x, par1ChunkPosition.y + 1, par1ChunkPosition.z) : (BlockRail.isRailBlockAt(this.worldObj, par1ChunkPosition.x, par1ChunkPosition.y - 1, par1ChunkPosition.z) ? new RailLogic(this.rail, this.worldObj, par1ChunkPosition.x, par1ChunkPosition.y - 1, par1ChunkPosition.z) : null)); } private boolean isConnectedTo(RailLogic par1RailLogic) { for (int var2 = 0; var2 < this.connectedTracks.size(); ++var2) { ChunkPosition var3 = (ChunkPosition)this.connectedTracks.get(var2); if (var3.x == par1RailLogic.trackX && var3.z == par1RailLogic.trackZ) { return true; } } return false; } /** * Returns true if the specified block is in the same railway. */ private boolean isInTrack(int par1, int par2, int par3) { for (int var4 = 0; var4 < this.connectedTracks.size(); ++var4) { ChunkPosition var5 = (ChunkPosition)this.connectedTracks.get(var4); if (var5.x == par1 && var5.z == par3) { return true; } } return false; } private int getAdjacentTracks() { int var1 = 0; if (this.isMinecartTrack(this.trackX, this.trackY, this.trackZ - 1)) { ++var1; } if (this.isMinecartTrack(this.trackX, this.trackY, this.trackZ + 1)) { ++var1; } if (this.isMinecartTrack(this.trackX - 1, this.trackY, this.trackZ)) { ++var1; } if (this.isMinecartTrack(this.trackX + 1, this.trackY, this.trackZ)) { ++var1; } return var1; } /** * Determines whether or not the track can bend to meet the specified rail */ private boolean canConnectTo(RailLogic par1RailLogic) { if (this.isConnectedTo(par1RailLogic)) { return true; } else if (this.connectedTracks.size() == 2) { return false; } else if (this.connectedTracks.isEmpty()) { return true; } else { ChunkPosition var2 = (ChunkPosition)this.connectedTracks.get(0); return true; } } /** * The specified neighbor has just formed a new connection, so update accordingly */ private void connectToNeighbor(RailLogic par1RailLogic) { this.connectedTracks.add(new ChunkPosition(par1RailLogic.trackX, par1RailLogic.trackY, par1RailLogic.trackZ)); boolean var2 = this.isInTrack(this.trackX, this.trackY, this.trackZ - 1); boolean var3 = this.isInTrack(this.trackX, this.trackY, this.trackZ + 1); boolean var4 = this.isInTrack(this.trackX - 1, this.trackY, this.trackZ); boolean var5 = this.isInTrack(this.trackX + 1, this.trackY, this.trackZ); byte var6 = -1; if (var2 || var3) { var6 = 0; } if (var4 || var5) { var6 = 1; } if (!this.isPoweredRail) { if (var3 && var5 && !var2 && !var4) { var6 = 6; } if (var3 && var4 && !var2 && !var5) { var6 = 7; } if (var2 && var4 && !var3 && !var5) { var6 = 8; } if (var2 && var5 && !var3 && !var4) { var6 = 9; } } if (var6 == 0 && canMakeSlopes) { if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ - 1)) { var6 = 4; } if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ + 1)) { var6 = 5; } } if (var6 == 1 && canMakeSlopes) { if (BlockRail.isRailBlockAt(this.worldObj, this.trackX + 1, this.trackY + 1, this.trackZ)) { var6 = 2; } if (BlockRail.isRailBlockAt(this.worldObj, this.trackX - 1, this.trackY + 1, this.trackZ)) { var6 = 3; } } if (var6 < 0) { var6 = 0; } int var7 = var6; if (this.isPoweredRail) { var7 = this.worldObj.getBlockMetadata(this.trackX, this.trackY, this.trackZ) & 8 | var6; } this.worldObj.setBlockMetadataWithNotify(this.trackX, this.trackY, this.trackZ, var7); } /** * Determines whether or not the target rail can connect to this rail */ private boolean canConnectFrom(int par1, int par2, int par3) { RailLogic var4 = this.getMinecartTrackLogic(new ChunkPosition(par1, par2, par3)); if (var4 == null) { return false; } else { var4.refreshConnectedTracks(); return var4.canConnectTo(this); } } /** * Completely recalculates the track shape based on neighboring tracks and power state */ public void refreshTrackShape(boolean par1, boolean par2) { boolean var3 = this.canConnectFrom(this.trackX, this.trackY, this.trackZ - 1); boolean var4 = this.canConnectFrom(this.trackX, this.trackY, this.trackZ + 1); boolean var5 = this.canConnectFrom(this.trackX - 1, this.trackY, this.trackZ); boolean var6 = this.canConnectFrom(this.trackX + 1, this.trackY, this.trackZ); byte var7 = -1; if ((var3 || var4) && !var5 && !var6) { var7 = 0; } if ((var5 || var6) && !var3 && !var4) { var7 = 1; } if (!this.isPoweredRail) { if (var4 && var6 && !var3 && !var5) { var7 = 6; } if (var4 && var5 && !var3 && !var6) { var7 = 7; } if (var3 && var5 && !var4 && !var6) { var7 = 8; } if (var3 && var6 && !var4 && !var5) { var7 = 9; } } if (var7 == -1) { if (var3 || var4) { var7 = 0; } if (var5 || var6) { var7 = 1; } if (!this.isPoweredRail) { if (par1) { if (var4 && var6) { var7 = 6; } if (var5 && var4) { var7 = 7; } if (var6 && var3) { var7 = 9; } if (var3 && var5) { var7 = 8; } } else { if (var3 && var5) { var7 = 8; } if (var6 && var3) { var7 = 9; } if (var5 && var4) { var7 = 7; } if (var4 && var6) { var7 = 6; } } } } if (var7 == 0 && canMakeSlopes) { if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ - 1)) { var7 = 4; } if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ + 1)) { var7 = 5; } } if (var7 == 1 && canMakeSlopes) { if (BlockRail.isRailBlockAt(this.worldObj, this.trackX + 1, this.trackY + 1, this.trackZ)) { var7 = 2; } if (BlockRail.isRailBlockAt(this.worldObj, this.trackX - 1, this.trackY + 1, this.trackZ)) { var7 = 3; } } if (var7 < 0) { var7 = 0; } this.setConnections(var7); int var8 = var7; if (this.isPoweredRail) { var8 = this.worldObj.getBlockMetadata(this.trackX, this.trackY, this.trackZ) & 8 | var7; } if (par2 || this.worldObj.getBlockMetadata(this.trackX, this.trackY, this.trackZ) != var8) { this.worldObj.setBlockMetadataWithNotify(this.trackX, this.trackY, this.trackZ, var8); for (int var9 = 0; var9 < this.connectedTracks.size(); ++var9) { RailLogic var10 = this.getMinecartTrackLogic((ChunkPosition)this.connectedTracks.get(var9)); if (var10 != null) { var10.refreshConnectedTracks(); if (var10.canConnectTo(this)) { var10.connectToNeighbor(this); } } } } } /** * Get the number of adjacent tracks. */ public static int getAdjacentTrackCount(RailLogic par0RailLogic) { return par0RailLogic.getAdjacentTracks(); } }