Jump to content

[1.7.2] Texture name from NBT. Edit: Updating texture.


Recommended Posts

Posted

Hello,

 

Could someone knowledgeable tell me how stupid (or not) is the idea of holding texture name for current itemstack in its NBT created in Item.onCreated() method?

 

I have a lot of sword types which textures are defined by items used to craft them. What exacly I am writing is a system that using "improved" crafting will count some factors and generate texture for item in runtime (using some pre-made shapes and colour maps) for all clients that need to have it - and by that I mean they actually need to get texture to any renderer (ofc. if they alredy seen it once it is stored as id.png for given itemstack, the problem of cleaning that up I'll probably solve with timestamps that will manage deleting files).

 

Note: (if you didn't understand "generate texture for item in runtime"):

 

When player creates item it will launch client side process that will generate and load texture for given itemstack and save its name in NBT. The .png file will be stored there for few days (until timestamp cleanup). Any player that would see the item (in hand/on floor/picked up) will launch same client process, get data from itemstack's NBT and generate identical .png file as the oryginal creator. The timestamp will make sure the .png wont be "living" too long, and if item exists after time is up - it will generate it again.

 

 

Question is - how can I nicely load textures in runtime?

 

Edit:

The other option would be to pre-make images (a lot of them) and load them once on client startup, but then again - metadata for item is 16 big (unless they have changed it since I've used it last time - first Full Minecarft Version) so I'd have to store it in NBT - would simple itemstack.readFromNBT(texturename) in getIconIndex() work?

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

Posted

i have been playing around with adding and reading nbt tags from item stacks today

(have a look at the video and item code i posted here http://www.minecraftforge.net/forum/index.php/topic,21125.0.html)

 

at one point the accessCode String i added to my nbt was so long it took up the whole screen but given you would only need to store the textures name (you can use the modid to get the first part of a textures location) i dont see why it wouldnt work

 

wonder if you can dynamicly change the unlocalised name? that would allow you to change the skin and using the lang file, the name of the sword (if you set up the skins to load based on the unlocalised name

 

hope that helps

Posted

I wouldn't go so far as to call this stupid... Aside from a better way that I don't know, this is exactly what I would do. The only potential problem I am seeing is - well, does your dynamic texture loader work yet? If it does, no problems from me.

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Posted

Hi

 

If your textures truly are unique for every item, why not just store the texture itself in the NBT and avoid the temporary file problem?  a 16x16 pixel 32 bit texture is only 1K which is nothing.

See SimpleTexture.java for ideas on how to convert a BufferedImage stream to a minecraft texture you can bind and use for a custom IIconRenderer.

 

-TGG

 

 

Posted

TheGreyGhost

 

I am not quite sure about client-server compatybility here. I've seen this in Item code:

    public boolean getShareTag()

    {

        return true;

    }

Which is by default set to true.

Till this time i was sure that client only saves data when you are on SP, and when you login on MP you get all data from server files (read: server NBT). Please, answer if you know: Is the itemstack saved somewhere on client Hard Drive during mulitplayer session and then removed on close, or is it just sent to him in runtime (RAM) as a copy of server data? Would generating a byte-image as you said work if I'd do it on server side and send it over to all players as above said - itemstack's NBT?

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

Posted

Hi

 

vanilla automatically synchronises ItemStack NBT information between the client and the server.  The server keeps the master copy (saves to disk in the save game files), the client keeps a copy in RAM.  This is true regardless of whether you're running SP or MP, because SP runs its own internal server (IntegratedServer).

 

So the idea would be: generate the image on the server, store it in the itemstack NBT (it gets saved to disk on the server) and the server will automatically send it to the client for you, where the client can render it.  You don't need to save it to disk if you take the information from the NBT and create a texture from it directly (as in SimpleTexture)

 

-TGG

Posted

Well, the whole idea of sending anything bigger than 1kB (the image 16x16, or bigger) in NBT is just plain stupid, updating it happes I think once per tick and having more players on server would simply kill the transfer.

 

I will simply write mod that launches process that downloads texture files from server before registration of IIcon.

The other thing is reloading the actual image in runtime.

I'm doing tests now to find neat way of doing it.

 

1. .png files are downloaded to /x/ directory.

2. We have Test.class which extends Item and has a HashMap<String, IIcon> in it.

Then we register them .png from /x/ dir on client startup.

protected HashMap<String, IIcon> NBTIcons = new HashMap<String, IIcon>();
@Override
public void registerIcons(IIconRegister iconRegister)
    {
	registerNBTIcons(iconRegister);
        this.itemIcon = iconRegister.registerIcon(this.getIconString()); //everything stays like it was, i am just adding void in line above
    }

public void registerNBTIcons(IIconRegister iconRegister)
{
//There is a loop here for actual loading and putting stuff into HashMap, i just made example below.
	NBTIcons.put("itworksbaby", iconRegister.registerIcon(InitUtil.ModID + ":" + "yay"));
}

 

Right now we have to load those registered icons for the actual items using this Test.class as constructor.

So I made this:

 

@Override
public IIcon getIcon(ItemStack stack, int pass)
    {
	String s = "";
	if (stack.getTagCompound() != null)
	{
		System.out.println(stack.getTagCompound().getString("texture"));
		s = stack.getTagCompound().getString("texture");
	}
        return NBTIcons.get(s);
    }

 

Ofc. NBT itself exist (defined in onCreated()). Problem is - this forge function is only used to update this "in-hand" renderer.

So the result is that I have item with missing texture when in inventory/on ground. And with texture when held.

 

How do I update icons for the item itself? (Probably something in resourcepack manager, but can't find anything particular).

 

Any idea?

 

Thanks,

And here is a potato for long post:

http://barringtonstageco.org/media/potato.jpg

 

 

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

Posted

Well, the whole idea of sending anything bigger than 1kB (the image 16x16, or bigger) in NBT is just plain stupid, updating it happes I think once per tick and having more players on server would simply kill the transfer.

steady on dude, that's harsh :)!  Did you actually test it, or is that just a guess?

 

Unless things have changed recently, the server only sends item information when it's updated or moved around, and 1 KB really isn't that much.

Even if you don't like that idea, you still don't need to store png files on disk.  Just send the image from server to client as a BufferedImage and store it as a texture in ram.  See SimpleTexture for hints on how.  As far as rendering goes, I think it would be best to use an IItemRenderer - just bind your custom texture and render it using the Tessellator.

 

See this link for information on ItemRendering (the "Item Rendering" sections)

http://greyminecraftcoder.blogspot.com.au/p/list-of-topics.html

 

-TGG

 

  • 2 months later...
Posted

Ernio, I was trying to solve this same problem, and found the solution. In your item, you need to implement both of these

 

public IIcon getIcon(ItemStack stack, int pass); //used for in-hand rendering

 

public IIcon getIconIndex(ItemStack stack); //used for everything else

 

 

Maybe you already solved this, but thought I'd leave the solution in case others are having trouble and find this post like I did.

 

 

 

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



×
×
  • Create New...

Important Information

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