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 }