    001    package net.minecraft.src;
    002
    003    import net.minecraftforge.common.ForgeDirection;
    004    import cpw.mods.fml.common.Side;
    005    import cpw.mods.fml.common.asm.SideOnly;
    006
    007    public class BlockTrapDoor extends Block
    008    {
    009        /** Set this to allow trapdoors to remain free-floating */
    010        public static boolean disableValidation = false;
    011
    012        protected BlockTrapDoor(int par1, Material par2Material)
    013        {
    014            super(par1, par2Material);
    015            this.blockIndexInTexture = 84;
    016
    017            if (par2Material == Material.iron)
    018            {
    019                ++this.blockIndexInTexture;
    020            }
    021
    022            float var3 = 0.5F;
    023            float var4 = 1.0F;
    024            this.setBlockBounds(0.5F - var3, 0.0F, 0.5F - var3, 0.5F + var3, var4, 0.5F + var3);
    025            this.setCreativeTab(CreativeTabs.tabRedstone);
    026        }
    027
    028        /**
    029         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    030         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    031         */
    032        public boolean isOpaqueCube()
    033        {
    034            return false;
    035        }
    036
    037        /**
    038         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    039         */
    040        public boolean renderAsNormalBlock()
    041        {
    042            return false;
    043        }
    044
    045        public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    046        {
    047            return !isTrapdoorOpen(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
    048        }
    049
    050        /**
    051         * The type of render function that is called for this block
    052         */
    053        public int getRenderType()
    054        {
    055            return 0;
    056        }
    057
    058        @SideOnly(Side.CLIENT)
    059
    060        /**
    061         * Returns the bounding box of the wired rectangular prism to render.
    062         */
    063        public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    064        {
    065            this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
    066            return super.getSelectedBoundingBoxFromPool(par1World, par2, par3, par4);
    067        }
    068
    069        /**
    070         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
    071         * cleared to be reused)
    072         */
    073        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    074        {
    075            this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
    076            return super.getCollisionBoundingBoxFromPool(par1World, par2, par3, par4);
    077        }
    078
    079        /**
    080         * Updates the blocks bounds based on its current state. Args: world, x, y, z
    081         */
    082        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    083        {
    084            this.setBlockBoundsForBlockRender(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
    085        }
    086
    087        /**
    088         * Sets the block's bounds for rendering it as an item
    089         */
    090        public void setBlockBoundsForItemRender()
    091        {
    092            float var1 = 0.1875F;
    093            this.setBlockBounds(0.0F, 0.5F - var1 / 2.0F, 0.0F, 1.0F, 0.5F + var1 / 2.0F, 1.0F);
    094        }
    095
    096        public void setBlockBoundsForBlockRender(int par1)
    097        {
    098            float var2 = 0.1875F;
    099
    100            if ((par1 & 8) != 0)
    101            {
    102                this.setBlockBounds(0.0F, 1.0F - var2, 0.0F, 1.0F, 1.0F, 1.0F);
    103            }
    104            else
    105            {
    106                this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var2, 1.0F);
    107            }
    108
    109            if (isTrapdoorOpen(par1))
    110            {
    111                if ((par1 & 3) == 0)
    112                {
    113                    this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F);
    114                }
    115
    116                if ((par1 & 3) == 1)
    117                {
    118                    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2);
    119                }
    120
    121                if ((par1 & 3) == 2)
    122                {
    123                    this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    124                }
    125
    126                if ((par1 & 3) == 3)
    127                {
    128                    this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F);
    129                }
    130            }
    131        }
    132
    133        /**
    134         * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
    135         */
    136        public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) {}
    137
    138        /**
    139         * Called upon block activation (right click on the block.)
    140         */
    141        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    142        {
    143            if (this.blockMaterial == Material.iron)
    144            {
    145                return true;
    146            }
    147            else
    148            {
    149                int var10 = par1World.getBlockMetadata(par2, par3, par4);
    150                par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 ^ 4);
    151                par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0);
    152                return true;
    153            }
    154        }
    155
    156        public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5)
    157        {
    158            int var6 = par1World.getBlockMetadata(par2, par3, par4);
    159            boolean var7 = (var6 & 4) > 0;
    160
    161            if (var7 != par5)
    162            {
    163                par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 ^ 4);
    164                par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0);
    165            }
    166        }
    167
    168        /**
    169         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    170         * their own) Args: x, y, z, neighbor blockID
    171         */
    172        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    173        {
    174            if (!par1World.isRemote)
    175            {
    176                int var6 = par1World.getBlockMetadata(par2, par3, par4);
    177                int var7 = par2;
    178                int var8 = par4;
    179
    180                if ((var6 & 3) == 0)
    181                {
    182                    var8 = par4 + 1;
    183                }
    184
    185                if ((var6 & 3) == 1)
    186                {
    187                    --var8;
    188                }
    189
    190                if ((var6 & 3) == 2)
    191                {
    192                    var7 = par2 + 1;
    193                }
    194
    195                if ((var6 & 3) == 3)
    196                {
    197                    --var7;
    198                }
    199
    200                if (!(isValidSupportBlock(par1World.getBlockId(var7, par3, var8)) || par1World.isBlockSolidOnSide(var7, par3, var8, ForgeDirection.getOrientation((var6 & 3) + 2))))
    201                {
    202                    par1World.setBlockWithNotify(par2, par3, par4, 0);
    203                    this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0);
    204                }
    205
    206                boolean var9 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4);
    207
    208                if (var9 || par5 > 0 && Block.blocksList[par5].canProvidePower())
    209                {
    210                    this.onPoweredBlockChange(par1World, par2, par3, par4, var9);
    211                }
    212            }
    213        }
    214
    215        /**
    216         * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
    217         * x, y, z, startVec, endVec
    218         */
    219        public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
    220        {
    221            this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
    222            return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
    223        }
    224
    225        public int func_85104_a(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
    226        {
    227            int var10 = 0;
    228
    229            if (par5 == 2)
    230            {
    231                var10 = 0;
    232            }
    233
    234            if (par5 == 3)
    235            {
    236                var10 = 1;
    237            }
    238
    239            if (par5 == 4)
    240            {
    241                var10 = 2;
    242            }
    243
    244            if (par5 == 5)
    245            {
    246                var10 = 3;
    247            }
    248
    249            if (par5 != 1 && par5 != 0 && par7 > 0.5F)
    250            {
    251                var10 |= 8;
    252            }
    253
    254            return var10;
    255        }
    256
    257        /**
    258         * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
    259         */
    260        public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
    261        {
    262            if (disableValidation)
    263            {
    264                return true;
    265            }
    266            if (par5 == 0)
    267            {
    268                return false;
    269            }
    270            else if (par5 == 1)
    271            {
    272                return false;
    273            }
    274            else
    275            {
    276                if (par5 == 2)
    277                {
    278                    ++par4;
    279                }
    280
    281                if (par5 == 3)
    282                {
    283                    --par4;
    284                }
    285
    286                if (par5 == 4)
    287                {
    288                    ++par2;
    289                }
    290
    291                if (par5 == 5)
    292                {
    293                    --par2;
    294                }
    295
    296                return isValidSupportBlock(par1World.getBlockId(par2, par3, par4)) || par1World.isBlockSolidOnSide(par2, par3, par4, ForgeDirection.UP);
    297            }
    298        }
    299
    300        public static boolean isTrapdoorOpen(int par0)
    301        {
    302            return (par0 & 4) != 0;
    303        }
    304
    305        /**
    306         * Checks if the block ID is a valid support block for the trap door to connect with. If it is not the trapdoor is
    307         * dropped into the world.
    308         */
    309        private static boolean isValidSupportBlock(int par0)
    310        {
    311            if (disableValidation)
    312            {
    313                return true;
    314            }
    315            if (par0 <= 0)
    316            {
    317                return false;
    318            }
    319            else
    320            {
    321                Block var1 = Block.blocksList[par0];
    322                return var1 != null && var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() || var1 == Block.glowStone || var1 instanceof BlockHalfSlab || var1 instanceof BlockStairs;
    323            }
    324        }
    325    }