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