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