[TUTORIAL] Custom Item Models in 1.9

Discussion in 'Spigot Plugin Development' started by NathanWolf, Mar 25, 2016.

  1. NOTE: I've moved this to the wiki! I'll try to keep them both updated, but the wiki is probably your best bet:

    https://www.spigotmc.org/wiki/custom-item-models-in-1-9-and-up/

    NOTE#2: NO, this can not currently be used for armor, Elytra or mobs. Only items, and only those items that have durability (so tools and weapons, basically)

    THE GOAL
    One of the most exciting things in 1.9 is that items can now show a different model depending on their damage (durability). Presumably this is so you can show items wearing down, but we can also exploit this to add 1000's of new items to Minecraft!

    For example, everything shown here is a wooden hoe, with different durability values:
    [​IMG]

    THE CODE
    This part is relatively easy. Pick an item with durability (e.g. a tool), and create an ItemStack for that item with a set durability, let's use a durability of 1 for this example:
    Code (Text):
    ItemStack customItem = new ItemStack(Material.WOOD_HOE, 1, (short)1);
    This will give you a wooden hoe that is slightly damaged, like so:
    [​IMG]

    But of course we don't want the durability bar to show up, we also don't want the durability to change if the item is used like a tool. Fortunately, there is a tag for that!

    Unfortunately, the method currently only exists in the Spigot API. If Craftbukkit compatibility is important to you, you may want to dig into NMS to set this flag (hoping this will change soon)

    https://hub.spigotmc.org/javadocs/s.../ItemMeta.Spigot.html#setUnbreakable(boolean)

    Code (Text):
    ItemStack customItem = new ItemStack(Material.WOOD_HOE, 1, (short)1);
    ItemMeta meta = customItem.getItemMeta();
    meta.spigot().setUnbreakable(true);
    customItem.setItemMeta(meta);
    Which gives us this:
    [​IMG]

    Ok nice, no damage meter! But if making a custom item, we probably don't want all that vanilla lore. Fortunately there's more API! You can add flags to the item to hide lore, like so:

    Code (Text):
            ItemStack customItem = new ItemStack(Material.WOOD_HOE, 1, (short)1);
            ItemMeta meta = customItem.getItemMeta();
            meta.spigot().setUnbreakable(true);
            meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_UNBREAKABLE);
            customItem.setItemMeta(meta);
    [​IMG]

    Awesome, we now have an item with a set durability that won't change, and nothing weird in the lore.

    That's about it for the code side of things! You probably want to set a display name and lore in there as well, but I'll leave that up to you.

    This item is ready to become the custom item of your dreams.... it just needs a new skin.

    THE RESOURCE PACK
    Here is where things get a little weird. If you don't have any experience creating a resource pack, it's pretty easy. Create a new empty folder, and put in it a pack.mcmeta file that looks something like this:

    Code (Text):
    {
      "pack": {
        "pack_format": 2,
        "description": "Official elMakers Magic Resource Pack"
      }
    }
    And then add subfolders going all the way up to "assets/minecraft/models/item".

    In the item folder, create a new file called wooden_hoe.json. This will be the "container" for all of your custom items. It tells the client which models to use for certain durability values of the wooden hoe.

    This file will look something like this:
    Code (Text):
    {
      "parent": "item/handheld",
      "textures": {
        "layer0": "items/wood_hoe"
      },
      "overrides": [
        {"predicate": {"damaged": 0, "damage": 0.01666666666667}, "model": "item/my_cool_custom_item"}
      ]
    }
    Ok, so let's break this down.

    We are overriding wood hoe, but extending the base version. So the "parent" and "textures" are telling the client to use the wood hoe defaults. This means that a wood hoe with zero damage will look normal.

    Now for the new stuff- the "overrides" block lets you specify different models to use depending on certain properties of the item. These properties are called "predicates", and for our purposes we will focus on the "damage" predicate.

    This will vary the model based on damage, as a percentage from 0 to 1. So the value "0.016666" in there comes from the ratio "1/60" - because I want to apply this model at a damage/durability value of 1, and a wood hoe has a max durability of 60.

    See the mc wiki for all the durabilities of items: http://minecraft.gamepedia.com/Hoe

    You can add as many damage predicates as you want, up to the max durability of the item- just do the "x/60" math for each one.

    You can also use this tool to auto-generate a template given a specific type of tool, saving you from the maths: http://accidentalgames.com/media/durabilityModels.php

    Preserving the original items
    If you want to still be able to use the vanilla damageable items, this is possible!
    Add another entry to your model file, so it ends up looking like this:

    Code (Text):
    {
      "parent": "item/handheld",
      "textures": {
        "layer0": "items/wood_hoe"
      },
      "overrides": [
        {"predicate": {"damaged": 0, "damage": 0.01666666666667}, "model": "item/my_cool_custom_item"},
        {"predicate": {"damaged": 1, "damage": 0}, "model": "item/wooden_hoe"}
      ]
    }
    This will cause damaged versions to continue to use the base model. Note that if you use the JSON generator I linked above, you'll need to edit the final entry- it needs to refer to the model name, so wooden_hoe instead of wood_hoe for instance.

    Finally, put your custom item model in the same item folder in the resource pack, in this case it would be in "my_cool_custom_item.json". (Creating custom item models is not in the scope of this tutorial, I think there are some good ones out there already and also tools like Cubik you can use)

    Zip up the root folder of your RP, add it to your <minecraft>/resourcepacks folder and you should be able to load it and see your custom item!

    [​IMG]

    If in doubt, feel free to take a look at my resource pack structure on github:

    https://github.com/elBukkit/MagicPlugin/tree/master/Magic/src/resource-pack/survival

    FINAL NOTES
    Once you have this all working, there are some things to consider.
    • The higher-level tools will give you more item models to work with. A diamond hoe has a max durability of 1,562 (!)
    • When it's time to make it live, you'll need somewhere to host your resource pack! I think Dropbox will work, just get a direct link and add it to your server.properties file.
    • If you plan on updating your RP over time, keep in mind that you have to add the SHA1 hash to your server.properties as well, or rename the RP each time- otherwise clients will not redownload it.
    • Another cool 1.9 feature- items can now be worn as hats and will show up in-game! You need to add a "head" display block to the model json file for this to work, though- see here: https://github.com/elBukkit/MagicPl...ecraft/models/item/custom/magic_hat.json#L587
    I hope this helps you out! Please let me know if you find any issues anywhere in this tutorial - thanks for reading! :)
     
    #1 NathanWolf, Mar 25, 2016
    Last edited: May 30, 2017
    • Useful x 39
    • Like x 16
    • Winner x 11
    • Informative x 7
    • Friendly x 2
    • Agree x 1
    • Funny x 1
  2. I didn't realize a texture pack could distinguish between otherwise identical items with different durability values. Thanks for the tutorial!
     
    • Agree Agree x 3
    • Friendly Friendly x 2
    • Optimistic Optimistic x 1
  3. Choco

    Moderator

    You sir, never cease to amaze me... Completely forgot about this 1.9 feature, yet it's the coolest one. I hope to see this utilized in Magic (If it isn't already)
     
    • Like Like x 1
    • Agree Agree x 1
    • Friendly Friendly x 1
    • Useful Useful x 1
  4. Of course :D
    The 1.9 build of Magic moved all of the items to the wood hoe and gold sword, so I no longer have to "steal" the other gold tools, and was able to add a bunch of new wand appearances.

    That reminds me of a couple of notes about hats and RP updates, I'll go edit the post.

    EDIT: items can now be worn as hats (see final notes section), so in Magic I also don't have to use the monster egg blocks anymore. :)
     
    • Winner Winner x 1
  5. @NathanWolf thank you so much for this! I was looking for this everywhere.
     
    • Friendly Friendly x 1
  6. If you add "Unbreakable" tag doesn't it repair item automatically? So how I can use then multiple item models for same item for different durabilities?

    Right question is: How have you prevented items durability loss? Because unbrekable tag repairs item.
     
    #6 DeeCaaD, Mar 25, 2016
    Last edited: Mar 25, 2016
  7. The Unbreakable tag doesn't repair them, it just hides the durability and keeps it from changing, which is exactly what you want. They'll still keep whatever durability you set on the item!
     
    • Informative Informative x 2
    • Winner Winner x 1
  8. Well if it is like that then why this doesn't work?
    Code (Text):
                            ItemStack customItem = new ItemStack(Material.STONE_HOE, 1);
                            customItem.setDurability((short) 120);
                         
                            p.getInventory().addItem(customItem); // This give different textured model.
                         
                            ItemMeta meta = customItem.getItemMeta();
                            meta.spigot().setUnbreakable(true);
                            customItem.setItemMeta(meta);
                         
                            p.getInventory().addItem(customItem); // This doesn't. Because I added unbreakable tag.
                         
                            ItemStack customItem2 = new ItemStack(Material.STONE_HOE, 1);
                            customItem2.setDurability((short) 125);
                         
                            p.getInventory().addItem(customItem2); // This give different textured model.
                         
                            ItemMeta meta2 = customItem2.getItemMeta();
                            meta2.spigot().setUnbreakable(true);
                            customItem2.setItemMeta(meta2);
                         
                            p.getInventory().addItem(customItem2); // This doesn't. Because I added unbreakable tag.
     
  9. Does this work on armor textures, or elytra?
     
  10. It should work on every Item that has a durability.
     
    • Agree Agree x 2
  11. In theory, but worn armor is entirely different from hotbar item sprites.
     
  12. Are you saying you've tried this, and seen it to not work? If so, then I have no idea why it's not working for you, sorry :(

    I copy+pasted your code (slightly modified) and put it in a test plugin, and it worked fine for me:

    Code (Text):
                ItemStack customItem = new ItemStack(Material.WOOD_HOE, 1);
                customItem.setDurability((short) 1);
                ItemMeta meta = customItem.getItemMeta();
                meta.spigot().setUnbreakable(true);
                customItem.setItemMeta(meta);
                api.giveItemToPlayer(player, customItem);
    Gives me this item, which still has a durability, the unbreakable tag and shows the correct item model from my RP:

    [​IMG]

    I will thank you for making me actually test the code- I realized I had the wrong ItemStack constructor in the examples (forgot about the count), fixed now, sorry!
     
  13. I haven't figured out how to do this with armor yet since, as far as I can tell, they don't get json models. It'd be super amazing to be able to use this for armor!

    EDIT: Or with the Elytra. There is a json model for the Elytra as an item, but not while worn- as far as I can tell.
     
    #13 NathanWolf, Mar 25, 2016
    Last edited: Mar 25, 2016
  14. I didn't either. This will very useful for using one type of item to its limits then moving on to the next (for sake of efficiency of adding items)

    Thanks for the tutorial, this may come in handy. I also do believe that this would be a good feature with forcing resource packs on RPG servers.
     
    • Friendly Friendly x 1
  15. So if I use a damage value of 61/60 in the resource pack, what would happen? (I'm just trying to find a way to add these custom items and keep the vanilla ones)
     
  16. What build of Spigot are you using?

    Maybe negative durability values?
     
  17. Unfortunately I think you get the purple+black cube of death.

    EDIT: Or apparently not. Hm, maybe it's worth trying that (or DeeCad's idea)? I have a feeling it won't work, but I haven't actually tried assigning negative or greater than 1 values in the RP.
     
  18. Very nice tutorial. Thanks for this!
     
    • Friendly Friendly x 1
  19. git-Spigot-90839e6-c5d27c5

    I've been doing this since literally the first 1.9 build of Spigot - I'm currently 9 versions behind but I seriously doubt anything has gone in to break this in the last 9 commits.

    I had been waiting for this specific feature for months, if not years. There are also copious YouTube videos and other tutorials about how to do this in vanilla- I assure you it works :)
     
  20. I just tried both of these real quick, and unfortunately it seems to be a no-go.

    Negative damage values seem to map to 0, and values over the max map to 1. So for my RP I get a normal hoe for negative values, and my Ocarina (the highest damage value I currently have defined) for values over max.

    If anyone finds a way around this, please let us all know- that'd be a game-changer. :)

    EDIT: And sadly given the way the durability bar "wraps" when you use damage values greater than max, I suspect the client is filtering the value so I'm going to go out on a limb and say it can't be done.
     
    #20 NathanWolf, Mar 25, 2016
    Last edited: Mar 25, 2016