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