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