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         * {@link FMLNetworkHandler#handlePacket250(Packet250CustomPayload, NetworkManager, NetHandler)}
567         *
568         * @param packet
569         */
570        @Deprecated
571        public static void receivePacket(Packet250CustomPayload packet)
572        {
573        }
574    
575        @Deprecated
576        @SideOnly(CLIENT)
577        public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
578        {
579            return keys;
580        }
581    
582        @Deprecated
583        @SideOnly(CLIENT)
584        public static void registerAllTextureOverrides(RenderEngine cache)
585        {
586        }
587    
588        /**
589         * Register a new block
590         *
591         * @param block
592         */
593        public static void registerBlock(Block block)
594        {
595            GameRegistry.registerBlock(block);
596        }
597    
598        /**
599         * Register a new block
600         *
601         * @param block
602         * @param itemclass
603         */
604        public static void registerBlock(Block block, Class<? extends ItemBlock> itemclass)
605        {
606            GameRegistry.registerBlock(block, itemclass);
607        }
608    
609        public static void registerContainerID(BaseMod mod, int id)
610        {
611            ModLoaderHelper.buildGuiHelper(mod, id);
612        }
613        /**
614         * Register a new entity ID
615         *
616         * @param entityClass
617         * @param entityName
618         * @param id
619         */
620        public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id)
621        {
622            EntityRegistry.registerGlobalEntityID(entityClass, entityName, id);
623        }
624    
625        /**
626         * Register a new entity ID
627         *
628         * @param entityClass
629         * @param entityName
630         * @param id
631         * @param background
632         * @param foreground
633         */
634        public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id, int background, int foreground)
635        {
636            EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
637        }
638    
639        @SideOnly(CLIENT)
640        public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
641        {
642            ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
643        }
644    
645        /**
646         * Register the mod for packets on this channel.
647         * {@link NetworkRegistry#registerChannel(IPacketHandler, String)}
648         *
649         * @param mod
650         * @param channel
651         */
652        public static void registerPacketChannel(BaseMod mod, String channel)
653        {
654            NetworkRegistry.instance().registerChannel(ModLoaderHelper.buildPacketHandlerFor(mod), channel);
655        }
656    
657        /**
658         * Register a new tile entity class
659         *
660         * @param tileEntityClass
661         * @param id
662         */
663        public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id)
664        {
665            GameRegistry.registerTileEntity(tileEntityClass, id);
666        }
667    
668        @SideOnly(CLIENT)
669        public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
670        {
671            ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
672        }
673    
674        /**
675         * Remove a biome from the list of generated biomes
676         *
677         * @param biome
678         */
679        public static void removeBiome(BiomeGenBase biome)
680        {
681            GameRegistry.removeBiome(biome);
682        }
683    
684        /**
685         * Remove a spawn
686         *
687         * @param entityClass
688         * @param spawnList
689         */
690        public static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList)
691        {
692            EntityRegistry.removeSpawn(entityClass, spawnList, WorldType.base12Biomes);
693        }
694    
695        /**
696         * Remove a spawn
697         *
698         * @param entityClass
699         * @param spawnList
700         * @param biomes
701         */
702        public static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList, BiomeGenBase... biomes)
703        {
704            EntityRegistry.removeSpawn(entityClass, spawnList, biomes);
705        }
706    
707        /**
708         * Remove a spawn
709         *
710         * @param entityName
711         * @param spawnList
712         */
713        public static void removeSpawn(String entityName, EnumCreatureType spawnList)
714        {
715            EntityRegistry.removeSpawn(entityName, spawnList, WorldType.base12Biomes);
716        }
717    
718        /**
719         * Remove a spawn
720         *
721         * @param entityName
722         * @param spawnList
723         * @param biomes
724         */
725        public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
726        {
727            EntityRegistry.removeSpawn(entityName, spawnList, biomes);
728        }
729    
730        @Deprecated
731        @SideOnly(CLIENT)
732        public static boolean renderBlockIsItemFull3D(int modelID)
733        {
734            return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
735        }
736    
737        @Deprecated
738        @SideOnly(CLIENT)
739        public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
740        {
741            RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
742        }
743    
744        @Deprecated
745        @SideOnly(CLIENT)
746        public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
747        {
748            return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
749        }
750    
751        /**
752         * Configuration is handled elsewhere
753         * {@link ModLoaderModContainer}
754         */
755        @Deprecated
756        public static void saveConfig()
757        {
758        }
759    
760        /**
761         * Send a packet from client to server
762         *
763         * @param packet
764         */
765        public static void sendPacket(Packet packet) {
766            PacketDispatcher.sendPacketToServer(packet);
767        }
768        /**
769         * Send a chat message to the server
770         * {@link FMLNetworkHandler#handleChatMessage(NetHandler, Packet3Chat)}
771         *
772         * @param text
773         */
774        @Deprecated
775        public static void serverChat(String text)
776        {
777            //TODO
778        }
779    
780        @Deprecated
781        @SideOnly(CLIENT)
782        public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
783        {
784            //TODO
785        }
786    
787        public static void serverSendPacket(NetServerHandler handler, Packet packet)
788        {
789            if (handler != null)
790            {
791                PacketDispatcher.sendPacketToPlayer(packet, (Player)handler.getPlayer());
792            }
793        }
794        public static void serverOpenWindow(EntityPlayerMP player, Container container, int ID, int x, int y, int z)
795        {
796            ModLoaderHelper.openGui(ID, player, container, x, y, z);
797        }
798    
799        /**
800         * Indicate that you want to receive ticks
801         *
802         * @param mod receiving the events
803         * @param enable indicates whether you want to recieve them or not
804         * @param useClock don't receive render subticks, just world ticks
805         */
806        public static void setInGameHook(BaseMod mod, boolean enable, boolean useClock)
807        {
808            ModLoaderHelper.updateStandardTicks(mod, enable, useClock);
809        }
810    
811    
812        public static void setInGUIHook(BaseMod mod, boolean enable, boolean useClock)
813        {
814            ModLoaderHelper.updateGUITicks(mod, enable, useClock);
815        }
816    
817        /**
818         * Set a private field to a value using reflection
819         * {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, int, Object)}
820         *
821         * @param instanceclass
822         * @param instance
823         * @param fieldindex
824         * @param value
825         */
826        public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, int fieldindex, E value)
827        {
828            ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, fieldindex);
829        }
830    
831        /**
832         * Set a private field to a value using reflection
833         * {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, String, Object)}
834         *
835         * @param instanceclass
836         * @param instance
837         * @param field
838         * @param value
839         */
840        public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, String field, E value)
841        {
842            ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, field);
843        }
844    
845        /**
846         * This method is a call in hook from modified external code. Implemented elsewhere.
847         *
848         * @param player
849         * @param item
850         * @param matrix
851         */
852        @Deprecated
853        public static void takenFromCrafting(EntityPlayer player, ItemStack item, IInventory matrix)
854        {
855        }
856    
857        /**
858         * This method is a call in hook from modified external code. Implemented elsewhere.
859         *
860         * @param player
861         * @param item
862         */
863        @Deprecated
864        public static void takenFromFurnace(EntityPlayer player, ItemStack item)
865        {
866        }
867    
868        /**
869         * Throw the offered exception. Likely will stop the game.
870         *
871         * @param message
872         * @param e
873         */
874        public static void throwException(String message, Throwable e)
875        {
876            FMLCommonHandler.instance().raiseException(e, message, true);
877        }
878    
879        public static void throwException(Throwable e)
880        {
881            throwException("Exception in ModLoader", e);
882        }
883    }