    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
    012        /** The block that is used as model for the stair. */
    013        private final Block modelBlock;
    014        private final int field_72158_c;
    015        private boolean field_72156_cr = false;
    016        private int field_72160_cs = 0;
    017
    018        protected BlockStairs(int par1, Block par2Block, int par3)
    019        {
    020            super(par1, par2Block.blockIndexInTexture, par2Block.blockMaterial);
    021            this.modelBlock = par2Block;
    022            this.field_72158_c = par3;
    023            this.setHardness(par2Block.blockHardness);
    024            this.setResistance(par2Block.blockResistance / 3.0F);
    025            this.setStepSound(par2Block.stepSound);
    026            this.setLightOpacity(255);
    027            this.setCreativeTab(CreativeTabs.tabBlock);
    028        }
    029
    030        /**
    031         * Updates the blocks bounds based on its current state. Args: world, x, y, z
    032         */
    033        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    034        {
    035            if (this.field_72156_cr)
    036            {
    037                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));
    038            }
    039            else
    040            {
    041                this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    042            }
    043        }
    044
    045        /**
    046         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    047         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    048         */
    049        public boolean isOpaqueCube()
    050        {
    051            return false;
    052        }
    053
    054        /**
    055         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    056         */
    057        public boolean renderAsNormalBlock()
    058        {
    059            return false;
    060        }
    061
    062        /**
    063         * The type of render function that is called for this block
    064         */
    065        public int getRenderType()
    066        {
    067            return 10;
    068        }
    069
    070        /**
    071         * if the specified block is in the given AABB, add its collision bounding box to the given list
    072         */
    073        public void addCollidingBlockToList(World par1World, int par2, int par3, int par4, AxisAlignedBB par5AxisAlignedBB, List par6List, Entity par7Entity)
    074        {
    075            int var8 = par1World.getBlockMetadata(par2, par3, par4);
    076            int var9 = var8 & 3;
    077            float var10 = 0.0F;
    078            float var11 = 0.5F;
    079            float var12 = 0.5F;
    080            float var13 = 1.0F;
    081
    082            if ((var8 & 4) != 0)
    083            {
    084                var10 = 0.5F;
    085                var11 = 1.0F;
    086                var12 = 0.0F;
    087                var13 = 0.5F;
    088            }
    089
    090            this.setBlockBounds(0.0F, var10, 0.0F, 1.0F, var11, 1.0F);
    091            super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    092
    093            if (var9 == 0)
    094            {
    095                this.setBlockBounds(0.5F, var12, 0.0F, 1.0F, var13, 1.0F);
    096                super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    097            }
    098            else if (var9 == 1)
    099            {
    100                this.setBlockBounds(0.0F, var12, 0.0F, 0.5F, var13, 1.0F);
    101                super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    102            }
    103            else if (var9 == 2)
    104            {
    105                this.setBlockBounds(0.0F, var12, 0.5F, 1.0F, var13, 1.0F);
    106                super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    107            }
    108            else if (var9 == 3)
    109            {
    110                this.setBlockBounds(0.0F, var12, 0.0F, 1.0F, var13, 0.5F);
    111                super.addCollidingBlockToList(par1World, par2, par3, par4, par5AxisAlignedBB, par6List, par7Entity);
    112            }
    113
    114            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    115        }
    116
    117        @SideOnly(Side.CLIENT)
    118
    119        /**
    120         * A randomly called display update to be able to add particles or other items for display
    121         */
    122        public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
    123        {
    124            this.modelBlock.randomDisplayTick(par1World, par2, par3, par4, par5Random);
    125        }
    126
    127        /**
    128         * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
    129         */
    130        public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
    131        {
    132            this.modelBlock.onBlockClicked(par1World, par2, par3, par4, par5EntityPlayer);
    133        }
    134
    135        /**
    136         * Called right before the block is destroyed by a player.  Args: world, x, y, z, metaData
    137         */
    138        public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5)
    139        {
    140            this.modelBlock.onBlockDestroyedByPlayer(par1World, par2, par3, par4, par5);
    141        }
    142
    143        @SideOnly(Side.CLIENT)
    144
    145        /**
    146         * Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy computing for Fluids
    147         */
    148        public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    149        {
    150            return this.modelBlock.getMixedBrightnessForBlock(par1IBlockAccess, par2, par3, par4);
    151        }
    152
    153        @SideOnly(Side.CLIENT)
    154
    155        /**
    156         * How bright to render this block based on the light its receiving. Args: iBlockAccess, x, y, z
    157         */
    158        public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    159        {
    160            return this.modelBlock.getBlockBrightness(par1IBlockAccess, par2, par3, par4);
    161        }
    162
    163        /**
    164         * Returns how much this block can resist explosions from the passed in entity.
    165         */
    166        public float getExplosionResistance(Entity par1Entity)
    167        {
    168            return this.modelBlock.getExplosionResistance(par1Entity);
    169        }
    170
    171        /**
    172         * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
    173         */
    174        public int getBlockTextureFromSideAndMetadata(int par1, int par2)
    175        {
    176            return this.modelBlock.getBlockTextureFromSideAndMetadata(par1, this.field_72158_c);
    177        }
    178
    179        /**
    180         * Returns the block texture based on the side being looked at.  Args: side
    181         */
    182        public int getBlockTextureFromSide(int par1)
    183        {
    184            return this.modelBlock.getBlockTextureFromSideAndMetadata(par1, this.field_72158_c);
    185        }
    186
    187        @SideOnly(Side.CLIENT)
    188
    189        /**
    190         * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
    191         */
    192        public int getRenderBlockPass()
    193        {
    194            return this.modelBlock.getRenderBlockPass();
    195        }
    196
    197        /**
    198         * How many world ticks before ticking
    199         */
    200        public int tickRate()
    201        {
    202            return this.modelBlock.tickRate();
    203        }
    204
    205        @SideOnly(Side.CLIENT)
    206
    207        /**
    208         * Returns the bounding box of the wired rectangular prism to render.
    209         */
    210        public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    211        {
    212            return this.modelBlock.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4);
    213        }
    214
    215        /**
    216         * Can add to the passed in vector for a movement vector to be applied to the entity. Args: x, y, z, entity, vec3d
    217         */
    218        public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3)
    219        {
    220            this.modelBlock.velocityToAddToEntity(par1World, par2, par3, par4, par5Entity, par6Vec3);
    221        }
    222
    223        /**
    224         * Returns if this block is collidable (only used by Fire). Args: x, y, z
    225         */
    226        public boolean isCollidable()
    227        {
    228            return this.modelBlock.isCollidable();
    229        }
    230
    231        /**
    232         * Returns whether this block is collideable based on the arguments passed in Args: blockMetaData, unknownFlag
    233         */
    234        public boolean canCollideCheck(int par1, boolean par2)
    235        {
    236            return this.modelBlock.canCollideCheck(par1, par2);
    237        }
    238
    239        /**
    240         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    241         */
    242        public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    243        {
    244            return this.modelBlock.canPlaceBlockAt(par1World, par2, par3, par4);
    245        }
    246
    247        /**
    248         * Called whenever the block is added into the world. Args: world, x, y, z
    249         */
    250        public void onBlockAdded(World par1World, int par2, int par3, int par4)
    251        {
    252            this.onNeighborBlockChange(par1World, par2, par3, par4, 0);
    253            this.modelBlock.onBlockAdded(par1World, par2, par3, par4);
    254        }
    255
    256        /**
    257         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
    258         */
    259        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    260        {
    261            this.modelBlock.breakBlock(par1World, par2, par3, par4, par5, par6);
    262        }
    263
    264        /**
    265         * Called whenever an entity is walking on top of this block. Args: world, x, y, z, entity
    266         */
    267        public void onEntityWalking(World par1World, int par2, int par3, int par4, Entity par5Entity)
    268        {
    269            this.modelBlock.onEntityWalking(par1World, par2, par3, par4, par5Entity);
    270        }
    271
    272        /**
    273         * Ticks the block if it's been scheduled
    274         */
    275        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    276        {
    277            this.modelBlock.updateTick(par1World, par2, par3, par4, par5Random);
    278        }
    279
    280        /**
    281         * Called upon block activation (right click on the block.)
    282         */
    283        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    284        {
    285            return this.modelBlock.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F);
    286        }
    287
    288        /**
    289         * Called upon the block being destroyed by an explosion
    290         */
    291        public void onBlockDestroyedByExplosion(World par1World, int par2, int par3, int par4)
    292        {
    293            this.modelBlock.onBlockDestroyedByExplosion(par1World, par2, par3, par4);
    294        }
    295
    296        /**
    297         * Called when the block is placed in the world.
    298         */
    299        public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    300        {
    301            int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
    302            int var7 = par1World.getBlockMetadata(par2, par3, par4) & 4;
    303
    304            if (var6 == 0)
    305            {
    306                par1World.setBlockMetadataWithNotify(par2, par3, par4, 2 | var7);
    307            }
    308
    309            if (var6 == 1)
    310            {
    311                par1World.setBlockMetadataWithNotify(par2, par3, par4, 1 | var7);
    312            }
    313
    314            if (var6 == 2)
    315            {
    316                par1World.setBlockMetadataWithNotify(par2, par3, par4, 3 | var7);
    317            }
    318
    319            if (var6 == 3)
    320            {
    321                par1World.setBlockMetadataWithNotify(par2, par3, par4, 0 | var7);
    322            }
    323        }
    324
    325        /**
    326         * called before onBlockPlacedBy by ItemBlock and ItemReed
    327         */
    328        public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
    329        {
    330            if (par5 == 0 || par5 != 1 && (double)par7 > 0.5D)
    331            {
    332                int var9 = par1World.getBlockMetadata(par2, par3, par4);
    333                par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 | 4);
    334            }
    335        }
    336
    337        /**
    338         * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
    339         * x, y, z, startVec, endVec
    340         */
    341        public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
    342        {
    343            MovingObjectPosition[] var7 = new MovingObjectPosition[8];
    344            int var8 = par1World.getBlockMetadata(par2, par3, par4);
    345            int var9 = var8 & 3;
    346            boolean var10 = (var8 & 4) == 4;
    347            int[] var11 = field_72159_a[var9 + (var10 ? 4 : 0)];
    348            this.field_72156_cr = true;
    349            int var14;
    350            int var15;
    351            int var16;
    352
    353            for (int var12 = 0; var12 < 8; ++var12)
    354            {
    355                this.field_72160_cs = var12;
    356                int[] var13 = var11;
    357                var14 = var11.length;
    358
    359                for (var15 = 0; var15 < var14; ++var15)
    360                {
    361                    var16 = var13[var15];
    362
    363                    if (var16 == var12)
    364                    {
    365                        ;
    366                    }
    367                }
    368
    369                var7[var12] = super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
    370            }
    371
    372            int[] var21 = var11;
    373            int var24 = var11.length;
    374
    375            for (var14 = 0; var14 < var24; ++var14)
    376            {
    377                var15 = var21[var14];
    378                var7[var15] = null;
    379            }
    380
    381            MovingObjectPosition var23 = null;
    382            double var22 = 0.0D;
    383            MovingObjectPosition[] var25 = var7;
    384            var16 = var7.length;
    385
    386            for (int var17 = 0; var17 < var16; ++var17)
    387            {
    388                MovingObjectPosition var18 = var25[var17];
    389
    390                if (var18 != null)
    391                {
    392                    double var19 = var18.hitVec.squareDistanceTo(par6Vec3);
    393
    394                    if (var19 > var22)
    395                    {
    396                        var23 = var18;
    397                        var22 = var19;
    398                    }
    399                }
    400            }
    401
    402            return var23;
    403        }
    404    }