cad97
Forge Modder-
Posts
61 -
Joined
-
Last visited
Converted
-
Gender
Male
-
URL
http://CAD97.com
-
Personal Text
Short time modder, longer time coder
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
cad97's Achievements
Stone Miner (3/8)
9
Reputation
-
If my debug-crawling through the startup code is accurate, the current order is something like (trimmed to relevant items): The effect of this is that during the IRecipe registration event, vanilla JSON recipes are in the registry but forge-loaded ones are not. It would be more consistent to load all JSON recipes before firing the programmatic registration event. What's the reason I want this? During the recipe registration event, it is possible to remove vanilla JSON recipes: @SubscribeEvent public static void registerRecipes(RegistryEvent.Register<IRecipe> event) { ((IForgeRegistryModifiable<IRecipe>)event.getRegistry()).remove(new ResourceLocation("minecraft:anvil")); } With this listener registered, the minecraft:anvil recipe disappears without a trace. Unfortunately, because mod JSON recipes' loading is far off at this point, it is not possible to remove those, because they don't exist yet. Note that doing this during FMLInitializationEvent (via ForgeRegistries.RECIPES of course) removes the recipe but leads to a game crash when trying to render the recipe book. A feature to properly remove JSON loaded recipes programmatically (based on config settings) would render this unnecessary.
-
ob·fus·ca·tion ˌäbfəˈskāSH(ə)n/ noun noun: obfuscation; plural noun: obfuscations the action of making something obscure, unclear, or unintelligible. "when confronted with sharp questions they resort to obfuscation" The Minecraft source is obfuscated. That's where the unreadable parameter names come from (effectively). MCP is the community's mapping of these machine-generated names back into human-readable forms. You can try updating your mappings, and if that doesn't give names to the code (potentially breaking references -- be careful), you could consider contributing mappings yourself. But for the most part, trivial methods and newer methods have fewer/worse names because people haven't bothered to give them names again, because their effort was better spent on one of many other useful tasks.
-
bug ItemStackHolder crashes on private field (ObjectHolder doesn't)
cad97 replied to cad97's topic in Modder Support
Whoops. I could have sworn I gave a once-over for a proper board. Can this be moved or should I re-post? (@Draco18s) EDIT: reposted -
TL;DR reproduction case: import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.GameRegistry; import org.apache.logging.log4j.Logger; @Mod(modid = "itemstackholder") public class ISHMod { private Logger logger; @GameRegistry.ObjectHolder("minecraft:iron_bars") private static Item itemIronBars; @GameRegistry.ItemStackHolder("minecraft:iron_bars") private static ItemStack stackIronBars; public Logger getLogger() { return logger; } @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { logger = event.getModLog(); } @Mod.EventHandler public void postInit(FMLPostInitializationEvent event) { logger.info(itemIronBars.toString()); logger.info(stackIronBars.toString()); } } This crashes with: [20:24:57] [main/INFO] [FML]: Processing ObjectHolder annotations [20:24:57] [main/INFO] [FML]: Found 1169 ObjectHolder annotations [20:24:57] [main/INFO] [FML]: Identifying ItemStackHolder annotations [20:24:57] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ---- // Everything's going to plan. No, really, that was supposed to happen. Time: 7/6/17 8:24 PM Description: Initializing game java.lang.RuntimeException: java.lang.NoSuchFieldException: stackIronBars at com.google.common.base.Throwables.propagate(Throwables.java:240) at net.minecraftforge.fml.common.registry.ItemStackHolderInjector.addHolder(ItemStackHolderInjector.java:97) at net.minecraftforge.fml.common.registry.ItemStackHolderInjector.findHolders(ItemStackHolderInjector.java:63) at net.minecraftforge.fml.common.Loader.preinitializeMods(Loader.java:602) at net.minecraftforge.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:266) at net.minecraft.client.Minecraft.init(Minecraft.java:508) at net.minecraft.client.Minecraft.run(Minecraft.java:416) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) Caused by: java.lang.NoSuchFieldException: stackIronBars at java.lang.Class.getField(Class.java:1703) at net.minecraftforge.fml.common.registry.ItemStackHolderInjector.addHolder(ItemStackHolderInjector.java:91) ... 18 more A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Client thread Stacktrace: at com.google.common.base.Throwables.propagate(Throwables.java:240) at net.minecraftforge.fml.common.registry.ItemStackHolderInjector.addHolder(ItemStackHolderInjector.java:97) at net.minecraftforge.fml.common.registry.ItemStackHolderInjector.findHolders(ItemStackHolderInjector.java:63) at net.minecraftforge.fml.common.Loader.preinitializeMods(Loader.java:602) at net.minecraftforge.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:266) at net.minecraft.client.Minecraft.init(Minecraft.java:508) -- Initialization -- Details: Stacktrace: at net.minecraft.client.Minecraft.run(Minecraft.java:416) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) -- System Details -- Details: Minecraft Version: 1.12 Operating System: Windows 10 (amd64) version 10.0 Java Version: 1.8.0_121, Oracle Corporation Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 653341240 bytes (623 MB) / 789053440 bytes (752 MB) up to 3801088000 bytes (3625 MB) JVM Flags: 0 total; IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0 FML: MCP 9.40 Powered by Forge 14.21.1.2387 5 mods loaded, 5 mods active States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored UC minecraft{1.12} [Minecraft] (minecraft.jar) UC mcp{9.19} [Minecraft Coder Pack] (minecraft.jar) UC FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.12-14.21.1.2387.jar) UC forge{14.21.1.2387} [Minecraft Forge] (forgeSrc-1.12-14.21.1.2387.jar) UC itemstackholder{1.0} [itemstackholder] (itemstackholder_main) Loaded coremods (and transformers): GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 382.05' Renderer: 'GeForce GTX 860M/PCIe/SSE2' Launched Version: 1.12 LWJGL: 2.9.4 OpenGL: GeForce GTX 860M/PCIe/SSE2 GL version 4.5.0 NVIDIA 382.05, NVIDIA Corporation GL Caps: Using GL 1.3 multitexturing. Using GL 1.3 texture combiners. Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported. Shaders are available because OpenGL 2.1 is supported. VBOs are available because OpenGL 1.5 is supported. Using VBOs: Yes Is Modded: Definitely; Client brand changed to 'fml,forge' Type: Client (map_client.txt) Resource Packs: Current Language: English (US) Profiler Position: N/A (disabled) CPU: 8x Intel(R) Core(TM) i7-4810MQ CPU @ 2.80GHz [20:24:57] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: #@!@# Game crashed! Crash report saved to: #@!@# D:\...\itemstackholder\run\.\crash-reports\crash-2017-07-06_20.24.57-client.txt The crash comes from a catch/throw in Minecraft Forge with a comment // unpossible?, so should be worth looking into. The behaviors are different, so one is (probably) more wrong. The difference looks to be this: ItemStackHolderInjector uses Field f = clazz.getField(annotationTarget); and ObjectHolderRegistry uses Field f = clazz.getDeclaredField(annotationTarget);. Switching ItemStackHolderInjector to use Class::getDeclaredField like ObjectHolderRegistry would, at the very least, save future modders the confusion I felt when java told me that the field that is right there doesn't exist. This would also enable the use case where I discovered this: private fields populated with ItemStacks for use in recipe registration. Because I've caught Kotlin fever, the linked code there is in Kotlin, but compiles to the equivalent private static member (with a private set method and a public get method, as of the linked commit; I plan to make it fully private, this was just the work commit where I caught this issue). I can make this an issue and/or PR against the MinecraftForge GitHub, but I didn't want to needlessly clutter the repository if this is considered a non-issue. Consider my vote to apply this one-line patch, though. I haven't tested this, because I don't currently have the setup required to build a custom version of forge and test it.
-
The new rendering system uses JSON resources to specify item model rendering. You can see a basic working example here: http://modwiki.temporal-reality.com/mw/index.php/Render_Item_Basic-1.9 The correct registration call is ModelLoader.setCustomModelResourceLocation(this, 0, new ModelResourceLocation("itemID", "inventory")); And a JSON file located at main/resources/assets/<yourmod>/models/item/itemID.json { "parent": "builtin/generated", "textures": { "layer0": "modID:items/itemtexture" }, "display": { "thirdperson": { "rotation": [ -90, 0, 0 ], "translation": [ 0, 1, -3 ], "scale": [ 0.55, 0.55, 0.55 ] }, "firstperson": { "rotation": [ 0, -135, 25 ], "translation": [ 0, 4, 2 ], "scale": [ 1.7, 1.7, 1.7 ] } } }
-
I noticed that net.minecraft.Block::isOpaqueCube(IBlockState) is @Deprecated. What is the preferred method of achieving a non-opaque block, in this case? Was the method deprecated incorrectly or is there a better way to achieve the same effect as overriding the method to return false? (I am looking at forgeSrc-1.10-12.18.0.1996-1.10.0-sources.jar)
-
Thanks, that's exactly what I needed. (And duh, I've done that before. Why didn't I think of that.)
-
Between two versions of my mod I've changed how data on an item is stored. I can easy convert to the new version, but where is the best place to call that update routine? I want a way to call updateToNewVersion(ItemStack) (for example) on all ItemStacks of one custom Item only one time if they need updating. (They need updating if they have non-zero metadata and no NBT tags.)
-
That's the answer I hoped not to hear, but it wasn't as hard to implement as I feared. Commit of solution here. I can't shake the feeling that I could have done NBTSensitiveShapedRecipe better though. All but 6 lines (effectively less) of the actual work methods are direct rips from the superclass ShapedRecipes, and copy/pasting code is a bad practice -- I mean OOP is about reusing code. The thing is the only way I saw to override checkMatch() (which is what I needed to add those 6 lines to) was to point matches() at a new version, as it is a private member of the superclass and as such cannot be overwritten directly. This is probably the easiest way to do it, but I still feel it could be done better with less repeated code. Even if what I wanted to do originally (@Override checkMatch()) wouldn't even have saved most of the copied lines. It's just those 6 lines of check need to be in that part of the process.
-
I'm trying to move my mod SpawnerCraft over to the new EntityRegistry system: i.e. looking at Strings and checking those against Forge's database instead of using the ID system used by Spawn Eggs as of old. This means that I've moved from using metadata to specify the mob in an item to an NBT tag. I need help creating a NBT sensitive recipe. I have my current recipe registration here but apparently the NBT tag on the ingredient is not considered in this way. It always gives out for creepers (the first on the EntityEgg list). How can I register a recipe that requires the same NBT data and spits out an item with the same NBT data? (To be clear, in abstract I want: four of my items in a square with identical NBT structure. It spits out one of next tier with the same NBT structure.)
-
Aaaand I'm a derp. configuration.get() takes the category then the field while configuration.getBoolean() takes the field and then the category. I switched them up and got weird results. It works though now!
-
You need to use this method: /** * Gets the block's texture. Args: side, meta */ @SideOnly(Side.CLIENT) public IIcon getIcon(int p_149691_1_, int p_149691_2_) In BlockSapling the body is this: { p_149691_2_ &= 7; return field_149881_b[MathHelper.clamp_int(p_149691_2_, 0, 5)]; } So looking at your code the body should look something like this: { p_149691_2_ &= 7; // Though I don't know exactly what this is for, I would keep it as long as it won't cause a problem. // This is a binary and on binary 0111 if you're curious, should have the same effect as %= 7 if I'm not mistaken. return saplingicon[MathHelper.clamp_int(p_149691_2_, 0, 1)]; // 0, 1 in clamp_int is to make sure you don't overIndex your saplingicon[] //which currently has two icons in it (at indexes 0 and 1). } And as always, feel free to rename parameter names in overridden code, you don't need to keep the parameter names just the types.
-
Thanks, diesieben, for clarifying, and jabelar and WorldsEnder for posting their .gitignores. I've got what I need now, thanks!
-
It took me a while to find, but I got it. I'd looked before for the solution you suggested, jabelar, by going through the event.harvester options, but not found it. Looking at the stacktrace for event.isSilkTouching, though, I was able to find the call required: EnchantmentHelper.getSilkTouchModifier(event.harvester) . Looking more at isSilkTouching it does only seem to be true for silktouch-able blocks.