    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 getAdjacentTracks(RailLogic par0RailLogic)
    485        {
    486            return par0RailLogic.getAdjacentTracks();
    487        }
    488    }