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