001 package net.minecraftforge.common; 002 003 import java.util.*; 004 005 import cpw.mods.fml.common.FMLLog; 006 007 import net.minecraft.src.*; 008 import net.minecraftforge.event.entity.item.ItemTossEvent; 009 import net.minecraftforge.event.entity.living.*; 010 import net.minecraftforge.event.entity.living.LivingEvent.*; 011 012 public class ForgeHooks 013 { 014 static class GrassEntry extends WeightedRandomItem 015 { 016 public final Block block; 017 public final int metadata; 018 public GrassEntry(Block block, int meta, int weight) 019 { 020 super(weight); 021 this.block = block; 022 this.metadata = meta; 023 } 024 } 025 026 static class SeedEntry extends WeightedRandomItem 027 { 028 public final ItemStack seed; 029 public SeedEntry(ItemStack seed, int weight) 030 { 031 super(weight); 032 this.seed = seed; 033 } 034 } 035 static final List<GrassEntry> grassList = new ArrayList<GrassEntry>(); 036 static final List<SeedEntry> seedList = new ArrayList<SeedEntry>(); 037 038 public static void plantGrass(World world, int x, int y, int z) 039 { 040 GrassEntry grass = (GrassEntry)WeightedRandom.getRandomItem(world.rand, grassList); 041 if (grass == null || grass.block == null || !grass.block.canBlockStay(world, x, y, z)) 042 { 043 return; 044 } 045 world.setBlockAndMetadataWithNotify(x, y, z, grass.block.blockID, grass.metadata); 046 } 047 048 public static ItemStack getGrassSeed(World world) 049 { 050 SeedEntry entry = (SeedEntry)WeightedRandom.getRandomItem(world.rand, seedList); 051 if (entry == null || entry.seed == null) 052 { 053 return null; 054 } 055 return entry.seed.copy(); 056 } 057 058 private static boolean toolInit = false; 059 static HashMap<Item, List> toolClasses = new HashMap<Item, List>(); 060 static HashMap<List, Integer> toolHarvestLevels = new HashMap<List, Integer>(); 061 static HashSet<List> toolEffectiveness = new HashSet<List>(); 062 063 public static boolean canHarvestBlock(Block block, EntityPlayer player, int metadata) 064 { 065 if (block.blockMaterial.isHarvestable()) 066 { 067 return true; 068 } 069 070 ItemStack stack = player.inventory.getCurrentItem(); 071 if (stack == null) 072 { 073 return player.canHarvestBlock(block); 074 } 075 076 List info = (List)toolClasses.get(stack.getItem()); 077 if (info == null) 078 { 079 return player.canHarvestBlock(block); 080 } 081 082 Object[] tmp = info.toArray(); 083 String toolClass = (String)tmp[0]; 084 int harvestLevel = (Integer)tmp[1]; 085 086 Integer blockHarvestLevel = (Integer)toolHarvestLevels.get(Arrays.asList(block, metadata, toolClass)); 087 if (blockHarvestLevel == null) 088 { 089 return player.canHarvestBlock(block); 090 } 091 092 if (blockHarvestLevel > harvestLevel) 093 { 094 return false; 095 } 096 return true; 097 } 098 099 public static float blockStrength(Block block, EntityPlayer player, World world, int x, int y, int z) 100 { 101 int metadata = world.getBlockMetadata(x, y, z); 102 float hardness = block.getBlockHardness(world, x, y, z); 103 if (hardness < 0.0F) 104 { 105 return 0.0F; 106 } 107 108 if (!canHarvestBlock(block, player, metadata)) 109 { 110 return 1.0F / hardness / 100F; 111 } 112 else 113 { 114 return player.getCurrentPlayerStrVsBlock(block, metadata) / hardness / 30F; 115 } 116 } 117 118 public static boolean isToolEffective(ItemStack stack, Block block, int metadata) 119 { 120 List toolClass = (List)toolClasses.get(stack.getItem()); 121 if (toolClass == null) 122 { 123 return false; 124 } 125 return toolEffectiveness.contains(Arrays.asList(block, metadata, (String)toolClass.get(0))); 126 } 127 128 static void initTools() 129 { 130 if (toolInit) 131 { 132 return; 133 } 134 toolInit = true; 135 136 MinecraftForge.setToolClass(Item.pickaxeWood, "pickaxe", 0); 137 MinecraftForge.setToolClass(Item.pickaxeStone, "pickaxe", 1); 138 MinecraftForge.setToolClass(Item.pickaxeSteel, "pickaxe", 2); 139 MinecraftForge.setToolClass(Item.pickaxeGold, "pickaxe", 0); 140 MinecraftForge.setToolClass(Item.pickaxeDiamond, "pickaxe", 3); 141 142 MinecraftForge.setToolClass(Item.axeWood, "axe", 0); 143 MinecraftForge.setToolClass(Item.axeStone, "axe", 1); 144 MinecraftForge.setToolClass(Item.axeSteel, "axe", 2); 145 MinecraftForge.setToolClass(Item.axeGold, "axe", 0); 146 MinecraftForge.setToolClass(Item.axeDiamond, "axe", 3); 147 148 MinecraftForge.setToolClass(Item.shovelWood, "shovel", 0); 149 MinecraftForge.setToolClass(Item.shovelStone, "shovel", 1); 150 MinecraftForge.setToolClass(Item.shovelSteel, "shovel", 2); 151 MinecraftForge.setToolClass(Item.shovelGold, "shovel", 0); 152 MinecraftForge.setToolClass(Item.shovelDiamond, "shovel", 3); 153 154 for (Block block : ItemPickaxe.blocksEffectiveAgainst) 155 { 156 MinecraftForge.setBlockHarvestLevel(block, "pickaxe", 0); 157 } 158 159 for (Block block : ItemSpade.blocksEffectiveAgainst) 160 { 161 MinecraftForge.setBlockHarvestLevel(block, "shovel", 0); 162 } 163 164 for (Block block : ItemAxe.blocksEffectiveAgainst) 165 { 166 MinecraftForge.setBlockHarvestLevel(block, "axe", 0); 167 } 168 169 MinecraftForge.setBlockHarvestLevel(Block.obsidian, "pickaxe", 3); 170 MinecraftForge.setBlockHarvestLevel(Block.oreEmerald, "pickaxe", 2); 171 MinecraftForge.setBlockHarvestLevel(Block.oreDiamond, "pickaxe", 2); 172 MinecraftForge.setBlockHarvestLevel(Block.blockDiamond, "pickaxe", 2); 173 MinecraftForge.setBlockHarvestLevel(Block.oreGold, "pickaxe", 2); 174 MinecraftForge.setBlockHarvestLevel(Block.blockGold, "pickaxe", 2); 175 MinecraftForge.setBlockHarvestLevel(Block.oreIron, "pickaxe", 1); 176 MinecraftForge.setBlockHarvestLevel(Block.blockSteel, "pickaxe", 1); 177 MinecraftForge.setBlockHarvestLevel(Block.oreLapis, "pickaxe", 1); 178 MinecraftForge.setBlockHarvestLevel(Block.blockLapis, "pickaxe", 1); 179 MinecraftForge.setBlockHarvestLevel(Block.oreRedstone, "pickaxe", 2); 180 MinecraftForge.setBlockHarvestLevel(Block.oreRedstoneGlowing, "pickaxe", 2); 181 MinecraftForge.removeBlockEffectiveness(Block.oreRedstone, "pickaxe"); 182 MinecraftForge.removeBlockEffectiveness(Block.obsidian, "pickaxe"); 183 MinecraftForge.removeBlockEffectiveness(Block.oreRedstoneGlowing, "pickaxe"); 184 } 185 186 public static String getTexture(String _default, Object obj) 187 { 188 if (obj instanceof Item) 189 { 190 return ((Item)obj).getTextureFile(); 191 } 192 else if (obj instanceof Block) 193 { 194 return ((Block)obj).getTextureFile(); 195 } 196 else 197 { 198 return _default; 199 } 200 } 201 202 public static int getTotalArmorValue(EntityPlayer player) 203 { 204 int ret = 0; 205 for (int x = 0; x < player.inventory.armorInventory.length; x++) 206 { 207 ItemStack stack = player.inventory.armorInventory[x]; 208 if (stack != null && stack.getItem() instanceof ISpecialArmor) 209 { 210 ret += ((ISpecialArmor)stack.getItem()).getArmorDisplay(player, stack, x); 211 } 212 else if (stack != null && stack.getItem() instanceof ItemArmor) 213 { 214 ret += ((ItemArmor)stack.getItem()).damageReduceAmount; 215 } 216 } 217 return ret; 218 } 219 220 static 221 { 222 grassList.add(new GrassEntry(Block.plantYellow, 0, 20)); 223 grassList.add(new GrassEntry(Block.plantRed, 0, 10)); 224 seedList.add(new SeedEntry(new ItemStack(Item.seeds), 10)); 225 initTools(); 226 } 227 228 /** 229 * Called when a player uses 'pick block', calls new Entity and Block hooks. 230 */ 231 public static boolean onPickBlock(MovingObjectPosition target, EntityPlayer player, World world) 232 { 233 ItemStack result = null; 234 boolean isCreative = player.capabilities.isCreativeMode; 235 236 if (target.typeOfHit == EnumMovingObjectType.TILE) 237 { 238 int x = target.blockX; 239 int y = target.blockY; 240 int z = target.blockZ; 241 Block var8 = Block.blocksList[world.getBlockId(x, y, z)]; 242 243 if (var8 == null) 244 { 245 return false; 246 } 247 248 result = var8.getPickBlock(target, world, x, y, z); 249 } 250 else 251 { 252 if (target.typeOfHit != EnumMovingObjectType.ENTITY || target.entityHit == null || !isCreative) 253 { 254 return false; 255 } 256 257 result = target.entityHit.getPickedResult(target); 258 } 259 260 if (result == null) 261 { 262 return false; 263 } 264 265 for (int x = 0; x < 9; x++) 266 { 267 ItemStack stack = player.inventory.getStackInSlot(x); 268 if (stack != null && stack.isItemEqual(result)) 269 { 270 player.inventory.currentItem = x; 271 return true; 272 } 273 } 274 275 if (!isCreative) 276 { 277 return false; 278 } 279 280 int slot = player.inventory.getFirstEmptyStack(); 281 if (slot < 0 || slot >= 9) 282 { 283 slot = player.inventory.currentItem; 284 } 285 286 player.inventory.setInventorySlotContents(slot, result); 287 player.inventory.currentItem = slot; 288 return true; 289 } 290 291 //Optifine Helper Functions u.u, these are here specifically for Optifine 292 //Note: When using Optfine, these methods are invoked using reflection, which 293 //incurs a major performance penalty. 294 public static void onLivingSetAttackTarget(EntityLiving entity, EntityLiving target) 295 { 296 MinecraftForge.EVENT_BUS.post(new LivingSetAttackTargetEvent(entity, target)); 297 } 298 299 public static boolean onLivingUpdate(EntityLiving entity) 300 { 301 return MinecraftForge.EVENT_BUS.post(new LivingUpdateEvent(entity)); 302 } 303 304 public static boolean onLivingAttack(EntityLiving entity, DamageSource src, int amount) 305 { 306 return MinecraftForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, amount)); 307 } 308 309 public static int onLivingHurt(EntityLiving entity, DamageSource src, int amount) 310 { 311 LivingHurtEvent event = new LivingHurtEvent(entity, src, amount); 312 return (MinecraftForge.EVENT_BUS.post(event) ? 0 : event.ammount); 313 } 314 315 public static boolean onLivingDeath(EntityLiving entity, DamageSource src) 316 { 317 return MinecraftForge.EVENT_BUS.post(new LivingDeathEvent(entity, src)); 318 } 319 320 public static boolean onLivingDrops(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue) 321 { 322 return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit, specialDropValue)); 323 } 324 325 public static float onLivingFall(EntityLiving entity, float distance) 326 { 327 LivingFallEvent event = new LivingFallEvent(entity, distance); 328 return (MinecraftForge.EVENT_BUS.post(event) ? 0.0f : event.distance); 329 } 330 331 public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z) 332 { 333 return block != null && block.isLadder(world, x, y, z); 334 } 335 336 public static void onLivingJump(EntityLiving entity) 337 { 338 MinecraftForge.EVENT_BUS.post(new LivingJumpEvent(entity)); 339 } 340 341 public static EntityItem onPlayerTossEvent(EntityPlayer player, ItemStack item) 342 { 343 player.captureDrops = true; 344 EntityItem ret = player.dropPlayerItemWithRandomChoice(item, false); 345 player.capturedDrops.clear(); 346 player.captureDrops = false; 347 348 ItemTossEvent event = new ItemTossEvent(ret, player); 349 if (MinecraftForge.EVENT_BUS.post(event)) 350 { 351 return null; 352 } 353 354 player.joinEntityItemWithWorld(event.entityItem); 355 return event.entityItem; 356 } 357 }