    001    package net.minecraft.src;
    002
    003    import java.util.List;
    004    import java.util.Random;
    005
    006    import net.minecraftforge.common.ForgeDirection;
    007
    008    import static net.minecraftforge.common.ForgeDirection.*;
    009
    010    public class BlockButton extends Block
    011    {
    012        private final boolean field_82537_a;
    013
    014        protected BlockButton(int par1, int par2, boolean par3)
    015        {
    016            super(par1, par2, Material.circuits);
    017            this.setTickRandomly(true);
    018            this.setCreativeTab(CreativeTabs.tabRedstone);
    019            this.field_82537_a = par3;
    020        }
    021
    022        /**
    023         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
    024         * cleared to be reused)
    025         */
    026        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    027        {
    028            return null;
    029        }
    030
    031        /**
    032         * How many world ticks before ticking
    033         */
    034        public int tickRate()
    035        {
    036            return this.field_82537_a ? 30 : 20;
    037        }
    038
    039        /**
    040         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    041         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    042         */
    043        public boolean isOpaqueCube()
    044        {
    045            return false;
    046        }
    047
    048        /**
    049         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    050         */
    051        public boolean renderAsNormalBlock()
    052        {
    053            return false;
    054        }
    055
    056        /**
    057         * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
    058         */
    059        public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
    060        {
    061            ForgeDirection dir = ForgeDirection.getOrientation(par5);
    062            return (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) ||
    063                   (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) ||
    064                   (dir == WEST  && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) ||
    065                   (dir == EAST  && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST));
    066        }
    067
    068        /**
    069         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    070         */
    071        public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    072        {
    073            return (par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST)) ||
    074                   (par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) ||
    075                   (par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) ||
    076                   (par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH));
    077        }
    078
    079        /**
    080         * called before onBlockPlacedBy by ItemBlock and ItemReed
    081         */
    082        public void updateBlockMetadata(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8)
    083        {
    084            int var9 = par1World.getBlockMetadata(par2, par3, par4);
    085            int var10 = var9 & 8;
    086            var9 &= 7;
    087
    088            ForgeDirection dir = ForgeDirection.getOrientation(par5);
    089
    090            if (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH))
    091            {
    092                var9 = 4;
    093            }
    094            else if (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH))
    095            {
    096                var9 = 3;
    097            }
    098            else if (dir == WEST && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST))
    099            {
    100                var9 = 2;
    101            }
    102            else if (dir == EAST && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST))
    103            {
    104                var9 = 1;
    105            }
    106            else
    107            {
    108                var9 = this.getOrientation(par1World, par2, par3, par4);
    109            }
    110
    111            par1World.setBlockMetadataWithNotify(par2, par3, par4, var9 + var10);
    112        }
    113
    114        /**
    115         * Get side which this button is facing.
    116         */
    117        private int getOrientation(World par1World, int par2, int par3, int par4)
    118        {
    119            if (par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST)) return 1;
    120            if (par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST)) return 2;
    121            if (par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) return 3;
    122            if (par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) return 4;
    123            return 1;
    124        }
    125
    126        /**
    127         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    128         * their own) Args: x, y, z, neighbor blockID
    129         */
    130        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    131        {
    132            if (this.redundantCanPlaceBlockAt(par1World, par2, par3, par4))
    133            {
    134                int var6 = par1World.getBlockMetadata(par2, par3, par4) & 7;
    135                boolean var7 = false;
    136
    137                if (!par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST) && var6 == 1)
    138                {
    139                    var7 = true;
    140                }
    141
    142                if (!par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST) && var6 == 2)
    143                {
    144                    var7 = true;
    145                }
    146
    147                if (!par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH) && var6 == 3)
    148                {
    149                    var7 = true;
    150                }
    151
    152                if (!par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH) && var6 == 4)
    153                {
    154                    var7 = true;
    155                }
    156
    157                if (var7)
    158                {
    159                    this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
    160                    par1World.setBlockWithNotify(par2, par3, par4, 0);
    161                }
    162            }
    163        }
    164
    165        /**
    166         * This method is redundant, check it out...
    167         */
    168        private boolean redundantCanPlaceBlockAt(World par1World, int par2, int par3, int par4)
    169        {
    170            if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
    171            {
    172                this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
    173                par1World.setBlockWithNotify(par2, par3, par4, 0);
    174                return false;
    175            }
    176            else
    177            {
    178                return true;
    179            }
    180        }
    181
    182        /**
    183         * Updates the blocks bounds based on its current state. Args: world, x, y, z
    184         */
    185        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    186        {
    187            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
    188            this.func_82534_e(var5);
    189        }
    190
    191        private void func_82534_e(int par1)
    192        {
    193            int var2 = par1 & 7;
    194            boolean var3 = (par1 & 8) > 0;
    195            float var4 = 0.375F;
    196            float var5 = 0.625F;
    197            float var6 = 0.1875F;
    198            float var7 = 0.125F;
    199
    200            if (var3)
    201            {
    202                var7 = 0.0625F;
    203            }
    204
    205            if (var2 == 1)
    206            {
    207                this.setBlockBounds(0.0F, var4, 0.5F - var6, var7, var5, 0.5F + var6);
    208            }
    209            else if (var2 == 2)
    210            {
    211                this.setBlockBounds(1.0F - var7, var4, 0.5F - var6, 1.0F, var5, 0.5F + var6);
    212            }
    213            else if (var2 == 3)
    214            {
    215                this.setBlockBounds(0.5F - var6, var4, 0.0F, 0.5F + var6, var5, var7);
    216            }
    217            else if (var2 == 4)
    218            {
    219                this.setBlockBounds(0.5F - var6, var4, 1.0F - var7, 0.5F + var6, var5, 1.0F);
    220            }
    221        }
    222
    223        /**
    224         * Called when the block is clicked by a player. Args: x, y, z, entityPlayer
    225         */
    226        public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) {}
    227
    228        /**
    229         * Called upon block activation (right click on the block.)
    230         */
    231        public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
    232        {
    233            int var10 = par1World.getBlockMetadata(par2, par3, par4);
    234            int var11 = var10 & 7;
    235            int var12 = 8 - (var10 & 8);
    236
    237            if (var12 == 0)
    238            {
    239                return true;
    240            }
    241            else
    242            {
    243                par1World.setBlockMetadataWithNotify(par2, par3, par4, var11 + var12);
    244                par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
    245                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, 0.6F);
    246                this.func_82536_d(par1World, par2, par3, par4, var11);
    247                par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate());
    248                return true;
    249            }
    250        }
    251
    252        /**
    253         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
    254         */
    255        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    256        {
    257            if ((par6 & 8) > 0)
    258            {
    259                int var7 = par6 & 7;
    260                this.func_82536_d(par1World, par2, par3, par4, var7);
    261            }
    262
    263            super.breakBlock(par1World, par2, par3, par4, par5, par6);
    264        }
    265
    266        /**
    267         * Is this block powering the block on the specified side
    268         */
    269        public boolean isPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    270        {
    271            return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) > 0;
    272        }
    273
    274        /**
    275         * Is this block indirectly powering the block on the specified side
    276         */
    277        public boolean isIndirectlyPoweringTo(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    278        {
    279            int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
    280
    281            if ((var6 & 8) == 0)
    282            {
    283                return false;
    284            }
    285            else
    286            {
    287                int var7 = var6 & 7;
    288                return var7 == 5 && par5 == 1 ? true : (var7 == 4 && par5 == 2 ? true : (var7 == 3 && par5 == 3 ? true : (var7 == 2 && par5 == 4 ? true : var7 == 1 && par5 == 5)));
    289            }
    290        }
    291
    292        /**
    293         * Can this block provide power. Only wire currently seems to have this change based on its state.
    294         */
    295        public boolean canProvidePower()
    296        {
    297            return true;
    298        }
    299
    300        /**
    301         * Ticks the block if it's been scheduled
    302         */
    303        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    304        {
    305            if (!par1World.isRemote)
    306            {
    307                int var6 = par1World.getBlockMetadata(par2, par3, par4);
    308
    309                if ((var6 & 8) != 0)
    310                {
    311                    if (this.field_82537_a)
    312                    {
    313                        this.func_82535_o(par1World, par2, par3, par4);
    314                    }
    315                    else
    316                    {
    317                        par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 & 7);
    318                        int var7 = var6 & 7;
    319                        this.func_82536_d(par1World, par2, par3, par4, var7);
    320                        par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, 0.5F);
    321                        par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
    322                    }
    323                }
    324            }
    325        }
    326
    327        /**
    328         * Sets the block's bounds for rendering it as an item
    329         */
    330        public void setBlockBoundsForItemRender()
    331        {
    332            float var1 = 0.1875F;
    333            float var2 = 0.125F;
    334            float var3 = 0.125F;
    335            this.setBlockBounds(0.5F - var1, 0.5F - var2, 0.5F - var3, 0.5F + var1, 0.5F + var2, 0.5F + var3);
    336        }
    337
    338        /**
    339         * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity
    340         */
    341        public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
    342        {
    343            if (!par1World.isRemote)
    344            {
    345                if (this.field_82537_a)
    346                {
    347                    if ((par1World.getBlockMetadata(par2, par3, par4) & 8) == 0)
    348                    {
    349                        this.func_82535_o(par1World, par2, par3, par4);
    350                    }
    351                }
    352            }
    353        }
    354
    355        private void func_82535_o(World par1World, int par2, int par3, int par4)
    356        {
    357            int var5 = par1World.getBlockMetadata(par2, par3, par4);
    358            int var6 = var5 & 7;
    359            boolean var7 = (var5 & 8) != 0;
    360            this.func_82534_e(var5);
    361            List var9 = par1World.getEntitiesWithinAABB(EntityArrow.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par2 + this.minX, (double)par3 + this.minY, (double)par4 + this.minZ, (double)par2 + this.maxX, (double)par3 + this.maxY, (double)par4 + this.maxZ));
    362            boolean var8 = !var9.isEmpty();
    363
    364            if (var8 && !var7)
    365            {
    366                par1World.setBlockMetadataWithNotify(par2, par3, par4, var6 | 8);
    367                this.func_82536_d(par1World, par2, par3, par4, var6);
    368                par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
    369                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, 0.6F);
    370            }
    371
    372            if (!var8 && var7)
    373            {
    374                par1World.setBlockMetadataWithNotify(par2, par3, par4, var6);
    375                this.func_82536_d(par1World, par2, par3, par4, var6);
    376                par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
    377                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "random.click", 0.3F, 0.5F);
    378            }
    379
    380            if (var8)
    381            {
    382                par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate());
    383            }
    384        }
    385
    386        private void func_82536_d(World par1World, int par2, int par3, int par4, int par5)
    387        {
    388            par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
    389
    390            if (par5 == 1)
    391            {
    392                par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
    393            }
    394            else if (par5 == 2)
    395            {
    396                par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
    397            }
    398            else if (par5 == 3)
    399            {
    400                par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
    401            }
    402            else if (par5 == 4)
    403            {
    404                par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
    405            }
    406            else
    407            {
    408                par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID);
    409            }
    410        }
    411    }