DevOnTheRocks / RockyTweaks

A Minecraft Forge mod that adds additional functionality to other mods.
GNU General Public License v3.0
5 stars 2 forks source link

Anvil recipies with NBT tags or anyDamage as input #21

Closed 0xebjc closed 5 years ago

0xebjc commented 5 years ago

If you already have this feature and I missed it I apologize.

When creating an anvil recipe I want to set the input as an item with any damage.

Example: Anvil.addRecipe(.anyDamage(), * 2, , 2);

Then I would get out a diamond sword with full durability using a gold sword with any durability.

Additionally I would like to pass enchantments from one item to the next in the anvil recipes.

Example: Anvil.addRecipe(.copyEnchantments(), * 2, .appendEnchantments(), 2);

So If I put a gold sword with smite I would get out a diamond sword with smite.

0xebjc commented 5 years ago

I used the term appendEnchantment() because if the item being crafted already has nbt data, say from a mod or other preset nbt data then the goal would be not to overwrite that nbt data, just append the enchantments.

Additionally the anyDamage() method would be helpful to create repair recipes.

Example: Anvil.addRecipe(minecraft:golden_sword.anyDamage(), minecraft:gold_ingot * 2, minecraft:golden_sword, 2); This would repair the item.

Mohron commented 5 years ago

Is item.copyEnchantments() a part of CraftTweaker? I wasn't able to find it in the docs (https://crafttweaker.readthedocs.io). Supporting CraftTweaker item conditions like item.anyDamage() on the other hand is something the mod should really be doing so I'll work on making it possible.

0xebjc commented 5 years ago

I just made up "item.copyEnchantments()" as an example of the feature I was looking for. It does not exist. Crafttweaker does support recipe enchantment copy in a complex method, see ( https://docs.blamejared.com/en/#Vanilla/Recipes/Crafting/Recipe_Functions/ ) but it not the simplest method. I don't believe Rocky Core Anvil recipes supports anything like this? Basically just like when you repair an item in the Anvil your get back the same item with increased durability with all the same NBT data. I was hoping that the anvil recipe would allow a similar method for repairing items or a way to upgrade them and keep their NBT data.

Mohron commented 5 years ago

Would you be willing to test out a build updated to support item conditions with some of your planed recipes? The enchantment thing is going to take some serious digging to see if it's even viable without an extra parameter which wouldn't be as flexible as being able to tag items in the recipe.

0xebjc commented 5 years ago

Sure. I am packing today for a 8 day road trip through, leaving tomorrow at 6am. So, definitely will help, but it will be after next Sunday when I can take a look. -jc

Mohron commented 5 years ago

Now that I feel like fully understand your ask, it's really a duplicate of two separate issues: Item Conditions: https://github.com/DevOnTheRocks/RockyTweaks/issues/13 Recipe Functions: https://github.com/DevOnTheRocks/RockyTweaks/issues/11.

Mohron commented 5 years ago

If you would like to test this feature and provide feedback, a build is available here: https://github.com/DevOnTheRocks/RockyTweaks/releases/tag/0.6.0-PRE-RELEASE-1

0xebjc commented 5 years ago

I am testing your pre-release. The Item Conditions , i've tested <>.anyDamage() and it is working. for example.

Anvil.addRecipe(<minecraft:golden_sword:>.anyDamage(), 4, , 8);

This works as expected. I can use a golden sword with any damage and get a new diamond sword.

0xebjc commented 5 years ago

I either do not understand your needed syntax for IRecipeFunction or this feature is not working. Here's my code.

Anvil.addRecipe(<minecraft:golden_sword:>.anyDamage(), 4, , 8, function(out, ins, crafting){

        if(ins.input_item.tag has "ench") {
            return out.withTag({ench: ins.input_item.tag.ench});
        } else {
            return <minecraft:diamond_sword>;
        }
});

when I place the input ingredients into the Anvil I get an error message printed in the chat log repeated eight times.

ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction: ERROR: Could not execute RecipeFunction:

0xebjc commented 5 years ago

the above syntax for the function(out, ins, crafting) works in crafttweaker for recipe.addshaped

0xebjc commented 5 years ago

I also tried to use the funciton with out the item condition and got the same error message.

Code:

Anvil.addRecipe(<minecraft:golden_sword:*>, <minecraft:diamond> * 4, <minecraft:diamond_sword>, 8, function(out, ins, crafting){
        if(ins.input_item.tag has "ench") {
            return out.withTag({ench: ins.input_item.tag.ench});
        } else {
            return <minecraft:diamond_sword>;
        }
});
0xebjc commented 5 years ago

FYI, I'm pasting in the code, but the form is stripping out the greater than and less than brackets.

Mohron commented 5 years ago

Try using a code block:

``` code ```

Also, ins should have ins.left and ins.right as your inputs

0xebjc commented 5 years ago

Both features work now on client only game, awesome! Tested with mod items also. I will be testing on server/client next.

Here's the code that worked:

Anvil.remove(<carbonado:carbonado_sword>);
<carbonado:carbonado_sword>.displayName= "Black Diamond Sword";
//Anvil.addRecipe(<tp:wub_sword:*>, <carbonado:carbonado> * 4, <carbonado:carbonado_sword>, 8);

Anvil.addRecipe(<tp:wub_sword:*>.anyDamage(), <carbonado:carbonado> * 4, <carbonado:carbonado_sword>, 8, function(out, ins, cInfo){

            if(ins.left.tag has "ench") {
                return out.withTag({ench: ins.left.tag.ench});
            } else {
                return <carbonado:carbonado_sword>;
            }
    });

Anvil.addRecipe(<advancedcombat:advanced_stone_sword:*>, <carbonado:carbonado> * 4, <carbonado:carbonado_sword>, 8, function(out, ins, cInfo){

            if(ins.left.tag has "ench") {
                return out.withTag({ench: ins.left.tag.ench});
            } else {
                return <carbonado:carbonado_sword>;
            }
    });

Anvil.addRecipe(<minecraft:golden_sword:*>.anyDamage(), <carbonado:carbonado> * 4, <carbonado:carbonado_sword>, 8);
0xebjc commented 5 years ago

tested client/server no issues with mod'd and vanilla items, worked as expected with the previously posted code.

Mohron commented 5 years ago

Glad to hear. What's your thoughts on me making a custom function instead of reusing the one from crafting table recipes? The Crafting Info parameter is completely useless and I feel like the input thing can be confusing. I could make a anvil specific function like function(output, left, right) or function(output, input).

0xebjc commented 5 years ago

I've actually used the crafting parameter for checking things like a players xp crafting.player.xp


//
//  <carbonado:carbonado_sword>, [
//
//    [null,        <carbonado:carbonado>.transformConsume(4).onlyStack(4) * 4,     <tp:stone_hammer>.reuse()],
//
//    [null,        <tp:wub_sword:*>.marked("input_item"),                          null],
//
//    [null,        <minecraft:anvil>.reuse(),                                      null]],
//    
//    function(out, ins, crafting) {
//
//      if crafting.player.xp >= 8 {
//          crafting.player.sendChat("Players Level is " ~ crafting.player.xp);
//
//          if(ins.input_item.tag has "ench") {
//              return out.withTag({ench: ins.input_item.tag.ench});
//          } else {
//              return <carbonado:carbonado_sword>;
//          }
//      } else {
//          return null;
//      }
//    }, function(output, crafting, player) {
//          var xpLevelCost = 8;
//          player.xp -= xpLevelCost;
//          player.sendChat("Removed " ~ xpLevelCost ~ " XP Levels.");
//  });```

but not sure if you really need anything like this since the anvil already handles xp deductions and assuming it validates available xp beforehand.
0xebjc commented 5 years ago

I would probably leave it because it offers a more universal option that aligns with crafttweaker syntax. If someone wants to implement something in crafttweaker or rockytweaks they would already understand the syntax.

0xebjc commented 5 years ago

What I think would be a great addition to creafttweaker that could be inherited by your mod would be a way to more easily handle NBT data from input to output items, simliar to

.anyDamage()
Ideas would be out.replaceNBT(input.NBT) or out.appendNBT(input.NBT), or out.appendNBT(input.NBT.onlyEnch)
recpies.addshaped(<minecraft:diamond_sword.appendNBT(input_weapon.onlyEnch), 
    [[null, <minecraft:diamond>, null],
    [<minecraft:diamond>, <minecraft:golden_sword>.maked("input_weapon"), <minecraft:diamond>],
    [null, <minecraft:diamond>, <minecraft:diamond>]]);
REPLACE THIS:

Anvil.addRecipe(<minecraft:golden_sword:*>.anyDamage(), <minecraft:diamond> * 4, <minecraft:diamond_sword>, 8, function(out, ins, cInfo){
            if(ins.left.tag has "ench") {
                return out.withTag({ench: ins.left.tag.ench});
            } else {
                return out;
            }
    });

WITH:

Anvil.addRecipe(<minecraft:golden_sword:*>.anyDamage(), <minecraft:diamond> * 4, <minecraft:diamond_sword>.appendNBT(in.left.NBT.onlyEnch), 8);

I would prefer to have options to append or replace nbt data because I have mods that have custom NBT data already added from within the class definition that I would not want to replace.

really, you've done a great job and I'm using your pre-release now, it does exactly what I was looking for, and it's just a matter of understanding the function parameter for crafting and how it works.