001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import cpw.mods.fml.common.registry.GameRegistry; 006 007 import java.util.Random; 008 009 public class BlockDispenser extends BlockContainer 010 { 011 public static final IRegistry field_82527_a = new RegistryDefaulted(new BehaviorDefaultDispenseItem()); 012 private Random random = new Random(); 013 014 protected BlockDispenser(int par1) 015 { 016 super(par1, Material.rock); 017 this.blockIndexInTexture = 45; 018 this.setCreativeTab(CreativeTabs.tabRedstone); 019 } 020 021 /** 022 * How many world ticks before ticking 023 */ 024 public int tickRate() 025 { 026 return 4; 027 } 028 029 /** 030 * Returns the ID of the items to drop on destruction. 031 */ 032 public int idDropped(int par1, Random par2Random, int par3) 033 { 034 return Block.dispenser.blockID; 035 } 036 037 /** 038 * Called whenever the block is added into the world. Args: world, x, y, z 039 */ 040 public void onBlockAdded(World par1World, int par2, int par3, int par4) 041 { 042 super.onBlockAdded(par1World, par2, par3, par4); 043 this.setDispenserDefaultDirection(par1World, par2, par3, par4); 044 } 045 046 /** 047 * sets Dispenser block direction so that the front faces an non-opaque block; chooses west to be direction if all 048 * surrounding blocks are opaque. 049 */ 050 private void setDispenserDefaultDirection(World par1World, int par2, int par3, int par4) 051 { 052 if (!par1World.isRemote) 053 { 054 int var5 = par1World.getBlockId(par2, par3, par4 - 1); 055 int var6 = par1World.getBlockId(par2, par3, par4 + 1); 056 int var7 = par1World.getBlockId(par2 - 1, par3, par4); 057 int var8 = par1World.getBlockId(par2 + 1, par3, par4); 058 byte var9 = 3; 059 060 if (Block.opaqueCubeLookup[var5] && !Block.opaqueCubeLookup[var6]) 061 { 062 var9 = 3; 063 } 064 065 if (Block.opaqueCubeLookup[var6] && !Block.opaqueCubeLookup[var5]) 066 { 067 var9 = 2; 068 } 069 070 if (Block.opaqueCubeLookup[var7] && !Block.opaqueCubeLookup[var8]) 071 { 072 var9 = 5; 073 } 074 075 if (Block.opaqueCubeLookup[var8] && !Block.opaqueCubeLookup[var7]) 076 { 077 var9 = 4; 078 } 079 080 par1World.setBlockMetadataWithNotify(par2, par3, par4, var9); 081 } 082 } 083 084 @SideOnly(Side.CLIENT) 085 086 /** 087 * Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side 088 */ 089 public int getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 090 { 091 if (par5 == 1) 092 { 093 return this.blockIndexInTexture + 17; 094 } 095 else if (par5 == 0) 096 { 097 return this.blockIndexInTexture + 17; 098 } 099 else 100 { 101 int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4); 102 return par5 == var6 ? this.blockIndexInTexture + 1 : this.blockIndexInTexture; 103 } 104 } 105 106 /** 107 * Returns the block texture based on the side being looked at. Args: side 108 */ 109 public int getBlockTextureFromSide(int par1) 110 { 111 return par1 == 1 ? this.blockIndexInTexture + 17 : (par1 == 0 ? this.blockIndexInTexture + 17 : (par1 == 3 ? this.blockIndexInTexture + 1 : this.blockIndexInTexture)); 112 } 113 114 /** 115 * Called upon block activation (right click on the block.) 116 */ 117 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 118 { 119 if (par1World.isRemote) 120 { 121 return true; 122 } 123 else 124 { 125 TileEntityDispenser var10 = (TileEntityDispenser)par1World.getBlockTileEntity(par2, par3, par4); 126 127 if (var10 != null) 128 { 129 par5EntityPlayer.displayGUIDispenser(var10); 130 } 131 132 return true; 133 } 134 } 135 136 private void func_82526_n(World par1World, int par2, int par3, int par4) 137 { 138 BlockSourceImpl var5 = new BlockSourceImpl(par1World, par2, par3, par4); 139 TileEntityDispenser var6 = (TileEntityDispenser)var5.func_82619_j(); 140 141 if (var6 != null) 142 { 143 int var7 = var6.getRandomStackFromInventory(); 144 145 if (var7 < 0) 146 { 147 par1World.playAuxSFX(1001, par2, par3, par4, 0); 148 } 149 else 150 { 151 ItemStack var8 = var6.getStackInSlot(var7); 152 IBehaviorDispenseItem var9 = (IBehaviorDispenseItem)field_82527_a.func_82594_a(var8.getItem()); 153 154 if (var9 != IBehaviorDispenseItem.field_82483_a) 155 { 156 ItemStack var10 = var9.func_82482_a(var5, var8); 157 var6.setInventorySlotContents(var7, var10.stackSize == 0 ? null : var10); 158 } 159 } 160 } 161 } 162 163 /** 164 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 165 * their own) Args: x, y, z, neighbor blockID 166 */ 167 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 168 { 169 if (par5 > 0 && Block.blocksList[par5].canProvidePower()) 170 { 171 boolean var6 = par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4); 172 173 if (var6) 174 { 175 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate()); 176 } 177 } 178 } 179 180 /** 181 * Ticks the block if it's been scheduled 182 */ 183 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 184 { 185 if (!par1World.isRemote && (par1World.isBlockIndirectlyGettingPowered(par2, par3, par4) || par1World.isBlockIndirectlyGettingPowered(par2, par3 + 1, par4))) 186 { 187 this.func_82526_n(par1World, par2, par3, par4); 188 } 189 } 190 191 /** 192 * Returns a new instance of a block's tile entity class. Called on placing the block. 193 */ 194 public TileEntity createNewTileEntity(World par1World) 195 { 196 return new TileEntityDispenser(); 197 } 198 199 /** 200 * Called when the block is placed in the world. 201 */ 202 public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving) 203 { 204 int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; 205 206 if (var6 == 0) 207 { 208 par1World.setBlockMetadataWithNotify(par2, par3, par4, 2); 209 } 210 211 if (var6 == 1) 212 { 213 par1World.setBlockMetadataWithNotify(par2, par3, par4, 5); 214 } 215 216 if (var6 == 2) 217 { 218 par1World.setBlockMetadataWithNotify(par2, par3, par4, 3); 219 } 220 221 if (var6 == 3) 222 { 223 par1World.setBlockMetadataWithNotify(par2, par3, par4, 4); 224 } 225 } 226 227 /** 228 * ejects contained items into the world, and notifies neighbours of an update, as appropriate 229 */ 230 public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) 231 { 232 TileEntityDispenser var7 = (TileEntityDispenser)par1World.getBlockTileEntity(par2, par3, par4); 233 234 if (var7 != null) 235 { 236 for (int var8 = 0; var8 < var7.getSizeInventory(); ++var8) 237 { 238 ItemStack var9 = var7.getStackInSlot(var8); 239 240 if (var9 != null) 241 { 242 float var10 = this.random.nextFloat() * 0.8F + 0.1F; 243 float var11 = this.random.nextFloat() * 0.8F + 0.1F; 244 float var12 = this.random.nextFloat() * 0.8F + 0.1F; 245 246 while (var9.stackSize > 0) 247 { 248 int var13 = this.random.nextInt(21) + 10; 249 250 if (var13 > var9.stackSize) 251 { 252 var13 = var9.stackSize; 253 } 254 255 var9.stackSize -= var13; 256 EntityItem var14 = new EntityItem(par1World, (double)((float)par2 + var10), (double)((float)par3 + var11), (double)((float)par4 + var12), new ItemStack(var9.itemID, var13, var9.getItemDamage())); 257 258 if (var9.hasTagCompound()) 259 { 260 var14.item.setTagCompound((NBTTagCompound)var9.getTagCompound().copy()); 261 } 262 263 float var15 = 0.05F; 264 var14.motionX = (double)((float)this.random.nextGaussian() * var15); 265 var14.motionY = (double)((float)this.random.nextGaussian() * var15 + 0.2F); 266 var14.motionZ = (double)((float)this.random.nextGaussian() * var15); 267 par1World.spawnEntityInWorld(var14); 268 } 269 } 270 } 271 } 272 273 super.breakBlock(par1World, par2, par3, par4, par5, par6); 274 } 275 276 public static IPosition func_82525_a(IBlockSource par0IBlockSource) 277 { 278 EnumFacing var1 = EnumFacing.func_82600_a(par0IBlockSource.func_82620_h()); 279 double var2 = par0IBlockSource.func_82615_a() + 0.6D * (double)var1.func_82601_c(); 280 double var4 = par0IBlockSource.func_82617_b(); 281 double var6 = par0IBlockSource.func_82616_c() + 0.6D * (double)var1.func_82599_e(); 282 return new PositionImpl(var2, var4, var6); 283 } 284 }