Posted January 16, 20214 yr I have registered blocks for both a Standing Sign, and Wall Sign and I have registered an item for the sign. I did reflection for registering a wood type, and am using this wood type in the signs I have the texture for the wood type under textures/entity/signs and I have created the blockstate and model files, copying the vanilla ones (where the blockstates point to a model file that only has a texture for particles) However, the Sign still won't render, and the edit sign screen won't show up. Sometimes the game crashes when I place a sign, with a NPE, but it isn't consistent. Sign block registration: EFFETE_SIGN = registerNoItem("effete_sign", () -> new StandingSignBlock( AbstractBlock.Properties.create(Material.NETHER_WOOD, MaterialColor.LIME) .doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD), Main.EFFETE_WOOD_TYPE)); EFFETE_WALL_SIGN = registerNoItem("effete_wall_sign", () -> new WallSignBlock( AbstractBlock.Properties.create(Material.NETHER_WOOD, MaterialColor.LIME) .doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD).lootFrom(EFFETE_SIGN.get()), Main.EFFETE_WOOD_TYPE)); Blockstate and model files: { "textures": { "particle": "effetewood:block/effete_planks" } } { "variants": { "": { "model": "effetewood:block/effete_sign" } } } Wood Type registration and Reflection code: private void setup(final FMLCommonSetupEvent event) { reflectionSetup(); try { EFFETE_WOOD_TYPE = (WoodType) registerWoodTypeMethod.invoke(null, woodTypeConstructor.newInstance("effete")); } catch (Exception e) { LOGGER.error("Error registering wood type"); e.printStackTrace(); } } private void reflectionSetup() { if (woodTypeConstructor != null) woodTypeConstructor.setAccessible(true); if (registerWoodTypeMethod != null) registerWoodTypeMethod.setAccessible(true); } private static final Constructor<WoodType> woodTypeConstructor; private static final Method registerWoodTypeMethod; private static Constructor<WoodType> getWoodTypeConstructor() { try { return WoodType.class.getDeclaredConstructor(String.class); } catch (Exception e) { LOGGER.error("Exception in getWoodTypeConstructor: " + e.getMessage()); e.printStackTrace(); return null; } } private static Method getRegisterWoodTypeMethod(){ try { return WoodType.class.getDeclaredMethod("register", WoodType.class); } catch (Exception e) { LOGGER.error("Exception in getRegisterWoodTypeMethod: " + e.getMessage()); e.printStackTrace(); return null; } } static { woodTypeConstructor = getWoodTypeConstructor(); registerWoodTypeMethod = getRegisterWoodTypeMethod(); } Edited January 17, 20214 yr by kiou.23
January 16, 20214 yr Author 1 hour ago, diesieben07 said: You do not need to use reflection to invoke the constructor, just make a subclass. I had asked on discord and someone suggested using reflection. but yeah, a subclass is way better This is correct? public class ModWoodType extends WoodType { public static final WoodType EFFETE = new ModWoodType("effete"); protected ModWoodType(String name) { super(name); } } 1 hour ago, diesieben07 said: That is never how you handle exceptions. Think about what happens if these reflection things fail - you now don't have a WoodType instance. What does your sign do then? Return null? Then it's going to crash - but with some random null pointer exception somewhere, which has no bearing on the actual error (the reflection failed). Make your reflection code throw an exception if it fails! That said - you need to use ObfuscationReflectionHelper and SRG names, or your code will not work outside the development environment. Yeah, you told me that in another thread. But since I don't need to use reflection, I'm going to postpone studying error handling to another week 1 hour ago, diesieben07 said: Sign textures are baked in Atlases.collectAllMaterials - which is called from the static initializer of ModelBakery. This class will be initialized very early, way before any mod loading happens probably. That means, Minecraft won't have your wood type when it is stichting textures / baking models. You probably need to hack them in in some way in ModelRegistryEvent. And how should I go about doing that? I tried: @SubscribeEvent public static void modelRegistryEvent(ModelRegistryEvent e) { Atlases.SIGN_MATERIALS.put(ModWoodType.EFFETE, new RenderMaterial(Atlases.SIGN_ATLAS, new ResourceLocation("effetewood:entity/signs/effete"))); } It still doesn't work (The edit screen pops up for less than a second, and appear to have the missing pink/black texture), and the actual block just is invisible (dumb question: I don't need to specify "textures/entity/..." in the resouce location, right?) Edited January 16, 20214 yr by kiou.23
January 16, 20214 yr Author 9 minutes ago, diesieben07 said: You still need reflection to register it. Alright, where can I learn about the ObsfuscationReflectionHelper and SRG names? (and by register, you mean registering to the VALUES field from the WoodType class?) 10 minutes ago, diesieben07 said: I don't know. It might be better to just make your own renderer and not use this vanilla stuff. doesn't this do it? Atlases.SIGN_MATERIALS.put(ModWoodType.EFFETE, new RenderMaterial(Atlases.SIGN_ATLAS, new ResourceLocation("effetewood:entity/signs/effete"))); if it doesn't, can you point me towards how I would write my own renderer?
January 16, 20214 yr Author 14 minutes ago, diesieben07 said: No, because SIGN_MATERIALS is copied into ModelBakery.LOCATIONS_BUILTIN_TEXTURES in Atlases.collectAllMaterials which is called from ModelBakery static init, which happens way before this event. Any changes to SIGN_MATERIALS later will be ignored. You'd have to also add it to LOCATIONS_BUILTIN_TEXTURES, but I don't know if that would even be enough - worth a try though. I'll try it (Edit: nvm, no idea how to try it, and it may not even work) there seems to be another problem tho: I changed the wood type of the sign to OAK, just to see if it rendered with a vanilla wood type, and nope. it's still invisible. however, the edit screen has the oak sign texture (it still only stays up for milliseconds) this has to be related to something else, right? Edited January 16, 20214 yr by kiou.23
January 16, 20214 yr Author 19 minutes ago, diesieben07 said: Probably. Vanilla loves hardcoding things. Would be best to see a Git repo of your mod so I can use the debugger. git repo: https://github.com/jvcmarcenes/effetewood
January 16, 20214 yr Author 3 minutes ago, diesieben07 said: You cannot use the vanilla sign blocks, because they use SignTileEntity, which is only marked valid for the vanilla signs. You need to make your own TileEntityType and use that. so I also need to write my own Sign blocks? and can I just make them a subclass of the vanilla classes?
January 16, 20214 yr Author Okay, so my Custom Sign Tile Entity has to extend SignTileEntity, because PlayerEntity#openSignEditor() expects a SignTileEntity. but from there I can't call super() and pass in my custom Tile Entity Type, because the TileEntityType for SignTileEntity is hardcoded in the constructor. How to proceed?
January 16, 20214 yr Author Did the classes, now the edit screen shows up, and if I use a vanilla WoodType for the sign, the texture shows up in the edit screen (not in the actual block tho, it still won't render) the changes are on github. How should I go about rendering the Sign again? I'll need to write my own TileEntityRenderer?
January 16, 20214 yr Author Wow that's alot, I was trying to do the brute force way of simply reimplementing all the classes over, but it didn't quite work. I'll take a look at your solution and try doing that. Thank you a lot for taking the time to help me with this! (is it fine for me to dm you on discord if I face a roadblock again? relevant to adding this signs of course)
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.