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 }