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