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