From c87c45870f13c15e187e53ee7f11c1744899f45f Mon Sep 17 00:00:00 2001 From: LatvianModder Date: Mon, 8 Jul 2024 00:23:34 +0300 Subject: [PATCH] Renamed `recipe_schemas` directory to `recipe_schema`, added type and key overrides --- .../kubejs/error/KubeRuntimeException.java | 5 +- .../mods/kubejs/recipe/KubeRecipe.java | 2 +- .../latvian/mods/kubejs/recipe/RecipeKey.java | 4 -- .../kubejs/recipe/RecipeTypeFunction.java | 16 ++--- .../component/RecipeComponentBuilderMap.java | 7 +- .../recipe/schema/JsonRecipeSchemaLoader.java | 62 ++++++++++++++---- .../recipe/schema/RecipeConstructor.java | 20 ++++-- .../kubejs/recipe/schema/RecipeSchema.java | 65 +++++++++++-------- .../recipe/schema/RecipeSchemaStorage.java | 6 +- .../recipe/schema/RecipeSchemaType.java | 6 +- .../recipe/schema/UnknownRecipeSchema.java | 7 ++ .../kubejs/server/ServerScriptManager.java | 2 +- .../upgrade.json | 0 .../shaped_table.json | 0 .../shapeless_table.json | 0 .../shaped.json | 0 .../shapeless.json | 0 .../blasting.json | 0 .../campfire_cooking.json | 0 .../cooking.json | 0 .../crafting_decorated_pot.json | 0 .../crafting_shaped.json | 0 .../crafting_shapeless.json | 0 .../crafting_special_armordye.json | 0 .../crafting_special_bannerduplicate.json | 0 .../crafting_special_bookcloning.json | 0 .../crafting_special_firework_rocket.json | 0 .../crafting_special_firework_star.json | 0 .../crafting_special_firework_star_fade.json | 0 .../crafting_special_mapcloning.json | 0 .../crafting_special_mapextending.json | 0 .../crafting_special_repairitem.json | 0 .../crafting_special_shielddecoration.json | 0 .../crafting_special_shulkerboxcoloring.json | 0 .../crafting_special_suspiciousstew.json | 0 .../crafting_special_tippedarrow.json | 0 .../shaped.json | 0 .../shapeless.json | 0 .../smelting.json | 0 .../smithing_transform.json | 0 .../smithing_trim.json | 0 .../smoking.json | 0 .../special.json | 0 .../stonecutting.json | 0 44 files changed, 133 insertions(+), 69 deletions(-) rename src/main/resources/data/dankstorage/kubejs/{recipe_schemas => recipe_schema}/upgrade.json (100%) rename src/main/resources/data/extendedcrafting/kubejs/{recipe_schemas => recipe_schema}/shaped_table.json (100%) rename src/main/resources/data/extendedcrafting/kubejs/{recipe_schemas => recipe_schema}/shapeless_table.json (100%) rename src/main/resources/data/kubejs/kubejs/{recipe_schemas => recipe_schema}/shaped.json (100%) rename src/main/resources/data/kubejs/kubejs/{recipe_schemas => recipe_schema}/shapeless.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/blasting.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/campfire_cooking.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/cooking.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_decorated_pot.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_shaped.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_shapeless.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_armordye.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_bannerduplicate.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_bookcloning.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_firework_rocket.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_firework_star.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_firework_star_fade.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_mapcloning.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_mapextending.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_repairitem.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_shielddecoration.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_shulkerboxcoloring.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_suspiciousstew.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/crafting_special_tippedarrow.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/shaped.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/shapeless.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/smelting.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/smithing_transform.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/smithing_trim.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/smoking.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/special.json (100%) rename src/main/resources/data/minecraft/kubejs/{recipe_schemas => recipe_schema}/stonecutting.json (100%) diff --git a/src/main/java/dev/latvian/mods/kubejs/error/KubeRuntimeException.java b/src/main/java/dev/latvian/mods/kubejs/error/KubeRuntimeException.java index 4a64890b4..16f054518 100644 --- a/src/main/java/dev/latvian/mods/kubejs/error/KubeRuntimeException.java +++ b/src/main/java/dev/latvian/mods/kubejs/error/KubeRuntimeException.java @@ -31,7 +31,10 @@ public String toString() { } public KubeRuntimeException source(SourceLine sourceLine) { - this.sourceLine = sourceLine; + if (this.sourceLine.isUnknown()) { + this.sourceLine = sourceLine; + } + return this; } } \ No newline at end of file diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java b/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java index aa72bd5ab..93318feb8 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/KubeRecipe.java @@ -155,7 +155,7 @@ public void initValues(boolean created) { save(); } - if (type.schemaType.schema.keys.length > 0) { + if (!type.schemaType.schema.keys.isEmpty()) { valueMap = new RecipeComponentBuilderMap(type.schemaType.schema.keys); if (created) { diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeKey.java b/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeKey.java index c8c0f5870..8a7423e77 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeKey.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeKey.java @@ -165,10 +165,6 @@ public RecipeKey exclude() { return this; } - public boolean includeInAutoConstructors() { - return optional == null || !excluded; - } - /** * Disables the generation of builder functions for this key. */ diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeTypeFunction.java b/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeTypeFunction.java index 11b9c7f9a..cf0c1f42a 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeTypeFunction.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeTypeFunction.java @@ -45,6 +45,8 @@ public KubeRecipe call(Context cx, Scriptable scope, Scriptable thisObj, Object[ } public KubeRecipe createRecipe(Context cx, Object[] args) { + var sourceLine = SourceLine.of(cx); + try { for (int i = 0; i < args.length; i++) { args[i] = Wrapper.unwrapped(args[i]); @@ -56,13 +58,13 @@ public KubeRecipe createRecipe(Context cx, Object[] args) { if (constructor == null) { if (args.length == 1 && (args[0] instanceof Map || args[0] instanceof JsonObject)) { - var recipe = schemaType.schema.deserialize(SourceLine.of(cx), this, null, MapJS.json(cx, args[0])); + var recipe = schemaType.schema.deserialize(sourceLine, this, null, MapJS.json(cx, args[0])); recipe.afterLoaded(); return event.addRecipe(recipe, true); // throw new RecipeExceptionJS("Use event.custom(json) for json recipes!"); } - throw new KubeRuntimeException("Constructor for " + id + " with " + args.length + " arguments not found!"); + throw new KubeRuntimeException("Constructor for " + id + " with " + args.length + " arguments not found!").source(sourceLine); } /* @@ -80,13 +82,13 @@ public KubeRecipe createRecipe(Context cx, Object[] args) { argMap.put(key, Wrapper.unwrapped(args[index++])); } - var recipe = constructor.create(cx, this, schemaType, argMap); + var recipe = constructor.create(cx, sourceLine, this, schemaType, argMap); recipe.afterLoaded(); return event.addRecipe(recipe, false); } catch (KubeRuntimeException rex) { - throw rex; + throw rex.source(sourceLine); } catch (Throwable ex) { - throw new KubeRuntimeException("Failed to create recipe for type '" + id + "' with args " + Arrays.stream(args).map(o -> o == null ? "null" : (o + ": " + o.getClass().getSimpleName())).collect(Collectors.joining(", ", "[", "]")), ex); + throw new KubeRuntimeException("Failed to create recipe for type '" + id + "' with args " + Arrays.stream(args).map(o -> o == null ? "null" : (o + ": " + o.getClass().getSimpleName())).collect(Collectors.joining(", ", "[", "]")), ex).source(sourceLine); } } @@ -95,10 +97,6 @@ public String toString() { return idString; } - public String getMod() { - return id.getNamespace(); - } - @Override public int hashCode() { return idString.hashCode(); diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/component/RecipeComponentBuilderMap.java b/src/main/java/dev/latvian/mods/kubejs/recipe/component/RecipeComponentBuilderMap.java index d5511dc5a..87e921ce2 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/component/RecipeComponentBuilderMap.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/component/RecipeComponentBuilderMap.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import java.util.AbstractMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -35,11 +36,11 @@ public RecipeComponentBuilderMap(RecipeComponentValue[] holders) { } } - public RecipeComponentBuilderMap(RecipeKey[] keys) { - this.holders = new RecipeComponentValue[keys.length]; + public RecipeComponentBuilderMap(List> keys) { + this.holders = new RecipeComponentValue[keys.size()]; for (int i = 0; i < holders.length; i++) { - this.holders[i] = new RecipeComponentValue<>(keys[i], i); + this.holders[i] = new RecipeComponentValue<>(keys.get(i), i); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/JsonRecipeSchemaLoader.java b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/JsonRecipeSchemaLoader.java index 8d853017f..1a0f93bc6 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/JsonRecipeSchemaLoader.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/JsonRecipeSchemaLoader.java @@ -2,7 +2,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.mojang.serialization.JsonOps; +import com.mojang.serialization.DynamicOps; import dev.latvian.mods.kubejs.recipe.RecipeKey; import dev.latvian.mods.kubejs.recipe.component.ComponentRole; import dev.latvian.mods.kubejs.script.ConsoleJS; @@ -26,14 +26,17 @@ private record FunctionBuilder(String name, JsonObject json) { private static final class RecipeSchemaBuilder { private final ResourceLocation id; private final JsonObject json; + private RecipeSchema schema; + private RecipeSchemaBuilder parent; + private ResourceLocation overrideType; private List> keys; private List constructors; private Map functions; private KubeRecipeFactory recipeFactory; private List unique; private boolean hidden; - private RecipeSchema schema; + private Map overrideKeys; private RecipeSchemaBuilder(ResourceLocation id, JsonObject json) { this.id = id; @@ -100,9 +103,9 @@ private boolean isHidden() { } } - private RecipeSchema getSchema() { + private RecipeSchema getSchema(DynamicOps jsonOps) { if (schema == null) { - if (keys != null || constructors != null || functions != null || recipeFactory != null || unique != null) { + if (overrideType != null || keys != null || constructors != null || functions != null || recipeFactory != null || unique != null || overrideKeys != null) { var keys = getKeys(); var keyMap = new HashMap>(); @@ -113,7 +116,26 @@ private RecipeSchema getSchema() { var functionMap = new HashMap(); gatherFunctions(functionMap); - schema = new RecipeSchema(getKeys().toArray(new RecipeKey[0])); + var keyOverrides = new IdentityHashMap, RecipeOptional>(overrideKeys == null ? 0 : overrideKeys.size()); + + if (overrideKeys != null) { + for (var entry : overrideKeys.entrySet()) { + var key = keyMap.get(entry.getKey()); + + if (key != null) { + try { + keyOverrides.put(key, new RecipeOptional.Constant(key.codec.decode(jsonOps, entry.getValue()).getOrThrow().getFirst())); + } catch (Exception ex) { + throw new IllegalArgumentException("Failed to create optional value for key '" + key + "' of '" + id + "' from " + entry.getValue(), ex); + } + } else { + throw new NullPointerException("Key '" + entry.getKey() + "' not found in key overrides of recipe schema '" + id + "'"); + } + } + } + + schema = new RecipeSchema(keyOverrides, getKeys()); + schema.typeOverride = overrideType; var rf = getRecipeFactory(); @@ -147,7 +169,7 @@ private RecipeSchema getSchema() { if (key != null) { try { - constructor.overrides.put(key, new RecipeOptional.Constant(key.codec.decode(JsonOps.INSTANCE, entry.getValue()).getOrThrow().getFirst())); + constructor.overrides.put(key, new RecipeOptional.Constant(key.codec.decode(jsonOps, entry.getValue()).getOrThrow().getFirst())); } catch (Exception ex) { throw new IllegalArgumentException("Failed to create optional value for key '" + key + "' of '" + id + "' from " + entry.getValue(), ex); } @@ -173,7 +195,7 @@ private RecipeSchema getSchema() { var key = keyMap.get(entry1.getKey()); if (key != null) { - map.put(key, key.codec.decode(JsonOps.INSTANCE, entry1.getValue()).getOrThrow().getFirst()); + map.put(key, key.codec.decode(jsonOps, entry1.getValue()).getOrThrow().getFirst()); } else { throw new NullPointerException("Key '" + entry1.getKey() + "' not found in function '" + entry1.getKey() + "' of recipe schema '" + id + "'"); } @@ -207,9 +229,9 @@ private RecipeSchema getSchema() { schema.hidden = isHidden(); } else if (parent != null) { - schema = parent.getSchema(); + schema = parent.getSchema(jsonOps); } else { - schema = new RecipeSchema(); + schema = new RecipeSchema(Map.of(), List.of()); schema.constructor(); } } @@ -218,13 +240,13 @@ private RecipeSchema getSchema() { } } - public static void load(RecipeSchemaStorage storage, RecipeSchemaRegistry event, ResourceManager resourceManager) { + public static void load(RecipeSchemaStorage storage, RecipeSchemaRegistry event, ResourceManager resourceManager, DynamicOps jsonOps) { var map = new HashMap(); - for (var entry : resourceManager.listResources("kubejs/recipe_schemas", path -> path.getPath().endsWith(".json")).entrySet()) { + for (var entry : resourceManager.listResources("kubejs/recipe_schema", path -> path.getPath().endsWith(".json")).entrySet()) { try (var reader = entry.getValue().openAsReader()) { var json = JsonUtils.GSON.fromJson(reader, JsonObject.class); - var holder = new RecipeSchemaBuilder(ResourceLocation.fromNamespaceAndPath(entry.getKey().getNamespace(), entry.getKey().getPath().substring("kubejs/recipe_schemas/".length(), entry.getKey().getPath().length() - ".json".length())), json); + var holder = new RecipeSchemaBuilder(ResourceLocation.fromNamespaceAndPath(entry.getKey().getNamespace(), entry.getKey().getPath().substring("kubejs/recipe_schema/".length(), entry.getKey().getPath().length() - ".json".length())), json); map.put(holder.id, holder); if (holder.json.has("mappings")) { @@ -244,6 +266,10 @@ public static void load(RecipeSchemaStorage storage, RecipeSchemaRegistry event, holder.parent = holder.json.has("parent") ? map.get(ResourceLocation.parse(holder.json.get("parent").getAsString())) : null; + if (holder.json.has("override_type")) { + holder.overrideType = ResourceLocation.parse(holder.json.get("override_type").getAsString()); + } + if (holder.json.has("factory")) { var fname = ResourceLocation.parse(holder.json.get("factory").getAsString()); holder.recipeFactory = storage.recipeTypes.get(fname); @@ -276,7 +302,7 @@ public static void load(RecipeSchemaStorage storage, RecipeSchemaRegistry event, key.defaultOptional(); } else { try { - key.optional = new RecipeOptional.Constant(key.codec.decode(JsonOps.INSTANCE, optionalJson).getOrThrow().getFirst()); + key.optional = new RecipeOptional.Constant(key.codec.decode(jsonOps, optionalJson).getOrThrow().getFirst()); } catch (Exception ex) { throw new IllegalArgumentException("Failed to create optional value for key '" + key + "' of '" + holder.id + "' from " + optionalJson, ex); } @@ -358,10 +384,18 @@ public static void load(RecipeSchemaStorage storage, RecipeSchemaRegistry event, holder.functions.put(entry.getKey(), new FunctionBuilder(entry.getKey(), entry.getValue().getAsJsonObject())); } } + + if (holder.json.has("override_keys")) { + holder.overrideKeys = new HashMap<>(); + + for (var e : holder.json.getAsJsonObject("override_keys").entrySet()) { + holder.overrideKeys.put(e.getKey(), e.getValue()); + } + } } for (var holder : map.values()) { - var schema = holder.getSchema(); + var schema = holder.getSchema(jsonOps); event.namespace(holder.id.getNamespace()).register(holder.id.getPath(), schema); } } diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeConstructor.java b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeConstructor.java index 292db57ac..ed8873320 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeConstructor.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeConstructor.java @@ -9,20 +9,24 @@ import dev.latvian.mods.kubejs.util.Cast; import dev.latvian.mods.rhino.Context; -import java.util.Arrays; import java.util.IdentityHashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class RecipeConstructor { - public final RecipeKey[] keys; + public final List> keys; public Map, RecipeOptional> overrides; - public RecipeConstructor(RecipeKey... keys) { + public RecipeConstructor(List> keys) { this.keys = keys; this.overrides = Map.of(); } + public RecipeConstructor(RecipeKey... keys) { + this(List.of(keys)); + } + public RecipeConstructor override(RecipeKey key, RecipeOptional value) { if (overrides.isEmpty()) { overrides = new IdentityHashMap<>(1); @@ -43,12 +47,12 @@ public RecipeConstructor overrides(Map, RecipeOptional> map) { @Override public String toString() { - return Arrays.stream(keys).map(RecipeKey::toString).collect(Collectors.joining(", ", "(", ")")); + return keys.stream().map(RecipeKey::toString).collect(Collectors.joining(", ", "(", ")")); } - public KubeRecipe create(Context cx, RecipeTypeFunction type, RecipeSchemaType schemaType, ComponentValueMap from) { + public KubeRecipe create(Context cx, SourceLine sourceLine, RecipeTypeFunction type, RecipeSchemaType schemaType, ComponentValueMap from) { var r = schemaType.schema.recipeFactory.create(); - r.sourceLine = SourceLine.of(cx); + r.sourceLine = sourceLine; r.type = type; r.json = new JsonObject(); r.json.addProperty("type", "unknown"); @@ -66,5 +70,9 @@ public void setValues(Context cx, KubeRecipe recipe, RecipeSchemaType schemaType for (var entry : overrides.entrySet()) { recipe.setValue(entry.getKey(), Cast.to(entry.getValue().getDefaultValue(schemaType))); } + + for (var entry : schemaType.schema.keyOverrides.entrySet()) { + recipe.setValue(entry.getKey(), Cast.to(entry.getValue().getDefaultValue(schemaType))); + } } } diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchema.java b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchema.java index f269b59b2..eef86b867 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchema.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchema.java @@ -16,9 +16,9 @@ import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.SequencedCollection; import java.util.function.Function; @@ -26,7 +26,7 @@ /** * A recipe schema is a set of keys that defines how a recipe is constructed * from both KubeJS scripts (through the {@link #constructors}) and JSON files - * (using the {@link #deserialize(RecipeTypeFunction, ResourceLocation, JsonObject)} method). + * (using the {@link #deserialize(SourceLine, RecipeTypeFunction, ResourceLocation, JsonObject)} method). *

* The schema also defines a {@link #recipeFactory} in order to create a {@link KubeRecipe} object that * implements serialization logic, post-load validation ({@link KubeRecipe#afterLoaded()}), @@ -39,7 +39,10 @@ public class RecipeSchema { public static final Function DEFAULT_UNIQUE_ID_FUNCTION = r -> null; public KubeRecipeFactory recipeFactory; - public final RecipeKey[] keys; + public ResourceLocation typeOverride; + public final List> keys; + public final List> includedKeys; + public final Map, RecipeOptional> keyOverrides; public final Map functions; private int inputCount; private int outputCount; @@ -56,9 +59,12 @@ public class RecipeSchema { * * @param keys The keys that define this schema. */ - public RecipeSchema(RecipeKey... keys) { + public RecipeSchema(Map, RecipeOptional> keyOverrides, List> keys) { this.recipeFactory = KubeRecipeFactory.DEFAULT; - this.keys = keys; + this.typeOverride = null; + this.keys = List.copyOf(keys); + this.keyOverrides = Map.copyOf(keyOverrides); + this.includedKeys = List.copyOf(this.keys.stream().filter(k -> (k.optional == null || !k.excluded) && !this.keyOverrides.containsKey(k)).toList()); this.functions = new LinkedHashMap<>(0); this.minRequiredArguments = 0; this.inputCount = 0; @@ -66,50 +72,61 @@ public RecipeSchema(RecipeKey... keys) { var set = new HashSet(); - for (int i = 0; i < keys.length; i++) { - if (keys[i].optional()) { + for (int i = 0; i < includedKeys.size(); i++) { + var k = includedKeys.get(i); + + if (k.optional()) { if (minRequiredArguments == 0) { minRequiredArguments = i; } } else if (minRequiredArguments > 0) { - throw new IllegalArgumentException("Required key '" + keys[i].name + "' must be ahead of optional keys!"); + throw new IllegalArgumentException("Required key '" + k.name + "' must be ahead of optional keys!"); } - if (!set.add(keys[i].name)) { - throw new IllegalArgumentException("Duplicate key '" + keys[i].name + "' found!"); + if (!set.add(k.name)) { + throw new IllegalArgumentException("Duplicate key '" + k.name + "' found!"); } - if (keys[i].role.isInput()) { + if (k.role.isInput()) { inputCount++; - } else if (keys[i].role.isOutput()) { + } else if (k.role.isOutput()) { outputCount++; } - if (keys[i].alwaysWrite && keys[i].optional() && keys[i].optional.isDefault()) { - throw new IllegalArgumentException("Key '" + keys[i] + "' can't have alwaysWrite() enabled with defaultOptional()!"); + if (k.alwaysWrite && k.optional() && k.optional.isDefault()) { + throw new IllegalArgumentException("Key '" + k + "' can't have alwaysWrite() enabled with defaultOptional()!"); } } if (minRequiredArguments == 0) { - minRequiredArguments = keys.length; + minRequiredArguments = includedKeys.size(); } this.uniqueIdFunction = DEFAULT_UNIQUE_ID_FUNCTION; this.hidden = false; } + public RecipeSchema(RecipeKey... keys) { + this(Map.of(), List.of(keys)); + } + public RecipeSchema factory(KubeRecipeFactory factory) { this.recipeFactory = factory; return this; } + public RecipeSchema typeOverride(ResourceLocation id) { + this.typeOverride = id; + return this; + } + public RecipeSchema constructor(RecipeConstructor constructor) { if (constructors == null) { - constructors = new Int2ObjectArrayMap<>(keys.length - minRequiredArguments + 1); + constructors = new Int2ObjectArrayMap<>(keys.size() - minRequiredArguments() + 1); } - if (constructors.put(constructor.keys.length, constructor) != null) { - throw new IllegalStateException("Constructor with " + constructor.keys.length + " arguments already exists!"); + if (constructors.put(constructor.keys.size(), constructor) != null) { + throw new IllegalStateException("Constructor with " + constructor.keys.size() + " arguments already exists!"); } return this; @@ -183,19 +200,15 @@ public RecipeSchema uniqueIds(SequencedCollection> keys) { public Int2ObjectMap constructors() { if (constructors == null) { - var keys1 = Arrays.stream(keys).filter(RecipeKey::includeInAutoConstructors).toArray(RecipeKey[]::new); - - constructors = keys1.length == 0 ? new Int2ObjectArrayMap<>() : new Int2ObjectArrayMap<>(keys1.length - minRequiredArguments + 1); + constructors = includedKeys.isEmpty() ? new Int2ObjectArrayMap<>() : new Int2ObjectArrayMap<>(includedKeys.size() - minRequiredArguments + 1); boolean dev = DevProperties.get().logRecipeDebug; if (dev) { - KubeJS.LOGGER.info("Generating constructors for " + new RecipeConstructor(keys1)); + KubeJS.LOGGER.info("Generating constructors for " + new RecipeConstructor(includedKeys)); } - for (int a = minRequiredArguments; a <= keys1.length; a++) { - var k = new RecipeKey[a]; - System.arraycopy(keys1, 0, k, 0, a); - var c = new RecipeConstructor(k); + for (int a = minRequiredArguments; a <= includedKeys.size(); a++) { + var c = new RecipeConstructor(List.copyOf(includedKeys.subList(0, a))); constructors.put(a, c); if (dev) { diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaStorage.java b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaStorage.java index e4ca28da5..d0d491b7d 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaStorage.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaStorage.java @@ -1,8 +1,10 @@ package dev.latvian.mods.kubejs.recipe.schema; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.brigadier.StringReader; +import com.mojang.serialization.DynamicOps; import dev.latvian.mods.kubejs.bindings.event.ServerEvents; import dev.latvian.mods.kubejs.plugin.KubeJSPlugin; import dev.latvian.mods.kubejs.plugin.KubeJSPlugins; @@ -43,7 +45,7 @@ public RecipeNamespace namespace(String namespace) { return namespaces.computeIfAbsent(namespace, n -> new RecipeNamespace(this, n)); } - public void fireEvents(ResourceManager resourceManager) { + public void fireEvents(ResourceManager resourceManager, DynamicOps jsonOps) { recipeTypes.clear(); namespaces.clear(); mappings.clear(); @@ -102,7 +104,7 @@ public void fireEvents(ResourceManager resourceManager) { } var schemaRegistry = new RecipeSchemaRegistry(this); - JsonRecipeSchemaLoader.load(this, schemaRegistry, resourceManager); + JsonRecipeSchemaLoader.load(this, schemaRegistry, resourceManager, jsonOps); shapedSchema = Objects.requireNonNull(namespace("minecraft").get("shaped").schema); shapelessSchema = Objects.requireNonNull(namespace("minecraft").get("shapeless").schema); diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaType.java b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaType.java index 36a9602f7..162f4912a 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaType.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/RecipeSchemaType.java @@ -21,14 +21,16 @@ public RecipeSchemaType(RecipeNamespace namespace, ResourceLocation id, RecipeSc } public RecipeSerializer getSerializer() { + var serializerId = schema.typeOverride == null ? id : schema.typeOverride; + if (serializer == null) { - serializer = Optional.ofNullable(RegistryInfo.RECIPE_SERIALIZER.getValue(id)); + serializer = Optional.ofNullable(RegistryInfo.RECIPE_SERIALIZER.getValue(serializerId)); } var s = serializer.orElse(null); if (s == null) { - throw new KubeRuntimeException("Serializer for type " + id + " is not found!"); + throw new KubeRuntimeException("Serializer for type " + serializerId + " is not found!"); } return s; diff --git a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/UnknownRecipeSchema.java b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/UnknownRecipeSchema.java index c7dc91824..7e393a16d 100644 --- a/src/main/java/dev/latvian/mods/kubejs/recipe/schema/UnknownRecipeSchema.java +++ b/src/main/java/dev/latvian/mods/kubejs/recipe/schema/UnknownRecipeSchema.java @@ -2,7 +2,14 @@ import org.jetbrains.annotations.ApiStatus; +import java.util.List; +import java.util.Map; + @ApiStatus.Internal public class UnknownRecipeSchema extends RecipeSchema { public static final RecipeSchema SCHEMA = new UnknownRecipeSchema().factory(UnknownKubeRecipe.RECIPE_FACTORY); + + private UnknownRecipeSchema() { + super(Map.of(), List.of()); + } } diff --git a/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java b/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java index 2f642589a..83dbaf338 100644 --- a/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java +++ b/src/main/java/dev/latvian/mods/kubejs/server/ServerScriptManager.java @@ -168,7 +168,7 @@ public boolean recipes(RecipeManagerKJS recipeManager, ResourceManager resourceM boolean result = false; RecipesKubeEvent.TEMP_ITEM_TAG_LOOKUP.setValue(getRegistries().cachedItemTags); - recipeSchemaStorage.fireEvents(resourceManager); + recipeSchemaStorage.fireEvents(resourceManager, getRegistries().json()); SpecialRecipeSerializerManager.INSTANCE.reset(); ServerEvents.SPECIAL_RECIPES.post(ScriptType.SERVER, SpecialRecipeSerializerManager.INSTANCE); diff --git a/src/main/resources/data/dankstorage/kubejs/recipe_schemas/upgrade.json b/src/main/resources/data/dankstorage/kubejs/recipe_schema/upgrade.json similarity index 100% rename from src/main/resources/data/dankstorage/kubejs/recipe_schemas/upgrade.json rename to src/main/resources/data/dankstorage/kubejs/recipe_schema/upgrade.json diff --git a/src/main/resources/data/extendedcrafting/kubejs/recipe_schemas/shaped_table.json b/src/main/resources/data/extendedcrafting/kubejs/recipe_schema/shaped_table.json similarity index 100% rename from src/main/resources/data/extendedcrafting/kubejs/recipe_schemas/shaped_table.json rename to src/main/resources/data/extendedcrafting/kubejs/recipe_schema/shaped_table.json diff --git a/src/main/resources/data/extendedcrafting/kubejs/recipe_schemas/shapeless_table.json b/src/main/resources/data/extendedcrafting/kubejs/recipe_schema/shapeless_table.json similarity index 100% rename from src/main/resources/data/extendedcrafting/kubejs/recipe_schemas/shapeless_table.json rename to src/main/resources/data/extendedcrafting/kubejs/recipe_schema/shapeless_table.json diff --git a/src/main/resources/data/kubejs/kubejs/recipe_schemas/shaped.json b/src/main/resources/data/kubejs/kubejs/recipe_schema/shaped.json similarity index 100% rename from src/main/resources/data/kubejs/kubejs/recipe_schemas/shaped.json rename to src/main/resources/data/kubejs/kubejs/recipe_schema/shaped.json diff --git a/src/main/resources/data/kubejs/kubejs/recipe_schemas/shapeless.json b/src/main/resources/data/kubejs/kubejs/recipe_schema/shapeless.json similarity index 100% rename from src/main/resources/data/kubejs/kubejs/recipe_schemas/shapeless.json rename to src/main/resources/data/kubejs/kubejs/recipe_schema/shapeless.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/blasting.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/blasting.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/blasting.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/blasting.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/campfire_cooking.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/campfire_cooking.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/campfire_cooking.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/campfire_cooking.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/cooking.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/cooking.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/cooking.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/cooking.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_decorated_pot.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_decorated_pot.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_decorated_pot.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_decorated_pot.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_shaped.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_shaped.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_shaped.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_shaped.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_shapeless.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_shapeless.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_shapeless.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_shapeless.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_armordye.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_armordye.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_armordye.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_armordye.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_bannerduplicate.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_bannerduplicate.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_bannerduplicate.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_bannerduplicate.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_bookcloning.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_bookcloning.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_bookcloning.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_bookcloning.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_firework_rocket.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_firework_rocket.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_firework_rocket.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_firework_rocket.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_firework_star.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_firework_star.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_firework_star.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_firework_star.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_firework_star_fade.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_firework_star_fade.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_firework_star_fade.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_firework_star_fade.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_mapcloning.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_mapcloning.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_mapcloning.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_mapcloning.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_mapextending.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_mapextending.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_mapextending.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_mapextending.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_repairitem.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_repairitem.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_repairitem.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_repairitem.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_shielddecoration.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_shielddecoration.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_shielddecoration.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_shielddecoration.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_shulkerboxcoloring.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_shulkerboxcoloring.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_shulkerboxcoloring.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_shulkerboxcoloring.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_suspiciousstew.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_suspiciousstew.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_suspiciousstew.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_suspiciousstew.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_tippedarrow.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_tippedarrow.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/crafting_special_tippedarrow.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/crafting_special_tippedarrow.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/shaped.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/shaped.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/shaped.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/shaped.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/shapeless.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/shapeless.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/shapeless.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/shapeless.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/smelting.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/smelting.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/smelting.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/smelting.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/smithing_transform.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/smithing_transform.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/smithing_transform.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/smithing_transform.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/smithing_trim.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/smithing_trim.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/smithing_trim.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/smithing_trim.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/smoking.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/smoking.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/smoking.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/smoking.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/special.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/special.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/special.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/special.json diff --git a/src/main/resources/data/minecraft/kubejs/recipe_schemas/stonecutting.json b/src/main/resources/data/minecraft/kubejs/recipe_schema/stonecutting.json similarity index 100% rename from src/main/resources/data/minecraft/kubejs/recipe_schemas/stonecutting.json rename to src/main/resources/data/minecraft/kubejs/recipe_schema/stonecutting.json