    001    package net.minecraft.block;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.Random;
    006    import net.minecraft.block.material.Material;
    007    import net.minecraft.creativetab.CreativeTabs;
    008    import net.minecraft.entity.player.EntityPlayer;
    009    import net.minecraft.item.Item;
    010    import net.minecraft.item.ItemStack;
    011    import net.minecraft.stats.StatList;
    012    import net.minecraft.util.AxisAlignedBB;
    013    import net.minecraft.world.EnumSkyBlock;
    014    import net.minecraft.world.IBlockAccess;
    015    import net.minecraft.world.World;
    016
    017    public class BlockSnow extends Block
    018    {
    019        protected BlockSnow(int par1, int par2)
    020        {
    021            super(par1, par2, Material.snow);
    022            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
    023            this.setTickRandomly(true);
    024            this.setCreativeTab(CreativeTabs.tabDecorations);
    025        }
    026
    027        /**
    028         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
    029         * cleared to be reused)
    030         */
    031        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    032        {
    033            int var5 = par1World.getBlockMetadata(par2, par3, par4) & 7;
    034            return var5 >= 3 ? AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par2 + this.minX, (double)par3 + this.minY, (double)par4 + this.minZ, (double)par2 + this.maxX, (double)((float)par3 + 0.5F), (double)par4 + this.maxZ) : null;
    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        /**
    055         * Updates the blocks bounds based on its current state. Args: world, x, y, z
    056         */
    057        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    058        {
    059            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 7;
    060            float var6 = (float)(2 * (1 + var5)) / 16.0F;
    061            this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, var6, 1.0F);
    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            int var5 = par1World.getBlockId(par2, par3 - 1, par4);
    070            Block block = Block.blocksList[var5];
    071            return block != null && (block.isLeaves(par1World, par2, par3 - 1, par4) || Block.blocksList[var5].isOpaqueCube()) ? par1World.getBlockMaterial(par2, par3 - 1, par4).blocksMovement() : false;
    072        }
    073
    074        /**
    075         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    076         * their own) Args: x, y, z, neighbor blockID
    077         */
    078        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    079        {
    080            this.canSnowStay(par1World, par2, par3, par4);
    081        }
    082
    083        /**
    084         * Checks if this snow block can stay at this location.
    085         */
    086        private boolean canSnowStay(World par1World, int par2, int par3, int par4)
    087        {
    088            if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
    089            {
    090                par1World.setBlockWithNotify(par2, par3, par4, 0);
    091                return false;
    092            }
    093            else
    094            {
    095                return true;
    096            }
    097        }
    098
    099        /**
    100         * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the
    101         * block and l is the block's subtype/damage.
    102         */
    103        public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6)
    104        {
    105            super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6);
    106            par1World.setBlockWithNotify(par3, par4, par5, 0);
    107        }
    108
    109        /**
    110         * Returns the ID of the items to drop on destruction.
    111         */
    112        public int idDropped(int par1, Random par2Random, int par3)
    113        {
    114            return Item.snowball.shiftedIndex;
    115        }
    116
    117        /**
    118         * Returns the quantity of items to drop on block destruction.
    119         */
    120        public int quantityDropped(Random par1Random)
    121        {
    122            return 1;
    123        }
    124
    125        /**
    126         * Ticks the block if it's been scheduled
    127         */
    128        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    129        {
    130            if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11)
    131            {
    132                par1World.setBlockWithNotify(par2, par3, par4, 0);
    133            }
    134        }
    135
    136        @SideOnly(Side.CLIENT)
    137
    138        /**
    139         * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
    140         * coordinates.  Args: blockAccess, x, y, z, side
    141         */
    142        public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    143        {
    144            return par5 == 1 ? true : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5);
    145        }
    146    }