001 package net.minecraft.block; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 import net.minecraft.world.ChunkPosition; 006 import net.minecraft.world.World; 007 008 public class RailLogic 009 { 010 /** Reference to the World object. */ 011 private World worldObj; 012 private int trackX; 013 private int trackY; 014 private int trackZ; 015 016 /** 017 * A boolean value that is true if the rail is powered, and false if its not. 018 */ 019 private final boolean isPoweredRail; 020 private List connectedTracks; 021 022 final BlockRail rail; 023 private final boolean canMakeSlopes; 024 025 public RailLogic(BlockRail par1BlockRail, World par2World, int par3, int par4, int par5) 026 { 027 this.rail = par1BlockRail; 028 this.connectedTracks = new ArrayList(); 029 this.worldObj = par2World; 030 this.trackX = par3; 031 this.trackY = par4; 032 this.trackZ = par5; 033 int var6 = par2World.getBlockId(par3, par4, par5); 034 035 BlockRail target = (BlockRail)Block.blocksList[var6]; 036 int var7 = target.getBasicRailMetadata(par2World, null, par3, par4, par5); 037 isPoweredRail = !target.isFlexibleRail(par2World, par3, par4, par5); 038 canMakeSlopes = target.canMakeSlopes(par2World, par3, par4, par5); 039 this.setConnections(var7); 040 } 041 042 private void setConnections(int par1) 043 { 044 this.connectedTracks.clear(); 045 046 if (par1 == 0) 047 { 048 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); 049 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); 050 } 051 else if (par1 == 1) 052 { 053 this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); 054 this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); 055 } 056 else if (par1 == 2) 057 { 058 this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); 059 this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY + 1, this.trackZ)); 060 } 061 else if (par1 == 3) 062 { 063 this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY + 1, this.trackZ)); 064 this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); 065 } 066 else if (par1 == 4) 067 { 068 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY + 1, this.trackZ - 1)); 069 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); 070 } 071 else if (par1 == 5) 072 { 073 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); 074 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY + 1, this.trackZ + 1)); 075 } 076 else if (par1 == 6) 077 { 078 this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); 079 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); 080 } 081 else if (par1 == 7) 082 { 083 this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); 084 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ + 1)); 085 } 086 else if (par1 == 8) 087 { 088 this.connectedTracks.add(new ChunkPosition(this.trackX - 1, this.trackY, this.trackZ)); 089 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); 090 } 091 else if (par1 == 9) 092 { 093 this.connectedTracks.add(new ChunkPosition(this.trackX + 1, this.trackY, this.trackZ)); 094 this.connectedTracks.add(new ChunkPosition(this.trackX, this.trackY, this.trackZ - 1)); 095 } 096 } 097 098 /** 099 * Neighboring tracks have potentially been broken, so prune the connected track list 100 */ 101 private void refreshConnectedTracks() 102 { 103 for (int var1 = 0; var1 < this.connectedTracks.size(); ++var1) 104 { 105 RailLogic var2 = this.getMinecartTrackLogic((ChunkPosition)this.connectedTracks.get(var1)); 106 107 if (var2 != null && var2.isConnectedTo(this)) 108 { 109 this.connectedTracks.set(var1, new ChunkPosition(var2.trackX, var2.trackY, var2.trackZ)); 110 } 111 else 112 { 113 this.connectedTracks.remove(var1--); 114 } 115 } 116 } 117 118 private boolean isMinecartTrack(int par1, int par2, int par3) 119 { 120 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)); 121 } 122 123 private RailLogic getMinecartTrackLogic(ChunkPosition par1ChunkPosition) 124 { 125 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)); 126 } 127 128 private boolean isConnectedTo(RailLogic par1RailLogic) 129 { 130 for (int var2 = 0; var2 < this.connectedTracks.size(); ++var2) 131 { 132 ChunkPosition var3 = (ChunkPosition)this.connectedTracks.get(var2); 133 134 if (var3.x == par1RailLogic.trackX && var3.z == par1RailLogic.trackZ) 135 { 136 return true; 137 } 138 } 139 140 return false; 141 } 142 143 /** 144 * Returns true if the specified block is in the same railway. 145 */ 146 private boolean isInTrack(int par1, int par2, int par3) 147 { 148 for (int var4 = 0; var4 < this.connectedTracks.size(); ++var4) 149 { 150 ChunkPosition var5 = (ChunkPosition)this.connectedTracks.get(var4); 151 152 if (var5.x == par1 && var5.z == par3) 153 { 154 return true; 155 } 156 } 157 158 return false; 159 } 160 161 private int getAdjacentTracks() 162 { 163 int var1 = 0; 164 165 if (this.isMinecartTrack(this.trackX, this.trackY, this.trackZ - 1)) 166 { 167 ++var1; 168 } 169 170 if (this.isMinecartTrack(this.trackX, this.trackY, this.trackZ + 1)) 171 { 172 ++var1; 173 } 174 175 if (this.isMinecartTrack(this.trackX - 1, this.trackY, this.trackZ)) 176 { 177 ++var1; 178 } 179 180 if (this.isMinecartTrack(this.trackX + 1, this.trackY, this.trackZ)) 181 { 182 ++var1; 183 } 184 185 return var1; 186 } 187 188 /** 189 * Determines whether or not the track can bend to meet the specified rail 190 */ 191 private boolean canConnectTo(RailLogic par1RailLogic) 192 { 193 if (this.isConnectedTo(par1RailLogic)) 194 { 195 return true; 196 } 197 else if (this.connectedTracks.size() == 2) 198 { 199 return false; 200 } 201 else if (this.connectedTracks.isEmpty()) 202 { 203 return true; 204 } 205 else 206 { 207 ChunkPosition var2 = (ChunkPosition)this.connectedTracks.get(0); 208 return true; 209 } 210 } 211 212 /** 213 * The specified neighbor has just formed a new connection, so update accordingly 214 */ 215 private void connectToNeighbor(RailLogic par1RailLogic) 216 { 217 this.connectedTracks.add(new ChunkPosition(par1RailLogic.trackX, par1RailLogic.trackY, par1RailLogic.trackZ)); 218 boolean var2 = this.isInTrack(this.trackX, this.trackY, this.trackZ - 1); 219 boolean var3 = this.isInTrack(this.trackX, this.trackY, this.trackZ + 1); 220 boolean var4 = this.isInTrack(this.trackX - 1, this.trackY, this.trackZ); 221 boolean var5 = this.isInTrack(this.trackX + 1, this.trackY, this.trackZ); 222 byte var6 = -1; 223 224 if (var2 || var3) 225 { 226 var6 = 0; 227 } 228 229 if (var4 || var5) 230 { 231 var6 = 1; 232 } 233 234 if (!this.isPoweredRail) 235 { 236 if (var3 && var5 && !var2 && !var4) 237 { 238 var6 = 6; 239 } 240 241 if (var3 && var4 && !var2 && !var5) 242 { 243 var6 = 7; 244 } 245 246 if (var2 && var4 && !var3 && !var5) 247 { 248 var6 = 8; 249 } 250 251 if (var2 && var5 && !var3 && !var4) 252 { 253 var6 = 9; 254 } 255 } 256 257 if (var6 == 0 && canMakeSlopes) 258 { 259 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ - 1)) 260 { 261 var6 = 4; 262 } 263 264 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ + 1)) 265 { 266 var6 = 5; 267 } 268 } 269 270 if (var6 == 1 && canMakeSlopes) 271 { 272 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX + 1, this.trackY + 1, this.trackZ)) 273 { 274 var6 = 2; 275 } 276 277 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX - 1, this.trackY + 1, this.trackZ)) 278 { 279 var6 = 3; 280 } 281 } 282 283 if (var6 < 0) 284 { 285 var6 = 0; 286 } 287 288 int var7 = var6; 289 290 if (this.isPoweredRail) 291 { 292 var7 = this.worldObj.getBlockMetadata(this.trackX, this.trackY, this.trackZ) & 8 | var6; 293 } 294 295 this.worldObj.setBlockMetadataWithNotify(this.trackX, this.trackY, this.trackZ, var7); 296 } 297 298 /** 299 * Determines whether or not the target rail can connect to this rail 300 */ 301 private boolean canConnectFrom(int par1, int par2, int par3) 302 { 303 RailLogic var4 = this.getMinecartTrackLogic(new ChunkPosition(par1, par2, par3)); 304 305 if (var4 == null) 306 { 307 return false; 308 } 309 else 310 { 311 var4.refreshConnectedTracks(); 312 return var4.canConnectTo(this); 313 } 314 } 315 316 /** 317 * Completely recalculates the track shape based on neighboring tracks and power state 318 */ 319 public void refreshTrackShape(boolean par1, boolean par2) 320 { 321 boolean var3 = this.canConnectFrom(this.trackX, this.trackY, this.trackZ - 1); 322 boolean var4 = this.canConnectFrom(this.trackX, this.trackY, this.trackZ + 1); 323 boolean var5 = this.canConnectFrom(this.trackX - 1, this.trackY, this.trackZ); 324 boolean var6 = this.canConnectFrom(this.trackX + 1, this.trackY, this.trackZ); 325 byte var7 = -1; 326 327 if ((var3 || var4) && !var5 && !var6) 328 { 329 var7 = 0; 330 } 331 332 if ((var5 || var6) && !var3 && !var4) 333 { 334 var7 = 1; 335 } 336 337 if (!this.isPoweredRail) 338 { 339 if (var4 && var6 && !var3 && !var5) 340 { 341 var7 = 6; 342 } 343 344 if (var4 && var5 && !var3 && !var6) 345 { 346 var7 = 7; 347 } 348 349 if (var3 && var5 && !var4 && !var6) 350 { 351 var7 = 8; 352 } 353 354 if (var3 && var6 && !var4 && !var5) 355 { 356 var7 = 9; 357 } 358 } 359 360 if (var7 == -1) 361 { 362 if (var3 || var4) 363 { 364 var7 = 0; 365 } 366 367 if (var5 || var6) 368 { 369 var7 = 1; 370 } 371 372 if (!this.isPoweredRail) 373 { 374 if (par1) 375 { 376 if (var4 && var6) 377 { 378 var7 = 6; 379 } 380 381 if (var5 && var4) 382 { 383 var7 = 7; 384 } 385 386 if (var6 && var3) 387 { 388 var7 = 9; 389 } 390 391 if (var3 && var5) 392 { 393 var7 = 8; 394 } 395 } 396 else 397 { 398 if (var3 && var5) 399 { 400 var7 = 8; 401 } 402 403 if (var6 && var3) 404 { 405 var7 = 9; 406 } 407 408 if (var5 && var4) 409 { 410 var7 = 7; 411 } 412 413 if (var4 && var6) 414 { 415 var7 = 6; 416 } 417 } 418 } 419 } 420 421 if (var7 == 0 && canMakeSlopes) 422 { 423 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ - 1)) 424 { 425 var7 = 4; 426 } 427 428 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX, this.trackY + 1, this.trackZ + 1)) 429 { 430 var7 = 5; 431 } 432 } 433 434 if (var7 == 1 && canMakeSlopes) 435 { 436 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX + 1, this.trackY + 1, this.trackZ)) 437 { 438 var7 = 2; 439 } 440 441 if (BlockRail.isRailBlockAt(this.worldObj, this.trackX - 1, this.trackY + 1, this.trackZ)) 442 { 443 var7 = 3; 444 } 445 } 446 447 if (var7 < 0) 448 { 449 var7 = 0; 450 } 451 452 this.setConnections(var7); 453 int var8 = var7; 454 455 if (this.isPoweredRail) 456 { 457 var8 = this.worldObj.getBlockMetadata(this.trackX, this.trackY, this.trackZ) & 8 | var7; 458 } 459 460 if (par2 || this.worldObj.getBlockMetadata(this.trackX, this.trackY, this.trackZ) != var8) 461 { 462 this.worldObj.setBlockMetadataWithNotify(this.trackX, this.trackY, this.trackZ, var8); 463 464 for (int var9 = 0; var9 < this.connectedTracks.size(); ++var9) 465 { 466 RailLogic var10 = this.getMinecartTrackLogic((ChunkPosition)this.connectedTracks.get(var9)); 467 468 if (var10 != null) 469 { 470 var10.refreshConnectedTracks(); 471 472 if (var10.canConnectTo(this)) 473 { 474 var10.connectToNeighbor(this); 475 } 476 } 477 } 478 } 479 } 480 481 /** 482 * Get the number of adjacent tracks. 483 */ 484 public static int getAdjacentTrackCount(RailLogic par0RailLogic) 485 { 486 return par0RailLogic.getAdjacentTracks(); 487 } 488 }