001package net.minecraft.block;
002
003import cpw.mods.fml.relauncher.Side;
004import cpw.mods.fml.relauncher.SideOnly;
005import java.util.Random;
006import net.minecraft.block.material.Material;
007import net.minecraft.client.renderer.texture.IconRegister;
008import net.minecraft.creativetab.CreativeTabs;
009import net.minecraft.entity.player.EntityPlayer;
010import net.minecraft.item.Item;
011import net.minecraft.item.ItemStack;
012import net.minecraft.stats.StatList;
013import net.minecraft.util.AxisAlignedBB;
014import net.minecraft.world.EnumSkyBlock;
015import net.minecraft.world.IBlockAccess;
016import net.minecraft.world.World;
017
018public class BlockSnow extends Block
019{
020    protected BlockSnow(int par1)
021    {
022        super(par1, Material.snow);
023        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
024        this.setTickRandomly(true);
025        this.setCreativeTab(CreativeTabs.tabDecorations);
026        this.func_96478_d(0);
027    }
028
029    @SideOnly(Side.CLIENT)
030    public void func_94332_a(IconRegister par1IconRegister)
031    {
032        this.field_94336_cN = par1IconRegister.func_94245_a("snow");
033    }
034
035    /**
036     * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
037     * cleared to be reused)
038     */
039    public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
040    {
041        int l = par1World.getBlockMetadata(par2, par3, par4) & 7;
042        float f = 0.125F;
043        return AxisAlignedBB.getAABBPool().getAABB((double)par2 + this.minX, (double)par3 + this.minY, (double)par4 + this.minZ, (double)par2 + this.maxX, (double)((float)par3 + (float)l * f), (double)par4 + this.maxZ);
044    }
045
046    /**
047     * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
048     * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
049     */
050    public boolean isOpaqueCube()
051    {
052        return false;
053    }
054
055    /**
056     * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
057     */
058    public boolean renderAsNormalBlock()
059    {
060        return false;
061    }
062
063    /**
064     * Sets the block's bounds for rendering it as an item
065     */
066    public void setBlockBoundsForItemRender()
067    {
068        this.func_96478_d(0);
069    }
070
071    /**
072     * Updates the blocks bounds based on its current state. Args: world, x, y, z
073     */
074    public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
075    {
076        this.func_96478_d(par1IBlockAccess.getBlockMetadata(par2, par3, par4));
077    }
078
079    protected void func_96478_d(int par1)
080    {
081        int j = par1 & 7;
082        float f = (float)(2 * (1 + j)) / 16.0F;
083        this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F);
084    }
085
086    /**
087     * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
088     */
089    public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
090    {
091        int l = par1World.getBlockId(par2, par3 - 1, par4);        
092        Block block = Block.blocksList[l];
093        if (block == null) return false;
094        if (block == this && (par1World.getBlockMetadata(par2, par3 - 1, par4) & 7) == 7) return true;
095        if (block.isLeaves(par1World, par2, par3 - 1, par4) && Block.blocksList[l].isOpaqueCube()) return false;
096        return par1World.getBlockMaterial(par2, par3 - 1, par4).blocksMovement();
097    }
098
099    /**
100     * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
101     * their own) Args: x, y, z, neighbor blockID
102     */
103    public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
104    {
105        this.canSnowStay(par1World, par2, par3, par4);
106    }
107
108    /**
109     * Checks if this snow block can stay at this location.
110     */
111    private boolean canSnowStay(World par1World, int par2, int par3, int par4)
112    {
113        if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
114        {
115            par1World.func_94571_i(par2, par3, par4);
116            return false;
117        }
118        else
119        {
120            return true;
121        }
122    }
123
124    /**
125     * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the
126     * block and l is the block's subtype/damage.
127     */
128    public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6)
129    {
130        super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6);
131        par1World.func_94571_i(par3, par4, par5);
132    }
133
134    /**
135     * Returns the ID of the items to drop on destruction.
136     */
137    public int idDropped(int par1, Random par2Random, int par3)
138    {
139        return Item.snowball.itemID;
140    }
141
142    /**
143     * Returns the quantity of items to drop on block destruction.
144     */
145    public int quantityDropped(Random par1Random)
146    {
147        return 1;
148    }
149
150    /**
151     * Ticks the block if it's been scheduled
152     */
153    public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
154    {
155        if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11)
156        {
157            par1World.func_94571_i(par2, par3, par4);
158        }
159    }
160
161    @SideOnly(Side.CLIENT)
162
163    /**
164     * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
165     * coordinates.  Args: blockAccess, x, y, z, side
166     */
167    public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
168    {
169        return par5 == 1 ? true : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5);
170    }
171
172    @Override
173    public int quantityDropped(int meta, int fortune, Random random)
174    {
175        return (meta & 7) + 1;
176    }
177}