Jump to content

[SOLVED] [1.15.2] Different item model when rendered in the inventory vs. handheld


Recommended Posts

I'm trying to create an item that uses the standard 2D sprite model in the inventory, but for handheld rendering uses a different model. This item isn't a block. The only vanilla example of this is, I believe, the trident, but I can't figure out how to hook into the code for that in ItemRenderer.

 

I thought it was as simple as adding another model called, e.g. "special_item#inventory.json", but no. After some searching I've found loads of old forum threads on how to achieve this in previous versions, such as 1.12, or 1.8 (here), but it seems the relevant methods (ModelLoader#setCustomModelResourceLocation, or ModelLoader#registerItemVariants) no longer exist in 1.15.

 

How do you make an item model point to a different model file for the inventory variant?

 

EDIT: SOLVED - for anyone else who's interested, here's the solution I managed to find.

When Minecraft bakes all the models, it appends "#inventory" to every item model, so the model for your "special_item" is registered as "special_item#inventory".

Using ModelBakeEvent, you can exploit this knowledge to retrieve an item's IBakedModel from the registry map, with the key "special_item#inventory".

Having previously created a special handheld model, and saved it as "special_item_handheld.json" in the models folder (or any other name you like - it doesn't have to be "_handheld"), you can use FMLClientSetupEvent in your SidedProxy to call ModelLoader.addSpecialModel(new ModelResourceLocation("special_item" + "_handheld")); - this tells the game that it needs to load your handheld model as well.

Finally, in the ModelBakeEvent, you can now retrieve from the map both the default model ("special_item#inventory") and the as-yet-unassociated-to-any-item handheld model ("special_item_handheld#inventory") [remember that all item models get #inventory appended], and using these objects, declare a new anonymous extension of IBakedModel which delegates all its methods to the default model object, except for in handlePerspective() where you switch models according to TransformType. Then, shove this new wrapper model back into the map!

 

Example code for illustration.


public class ClientProxy implements SidedProxy
{
    @SubscribeEvent
    public void onLoad(FMLClientSetupEvent event)
    {
    	ModelLoader.addSpecialModel(new ModelResourceLocation(ModItems.SPECIAL_ITEM.get().getRegistryName() + "_handheld", "inventory"));
    }
    
    @SubscribeEvent
    public void onModelBake(ModelBakeEvent event)
    { 
    	Map<ResourceLocation, IBakedModel> map = event.getModelRegistry();

    	ResourceLocation specialItem = ModItems.SPECIAL_ITEM.get().getRegistryName();
    	ResourceLocation specialItem_inventory = new ModelResourceLocation(specialItem, "inventory");
    	ResourceLocation specialItem_hand = new ModelResourceLocation(specialItem + "_handheld", "inventory");
    	
    	IBakedModel specialItemModel_default = map.get(specialItem_inventory);
    	IBakedModel specialItemModel_hand = map.get(specialItem_hand);
    	IBakedModel specialItemModel_wrapper = new IBakedModel()
    	{
			@Override
			public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand)
			{
				return specialItemModel_default.getQuads(state, side, rand);
			}

			@Override
			public boolean isAmbientOcclusion()
			{
				return specialItemModel_default.isAmbientOcclusion();
			}

			@Override
			public boolean isGui3d()
			{
				return specialItemModel_default.isGui3d();
			}

			@Override
			public boolean func_230044_c_()
			{
				return specialItemModel_default.func_230044_c_();
			}

			@Override
			public boolean isBuiltInRenderer()
			{
				return specialItemModel_default.isBuiltInRenderer();
			}

			@Override
			public TextureAtlasSprite getParticleTexture()
			{
				return specialItemModel_default.getParticleTexture();
			}

			@Override
			public ItemOverrideList getOverrides()
			{
				return specialItemModel_default.getOverrides();
			}
    		
			@Override
			public IBakedModel handlePerspective(ItemCameraTransforms.TransformType transformType, MatrixStack mat)
			{
				IBakedModel modelToUse = specialItemModel_default;
				if (transformType == TransformType.FIRST_PERSON_LEFT_HAND || transformType == TransformType.FIRST_PERSON_RIGHT_HAND
						|| transformType == TransformType.THIRD_PERSON_LEFT_HAND || transformType == TransformType.THIRD_PERSON_RIGHT_HAND)
				{
					modelToUse = specialItemModel_hand;
				}
				return ForgeHooksClient.handlePerspective(modelToUse, transformType, mat);
			}
    	};
    	map.put(specialItem_inventory, specialItemModel_wrapper);
    }
}

 

Edited by Fluorescent Flamingo
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.