Values conversion problem from RecipeComponents
pietro-lopes opened this issue ยท 4 comments
Minecraft Version
1.20.1
KubeJS Version
latest
Rhino Version
latest
Architectury Version
latest
Forge/Fabric Version
Forge 47.1.3
Describe your issue
When we set an optional value to a RecipeKey and attach an alwaysWrite()
at some point the conversion from Double (Rhino?) to float fails
Here is a minimal setup for debugging purposes
at startup_scripts:
// priority: 0
const $RecipeSchema = Java.loadClass("dev.latvian.mods.kubejs.recipe.schema.RecipeSchema")
const $CookingRecipeSchema = Java.loadClass("dev.latvian.mods.kubejs.recipe.schema.minecraft.CookingRecipeSchema")
const $NumberComponent = Java.loadClass("dev.latvian.mods.kubejs.recipe.component.NumberComponent")
StartupEvents.recipeSchemaRegistry((event) => {
const XP = $NumberComponent.FLOAT.key("experience").optional(0.1).preferred("xp").alwaysWrite();
const buggedCookingSchema = new $RecipeSchema($CookingRecipeSchema.RESULT, $CookingRecipeSchema.INGREDIENT, XP, $CookingRecipeSchema.COOKING_TIME).uniqueOutputId($CookingRecipeSchema.RESULT)
event.namespace("minecraft").register("campfire_cooking", buggedCookingSchema)
})
at server_scripts:
// priority: 0
ServerEvents.recipes(event => {
event.recipes.minecraft.campfire_cooking("cooked_beef", "rabbit").id("minecraft:bugged_schema")
// event.recipes.minecraft.campfire_cooking("cooked_beef", "rabbit", 0.1).id("minecraft:bugged_schema") // <- this works without any issue
})
[05:06:37] [WARN] Error parsing recipe minecraft:bugged_schema[minecraft:campfire_cooking]: {"type":"unknown","result":{"item":"minecraft:cooked_beef","count":1},"ingredient":{"item":"minecraft:rabbit"}}: java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.Float (java.lang.Double and java.lang.Float are in module java.base of loader 'bootstrap')
Crash report/logs
No response
Is using this from scripts even a supported usecase ๐ค
Now you got me lol
99dad81 - does this commit means something about support being intended? looks like a problem with typewrapping, so ๐ค
Anyway, so far I'm accomplishing a lot using scripting only.
I wish we had a real component builder that I could define better the behavior of the components, like read/write/class/how to replaceInputOutput etc...
I also found a problem where I use replaceInput/Output, it successfully changes the value of a children component, but it fails to check changes because it compares value by reference (it has a workaround for builderMap with a flag hasChanged but the logic components (or/and) do not have that
So when it fails to check changes, it doesn't call the .write() function and it doesn't update.
Fixed ๐
- v.value = UtilsJS.cast(v.key.optional.getDefaultValue(type.schemaType));
+ v.value = UtilsJS.cast(v.key.component.read(this, UtilsJS.cast(v.key.optional.getDefaultValue(type.schemaType))));
I also found a problem where I use replaceInput/Output, it successfully changes the value of a children component, but it fails to check changes because it compares value by reference (it has a workaround for builderMap with a flag hasChanged but the logic components (or/and) do not have that So when it fails to check changes, it doesn't call the .write() function and it doesn't update.
Managed to fix this too here
https://github.com/KubeJS-Mods/KubeJS/blob/2002/common/src/main/java/dev/latvian/mods/kubejs/recipe/component/OrRecipeComponent.java
(I only made it work, please refactor or make it look better/safer ๐จ )
@Override
public boolean checkValueHasChanged(Either<H, L> oldValue, Either<H, L> newValue) {
if (oldValue == null || newValue == null) return RecipeComponent.super.checkValueHasChanged(oldValue, newValue);
var left = oldValue.left();
if (left.isPresent()) {
var h = high.checkValueHasChanged(oldValue.left().get(), newValue.left().get());
if (h) return true;
} else {
var l = low.checkValueHasChanged(oldValue.right().get(), newValue.right().get());
if (l) return true;
}
return RecipeComponent.super.checkValueHasChanged(oldValue, newValue);
}