    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            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var2, 1.0F);
    100
    101            if (isTrapdoorOpen(par1))
    102            {
    103                if ((par1 & 3) == 0)
    104                {
    105                    this.setBlockBounds(0.0F, 0.0F, 1.0F - var2, 1.0F, 1.0F, 1.0F);
    106                }
    107
    108                if ((par1 & 3) == 1)
    109                {
    110                    this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, var2);
    111                }
    112
    113                if ((par1 & 3) == 2)
    114                {
    115                    this.setBlockBounds(1.0F - var2, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
    116                }
    117
    118                if ((par1 & 3) == 3)
    119                {
    120                    this.setBlockBounds(0.0F, 0.0F, 0.0F, var2, 1.0F, 1.0F);
    121                }
    122            }
    123        }
    124
    125        /**
    126         * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
    127         */
    128        public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
    129        {
    130            this.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, 0, 0.0F, 0.0F, 0.0F);
    131        }
    132
    133        /**
    134         * Called upon block activation (right click on the block.)
    135         */
    136        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    137        {
    138            if (this.blockMaterial == Material.iron)
    139            {
    140                return true;
    141            }
    142            else
    143            {
    144                int var10 = par1World.getBlockMetadata(par2, par3, par4);
    145                par1World.setBlockMetadataWithNotify(par2, par3, par4, var10 ^ 4);
    146                par1World.playAuxSFXAtEntity(par5EntityPlayer, 1003, par2, par3, par4, 0);
    147                return true;
    148            }
    149        }
    150
    151        public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5)
    152        {
    153            int var6 = par1World.getBlockMetadata(par2, par3, par4);
    154            boolean var7 = (var6 & 4) > 0;
    155
    156            if (var7 != par5)
    157            {
    158                par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 ^ 4);
    159                par1World.playAuxSFXAtEntity((EntityPlayer)null, 1003, par2, par3, par4, 0);
    160            }
    161        }
    162
    163        /**
    164         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    165         * their own) Args: x, y, z, neighbor blockID
    166         */
    167        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    168        {
    169            if (!par1World.isRemote)
    170            {
    171                int var6 = par1World.getBlockMetadata(par2, par3, par4);
    172                int var7 = par2;
    173                int var8 = par4;
    174
    175                if ((var6 & 3) == 0)
    176                {
    177                    var8 = par4 + 1;
    178                }
    179
    180                if ((var6 & 3) == 1)
    181                {
    182                    --var8;
    183                }
    184
    185                if ((var6 & 3) == 2)
    186                {
    187                    var7 = par2 + 1;
    188                }
    189
    190                if ((var6 & 3) == 3)
    191                {
    192                    --var7;
    193                }
    194
    195                if (!(isValidSupportBlock(par1World.getBlockId(var7, par3, var8)) || par1World.isBlockSolidOnSide(var7, par3, var8, ForgeDirection.getOrientation((var6 & 3) + 2))))
    196                {
    197                    par1World.setBlockWithNotify(par2, par3, par4, 0);
    198                    this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0);
    199                }
    200
    201                boolean var9 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4);
    202
    203                if (var9 || par5 > 0 && Block.blocksList[par5].canProvidePower() || par5 == 0)
    204                {
    205                    this.onPoweredBlockChange(par1World, par2, par3, par4, var9);
    206                }
    207            }
    208        }
    209
    210        /**
    211         * Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
    212         * x, y, z, startVec, endVec
    213         */
    214        public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
    215        {
    216            this.setBlockBoundsBasedOnState(par1World, par2, par3, par4);
    217            return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
    218        }
    219
    220        /**
    221         * called before onBlockPlacedBy by ItemBlock and ItemReed
    222         */
    223        public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
    224        {
    225            byte var9 = 0;
    226
    227            if (par5 == 2)
    228            {
    229                var9 = 0;
    230            }
    231
    232            if (par5 == 3)
    233            {
    234                var9 = 1;
    235            }
    236
    237            if (par5 == 4)
    238            {
    239                var9 = 2;
    240            }
    241
    242            if (par5 == 5)
    243            {
    244                var9 = 3;
    245            }
    246
    247            par1World.setBlockMetadataWithNotify(par2, par3, par4, var9);
    248        }
    249
    250        /**
    251         * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
    252         */
    253        public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
    254        {
    255            if (disableValidation)
    256            {
    257                return true;
    258            }
    259            if (par5 == 0)
    260            {
    261                return false;
    262            }
    263            else if (par5 == 1)
    264            {
    265                return false;
    266            }
    267            else
    268            {
    269                if (par5 == 2)
    270                {
    271                    ++par4;
    272                }
    273
    274                if (par5 == 3)
    275                {
    276                    --par4;
    277                }
    278
    279                if (par5 == 4)
    280                {
    281                    ++par2;
    282                }
    283
    284                if (par5 == 5)
    285                {
    286                    --par2;
    287                }
    288
    289                return isValidSupportBlock(par1World.getBlockId(par2, par3, par4)) || par1World.isBlockSolidOnSide(par2, par3, par4, ForgeDirection.UP);
    290            }
    291        }
    292
    293        public static boolean isTrapdoorOpen(int par0)
    294        {
    295            return (par0 & 4) != 0;
    296        }
    297
    298        /**
    299         * Checks if the block ID is a valid support block for the trap door to connect with. If it is not the trapdoor is
    300         * dropped into the world.
    301         */
    302        private static boolean isValidSupportBlock(int par0)
    303        {
    304            if (disableValidation)
    305            {
    306                return true;
    307            }
    308            if (par0 <= 0)
    309            {
    310                return false;
    311            }
    312            else
    313            {
    314                Block var1 = Block.blocksList[par0];
    315                return var1 != null && var1.blockMaterial.isOpaque() && var1.renderAsNormalBlock() || var1 == Block.glowStone;
    316            }
    317        }
    318    }