001    /*
002     * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw
003     *
004     * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
005     * Software Foundation; either version 2.1 of the License, or any later version.
006     *
007     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
008     * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
009     *
010     * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
011     * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
012     */
013    package net.minecraft.src;
014    
015    import static cpw.mods.fml.common.Side.CLIENT;
016    
017    import java.awt.image.BufferedImage;
018    import java.util.Collections;
019    import java.util.List;
020    import java.util.Map;
021    import java.util.logging.Logger;
022    
023    import net.minecraft.client.Minecraft;
024    import net.minecraft.server.MinecraftServer;
025    import cpw.mods.fml.client.FMLClientHandler;
026    import cpw.mods.fml.client.SpriteHelper;
027    import cpw.mods.fml.client.TextureFXManager;
028    import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
029    import cpw.mods.fml.client.modloader.ModLoaderKeyBindingHandler;
030    import cpw.mods.fml.client.registry.ClientRegistry;
031    import cpw.mods.fml.client.registry.KeyBindingRegistry;
032    import cpw.mods.fml.client.registry.RenderingRegistry;
033    import cpw.mods.fml.common.FMLCommonHandler;
034    import cpw.mods.fml.common.FMLLog;
035    import cpw.mods.fml.common.Loader;
036    import cpw.mods.fml.common.ObfuscationReflectionHelper;
037    import cpw.mods.fml.common.asm.SideOnly;
038    import cpw.mods.fml.common.modloader.ModLoaderHelper;
039    import cpw.mods.fml.common.modloader.ModLoaderModContainer;
040    import cpw.mods.fml.common.network.NetworkRegistry;
041    import cpw.mods.fml.common.network.PacketDispatcher;
042    import cpw.mods.fml.common.network.Player;
043    import cpw.mods.fml.common.registry.EntityRegistry;
044    import cpw.mods.fml.common.registry.GameRegistry;
045    import cpw.mods.fml.common.registry.LanguageRegistry;
046    import cpw.mods.fml.server.FMLServerHandler;
047    
048    /**
049     * @author cpw
050     *
051     */
052    public class ModLoader
053    {
054        public static final String fmlMarker = "This is an FML marker";
055        // TODO dirty workaround for millinaire
056        @Deprecated
057        public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap();
058        /**
059         * Not used on the server.
060         *
061         * @param achievement
062         * @param name
063         * @param description
064         */
065        public static void addAchievementDesc(Achievement achievement, String name, String description)
066        {
067            String achName=achievement.getName();
068            addLocalization(achName, name);
069            addLocalization(achName+".desc", description);
070        }
071    
072        /**
073         * This method is a call in hook from modified external code. Implemented elsewhere.
074         *
075         * {@link FMLCommonHandler#fuelLookup(int, int)}
076         *
077         * @param id
078         * @param metadata
079         * @return
080         */
081        @Deprecated
082        public static int addAllFuel(int id, int metadata)
083        {
084            return 0;
085        }
086    
087        @Deprecated
088        @SideOnly(CLIENT)
089        public static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers)
090        {
091        }
092    
093        @SideOnly(CLIENT)
094        public static void addAnimation(TextureFX anim)
095        {
096            TextureFXManager.instance().addAnimation(anim);
097        }
098    
099        /**
100         *
101         * @param armor
102         * @return
103         */
104        @SideOnly(CLIENT)
105        public static int addArmor(String armor)
106        {
107            return RenderingRegistry.addNewArmourRendererPrefix(armor);
108        }
109    
110        /**
111         * This method adds the supplied biome to the set of candidate biomes for the default world generator type.
112         *
113         * @param biome
114         */
115        public static void addBiome(BiomeGenBase biome)
116        {
117            GameRegistry.addBiome(biome);
118        }
119    
120        public static void addEntityTracker(BaseMod mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval, boolean sendVelocityInfo)
121        {
122            ModLoaderHelper.buildEntityTracker(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
123        }
124    
125        public static void addCommand(ICommand command)
126        {
127            ModLoaderHelper.addCommand(command);
128        }
129        /**
130         * Add localization for the specified string
131         *
132         * @param key
133         * @param value
134         */
135        public static void addLocalization(String key, String value)
136        {
137            addLocalization(key, "en_US", value);
138        }
139    
140        /**
141         * Add localization for the specified string
142         *
143         * @param key
144         * @param lang
145         * @param value
146         */
147        public static void addLocalization(String key, String lang, String value)
148        {
149            LanguageRegistry.instance().addStringLocalization(key, lang, value);
150        }
151    
152        /**
153         * Name the specified minecraft object with the supplied name
154         *
155         * @param instance
156         * @param name
157         */
158        public static void addName(Object instance, String name)
159        {
160            addName(instance,"en_US",name);
161        }
162    
163        /**
164         * Unimplemented on the server as it does not generate names
165         *
166         * @param instance
167         * @param lang
168         * @param name
169         */
170        public static void addName(Object instance, String lang, String name)
171        {
172            LanguageRegistry.instance().addNameForObject(instance, lang, name);
173        }
174    
175        /**
176         * Unimplemented on the server as it does not render textures
177         *
178         * @param fileToOverride
179         * @param fileToAdd
180         * @return
181         */
182        @SideOnly(CLIENT)
183        public static int addOverride(String fileToOverride, String fileToAdd)
184        {
185            return RenderingRegistry.addTextureOverride(fileToOverride, fileToAdd);
186        }
187    
188        /**
189         * Unimplemented on the server as it does not render textures
190         *
191         * @param path
192         * @param overlayPath
193         * @param index
194         */
195        @SideOnly(CLIENT)
196        public static void addOverride(String path, String overlayPath, int index)
197        {
198            RenderingRegistry.addTextureOverride(path, overlayPath, index);
199        }
200    
201        /**
202         * Add a Shaped Recipe
203         *
204         * @param output
205         * @param params
206         */
207        public static void addRecipe(ItemStack output, Object... params)
208        {
209            GameRegistry.addRecipe(output, params);
210        }
211    
212        /**
213         * Add a shapeless recipe
214         *
215         * @param output
216         * @param params
217         */
218        public static void addShapelessRecipe(ItemStack output, Object... params)
219        {
220            GameRegistry.addShapelessRecipe(output, params);
221        }
222    
223        /**
224         * Add a new product to be smelted
225         *
226         * @param input
227         * @param output
228         */
229        public static void addSmelting(int input, ItemStack output)
230        {
231            GameRegistry.addSmelting(input, output, 1.0f);
232        }
233    
234        /**
235         * Add a new product to be smelted
236         *
237         * @param input
238         * @param output
239         */
240        public static void addSmelting(int input, ItemStack output, float experience)
241        {
242            GameRegistry.addSmelting(input, output, experience);
243        }
244        /**
245         * Add a mob to the spawn list
246         *
247         * @param entityClass
248         * @param weightedProb
249         * @param min
250         * @param max
251         * @param spawnList
252         */
253        public static void addSpawn(Class<? extends EntityLiving> entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList)
254        {
255            EntityRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, WorldType.base12Biomes);
256        }
257    
258        /**
259         * Add a mob to the spawn list
260         *
261         * @param entityClass
262         * @param weightedProb
263         * @param min
264         * @param max
265         * @param spawnList
266         * @param biomes
267         */
268        public static void addSpawn(Class<? extends EntityLiving> entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
269        {
270            EntityRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, biomes);
271        }
272    
273        /**
274         * Add a mob to the spawn list
275         *
276         * @param entityName
277         * @param weightedProb
278         * @param min
279         * @param max
280         * @param spawnList
281         */
282        public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList)
283        {
284            EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, WorldType.base12Biomes);
285        }
286    
287        /**
288         * Add a mob to the spawn list
289         *
290         * @param entityName
291         * @param weightedProb
292         * @param min
293         * @param max
294         * @param spawnList
295         * @param biomes
296         */
297        public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
298        {
299            EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
300        }
301    
302        public static void addTrade(int profession, TradeEntry entry)
303        {
304            ModLoaderHelper.registerTrade(profession, entry);
305        }
306        /**
307         * Send a packet from the client
308         * @param packet
309         */
310        public static void clientSendPacket(Packet packet)
311        {
312            PacketDispatcher.sendPacketToServer(packet);
313        }
314    
315        /**
316         * This method is a call in hook from modified external code. Implemented elsewhere.
317         *
318         * @param world
319         * @param x
320         * @param y
321         * @param z
322         * @param xVel
323         * @param zVel
324         * @param item
325         * @return
326         */
327        @Deprecated
328        public static boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
329        {
330            return false;
331        }
332    
333        /**
334         * Remove a container and drop all the items in it on the ground around
335         *
336         * @param world
337         * @param x
338         * @param y
339         * @param z
340         */
341        public static void genericContainerRemoval(World world, int x, int y, int z)
342        {
343    /*        TileEntity te = world.func_603_b(x, y, z);
344    
345            if (!(te instanceof IInventory))
346            {
347                return;
348            }
349    
350            IInventory inv = (IInventory)te;
351    
352            for (int l = 0; l < inv.func_469_c(); l++)
353            {
354                ItemStack itemstack = inv.func_468_c(l);
355    
356                if (itemstack == null)
357                {
358                    continue;
359                }
360    
361                float f = world.field_1037_n.nextFloat() * 0.8F + 0.1F;
362                float f1 = world.field_1037_n.nextFloat() * 0.8F + 0.1F;
363                float f2 = world.field_1037_n.nextFloat() * 0.8F + 0.1F;
364    
365                while (itemstack.field_1615_a > 0)
366                {
367                    int i1 = world.field_1037_n.nextInt(21) + 10;
368    
369                    if (i1 > itemstack.field_1615_a)
370                    {
371                        i1 = itemstack.field_1615_a;
372                    }
373    
374                    itemstack.field_1615_a -= i1;
375                    EntityItem entityitem = new EntityItem(world, (float)te.field_823_f + f, (float)te.field_822_g + f1, (float)te.field_821_h + f2, new ItemStack(itemstack.field_1617_c, i1, itemstack.func_21181_i()));
376                    float f3 = 0.05F;
377                    entityitem.field_608_an = (float) world.field_1037_n.nextGaussian() * f3;
378                    entityitem.field_607_ao = (float) world.field_1037_n.nextGaussian() * f3 + 0.2F;
379                    entityitem.field_606_ap = (float) world.field_1037_n.nextGaussian() * f3;
380    
381                    if (itemstack.func_40710_n())
382                    {
383                        entityitem.field_801_a.func_40706_d((NBTTagCompound) itemstack.func_40709_o().func_40195_b());
384                    }
385    
386                    world.func_674_a(entityitem);
387                }
388            }
389    */    }
390    
391        /**
392         * Get a list of all BaseMod loaded into the system
393         * {@link ModLoaderModContainer#findAll}
394         *
395         * @return
396         */
397        public static List<BaseMod> getLoadedMods()
398        {
399            return ModLoaderModContainer.findAll(BaseMod.class);
400        }
401    
402        /**
403         * Get a logger instance {@link FMLCommonHandler#getFMLLogger()}
404         *
405         * @return
406         */
407        public static Logger getLogger()
408        {
409            return FMLLog.getLogger();
410        }
411    
412        @SideOnly(CLIENT)
413        public static Minecraft getMinecraftInstance()
414        {
415            return FMLClientHandler.instance().getClient();
416        }
417    
418        /**
419         *
420         * @return
421         */
422        public static MinecraftServer getMinecraftServerInstance()
423        {
424            return FMLCommonHandler.instance().getMinecraftServerInstance();
425        }
426    
427        /**
428         * Get a value from a field using reflection
429         * {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, int)}
430         *
431         * @param instanceclass
432         * @param instance
433         * @param fieldindex
434         * @return
435         */
436        public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, int fieldindex)
437        {
438            return ObfuscationReflectionHelper.getPrivateValue(instanceclass, instance, fieldindex);
439        }
440    
441        /**
442         * Get a value from a field using reflection
443         * {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, String)}
444         *
445         * @param instanceclass
446         * @param instance
447         * @param field
448         * @return
449         */
450        public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, String field)
451        {
452            return ObfuscationReflectionHelper.getPrivateValue(instanceclass, instance, field);
453        }
454    
455        /**
456         * Stubbed method on the server to return a unique model id
457         *
458         */
459        @SideOnly(CLIENT)
460        public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
461        {
462            return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
463        }
464    
465        /**
466         * Get a new unique entity id
467         * {@link Entity#getNextId()}
468         *
469         * @return
470         */
471        public static int getUniqueEntityId()
472        {
473            return EntityRegistry.findGlobalUniqueEntityId();
474        }
475    
476        @SideOnly(CLIENT)
477        public static int getUniqueSpriteIndex(String path)
478        {
479            return SpriteHelper.getUniqueSpriteIndex(path);
480        }
481    
482        /**
483         * To properly implement packet 250 protocol you should always check your
484         * channel is active prior to sending the packet
485         *
486         * @param player
487         * @param channel
488         * @return
489         */
490        public static boolean isChannelActive(EntityPlayer player, String channel)
491        {
492            return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
493        }
494    
495        @SideOnly(CLIENT)
496        public static boolean isGUIOpen(Class<? extends GuiScreen> gui)
497        {
498            return FMLClientHandler.instance().getClient().currentScreen != null && FMLClientHandler.instance().getClient().currentScreen.equals(gui);
499        }
500    
501        /**
502         * Is the named mod loaded?
503         * {@link Loader#isModLoaded(String)}
504         *
505         * @param modname
506         * @return
507         */
508        public static boolean isModLoaded(String modname)
509        {
510            return Loader.isModLoaded(modname);
511        }
512    
513        /**
514         * Implemented elsewhere
515         */
516        @Deprecated
517        public static void loadConfig()
518        {
519        }
520    
521        @SideOnly(CLIENT)
522        public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
523        {
524            return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
525        }
526    
527        /**
528         * Call in from elsewhere. Unimplemented here.
529         * @param player
530         * @param item
531         */
532        @Deprecated
533        public static void onItemPickup(EntityPlayer player, ItemStack item)
534        {
535        }
536        /**
537         * Call in from elsewhere. Unimplemented here.
538         */
539        @Deprecated
540        @SideOnly(CLIENT)
541        public static void onTick(float tick, Minecraft game)
542        {
543        }
544    
545        @SideOnly(CLIENT)
546        public static void openGUI(EntityPlayer player, GuiScreen gui)
547        {
548            FMLClientHandler.instance().displayGuiScreen(player, gui);
549        }
550    
551        @Deprecated
552        public static void populateChunk(IChunkProvider generator, int chunkX, int chunkZ, World world)
553        {
554        }
555    
556        /**
557         * This method is a call in hook from modified external code. Implemented elsewhere.
558         * {@link FMLServerHandler#handlePacket250(Packet250CustomPayload, EntityPlayer)}
559         *
560         * @param packet
561         */
562        @Deprecated
563        public static void receivePacket(Packet250CustomPayload packet)
564        {
565        }
566    
567        @Deprecated
568        @SideOnly(CLIENT)
569        public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
570        {
571            return keys;
572        }
573    
574        @Deprecated
575        @SideOnly(CLIENT)
576        public static void registerAllTextureOverrides(RenderEngine cache)
577        {
578        }
579    
580        /**
581         * Register a new block
582         *
583         * @param block
584         */
585        public static void registerBlock(Block block)
586        {
587            GameRegistry.registerBlock(block);
588        }
589    
590        /**
591         * Register a new block
592         *
593         * @param block
594         * @param itemclass
595         */
596        public static void registerBlock(Block block, Class<? extends ItemBlock> itemclass)
597        {
598            GameRegistry.registerBlock(block, itemclass);
599        }
600    
601        public static void registerContainerID(BaseMod mod, int id)
602        {
603            ModLoaderHelper.buildGuiHelper(mod, id);
604        }
605        /**
606         * Register a new entity ID
607         *
608         * @param entityClass
609         * @param entityName
610         * @param id
611         */
612        public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id)
613        {
614            EntityRegistry.registerGlobalEntityID(entityClass, entityName, id);
615        }
616    
617        /**
618         * Register a new entity ID
619         *
620         * @param entityClass
621         * @param entityName
622         * @param id
623         * @param background
624         * @param foreground
625         */
626        public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id, int background, int foreground)
627        {
628            EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
629        }
630    
631        @SideOnly(CLIENT)
632        public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
633        {
634            ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
635        }
636    
637        /**
638         * Register the mod for packets on this channel.
639         * {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)}
640         *
641         * @param mod
642         * @param channel
643         */
644        public static void registerPacketChannel(BaseMod mod, String channel)
645        {
646            NetworkRegistry.instance().registerChannel(ModLoaderHelper.buildPacketHandlerFor(mod), channel);
647        }
648    
649        /**
650         * Register a new tile entity class
651         *
652         * @param tileEntityClass
653         * @param id
654         */
655        public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id)
656        {
657            GameRegistry.registerTileEntity(tileEntityClass, id);
658        }
659    
660        @SideOnly(CLIENT)
661        public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
662        {
663            ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
664        }
665    
666        /**
667         * Remove a biome from the list of generated biomes
668         *
669         * @param biome
670         */
671        public static void removeBiome(BiomeGenBase biome)
672        {
673            GameRegistry.removeBiome(biome);
674        }
675    
676        /**
677         * Remove a spawn
678         *
679         * @param entityClass
680         * @param spawnList
681         */
682        public static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList)
683        {
684            EntityRegistry.removeSpawn(entityClass, spawnList, WorldType.base12Biomes);
685        }
686    
687        /**
688         * Remove a spawn
689         *
690         * @param entityClass
691         * @param spawnList
692         * @param biomes
693         */
694        public static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList, BiomeGenBase... biomes)
695        {
696            EntityRegistry.removeSpawn(entityClass, spawnList, biomes);
697        }
698    
699        /**
700         * Remove a spawn
701         *
702         * @param entityName
703         * @param spawnList
704         */
705        public static void removeSpawn(String entityName, EnumCreatureType spawnList)
706        {
707            EntityRegistry.removeSpawn(entityName, spawnList, WorldType.base12Biomes);
708        }
709    
710        /**
711         * Remove a spawn
712         *
713         * @param entityName
714         * @param spawnList
715         * @param biomes
716         */
717        public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
718        {
719            EntityRegistry.removeSpawn(entityName, spawnList, biomes);
720        }
721    
722        @Deprecated
723        @SideOnly(CLIENT)
724        public static boolean renderBlockIsItemFull3D(int modelID)
725        {
726            return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
727        }
728    
729        @Deprecated
730        @SideOnly(CLIENT)
731        public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
732        {
733            RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
734        }
735    
736        @Deprecated
737        @SideOnly(CLIENT)
738        public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
739        {
740            return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
741        }
742    
743        /**
744         * Configuration is handled elsewhere
745         * {@link ModLoaderModContainer}
746         */
747        @Deprecated
748        public static void saveConfig()
749        {
750        }
751    
752        /**
753         * Send a packet from client to server
754         *
755         * @param packet
756         */
757        public static void sendPacket(Packet packet) {
758            PacketDispatcher.sendPacketToServer(packet);
759        }
760        /**
761         * Send a chat message to the server
762         * {@link FMLClientHandler#handleChatPacket(Packet3Chat, EntityPlayer)}
763         *
764         * @param text
765         */
766        @Deprecated
767        public static void serverChat(String text)
768        {
769            //TODO
770        }
771    
772        @Deprecated
773        @SideOnly(CLIENT)
774        public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
775        {
776            //TODO
777        }
778    
779        public static void serverSendPacket(NetServerHandler handler, Packet packet)
780        {
781            if (handler != null)
782            {
783                PacketDispatcher.sendPacketToPlayer(packet, (Player)handler.getPlayer());
784            }
785        }
786        public static void serverOpenWindow(EntityPlayerMP player, Container container, int ID, int x, int y, int z)
787        {
788            ModLoaderHelper.openGui(ID, player, container, x, y, z);
789        }
790    
791        /**
792         * Indicate that you want to receive ticks
793         *
794         * @param mod receiving the events
795         * @param enable indicates whether you want to recieve them or not
796         * @param useClock don't receive render subticks, just world ticks
797         */
798        public static void setInGameHook(BaseMod mod, boolean enable, boolean useClock)
799        {
800            ModLoaderHelper.updateStandardTicks(mod, enable, useClock);
801        }
802    
803    
804        public static void setInGUIHook(BaseMod mod, boolean enable, boolean useClock)
805        {
806            ModLoaderHelper.updateGUITicks(mod, enable, useClock);
807        }
808    
809        /**
810         * Set a private field to a value using reflection
811         * {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, int, Object)}
812         *
813         * @param instanceclass
814         * @param instance
815         * @param fieldindex
816         * @param value
817         */
818        public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, int fieldindex, E value)
819        {
820            ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, fieldindex);
821        }
822    
823        /**
824         * Set a private field to a value using reflection
825         * {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, String, Object)}
826         *
827         * @param instanceclass
828         * @param instance
829         * @param field
830         * @param value
831         */
832        public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, String field, E value)
833        {
834            ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, field);
835        }
836    
837        /**
838         * This method is a call in hook from modified external code. Implemented elsewhere.
839         *
840         * @param player
841         * @param item
842         * @param matrix
843         */
844        @Deprecated
845        public static void takenFromCrafting(EntityPlayer player, ItemStack item, IInventory matrix)
846        {
847        }
848    
849        /**
850         * This method is a call in hook from modified external code. Implemented elsewhere.
851         *
852         * @param player
853         * @param item
854         */
855        @Deprecated
856        public static void takenFromFurnace(EntityPlayer player, ItemStack item)
857        {
858        }
859    
860        /**
861         * Throw the offered exception. Likely will stop the game.
862         *
863         * @param message
864         * @param e
865         */
866        public static void throwException(String message, Throwable e)
867        {
868            FMLCommonHandler.instance().raiseException(e, message, true);
869        }
870    
871        public static void throwException(Throwable e)
872        {
873            throwException("Exception in ModLoader", e);
874        }
875    }