    001package net.minecraft.block;
    002
    003import java.util.ArrayList;
    004import java.util.List;
    005import net.minecraft.world.ChunkPosition;
    006import net.minecraft.world.World;
    007
    008public class BlockBaseRailLogic
    009{
    010    private World logicWorld;
    011    private int railX;
    012    private int railY;
    013    private int railZ;
    014    private final boolean isStraightRail;
    015
    016    /** The chunk position the rail is at. */
    017    private List railChunkPosition;
    018
    019    private final boolean canMakeSlopes;
    020
    021    final BlockRailBase theRail;
    022
    023    public BlockBaseRailLogic(BlockRailBase par1, World par2, int par3, int par4, int par5)
    024    {
    025        this.theRail = par1;
    026        this.railChunkPosition = new ArrayList();
    027        this.logicWorld = par2;
    028        this.railX = par3;
    029        this.railY = par4;
    030        this.railZ = par5;
    031        int l = par2.getBlockId(par3, par4, par5);
    032
    033        BlockRailBase target = (BlockRailBase)Block.blocksList[l];
    034        int i1 = target.getBasicRailMetadata(par2, null, par3, par4, par5);
    035        isStraightRail = !target.isFlexibleRail(par2, par3, par4, par5);
    036        canMakeSlopes = target.canMakeSlopes(par2, par3, par4, par5);
    037
    038        this.setBasicRail(i1);
    039    }
    040
    041    private void setBasicRail(int par1)
    042    {
    043        this.railChunkPosition.clear();
    044
    045        if (par1 == 0)
    046        {
    047            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1));
    048            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1));
    049        }
    050        else if (par1 == 1)
    051        {
    052            this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ));
    053            this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ));
    054        }
    055        else if (par1 == 2)
    056        {
    057            this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ));
    058            this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY + 1, this.railZ));
    059        }
    060        else if (par1 == 3)
    061        {
    062            this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY + 1, this.railZ));
    063            this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ));
    064        }
    065        else if (par1 == 4)
    066        {
    067            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY + 1, this.railZ - 1));
    068            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1));
    069        }
    070        else if (par1 == 5)
    071        {
    072            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1));
    073            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY + 1, this.railZ + 1));
    074        }
    075        else if (par1 == 6)
    076        {
    077            this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ));
    078            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1));
    079        }
    080        else if (par1 == 7)
    081        {
    082            this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ));
    083            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ + 1));
    084        }
    085        else if (par1 == 8)
    086        {
    087            this.railChunkPosition.add(new ChunkPosition(this.railX - 1, this.railY, this.railZ));
    088            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1));
    089        }
    090        else if (par1 == 9)
    091        {
    092            this.railChunkPosition.add(new ChunkPosition(this.railX + 1, this.railY, this.railZ));
    093            this.railChunkPosition.add(new ChunkPosition(this.railX, this.railY, this.railZ - 1));
    094        }
    095    }
    096
    097    private void refreshConnectedTracks()
    098    {
    099        for (int i = 0; i < this.railChunkPosition.size(); ++i)
    100        {
    101            BlockBaseRailLogic blockbaseraillogic = this.getRailLogic((ChunkPosition)this.railChunkPosition.get(i));
    102
    103            if (blockbaseraillogic != null && blockbaseraillogic.isRailChunkPositionCorrect(this))
    104            {
    105                this.railChunkPosition.set(i, new ChunkPosition(blockbaseraillogic.railX, blockbaseraillogic.railY, blockbaseraillogic.railZ));
    106            }
    107            else
    108            {
    109                this.railChunkPosition.remove(i--);
    110            }
    111        }
    112    }
    113
    114    private boolean isMinecartTrack(int par1, int par2, int par3)
    115    {
    116        return BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2, par3) ? true : (BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2 + 1, par3) ? true : BlockRailBase.isRailBlockAt(this.logicWorld, par1, par2 - 1, par3));
    117    }
    118
    119    private BlockBaseRailLogic getRailLogic(ChunkPosition par1ChunkPosition)
    120    {
    121        return BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y, par1ChunkPosition.z) ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y, par1ChunkPosition.z) : (BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y + 1, par1ChunkPosition.z) ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y + 1, par1ChunkPosition.z) : (BlockRailBase.isRailBlockAt(this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y - 1, par1ChunkPosition.z) ? new BlockBaseRailLogic(this.theRail, this.logicWorld, par1ChunkPosition.x, par1ChunkPosition.y - 1, par1ChunkPosition.z) : null));
    122    }
    123
    124    /**
    125     * Checks if the rail is at the chunk position it is expected to be.
    126     */
    127    private boolean isRailChunkPositionCorrect(BlockBaseRailLogic par1BlockBaseRailLogic)
    128    {
    129        for (int i = 0; i < this.railChunkPosition.size(); ++i)
    130        {
    131            ChunkPosition chunkposition = (ChunkPosition)this.railChunkPosition.get(i);
    132
    133            if (chunkposition.x == par1BlockBaseRailLogic.railX && chunkposition.z == par1BlockBaseRailLogic.railZ)
    134            {
    135                return true;
    136            }
    137        }
    138
    139        return false;
    140    }
    141
    142    private boolean isPartOfTrack(int par1, int par2, int par3)
    143    {
    144        for (int l = 0; l < this.railChunkPosition.size(); ++l)
    145        {
    146            ChunkPosition chunkposition = (ChunkPosition)this.railChunkPosition.get(l);
    147
    148            if (chunkposition.x == par1 && chunkposition.z == par3)
    149            {
    150                return true;
    151            }
    152        }
    153
    154        return false;
    155    }
    156
    157    public int getNumberOfAdjacentTracks()
    158    {
    159        int i = 0;
    160
    161        if (this.isMinecartTrack(this.railX, this.railY, this.railZ - 1))
    162        {
    163            ++i;
    164        }
    165
    166        if (this.isMinecartTrack(this.railX, this.railY, this.railZ + 1))
    167        {
    168            ++i;
    169        }
    170
    171        if (this.isMinecartTrack(this.railX - 1, this.railY, this.railZ))
    172        {
    173            ++i;
    174        }
    175
    176        if (this.isMinecartTrack(this.railX + 1, this.railY, this.railZ))
    177        {
    178            ++i;
    179        }
    180
    181        return i;
    182    }
    183
    184    private boolean canConnectTo(BlockBaseRailLogic par1BlockBaseRailLogic)
    185    {
    186        return this.isRailChunkPositionCorrect(par1BlockBaseRailLogic) ? true : (this.railChunkPosition.size() == 2 ? false : (this.railChunkPosition.isEmpty() ? true : true));
    187    }
    188
    189    private void connectToNeighbor(BlockBaseRailLogic par1BlockBaseRailLogic)
    190    {
    191        this.railChunkPosition.add(new ChunkPosition(par1BlockBaseRailLogic.railX, par1BlockBaseRailLogic.railY, par1BlockBaseRailLogic.railZ));
    192        boolean flag = this.isPartOfTrack(this.railX, this.railY, this.railZ - 1);
    193        boolean flag1 = this.isPartOfTrack(this.railX, this.railY, this.railZ + 1);
    194        boolean flag2 = this.isPartOfTrack(this.railX - 1, this.railY, this.railZ);
    195        boolean flag3 = this.isPartOfTrack(this.railX + 1, this.railY, this.railZ);
    196        byte b0 = -1;
    197
    198        if (flag || flag1)
    199        {
    200            b0 = 0;
    201        }
    202
    203        if (flag2 || flag3)
    204        {
    205            b0 = 1;
    206        }
    207
    208        if (!this.isStraightRail)
    209        {
    210            if (flag1 && flag3 && !flag && !flag2)
    211            {
    212                b0 = 6;
    213            }
    214
    215            if (flag1 && flag2 && !flag && !flag3)
    216            {
    217                b0 = 7;
    218            }
    219
    220            if (flag && flag2 && !flag1 && !flag3)
    221            {
    222                b0 = 8;
    223            }
    224
    225            if (flag && flag3 && !flag1 && !flag2)
    226            {
    227                b0 = 9;
    228            }
    229        }
    230
    231        if (b0 == 0 && canMakeSlopes)
    232        {
    233            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ - 1))
    234            {
    235                b0 = 4;
    236            }
    237
    238            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ + 1))
    239            {
    240                b0 = 5;
    241            }
    242        }
    243
    244        if (b0 == 1 && canMakeSlopes)
    245        {
    246            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX + 1, this.railY + 1, this.railZ))
    247            {
    248                b0 = 2;
    249            }
    250
    251            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX - 1, this.railY + 1, this.railZ))
    252            {
    253                b0 = 3;
    254            }
    255        }
    256
    257        if (b0 < 0)
    258        {
    259            b0 = 0;
    260        }
    261
    262        int i = b0;
    263
    264        if (this.isStraightRail)
    265        {
    266            i = this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) & 8 | b0;
    267        }
    268
    269        this.logicWorld.setBlockMetadataWithNotify(this.railX, this.railY, this.railZ, i, 3);
    270    }
    271
    272    private boolean canConnectFrom(int par1, int par2, int par3)
    273    {
    274        BlockBaseRailLogic blockbaseraillogic = this.getRailLogic(new ChunkPosition(par1, par2, par3));
    275
    276        if (blockbaseraillogic == null)
    277        {
    278            return false;
    279        }
    280        else
    281        {
    282            blockbaseraillogic.refreshConnectedTracks();
    283            return blockbaseraillogic.canConnectTo(this);
    284        }
    285    }
    286
    287    public void func_94511_a(boolean par1, boolean par2)
    288    {
    289        boolean flag2 = this.canConnectFrom(this.railX, this.railY, this.railZ - 1);
    290        boolean flag3 = this.canConnectFrom(this.railX, this.railY, this.railZ + 1);
    291        boolean flag4 = this.canConnectFrom(this.railX - 1, this.railY, this.railZ);
    292        boolean flag5 = this.canConnectFrom(this.railX + 1, this.railY, this.railZ);
    293        byte b0 = -1;
    294
    295        if ((flag2 || flag3) && !flag4 && !flag5)
    296        {
    297            b0 = 0;
    298        }
    299
    300        if ((flag4 || flag5) && !flag2 && !flag3)
    301        {
    302            b0 = 1;
    303        }
    304
    305        if (!this.isStraightRail)
    306        {
    307            if (flag3 && flag5 && !flag2 && !flag4)
    308            {
    309                b0 = 6;
    310            }
    311
    312            if (flag3 && flag4 && !flag2 && !flag5)
    313            {
    314                b0 = 7;
    315            }
    316
    317            if (flag2 && flag4 && !flag3 && !flag5)
    318            {
    319                b0 = 8;
    320            }
    321
    322            if (flag2 && flag5 && !flag3 && !flag4)
    323            {
    324                b0 = 9;
    325            }
    326        }
    327
    328        if (b0 == -1)
    329        {
    330            if (flag2 || flag3)
    331            {
    332                b0 = 0;
    333            }
    334
    335            if (flag4 || flag5)
    336            {
    337                b0 = 1;
    338            }
    339
    340            if (!this.isStraightRail)
    341            {
    342                if (par1)
    343                {
    344                    if (flag3 && flag5)
    345                    {
    346                        b0 = 6;
    347                    }
    348
    349                    if (flag4 && flag3)
    350                    {
    351                        b0 = 7;
    352                    }
    353
    354                    if (flag5 && flag2)
    355                    {
    356                        b0 = 9;
    357                    }
    358
    359                    if (flag2 && flag4)
    360                    {
    361                        b0 = 8;
    362                    }
    363                }
    364                else
    365                {
    366                    if (flag2 && flag4)
    367                    {
    368                        b0 = 8;
    369                    }
    370
    371                    if (flag5 && flag2)
    372                    {
    373                        b0 = 9;
    374                    }
    375
    376                    if (flag4 && flag3)
    377                    {
    378                        b0 = 7;
    379                    }
    380
    381                    if (flag3 && flag5)
    382                    {
    383                        b0 = 6;
    384                    }
    385                }
    386            }
    387        }
    388
    389        if (b0 == 0 && canMakeSlopes)
    390        {
    391            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ - 1))
    392            {
    393                b0 = 4;
    394            }
    395
    396            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX, this.railY + 1, this.railZ + 1))
    397            {
    398                b0 = 5;
    399            }
    400        }
    401
    402        if (b0 == 1 && canMakeSlopes)
    403        {
    404            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX + 1, this.railY + 1, this.railZ))
    405            {
    406                b0 = 2;
    407            }
    408
    409            if (BlockRailBase.isRailBlockAt(this.logicWorld, this.railX - 1, this.railY + 1, this.railZ))
    410            {
    411                b0 = 3;
    412            }
    413        }
    414
    415        if (b0 < 0)
    416        {
    417            b0 = 0;
    418        }
    419
    420        this.setBasicRail(b0);
    421        int i = b0;
    422
    423        if (this.isStraightRail)
    424        {
    425            i = this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) & 8 | b0;
    426        }
    427
    428        if (par2 || this.logicWorld.getBlockMetadata(this.railX, this.railY, this.railZ) != i)
    429        {
    430            this.logicWorld.setBlockMetadataWithNotify(this.railX, this.railY, this.railZ, i, 3);
    431
    432            for (int j = 0; j < this.railChunkPosition.size(); ++j)
    433            {
    434                BlockBaseRailLogic blockbaseraillogic = this.getRailLogic((ChunkPosition)this.railChunkPosition.get(j));
    435
    436                if (blockbaseraillogic != null)
    437                {
    438                    blockbaseraillogic.refreshConnectedTracks();
    439
    440                    if (blockbaseraillogic.canConnectTo(this))
    441                    {
    442                        blockbaseraillogic.connectToNeighbor(this);
    443                    }
    444                }
    445            }
    446        }
    447    }
    448}