    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    }