    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.List;
    006    import java.util.Random;
    007
    008    public class BlockStairs extends Block
    009    {
    010        private static final int[][] field_72159_a = new int[][] {{2, 6}, {3, 7}, {2, 3}, {6, 7}, {0, 4}, {1, 5}, {0, 1}, {4, 5}};
    011        private static final int[] field_82545_b = new int[] {1, -1, 0, 0};
    012        private static final int[] field_82546_c = new int[] {0, 0, 1, -1};
    013
    014        /** The block that is used as model for the stair. */
    015        private final Block modelBlock;
    016        private final int field_72158_c;
    017        private boolean field_72156_cr = false;
    018        private int field_72160_cs = 0;
    019
    020        protected BlockStairs(int par1, Block par2Block, int par3)
    021        {
    022            super(par1, par2Block.blockIndexInTexture, par2Block.blockMaterial);
    023            this.modelBlock = par2Block;
    024            this.field_72158_c = par3;
    025            this.setHardness(par2Block.blockHardness);
    026            this.setResistance(par2Block.blockResistance / 3.0F);
    027            this.setStepSound(par2Block.stepSound);
    028            this.setLightOpacity(255);
    029            this.setCreativeTab(CreativeTabs.tabBlock);
    030        }
    031
    032        /**
    033         * Updates the blocks bounds based on its current state. Args: world, x, y, z
    034         */
    035        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    036        {
    037            if (this.field_72156_cr)
    038            {
    039                this.setBlockBounds(0.5F * (float)(this.field_72160_cs % 2), 0.5F * (float)(this.field_72160_cs / 2 % 2), 0.5F * (float)(this.field_72160_cs / 4 % 2), 0.5F + 0.5F * (float)(this.field_72160_cs % 2), 0.5F + 0.5F * (float)(this.field_72160_cs / 2 % 2), 0.5F + 0.5F * (float)(this.field_72160_cs / 4 % 2));
    040            }
    041            else
    042            {
    043                this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    044            }
    045        }
    046
    047        /**
    048         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    049         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    050         */
    051        public boolean isOpaqueCube()
    052        {
    053            return false;
    054        }
    055
    056        /**
    057         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    058         */
    059        public boolean renderAsNormalBlock()
    060        {
    061            return false;
    062        }
    063
    064        /**
    065         * The type of render function that is called for this block
    066         */
    067        public int getRenderType()
    068        {
    069            return 10;
    070        }
    071
    072        public void func_82541_d(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    073        {
    074            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
    075
    076            if ((var5 & 4) != 0)
    077            {
    078                this.setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F);
    079            }
    080            else
    081            {
    082                this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F);
    083            }
    084        }
    085
    086        public static boolean func_82543_e(int par0)
    087        {
    088            return par0 > 0 && Block.blocksList[par0] instanceof BlockStairs;
    089        }
    090
    091        private boolean func_82540_f(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    092        {
    093            int var6 = par1IBlockAccess.getBlockId(par2, par3, par4);
    094            return func_82543_e(var6) && par1IBlockAccess.getBlockMetadata(par2, par3, par4) == par5;
    095        }
    096
    097        public boolean func_82542_g(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    098        {
    099            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
    100            int var6 = var5 & 3;
    101            float var7 = 0.5F;
    102            float var8 = 1.0F;
    103
    104            if ((var5 & 4) != 0)
    105            {
    106                var7 = 0.0F;
    107                var8 = 0.5F;
    108            }
    109
    110            float var9 = 0.0F;
    111            float var10 = 1.0F;
    112            float var11 = 0.0F;
    113            float var12 = 0.5F;
    114            boolean var13 = true;
    115            int var14;
    116            int var15;
    117            int var16;
    118
    119            if (var6 == 0)
    120            {
    121                var9 = 0.5F;
    122                var12 = 1.0F;
    123                var14 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4);
    124                var15 = par1IBlockAccess.getBlockMetadata(par2 + 1, par3, par4);
    125
    126                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    127                {
    128                    var16 = var15 & 3;
    129
    130                    if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5))
    131                    {
    132                        var12 = 0.5F;
    133                        var13 = false;
    134                    }
    135                    else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5))
    136                    {
    137                        var11 = 0.5F;
    138                        var13 = false;
    139                    }
    140                }
    141            }
    142            else if (var6 == 1)
    143            {
    144                var10 = 0.5F;
    145                var12 = 1.0F;
    146                var14 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4);
    147                var15 = par1IBlockAccess.getBlockMetadata(par2 - 1, par3, par4);
    148
    149                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    150                {
    151                    var16 = var15 & 3;
    152
    153                    if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5))
    154                    {
    155                        var12 = 0.5F;
    156                        var13 = false;
    157                    }
    158                    else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5))
    159                    {
    160                        var11 = 0.5F;
    161                        var13 = false;
    162                    }
    163                }
    164            }
    165            else if (var6 == 2)
    166            {
    167                var11 = 0.5F;
    168                var12 = 1.0F;
    169                var14 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1);
    170                var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 + 1);
    171
    172                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    173                {
    174                    var16 = var15 & 3;
    175
    176                    if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5))
    177                    {
    178                        var10 = 0.5F;
    179                        var13 = false;
    180                    }
    181                    else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5))
    182                    {
    183                        var9 = 0.5F;
    184                        var13 = false;
    185                    }
    186                }
    187            }
    188            else if (var6 == 3)
    189            {
    190                var14 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1);
    191                var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 - 1);
    192
    193                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    194                {
    195                    var16 = var15 & 3;
    196
    197                    if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5))
    198                    {
    199                        var10 = 0.5F;
    200                        var13 = false;
    201                    }
    202                    else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5))
    203                    {
    204                        var9 = 0.5F;
    205                        var13 = false;
    206                    }
    207                }
    208            }
    209
    210            this.setBlockBounds(var9, var7, var11, var10, var8, var12);
    211            return var13;
    212        }
    213
    214        public boolean func_82544_h(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    215        {
    216            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
    217            int var6 = var5 & 3;
    218            float var7 = 0.5F;
    219            float var8 = 1.0F;
    220
    221            if ((var5 & 4) != 0)
    222            {
    223                var7 = 0.0F;
    224                var8 = 0.5F;
    225            }
    226
    227            float var9 = 0.0F;
    228            float var10 = 0.5F;
    229            float var11 = 0.5F;
    230            float var12 = 1.0F;
    231            boolean var13 = false;
    232            int var14;
    233            int var15;
    234            int var16;
    235
    236            if (var6 == 0)
    237            {
    238                var14 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4);
    239                var15 = par1IBlockAccess.getBlockMetadata(par2 - 1, par3, par4);
    240
    241                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    242                {
    243                    var16 = var15 & 3;
    244
    245                    if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5))
    246                    {
    247                        var11 = 0.0F;
    248                        var12 = 0.5F;
    249                        var13 = true;
    250                    }
    251                    else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5))
    252                    {
    253                        var11 = 0.5F;
    254                        var12 = 1.0F;
    255                        var13 = true;
    256                    }
    257                }
    258            }
    259            else if (var6 == 1)
    260            {
    261                var14 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4);
    262                var15 = par1IBlockAccess.getBlockMetadata(par2 + 1, par3, par4);
    263
    264                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    265                {
    266                    var9 = 0.5F;
    267                    var10 = 1.0F;
    268                    var16 = var15 & 3;
    269
    270                    if (var16 == 3 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 - 1, var5))
    271                    {
    272                        var11 = 0.0F;
    273                        var12 = 0.5F;
    274                        var13 = true;
    275                    }
    276                    else if (var16 == 2 && !this.func_82540_f(par1IBlockAccess, par2, par3, par4 + 1, var5))
    277                    {
    278                        var11 = 0.5F;
    279                        var12 = 1.0F;
    280                        var13 = true;
    281                    }
    282                }
    283            }
    284            else if (var6 == 2)
    285            {
    286                var14 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1);
    287                var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 - 1);
    288
    289                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    290                {
    291                    var11 = 0.0F;
    292                    var12 = 0.5F;
    293                    var16 = var15 & 3;
    294
    295                    if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5))
    296                    {
    297                        var13 = true;
    298                    }
    299                    else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5))
    300                    {
    301                        var9 = 0.5F;
    302                        var10 = 1.0F;
    303                        var13 = true;
    304                    }
    305                }
    306            }
    307            else if (var6 == 3)
    308            {
    309                var14 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1);
    310                var15 = par1IBlockAccess.getBlockMetadata(par2, par3, par4 + 1);
    311
    312                if (func_82543_e(var14) && (var5 & 4) == (var15 & 4))
    313                {
    314                    var16 = var15 & 3;
    315
    316                    if (var16 == 1 && !this.func_82540_f(par1IBlockAccess, par2 - 1, par3, par4, var5))
    317                    {
    318                        var13 = true;
    319                    }
    320                    else if (var16 == 0 && !this.func_82540_f(par1IBlockAccess, par2 + 1, par3, par4, var5))
    321                    {
    322                        var9 = 0.5F;
    323                        var10 = 1.0F;
    324                        var13 = true;
    325                    }
    326                }
    327            }
    328
    329            if (var13)
    330            {
    331                this.setBlockBounds(var9, var7, var11, var10, var8, var12);
    332            }
    333
    334            return var13;
    335        }
    336
    337        /**
    338         * if the specified block is in the given AABB, add its collision bounding box to the given list
    339         */
    340        public void addCollidingBlockToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
    341        {
    342            this.func_82541_d(par1World, par2, par3, par4);
    343            super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    344            boolean var8 = this.func_82542_g(par1World, par2, par3, par4);
    345            super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    346
    347            if (var8 && this.func_82544_h(par1World, par2, par3, par4))
    348            {
    349                super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    350            }
    351
    352            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    353        }
    354
    355        @SideOnly(Side.CLIENT)
    356
    357        /**
    358         * A randomly called display update to be able to add particles or other items for display
    359         */
    360        public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
    361        {
    362            this.modelBlock.randomDisplayTick(par1World, par2, par3, par4, par5Random);
    363        }
    364
    365        /**
    366         * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
    367         */
    368        public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
    369        {
    370            this.modelBlock.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer);
    371        }
    372
    373        /**
    374         * Called right before the block is destroyed by a player.  Args: world, x, y, z, metaData
    375         */
    376        public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5)
    377        {
    378            this.modelBlock.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5);
    379        }
    380
    381        @SideOnly(Side.CLIENT)
    382
    383        /**
    384         * Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy computing for Fluids
    385         */
    386        public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    387        {
    388            return this.modelBlock.getMixedBrightnessForBlock(par1IBlockAccess, par2, par3, par4);
    389        }
    390
    391        @SideOnly(Side.CLIENT)
    392
    393        /**
    394         * How bright to render this block based on the light its receiving. Args: iBlockAccess, x, y, z
    395         */
    396        public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    397        {
    398            return this.modelBlock.getBlockBrightness(par1IBlockAccess, par2, par3, par4);
    399        }
    400
    401        /**
    402         * Returns how much this block can resist explosions from the passed in entity.
    403         */
    404        public float getExplosionResistance(Entity par1Entity)
    405        {
    406            return this.modelBlock.getExplosionResistance(par1Entity);
    407        }
    408
    409        /**
    410         * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
    411         */
    412        public int getBlockTextureFromSideAndMetadata(int par1, int par2)
    413        {
    414            return this.modelBlock.getBlockTextureFromSideAndMetadata(par1, this.field_72158_c);
    415        }
    416
    417        /**
    418         * Returns the block texture based on the side being looked at.  Args: side
    419         */
    420        public int getBlockTextureFromSide(int par1)
    421        {
    422            return this.modelBlock.getBlockTextureFromSideAndMetadata(par1, this.field_72158_c);
    423        }
    424
    425        @SideOnly(Side.CLIENT)
    426
    427        /**
    428         * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
    429         */
    430        public int getRenderBlockPass()
    431        {
    432            return this.modelBlock.getRenderBlockPass();
    433        }
    434
    435        /**
    436         * How many world ticks before ticking
    437         */
    438        public int tickRate()
    439        {
    440            return this.modelBlock.tickRate();
    441        }
    442
    443        @SideOnly(Side.CLIENT)
    444
    445        /**
    446         * Returns the bounding box of the wired rectangular prism to render.
    447         */
    448        public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    449        {
    450            return this.modelBlock.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4);
    451        }
    452
    453        /**
    454         * Can add to the passed in vector for a movement vector to be applied to the entity. Args: x, y, z, entity, vec3d
    455         */
    456        public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3)
    457        {
    458            this.modelBlock.velocityToAddToEntity(par1World, par2, par3, par4, par5Entity, par6Vec3);
    459        }
    460
    461        /**
    462         * Returns if this block is collidable (only used by Fire). Args: x, y, z
    463         */
    464        public boolean isCollidable()
    465        {
    466            return this.modelBlock.isCollidable();
    467        }
    468
    469        /**
    470         * Returns whether this block is collideable based on the arguments passed in Args: blockMetaData, unknownFlag
    471         */
    472        public boolean canCollideCheck(int par1, boolean par2)
    473        {
    474            return this.modelBlock.canCollideCheck(par1, par2);
    475        }
    476
    477        /**
    478         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    479         */
    480        public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    481        {
    482            return this.modelBlock.canPlaceBlockAt(par1World, par2, par3, par4);
    483        }
    484
    485        /**
    486         * Called whenever the block is added into the world. Args: world, x, y, z
    487         */
    488        public void onBlockAdded(World par1World, int par2, int par3, int par4)
    489        {
    490            this.onNeighborBlockChange(par1World, par2, par3, par4, 0);
    491            this.modelBlock.onBlockAdded(par1World, par2, par3, par4);
    492        }
    493
    494        /**
    495         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
    496         */
    497        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    498        {
    499            this.modelBlock.breakBlock(par1World, par2, par3, par4, par5, par6);
    500        }
    501
    502        /**
    503         * Called whenever an entity is walking on top of this block. Args: world, x, y, z, entity
    504         */
    505        public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity)
    506        {
    507            this.modelBlock.onEntityWalking(par1World, par2, par3, par4, par5Entity);
    508        }
    509
    510        /**
    511         * Ticks the block if it's been scheduled
    512         */
    513        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    514        {
    515            this.modelBlock.updateTick(par1World, par2, par3, par4, par5Random);
    516        }
    517
    518        /**
    519         * Called upon block activation (right click on the block.)
    520         */
    521        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    522        {
    523            return this.modelBlock.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F);
    524        }
    525
    526        /**
    527         * Called upon the block being destroyed by an explosion
    528         */
    529        public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4)
    530        {
    531            this.modelBlock.onBlockDestroyedByExplosion(par1World, par2, par3, par4);
    532        }
    533
    534        /**
    535         * Called when the block is placed in the world.
    536         */
    537        public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    538        {
    539            int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
    540            int var7 = par1World.getBlockMetadata(par2, par3, par4) & 4;
    541
    542            if (var6 == 0)
    543            {
    544                par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | var7);
    545            }
    546
    547            if (var6 == 1)
    548            {
    549                par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | var7);
    550            }
    551
    552            if (var6 == 2)
    553            {
    554                par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | var7);
    555            }
    556
    557            if (var6 == 3)
    558            {
    559                par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | var7);
    560            }
    561        }
    562
    563        /**
    564         * called before onBlockPlacedBy by ItemBlock and ItemReed
    565         */
    566        public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
    567        {
    568            if (par5 == 0 || par5 != 1 && (double)par7 > 0.5D)
    569            {
    570                int var9 = par1World.getBlockMetadata(par2, par3, par4);
    571                par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 | 4);
    572            }
    573        }
    574
    575        /**
    576         * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
    577         * x, y, z, startVec, endVec
    578         */
    579        public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
    580        {
    581            MovingObjectPosition[] var7 = new MovingObjectPosition[8];
    582            int var8 = par1World.getBlockMetadata(par2, par3, par4);
    583            int var9 = var8 & 3;
    584            boolean var10 = (var8 & 4) == 4;
    585            int[] var11 = field_72159_a[var9 + (var10 ? 4 : 0)];
    586            this.field_72156_cr = true;
    587            int var14;
    588            int var15;
    589            int var16;
    590
    591            for (int var12 = 0; var12 < 8; ++var12)
    592            {
    593                this.field_72160_cs = var12;
    594                int[] var13 = var11;
    595                var14 = var11.length;
    596
    597                for (var15 = 0; var15 < var14; ++var15)
    598                {
    599                    var16 = var13[var15];
    600
    601                    if (var16 == var12)
    602                    {
    603                        ;
    604                    }
    605                }
    606
    607                var7[var12] = super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
    608            }
    609
    610            int[] var21 = var11;
    611            int var24 = var11.length;
    612
    613            for (var14 = 0; var14 < var24; ++var14)
    614            {
    615                var15 = var21[var14];
    616                var7[var15] = null;
    617            }
    618
    619            MovingObjectPosition var23 = null;
    620            double var22 = 0.0D;
    621            MovingObjectPosition[] var25 = var7;
    622            var16 = var7.length;
    623
    624            for (int var17 = 0; var17 < var16; ++var17)
    625            {
    626                MovingObjectPosition var18 = var25[var17];
    627
    628                if (var18 != null)
    629                {
    630                    double var19 = var18.hitVec.squareDistanceTo(par6Vec3);
    631
    632                    if (var19 > var22)
    633                    {
    634                        var23 = var18;
    635                        var22 = var19;
    636                    }
    637                }
    638            }
    639
    640            return var23;
    641        }
    642    }