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 the number of adjacent tracks
492 */
493 public static int getAdjacentTracks(RailLogic par0RailLogic)
494 {
495 return par0RailLogic.getAdjacentTracks();
496 }
497 }