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 031 /** 032 * When this method is called, your block should register all the icons it needs with the given IconRegister. This 033 * is the only chance you get to register icons. 034 */ 035 public void registerIcons(IconRegister par1IconRegister) 036 { 037 this.blockIcon = par1IconRegister.registerIcon("snow"); 038 } 039 040 /** 041 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been 042 * cleared to be reused) 043 */ 044 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) 045 { 046 int l = par1World.getBlockMetadata(par2, par3, par4) & 7; 047 float f = 0.125F; 048 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); 049 } 050 051 /** 052 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 053 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 054 */ 055 public boolean isOpaqueCube() 056 { 057 return false; 058 } 059 060 /** 061 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 062 */ 063 public boolean renderAsNormalBlock() 064 { 065 return false; 066 } 067 068 /** 069 * Sets the block's bounds for rendering it as an item 070 */ 071 public void setBlockBoundsForItemRender() 072 { 073 this.func_96478_d(0); 074 } 075 076 /** 077 * Updates the blocks bounds based on its current state. Args: world, x, y, z 078 */ 079 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) 080 { 081 this.func_96478_d(par1IBlockAccess.getBlockMetadata(par2, par3, par4)); 082 } 083 084 protected void func_96478_d(int par1) 085 { 086 int j = par1 & 7; 087 float f = (float)(2 * (1 + j)) / 16.0F; 088 this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F); 089 } 090 091 /** 092 * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z 093 */ 094 public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) 095 { 096 int l = par1World.getBlockId(par2, par3 - 1, par4); 097 Block block = Block.blocksList[l]; 098 if (block == null) return false; 099 if (block == this && (par1World.getBlockMetadata(par2, par3 - 1, par4) & 7) == 7) return true; 100 if (!block.isLeaves(par1World, par2, par3 - 1, par4) && !Block.blocksList[l].isOpaqueCube()) return false; 101 return par1World.getBlockMaterial(par2, par3 - 1, par4).blocksMovement(); 102 } 103 104 /** 105 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 106 * their own) Args: x, y, z, neighbor blockID 107 */ 108 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 109 { 110 this.canSnowStay(par1World, par2, par3, par4); 111 } 112 113 /** 114 * Checks if this snow block can stay at this location. 115 */ 116 private boolean canSnowStay(World par1World, int par2, int par3, int par4) 117 { 118 if (!this.canPlaceBlockAt(par1World, par2, par3, par4)) 119 { 120 par1World.setBlockToAir(par2, par3, par4); 121 return false; 122 } 123 else 124 { 125 return true; 126 } 127 } 128 129 /** 130 * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the 131 * block and l is the block's subtype/damage. 132 */ 133 public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6) 134 { 135 super.harvestBlock(par1World, par2EntityPlayer, par3, par4, par5, par6); 136 par1World.setBlockToAir(par3, par4, par5); 137 } 138 139 /** 140 * Returns the ID of the items to drop on destruction. 141 */ 142 public int idDropped(int par1, Random par2Random, int par3) 143 { 144 return Item.snowball.itemID; 145 } 146 147 /** 148 * Returns the quantity of items to drop on block destruction. 149 */ 150 public int quantityDropped(Random par1Random) 151 { 152 return 1; 153 } 154 155 /** 156 * Ticks the block if it's been scheduled 157 */ 158 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 159 { 160 if (par1World.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4) > 11) 161 { 162 par1World.setBlockToAir(par2, par3, par4); 163 } 164 } 165 166 @SideOnly(Side.CLIENT) 167 168 /** 169 * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given 170 * coordinates. Args: blockAccess, x, y, z, side 171 */ 172 public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 173 { 174 return par5 == 1 ? true : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); 175 } 176 177 @Override 178 public int quantityDropped(int meta, int fortune, Random random) 179 { 180 return (meta & 7) + 1; 181 } 182}