Jump to content

1.9 make use of item models that only exist in code


UberAffe

Recommended Posts

I have an item type which generates an IFlexibleBakedModel based on it's nbt information. I have that model stored so that it only needs to get generated once. But how do I actually go about using that model when the item is rendered?

 

Edit:

Ended up updating to 1.9

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

If by pre-generated you mean during pre-postInit no. The available instances get created by the player in-game, some will be loaded from a file and could be generated during pre-postInit, the only way to make all of them available during pre-postInit would be to force a server restart each time they add an instance which I do not want to do.

 

I have this in my ClientProxy#postInit

ModelResourceLocation itemModel = Refs.modelResourceLocation;
ModelLoader.setCustomModelResourceLocation(MeleeCore.meleeCore, 0, itemModel);	

 

This is what I have for the ModelBakeEvent

        @SideOnly(Side.CLIENT)
@SubscribeEvent
public void onModelBakeEvent(ModelBakeEvent event)
{
	 Object obj = event.modelRegistry.getObject(DraftableSmartItemModel.modelResourceLocation);
	 if(obj instanceof IBakedModel)
	 {
		 event.modelRegistry.putObject(DraftableSmartItemModel.modelResourceLocation, new DraftableSmartItemModel());
	 }
}

 

Here is what I have for ISmartItemModel:

public class DraftableSmartItemModel implements ISmartItemModel{

public static final ModelResourceLocation modelResourceLocation = new ModelResourceLocation(Refs.MODID + ":draftable_Item","inventory"); // this file doesn't exist

@Override
public IFlexibleBakedModel handleItemState(ItemStack stack) {
      IFlexibleBakedModel model = null;
      if(stack.getTagCompound().hasKey(Refs.DRAFTABLE) && DraftableReg.Exists(stack.getTagCompound().getString(Refs.DRAFTABLE)))
         model = DraftableReg.getModel(stack.getTagCompound().getString(Refs.DRAFTABLE));
      return model;
   }
}

 

This is in the item class(I have my own registry of instances of this class)

         public ItemStack CreateItem() {
	LogHelper.info("creating " + name);
	ItemStack toReturn = new ItemStack(this, 1, 0);
	NBTTagCompound tag = new NBTTagCompound();
	tag.setString(Refs.DRAFTABLE, name);
	toReturn.setTagCompound(tag);
	return toReturn;
}

 

The models are just showing up as purple and black boxes. Is there something wrong with how I am assigning the models to the items?

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

postInit because I'm a noob when it comes to this, moved to preInit and both places now use

Refs.modelResourceLocation, I just moved the variable from DraftableSmartItemModel to Refs.

 

These are in DraftableReg

       @SideOnly(Side.CLIENT)
public static IFlexibleBakedModel GetModel(String draftItem) {
	return models.get(draftItem);
}

        public static void RegisterDraftable(IDraftable draftable){
	LogHelper.info("Registering Draftable :" + draftable.GetName());
	knowledgeBase.put(draftable.GetName(), draftable);
}

@SideOnly(Side.CLIENT)
public static void RegisterDraftableModel(IDraftable draftable){
	LogHelper.info("Registering Model for :" + draftable.GetName());
	models.put(draftable.GetName(), new DraftableBakedModel(draftable));
}

My proxies have a Register method that gets used to call either one or both of these register methods.

 

I put a breakpoint in GetModel and it doesn't get called, so something is still wrong with how I am assigning my DraftableSmartItemModel to the items.

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

I put a breakpoint in handleItemState and it never gets called so no.

This is the only error I can find in the log

 

[12:00:39] [Client thread/ERROR] [FML]: Exception loading model for variant lidr:draftable_Item#inventory for item "lidr:lidr_defaultmelee"
java.lang.Exception: Could not load model definition for variant lidr:draftable_Item#inventory
at net.minecraftforge.client.model.ModelLoader.getModelBlockDefinition(ModelLoader.java:215) ~[ModelLoader.class:?]
at net.minecraftforge.client.model.ModelLoader.loadItems(ModelLoader.java:259) ~[ModelLoader.class:?]
at net.minecraftforge.client.model.ModelLoader.setupModelRegistry(ModelLoader.java:116) ~[ModelLoader.class:?]
at net.minecraft.client.resources.model.ModelManager.onResourceManagerReload(ModelManager.java:28) [ModelManager.class:?]
at net.minecraft.client.resources.SimpleReloadableResourceManager.notifyReloadListeners(SimpleReloadableResourceManager.java:130) [simpleReloadableResourceManager.class:?]
at net.minecraft.client.resources.SimpleReloadableResourceManager.reloadResources(SimpleReloadableResourceManager.java:111) [simpleReloadableResourceManager.class:?]
at net.minecraft.client.Minecraft.refreshResources(Minecraft.java:772) [Minecraft.class:?]
at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:326) [FMLClientHandler.class:?]
at net.minecraft.client.Minecraft.startGame(Minecraft.java:532) [Minecraft.class:?]
at net.minecraft.client.Minecraft.run(Minecraft.java:360) [Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:116) [Main.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_45]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_45]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_45]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_45]
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
at GradleStart.main(GradleStart.java:26) [start/:?]
Caused by: java.lang.RuntimeException: Encountered an exception when loading model definition of model lidr:blockstates/draftable_Item.json
at net.minecraft.client.resources.model.ModelBakery.getModelBlockDefinition(ModelBakery.java:165) ~[ModelBakery.class:?]
at net.minecraftforge.client.model.ModelLoader.getModelBlockDefinition(ModelLoader.java:211) ~[ModelLoader.class:?]
... 22 more
Caused by: java.io.FileNotFoundException: lidr:blockstates/draftable_Item.json
at net.minecraft.client.resources.SimpleReloadableResourceManager.getAllResources(SimpleReloadableResourceManager.java:82) ~[simpleReloadableResourceManager.class:?]
at net.minecraft.client.resources.model.ModelBakery.getModelBlockDefinition(ModelBakery.java:143) ~[ModelBakery.class:?]
at net.minecraftforge.client.model.ModelLoader.getModelBlockDefinition(ModelLoader.java:211) ~[ModelLoader.class:?]
... 22 more
[12:00:39] [Client thread/ERROR] [FML]: Model definition for location lidr:draftable_Item#inventory not found

 

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

Ok so I have all of that in place now but there is one problem.

 

ISmartItemModel extends IBakedModel not IFlexibleBakedModel and bake wants an IFlexibleBakedModel.

Do I just need to update my forge version to fix this (im using 1764)?

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

You can implement two? Idk, I am alredy on 1.9 where there are no longer any of those. I totally skipped 1.8.9 (meaning I didn't touch rendering knowing that it will change).

 

And yeah - I suggest going to 1.9 directly, a lot of stuff has been replaced.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Alright so I now have gotten rid of all the obvious errors in code after updateing to 1.9 and I am essentially at the same point again. So for custom item model in 1.9 do I use a similar process as what you described but only using IBakedModel or is it something else?

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

ICustomModelLoader

 

public class DraftableModelLoader implements ICustomModelLoader{

@Override
public void onResourceManagerReload(IResourceManager resourceManager) {	}

@Override
public boolean accepts(ResourceLocation modelLocation) {
	return Refs.modelResourceLocation == modelLocation;
}

@Override
public IModel loadModel(ResourceLocation modelLocation) throws Exception {
	return new DraftableModel();
}
}

 

IModel

 

public class DraftableModel implements IModel{

@Override
public Collection<ResourceLocation> getDependencies() {
	return ImmutableList.of();
}

@Override
public Collection<ResourceLocation> getTextures() {
	return ImmutableList.of();
}

@Override
public IBakedModel bake(IModelState state, VertexFormat format,
		Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
	return DraftableBakedModel.instance;
}

@Override
public IModelState getDefaultState() {
	return TRSRTransformation.identity();
}
}

 

IBakedModel

 

public class DraftableBakedModel implements IBakedModel{

public static final DraftableBakedModel instance = new DraftableBakedModel();

private DraftableBakedModel() {
}

@Override
public ItemOverrideList getOverrides() {
	return new DraftableOverrideList(null);
}
        // removed code that handles creating BakedQuads from an IDraftable
}

 

ItemOverrideList

 

public class DraftableOverrideList extends ItemOverrideList{

public DraftableOverrideList(List<ItemOverride> overridesIn) {
	super(overridesIn);
}

@Override
public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity)
    {
        Item item = stack.getItem();
        if (item instanceof DraftingItemCore)
        {
            return DraftableReg.GetModel(((NBTTagCompound)stack.getTagCompound().getTag(Refs.MODID)).getString("name"));
        }
        return originalModel;
    }
}

 

 

I have this in my ClientProxy#preInit

ModelLoader.setCustomModelResourceLocation(MeleeCore.meleeCore, 0, Refs.modelResourceLocation);
ModelLoaderRegistry.registerLoader(new DraftableModelLoader());

and this in my CommonProxy#preInit

GameRegistry.registerItem(MeleeCore.meleeCore, Refs.MODID + "_" + MeleeCore.meleeCore.GetName());

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

in my ICustomModelLoader#accepts I put this

@Override
public boolean accepts(ResourceLocation modelLocation) {
	if(Refs.modelResourceLocation == modelLocation)
		Refs.NOP();
	return Refs.modelResourceLocation == modelLocation;
}

when I put a breakpoint on the nop it never gets triggered.

which means that

ModelLoader.setCustomModelResourceLocation(MeleeCore.meleeCore, 0, Refs.modelResourceLocation);

isn't doing what I thought it was.

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

Ok so I have it using my models now, I need to compare the modelResourceLocations with .equals not ==, I hate when that is the problem.

 

Anyways my Models seem to be completely transparent, so on to how I am creating the models.

          public DraftableBakedModel(IDraftable draft){
	 DraftableMap parts = draft.GetPartArray();
	 for(int xPos = 0; xPos < parts.GetWidth(); xPos++){
		 for(int yPos = 0; yPos < parts.GetHeight(); yPos++){
            for(int zPos = 0; zPos < parts.GetDepth(); zPos++){
               if(parts.GetPart(xPos + "," + yPos + "," + zPos) != null)
            	   quads.addAll(parts.GetPart(xPos + "," + yPos + "," + zPos).GetQuadsAt(xPos, yPos, zPos));
            }
		 }
	 }
 }

 

in the IPartType implementation

 

         public List<BakedQuad> GetQuadsAt(int offX, int offY, int offZ) {
	List<BakedQuad> list = new ArrayList<BakedQuad>();
	BakedQuad quad;
	//North
	quad = new BakedQuad(applyOffset(getVertices(EnumFacing.NORTH),offX,offY,offZ), 0, EnumFacing.NORTH, null, true, new VertexFormat());
	list.add(quad);
	//Up
	quad = new BakedQuad(applyOffset(getVertices(EnumFacing.UP),offX,offY,offZ), 0, EnumFacing.UP, null, true, new VertexFormat());
	list.add(quad);
	//East
	quad = new BakedQuad(applyOffset(getVertices(EnumFacing.EAST),offX,offY,offZ), 0, EnumFacing.EAST, null, true, new VertexFormat());
	list.add(quad);
	//South
	quad = new BakedQuad(applyOffset(getVertices(EnumFacing.SOUTH),offX,offY,offZ), 0, EnumFacing.SOUTH, null, true, new VertexFormat());
	list.add(quad);
	//Down
	quad = new BakedQuad(applyOffset(getVertices(EnumFacing.DOWN),offX,offY,offZ), 0, EnumFacing.DOWN, null, true, new VertexFormat());
	list.add(quad);
	//West
	quad = new BakedQuad(applyOffset(getVertices(EnumFacing.WEST),offX,offY,offZ), 0, EnumFacing.WEST, null, true, new VertexFormat());
	list.add(quad);
	return list;
}

        private int[] getVertices(EnumFacing face) {
	switch(face){
	case NORTH:
		return north();
	case EAST:
		return east();
	case WEST:
		return west();
	case SOUTH:
		return south();
	case UP:
		return up();
	case DOWN:
		return down();
	default:
		return null;
	}
}

        private int[] north() {
	int[] vertices = new int[28];
	//top left
	vertices[0] = 0; //x
	vertices[1] = 0; //y
	vertices[2] = 0; //z
	vertices[3] = asInt(luxin.GetColor()); // rrggbbaa
	vertices[4] = 0; //u 
	vertices[5] = 0; //v
	vertices[6] = 0; //unused
	//top right
	vertices[7] = 1; //x
	vertices[8] = 0; //y
	vertices[9] = 0; //z
	vertices[10] = asInt(luxin.GetColor()); // rrggbbaa
	vertices[11] = 0; //u 
	vertices[12] = 0; //v
	vertices[13] = 0; //unused
	//bottom right
	vertices[14] = 1; //x
	vertices[15] = 1; //y
	vertices[16] = 0; //z
	vertices[17] = asInt(luxin.GetColor()); // rrggbbaa
	vertices[18] = 0; //u 
	vertices[19] = 0; //v
	vertices[20] = 0; //unused
	//bottom left
	vertices[21] = 0; //x
	vertices[22] = 1; //y
	vertices[23] = 0; //z
	vertices[24] = asInt(luxin.GetColor()); // rrggbbaa
	vertices[25] = 0; //u 
	vertices[26] = 0; //v
	vertices[27] = 0; //unused
	return vertices;
}

        private int asInt(int[] color) {
	return (color[0]&0x0ff)<<24|(color[1]&0x0ff)<<16|(color[2]&0x0ff)<<8|(color[3]&0x0ff);//0 is r, 1 is g, 2 is b, 3 is a, &0x0ff limits each to 1 byte
}

 

 

and in my ILuxin implementations

        public int[] GetColor() {
	return new int[]{0,0,255,127};
}

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

Link to comment
Share on other sites

I'll be diving into minecraft code when I get home but I think I just need to figure out what minecraft does with the tint value. If they don't use it I may need to write my own ItemRenderer, if I do need to do you have any suggested resources to help me accomplish that?

Current Project: Armerger 

Planned mods: Light Drafter  | Ore Swords

Looking for help getting a mod off the ground? Coding  | Textures

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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Try deliting feur builder  It caused this issue in my modpack
    • I am not using hardcoded recipes, I'm using Vanilla's already existing code for leather armor dying. (via extending and implementing DyeableArmorItem / DyeableLeatherItem respectively) I have actually figured out that it's something to do with registering item colors to the ItemColors instance, but I'm trying to figure out where exactly in my mod's code I would be placing a call to the required event handler. Unfortunately the tutorial is criminally undescriptive. The most I've found is that it has to be done during client initialization. I'm currently trying to do the necessary setup via hijacking the item registry since trying to modify the item classes directly (via using SubscribeEvent in the item's constructor didn't work. Class so far: // mrrp mrow - mcmod item painter v1.0 - catzrule ch package catzadvitems.init; import net.minecraft.client.color.item.ItemColors; import net.minecraft.world.item.Item; import net.minecraftforge.registries.ObjectHolder; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.client.event.ColorHandlerEvent; import catzadvitems.item.DyeableWoolArmorItem; @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class Painter { @ObjectHolder("cai:dyeable_wool_chestplate") public static final Item W_CHEST = null; @ObjectHolder("cai:dyeable_wool_leggings") public static final Item W_LEGS = null; @ObjectHolder("cai:dyeable_wool_boots") public static final Item W_SOCKS = null; public Painter() { // left blank, idk if forge throws a fit if constructors are missing, not taking the chance of it happening. } @SubscribeEvent public static void init(FMLClientSetupEvent event) { new Painter(); } @Mod.EventBusSubscriber private static class ForgeBusEvents { @SubscribeEvent public static void registerItemColors(ColorHandlerEvent.Item event) { ItemColors col = event.getItemColors(); col.register(DyeableUnderArmorItem::getItemDyedColor, W_CHEST, W_LEGS, W_SOCKS); //placeholder for other dye-able items here later.. } } } (for those wondering, i couldn't think of a creative wool helmet name)
    • nvm found out it was because i had create h and not f
    • Maybe there's something happening in the 'leather armor + dye' recipe itself that would be updating the held item texture?
    • @SubscribeEvent public static void onRenderPlayer(RenderPlayerEvent.Pre e) { e.setCanceled(true); model.renderToBuffer(e.getPoseStack(), pBuffer, e.getPackedLight(), 0f, 0f, 0f, 0f, 0f); //ToaPlayerRenderer.render(); } Since getting the render method from a separate class is proving to be bit of a brick wall for me (but seems to be the solution in older versions of minecraft/forge) I've decided to try and pursue using the renderToBuffer method directly from the model itself. I've tried this route before but can't figure out what variables to feed it for the vertexConsumer and still can't seem to figure it out; if this is even a path to pursue.  The vanilla model files do not include any form of render methods, and seem to be fully constructed from their layer definitions? Their renderer files seem to take their layers which are used by the render method in the vanilla MobRenderer class. But for modded entities we @Override this function and don't have to feed the method variables because of that? I assume that the render method in the extended renderer takes the layer definitions from the renderer classes which take those from the model files. Or maybe instead of trying to use a render method I should be calling the super from the renderer like   new ToaPlayerRenderer(context, false); Except I'm not sure what I would provide for context? There's a context method in the vanilla EntityRendererProvider class which doesn't look especially helpful. I've been trying something like <e.getEntity(), model<e.getEntity()>> since that generally seems to be what is provided to the renderers for context, but I don't know if it's THE context I'm looking for? Especially since the method being called doesn't want to take this or variations of this.   In short; I feel like I'm super super close but I have to be missing something obvious? Maybe this insane inane ramble post will provide some insight into this puzzle?
  • Topics

×
×
  • Create New...

Important Information

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