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