Suggestion: more base Getter/Setter functionality for all supported mods
Guinaro opened this issue ยท 10 comments
What you suggest to include:
Where possible I would love more automatic processing capabilities for all the supported mod machines adding and removal recipes.
I'm talking about the same base functionality as recipes provides.
Wished for functionality
supportedmachine.all return List (maybe also commands for ingame use)
IsupportedmachineRecipe.name or .id returns string with name or id of the recipe
IsupportedmachineRecipe.commandstring returns string with the command to add the recipe
supportedmachine.removeRecipeByName
By extension:
Extended wished for: functionality that allows Splitting up commandstrings into the building components
It would be nice if we could split up the commandString in individual parts.
Currently I'm trying to split up the commandstring myself with Zenscript coding. But it would be much easier if I could use functionality as follows. And for large modpacks, probably much quicker in execution too.
Let's take ICraftingRecipe as example:
recipes.addShapeless("minecraft:yellow_concrete_powder", <minecraft:concrete_powder:4> * 8, [<minecraft:dye:11>, <minecraft:sand>, <minecraft:sand>, <minecraft:sand>, <minecraft:sand>, <minecraft:gravel>, <minecraft:gravel>, <minecraft:gravel>, <minecraft:gravel>]);
ICraftingRecipe.type (e.g. string: Shapeless (Shaped, ShapedMirrored))
ICraftingRecipe.fullname (string: minecraft:yellow_concrete_powder)(.name cuts of the minecraft:)
ICraftingRecipe.output (IItemStack: <minecraft:concrete_powder:4>
ICraftingRecipe.amount (int: 8)
ICraftingRecipe.ingredients (IIngredient[]: [<minecraft:dye:11>, <minecraft:sand>, <minecraft:sand>, <minecraft:sand>, <minecraft:sand>, <minecraft:gravel>, <minecraft:gravel>, <minecraft:gravel>, <minecraft:gravel>] (Shaped and Shaped mirrored would output IIngredient[][]))
ICraftingRecipe.IFunction (Do not know if this is possible, maybe simply the string, to be able to paste it back into a new/updated recipe)
ICraftingRecipe.IAction (Do not know if this is possible, maybe simply the string, to be able to paste it back into a new or updated recipe)
ICraftingRecipe.hidden (bool: false)
Automatic and procedurally replacing of e.g. <techreborn:ore:1>
with <minecraft:gold_ore>
would become much easier. Also for ore consolidation: Ore dictionary is a curse and and blessing to me.
Update all recipes for oredictionary support where missing, and then remove all but your chosen entry of the oredictionary entries. I only want one copper_ingot not seven. (Yes I am aware of the existance of Unidict, still I want to be in control, and when somebody really wants to add a mod to my pack, it will keep functioning if it said mod has implemented proper ore dictionary support).
Just do a run over all the implemented mods and machines, and replace what needed/ where encountered.
This would tremendously enhance the functionality of Crafttweaker and Modtweaker.
Creating a modpack like Feed The Beast Infinity Evolved Expert Mode would become a whole lot easier.
Still a lot of work but a lot of automation would be able to be obtained when .all, removebyname and commandstring splitting would be implemented.
This would be a lot of work, but I hope you take it into consideration.
If possible I would split the work into two stages.
Stage 1: recipes.all, removeByName and Commandstrings
Stage 2: Splitting up Commandstrings in Recipe.getters,(setters and update functionality?).
Guinaro.
Okay, let's see what it es exactly you want in ICraftingRecipe:
- Ingredients getter 1D
- Ingredients getter 2D
- isHidden getter
- Way to find out if a recipe is shaped or shapeless
- Recipe output getter (IItemStack already features
.amount
- Different methods to return different parts of the recipe name
- RecipeFunction/RecipeAction getter (Not possible, at least not without many cheaty try and catch-systems that would only work in about one in a hundred cases)
Let me evaluate on what of these is possible and the catches:
-
Ingredient getters:
I can not make a method that returns a 1D Array if the recipe is shaped and a 2D one if it is not. (Technically I can but that wouldn't be user-friendly in ZS since correct typecasting is something you need to have learned in ZS)- I could add two methods though, one returning a 1D array, the other one a 2D.
- In case of Shapeless, the 2D getter would return an Array of length 1 that contains an Array containing all items.
- In case of Shaped, the 1D getter would return the itemlist as 1 Dimensional Array
- I could add two methods though, one returning a 1D array, the other one a 2D.
-
isHidden getter
Doable, though in case of recipes not done via CrT not really reliable since I honestly have no idea what exactly people useisDynamic
for -
Is shaped or shapeless (or mirrored as well)
I can check if the recipe is an instance of IShapedRecipe, if mods don't use that (which they should!) there's not much I can do. As for mirrored recipes, that's doable for CrT recipes, but since there's no Interface for mirrored recipes there's not much I can do. -
Different methods to return different parts of the recipe name
Doable, though some parts of the resource location may be null -
RecipeFunctions/RecipeActions
I could at most give you a boolean if one exists and that only for CrT recipes
Bear in mind that while this is possible for Vanilla crafting table recipes, it simply isn't feasible for mods' recipe handlers!
OK thanks for making it more clear to me.
I hope the Stage One functionality is more doable then:
recipes.all for all the various mods,
recipe.name or recipe.id for the various mods
recipe.commandstring
recipes.removeByName.
I have with lots of trial and error, developed some scripts to handle things like getting substrings from a commandstring, some basic debugPrinting and basic errorhandling with functions returning strings and being able to assign null in the return, ... . Scripts in which I can do my getIngredients, checked for shaped, shapeless, ... recipe. I think when necessary I will find a way to hack the system of iFunction and iAction aswell.
That part I seem to be able to automate myself. However I really need the recipes.all functionality (with oredict support if at all possible, will hack it with out it, by doing replace on a detected oredicted item into it's oredict notation). And that removal by name in recipes has proven real handy for not needing to remove all recipes for 1 output, and then readding the ones that didn't need to be deleted.
Guinaro
After some more testing, encountered a NPE.
Issue Description:
Got a Nullpointer exception on ICraftingRecipe.ingredients2D
when iterating over the ingredients and encountering a null value.
What happens:
[INITIALIZATION][CLIENT][ERROR] [crafttweaker]: Error executing {[0:crafttweaker]: test3.zs}: null
java.lang.NullPointerException
What you expected to happen:
Being able to iterate over an IIngredients[][] array, even when it contains null values.
And a way to test for it, or another way of detecting it when iterating over an array containing a null ingredient. (A maybe also for * if needed?)
Script used (Please Pastebin or gist your script, posting an unpasted or ungist'd script will automatically close this issue):
https://gist.github.com/Guinaro/5fd16aa01c69f70407610e9496d3a782
Crafttweaker.log file (Please Pastebin or gist your file, posting an unpasted or ungist'd file will automatically close this issue):
https://gist.github.com/Guinaro/96334825d4b127799c6f9791d8e639c3
Affected Versions (Do not use "latest"):
- Minecraft: 1.12.2
- Forge: 14.23.2.2618
- Crafttweaker: 4.1.5 (Build from sources including #484)
Your most recent log file where the issue was present:
https://gist.github.com/Guinaro/5ab772f32052030b43ac59a3a2225eb2
That is a fault in your script:
recipes.addShaped(out, [[in1, null, in2], [null, in3, null],[in4, null]);
The above is a line on how to add a recipe with empty slots.
CrT uses null ingredients for empty ingredients.
So you need to check isNull(ingredients)
before calling ingredients.itemArray
I have already tested the added methods. Much nicer than having to rely on Zenscripting to split, remove and getting substrings.
Still missing
- Output getter (returning IItemstack I assume) (For handling recipes obtained via recipes.all)
- Ingredients1D and Ingredients2D returning Oredicted items instead of the First Itemstack of an an Oredict Entry. Just like you updated the commandString Functionality with it.
I could do a reverse lookup on the items for having an oredict entry. But in the end, I'm trying to create a framework for myself, where I can output recipes that need to be possibly oredicted, and recipes like e.g. woodtypes which shouldn't in certain cases, so I can create a blacklist.
Thank you very much for all the work you already put into Crafttweaker on my behalf.
It is certainly very much appreciated!
Guinaro
Thanks for helping out with the script. But got a new error:
[INITIALIZATION][CLIENT][INFO] Recipe Commandstring: recipes.addShaped("tconstruct:gadgets/brownstone/block/rough_bricks", tconstruct:brownstone:1 * 3, [[null, ore:sandstone, null], [ore:dustRedstone, ore:sandstone, ore:dustRedstone], [null, ore:sandstone, null]]);
[INITIALIZATION][CLIENT][ERROR] [crafttweaker]: Error executing {[0:crafttweaker]: test3.zs}: net.minecraftforge.oredict.ShapedOreRecipe cannot be cast to net.minecraft.item.crafting.ShapedRecipes
java.lang.ClassCastException: net.minecraftforge.oredict.ShapedOreRecipe cannot be cast to net.minecraft.item.crafting.ShapedRecipes
Happens somewhere at the line for row in 0 .. recipe.ingredients2D.length
in my script, rest of the new getters still work.
Hope it makes sense to you. Do not think I can solve this one on my own. Probably related to how Tinker's Construct creates it's recipes.
New script is https://gist.github.com/Guinaro/d3b8bd16b4b590f31951bda09acf72a2
New log is https://gist.github.com/Guinaro/47ed0afb5c8cd9a323f3342a82bea69a
Ye, mistyped a cast.
Are you on discord or anything so I can send you a test version?
I don't really like sending files via GH