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

Hey I tried this but for some reason nothing is appearing in my hand? I even tried using minecraft:trident_in_hand#inventory in case it was just my json file but still nothing appears

Edited by Jonesboy
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now


×
×
  • Create New...

Important Information

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