Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-6202

Recipes Can't Match Tools/Armor With Durability (With Legacy Plugins Present)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • None
    • None
    • Mac OS

    • git-Spigot-57bbdd8-dea4138 (MC: 1.16.3) (Implementing API version 1.16.3-R0.1-SNAPSHOT)
    • Yes

      Updated: Turns out the problem here is the legacy material system. The example provided did not specify an api-version. Adding an api-version fixes the problem, so this only affects legacy plugins.

      I understand if that makes this a "won't fix" bug but I thought I'd submit it anyway.

      Using the RecipeChoice API to try to make upgradeable armor, I'd like to be able to use damaged armor.

      However, choices that include armor or tools with durability do not work.

      Example plugin: https://github.com/NathanWolf/Bukkit-Unit-Tests/tree/crafting-multiple-damaged

      This plugin registers a recipe where putting a diamond on top of a leather helmet should yield a diamond helmet.

      It works for an undamaged helmet, but not for a damaged one.

      I am registering a list of ExactChoice ingredients for the helmet with all 55 damage values:

      NamespacedKey recipeKey = new NamespacedKey(this, "irondiamondhelmet");
      ShapedRecipe shapedRecipe = new ShapedRecipe(recipeKey, new ItemStack(Material.DIAMOND_HELMET));
      shapedRecipe.shape("o", "i");
      shapedRecipe.setIngredient('o', Material.DIAMOND);
      List<ItemStack> variants = new ArrayList<>();
      for (short damage = 0; damage < Material.LEATHER_HELMET.getMaxDurability(); damage++) {
          ItemStack variant = new ItemStack(Material.LEATHER_HELMET, 1, damage);
          variants.add(variant);
      }
      RecipeChoice.ExactChoice choice = new RecipeChoice.ExactChoice(variants);
      shapedRecipe.setIngredient('i', choice);
      getServer().addRecipe(shapedRecipe);

      The issue seems to stem from here in in CraftRecipe.toNMS:

       

      } else if (bukkit instanceof RecipeChoice.ExactChoice) {
          stack = new RecipeItemStack(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.server.RecipeItemStack.StackProvider(CraftItemStack.asNMSCopy(mat))));
          stack.exact = true;
      } else {
      

      The CraftItemStack.asNMSCopy method is trying to handle legacy item/data combos and as such drops the damage:

       

      Item item = CraftMagicNumbers.getItem(original.getType(), original.getDurability());
      

      This call returns air if the stack passed in has a durability value set for a leather helmet item.

       

      Perhaps getItem could special-case Materials that have durability?

      I am aware this is somewhat of a silly looking example because I could just use a MaterialChoice for the helmet, but the real goal is to combine this with CustomModelData for a custom crafting system, which is why I need the ExactChoice mechanism.

       

            Unassigned Unassigned
            NathanWolf Nathan Wolf
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: