Jump to content

[1.12.x] [SOLVED - For real this time] Setting/copying a block model from/to another block


CosmicDan

Recommended Posts

Howdy,

 

I've a desire of creating blocks dynamically based on the existence of other blocks in the game. These blocks are duplicates of other blocks but with slightly changed functionality - ore variants, if it's any significance. Everything works perfectly, except the world block models just show the missing texture placeholder (the hand and inventory model/textures are fine).

 

Changes since 1.7.10 have taught me that I need to set a block model which has proven a bit more complicated than overriding getIcon. I think I need to set the IBakedModel somewhere, but all I have is this:

 

public void registerBlockRender(Block newBlock, Block baseBlock) {
	// set item model
	ItemModelMesher itemModelMesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();
	itemModelMesher.register(Item.getItemFromBlock(newBlock), 0, new ModelResourceLocation(baseBlock.getRegistryName().getResourceDomain() + ":" + baseBlock.getRegistryName().getResourcePath()));

	// set world block model
	IBakedModel baseModel = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(baseBlock.getDefaultState());
	// ?
}

 

As mentioned, the item model works fine - it's an exact duplicate of the original item model - but I'm stuck on what to do about the actual world block model. I've looked around flailed around the sources trying to find this out but I'm clueless. Perhaps I need to register to a ModelBake event that I read about somewhere...?

 

Context: These blocks are created and registered during FMLInitializationEvent, which calls the above registration method via client proxy if the block creation and registration was successful. I do it here because I want to be sure that all other mods have registered their ores (which they should be doing in preInit).

Edited by CosmicDan
Mark as solved

Windows software, Android hacking, and other curios

Link to comment
Share on other sites

For blocks, you need a custom IPerspectiveAwareModel and IStateMapper.

 

Check out GrayGhost's Camouflage block

https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe04_block_dynamic_block_model1

  • Like 1

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

2 hours ago, Draco18s said:

For blocks, you need a custom IPerspectiveAwareModel and IStateMapper.

 

Check out GrayGhost's Camouflage block

https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe04_block_dynamic_block_model1

Ah I even have a tab of GreyGhost's MBE repo to help me get up to date, funny!

 

I couldn't get it to work on first attempt but this is quite a bit to take in. However I realize now it's probably better I just copy textures into the mod myself and manually define the ore block extras as it would allow Resource Packs to retexture them too. I'll just only register the ore variants if an oredict entry exists for it, similar to what you do in Ore Flowers.

 

Thanks :)

Windows software, Android hacking, and other curios

Link to comment
Share on other sites

At the risk of incurring the wrath of Lex, these new Forge changes feel like a serious case of over-engineering (or maybe it's Mojang to blame, or just the fact that it's an API strapped onto a reverse-engineered application...)

 

Determined to get the original goal I wanted - to assign textures/models dynamically from the base block of runtime-generated blocks - I still can't figure out the block model copying. The MBE case seems like it's way too complicated and not necessary for this case - since the models dont need to be *runtime dynamic* - I thought "Why can't I just grab the model from the base blockstate? I'll try that". So, something like this...

 

ModelLoader.setCustomStateMapper(newBlock, new BlockRichOreStateMapper());

...and...

public class BlockRichOreStateMapper extends StateMapperBase {
	@Override
	protected ModelResourceLocation getModelResourceLocation(IBlockState state) {
		log.info(state.getBlock().getClass().getName()); // hello world
		Block blockToModel = state.getBlock();
		if (state.getBlock() instanceof BlockRichOre) {
			blockToModel = ((BlockRichOre) state.getBlock()).getBaseBlock();
		}
		return new ModelResourceLocation(Block.REGISTRY.getNameForObject(blockToModel), this.getPropertyString(state.getProperties()));
	}
}

 

No idea if that would work, but it is just a test - I don't even get any log output, the getModelResourceLocation method is never called. I am calling setCustomStateMapper from a client-sided method in the init phase.

 

So I found out about some ModelRegistryEvent and moved it to there instead, but this event is fired before init - but I need to register the blocks in init. So it seems that models are registered preInit, or at least before init - and that might be why I couldn't get something based on GreyGhost's MBE's CamoBlock working either...

 

So. Given the situation that I need to register my blocks AFTER every other mod has registered blocks, how then can I assign models to these blocks when Forge needs/wants to - which is before my blocks even exist?

Edited by CosmicDan

Windows software, Android hacking, and other curios

Link to comment
Share on other sites

Blocks (and other registry entries) should be registered in the appropriate registry event (i.e. RegistryEvent.Register<Block>). You can control when your Blocks are registered in relation to the other mod using the EventPriority property of the @SubscribeEvent annotation.

  • Like 1

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

49 minutes ago, Choonster said:

Blocks (and other registry entries) should be registered in the appropriate registry event (i.e. RegistryEvent.Register<Block>). You can control when your Blocks are registered in relation to the other mod using the EventPriority property of the @SubscribeEvent annotation.

Thanks, I didn't realize that the event priority could help make my blocks register last.

 

Indeed, when using the new Forge registration events, the registration order is as desired: Blocks -> Items -> Renderers. Fingers crossed...!

Windows software, Android hacking, and other curios

Link to comment
Share on other sites

Migrating to the new registration event system solved everything. The simpler BlockRichOreStateMapper I shared above applied through ModelLoader.setCustomStateMapper via ModelRegistryEvent worked perfectly to copy the vanilla block model on registration :) As is usually the case, only my ignorance was to blame for this frustration.

 

Thanks again guys!

Windows software, Android hacking, and other curios

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.