    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    }