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    }