package lv.enes.mc.eris_alchemy; import com.google.gson.*; import jakarta.annotation.Nonnull; import lv.enes.mc.eris_alchemy.utils.RecipeUtils; import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.ShapedRecipe; import java.lang.reflect.Type; import java.util.List; public record SimplifiedRecipe(ItemStack output, List remainder, List input) { public SimplifiedRecipe(Recipe recipe, RegistryAccess registryAccess) { this( RecipeUtils.getOutput(recipe, registryAccess), List.of(), // TODO: RecipeUtils.getIngredients(recipe).stream().filter(ingredient -> !ingredient.isEmpty()).toList() ); } static class Deserializer implements JsonDeserializer { @Nonnull @Override public SimplifiedRecipe deserialize( JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext ) throws JsonParseException { if (!jsonElement.isJsonObject()) { throw new JsonParseException("Recipe must be an object"); } var obj = jsonElement.getAsJsonObject(); if (obj.get("output") == null || obj.get("input") == null) { throw new JsonParseException("Recipe must have 'output' and 'input' fields"); } var output = parseOutputOrRemainder(obj.get("output")); var remainder = parseRemainders(obj.get("remainder")); var input = parseInputs(obj.get("input")); return new SimplifiedRecipe(output, remainder, input); } private List parseInputs(JsonElement el) { if (el.isJsonArray()) { return el.getAsJsonArray().asList().stream().map(this::parseInput).map(Ingredient::of).toList(); } return List.of(Ingredient.of(parseInput(el))); } private ItemStack parseInput(JsonElement el) { if (el.isJsonObject()) { return ShapedRecipe.itemStackFromJson(el.getAsJsonObject()); } else if (el.isJsonPrimitive() && el.getAsJsonPrimitive().isString()) { var id = new ResourceLocation(el.getAsString()); return BuiltInRegistries.ITEM.get(id).getDefaultInstance(); } else { throw new JsonParseException("Every recipe input should be an object or a string"); } } private ItemStack parseOutputOrRemainder(JsonElement el) { if (el.isJsonObject()) { return ShapedRecipe.itemStackFromJson(el.getAsJsonObject()); } else if (el.isJsonPrimitive() && el.getAsJsonPrimitive().isString()) { var id = new ResourceLocation(el.getAsString()); return BuiltInRegistries.ITEM.get(id).getDefaultInstance(); } else { throw new JsonParseException("Recipe's output or remainder must be an object or a string"); } } private List parseRemainders(JsonElement el) { if (el == null) { return List.of(); } else if (el.isJsonArray()) { return el.getAsJsonArray().asList().stream().map(this::parseOutputOrRemainder).toList(); } else { return List.of(parseOutputOrRemainder(el)); } } } }