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