From 32368f8388a496c0a91ddb2174007bd60d7bb53d Mon Sep 17 00:00:00 2001 From: modmuss50 <modmuss50@gmail.com> Date: Fri, 28 Jan 2022 19:18:43 +0000 Subject: [PATCH] First look at data generated machine recipes. Doesn't support all the features but should be a good start. --- .../src/main/java/reborncore/RebornCore.java | 3 - .../crafting/ingredient/FluidIngredient.java | 1 - ...Ingredient.java => IngredientFactory.java} | 53 ++--- .../ingredient/IngredientManager.java | 76 ------- .../crafting/ingredient/RebornIngredient.java | 30 +-- .../crafting/ingredient/StackIngredient.java | 1 - .../crafting/ingredient/TagIngredient.java | 9 +- .../crafting/serde/AbstractRecipeSerde.java | 6 +- .../crafting/serde/RebornRecipeSerde.java | 2 +- .../datagen/TechRebornDataGen.groovy | 3 + .../recipes/TechRebornRecipesProvider.groovy | 7 + .../recipes/machine/IngredientBuilder.groovy | 80 +++++++ .../machine/MachineRecipeJsonFactory.groovy | 213 ++++++++++++++++++ .../grinder/GrinderRecipesProvider.groovy | 46 ++++ 14 files changed, 380 insertions(+), 150 deletions(-) rename RebornCore/src/main/java/reborncore/common/crafting/ingredient/{DummyIngredient.java => IngredientFactory.java} (59%) delete mode 100644 RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientManager.java create mode 100644 src/datagen/groovy/techreborn/datagen/recipes/machine/IngredientBuilder.groovy create mode 100644 src/datagen/groovy/techreborn/datagen/recipes/machine/MachineRecipeJsonFactory.groovy create mode 100644 src/datagen/groovy/techreborn/datagen/recipes/machine/grinder/GrinderRecipesProvider.groovy diff --git a/RebornCore/src/main/java/reborncore/RebornCore.java b/RebornCore/src/main/java/reborncore/RebornCore.java index 6604cbb14..c8cec9c7a 100644 --- a/RebornCore/src/main/java/reborncore/RebornCore.java +++ b/RebornCore/src/main/java/reborncore/RebornCore.java @@ -43,7 +43,6 @@ import reborncore.common.blockentity.MachineBaseBlockEntity; import reborncore.common.blocks.BlockWrenchEventHandler; import reborncore.common.chunkloading.ChunkLoaderManager; import reborncore.common.config.Configuration; -import reborncore.common.crafting.ingredient.IngredientManager; import reborncore.common.misc.ModSounds; import reborncore.common.misc.RebornCoreTags; import reborncore.common.multiblock.MultiblockRegistry; @@ -108,8 +107,6 @@ public class RebornCore implements ModInitializer { // packets ServerBoundPackets.init(); - IngredientManager.setup(); - RebornCoreCommands.setup(); RebornCoreTags.WATER_EXPLOSION_ITEM.toString(); diff --git a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/FluidIngredient.java b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/FluidIngredient.java index 24306087a..825a95419 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/FluidIngredient.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/FluidIngredient.java @@ -56,7 +56,6 @@ public class FluidIngredient extends RebornIngredient { private final Lazy<Ingredient> previewIngredient; public FluidIngredient(Fluid fluid, Optional<List<Item>> holders, Optional<Integer> count) { - super(IngredientManager.FLUID_RECIPE_TYPE); this.fluid = fluid; this.holders = holders; this.count = count; diff --git a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/DummyIngredient.java b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientFactory.java similarity index 59% rename from RebornCore/src/main/java/reborncore/common/crafting/ingredient/DummyIngredient.java rename to RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientFactory.java index 5de2017f5..e303b8fc9 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/DummyIngredient.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientFactory.java @@ -24,42 +24,31 @@ package reborncore.common.crafting.ingredient; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Ingredient; -import net.minecraft.util.Identifier; +import com.google.gson.JsonParseException; +import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.List; +public class IngredientFactory { + public static RebornIngredient deserialize(@Nullable JsonElement jsonElement) { + if (jsonElement == null || !jsonElement.isJsonObject()) { + throw new JsonParseException("ingredient must be a json object"); + } -public class DummyIngredient extends RebornIngredient { + final JsonObject json = jsonElement.getAsJsonObject(); - public DummyIngredient() { - super(new Identifier("reborncore", "dummy")); - } + if (json.has("type")) { + throw new UnsupportedOperationException("type is unsupported"); + } - @Override - public boolean test(ItemStack itemStack) { - return false; - } - - @Override - public Ingredient getPreview() { - return Ingredient.EMPTY; - } - - @Override - public List<ItemStack> getPreviewStacks() { - return Collections.emptyList(); - } - - @Override - protected JsonObject toJson(boolean networkSync) { - return new JsonObject(); - } - - @Override - public int getCount() { - return 0; + if (json.has("fluid")) { + return FluidIngredient.deserialize(json); + } else if (json.has("tag") || json.has("tag_server_sync")) { + return TagIngredient.deserialize(json); + } else if (json.has("item")) { + return StackIngredient.deserialize(json); + } else { + throw new UnsupportedOperationException("Unable to determine ingredient: " + json); + } } } diff --git a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientManager.java b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientManager.java deleted file mode 100644 index d406dc2a9..000000000 --- a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/IngredientManager.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of RebornCore, licensed under the MIT License (MIT). - * - * Copyright (c) 2021 TeamReborn - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package reborncore.common.crafting.ingredient; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import net.minecraft.util.Identifier; -import net.minecraft.util.JsonHelper; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.function.Function; - -public class IngredientManager { - - public static final Identifier STACK_RECIPE_TYPE = new Identifier("reborncore", "stack"); - public static final Identifier FLUID_RECIPE_TYPE = new Identifier("reborncore", "fluid"); - public static final Identifier TAG_RECIPE_TYPE = new Identifier("reborncore", "tag"); - - private static final HashMap<Identifier, Function<JsonObject, RebornIngredient>> recipeTypes = new HashMap<>(); - - public static void setup() { - recipeTypes.put(STACK_RECIPE_TYPE, StackIngredient::deserialize); - recipeTypes.put(FLUID_RECIPE_TYPE, FluidIngredient::deserialize); - recipeTypes.put(TAG_RECIPE_TYPE, TagIngredient::deserialize); - } - - public static RebornIngredient deserialize(@Nullable JsonElement jsonElement) { - if (jsonElement == null || !jsonElement.isJsonObject()) { - throw new JsonParseException("ingredient must be a json object"); - } - - JsonObject json = jsonElement.getAsJsonObject(); - - Identifier recipeTypeIdent = STACK_RECIPE_TYPE; - //TODO find a better way to do this. - if (json.has("fluid")) { - recipeTypeIdent = FLUID_RECIPE_TYPE; - } else if (json.has("tag")) { - recipeTypeIdent = TAG_RECIPE_TYPE; - } - - if (json.has("type")) { - recipeTypeIdent = new Identifier(JsonHelper.getString(json, "type")); - } - - Function<JsonObject, RebornIngredient> recipeTypeFunction = recipeTypes.get(recipeTypeIdent); - if (recipeTypeFunction == null) { - throw new JsonParseException("No recipe type found for " + recipeTypeIdent.toString()); - } - return recipeTypeFunction.apply(json); - } -} diff --git a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/RebornIngredient.java b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/RebornIngredient.java index b006560bc..26c340a68 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/RebornIngredient.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/RebornIngredient.java @@ -27,20 +27,11 @@ package reborncore.common.crafting.ingredient; import com.google.gson.JsonObject; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; -import net.minecraft.util.Identifier; import java.util.List; -import java.util.function.Consumer; import java.util.function.Predicate; public abstract class RebornIngredient implements Predicate<ItemStack> { - - private final Identifier ingredientType; - - public RebornIngredient(Identifier ingredientType) { - this.ingredientType = ingredientType; - } - @Override public abstract boolean test(ItemStack itemStack); @@ -48,26 +39,7 @@ public abstract class RebornIngredient implements Predicate<ItemStack> { public abstract List<ItemStack> getPreviewStacks(); - protected abstract JsonObject toJson(boolean networkSync); + public abstract JsonObject toJson(boolean networkSync); public abstract int getCount(); - - //Same as above but adds the type - public final JsonObject writeToJson(boolean networkSync) { - JsonObject jsonObject = toJson(networkSync); - jsonObject.addProperty("type", ingredientType.toString()); - return jsonObject; - } - - public final JsonObject writeToSyncJson() { - return writeToJson(true); - } - - public <T extends RebornIngredient> void ifType(Class<T> clazz, Consumer<T> consumer) { - if (this.getClass().isAssignableFrom(clazz)) { - //noinspection unchecked - consumer.accept((T) this); - } - } - } diff --git a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/StackIngredient.java b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/StackIngredient.java index 522f56b2a..cdbc8e77b 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/StackIngredient.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/StackIngredient.java @@ -54,7 +54,6 @@ public class StackIngredient extends RebornIngredient { private final boolean requireEmptyNbt; public StackIngredient(List<ItemStack> stacks, Optional<Integer> count, Optional<NbtCompound> nbt, boolean requireEmptyNbt) { - super(IngredientManager.STACK_RECIPE_TYPE); this.stacks = stacks; this.count = count; this.nbt = nbt; diff --git a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/TagIngredient.java b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/TagIngredient.java index 607589440..fadfa8781 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/ingredient/TagIngredient.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/ingredient/TagIngredient.java @@ -48,7 +48,6 @@ public class TagIngredient extends RebornIngredient { private final Optional<Integer> count; public TagIngredient(Tag.Identified<Item> tag, Optional<Integer> count) { - super(IngredientManager.TAG_RECIPE_TYPE); this.tag = tag; this.count = count; } @@ -81,7 +80,7 @@ public class TagIngredient extends RebornIngredient { count = Optional.of(JsonHelper.getInt(json, "count")); } - if (json.has("server_sync")) { + if (json.has("tag_server_sync")) { Identifier tagIdent = new Identifier(JsonHelper.getString(json, "tag_identifier")); List<Item> items = new ArrayList<>(); for (int i = 0; i < JsonHelper.getInt(json, "items"); i++) { @@ -109,13 +108,15 @@ public class TagIngredient extends RebornIngredient { return toItemJsonObject(); } - throw new UnsupportedOperationException("TODO"); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("tag", tag.getId().toString()); + return jsonObject; } private JsonObject toItemJsonObject() { //Tags are not synced across the server so we sync all the items JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("server_sync", true); + jsonObject.addProperty("tag_server_sync", true); Item[] items = tag.values().toArray(new Item[0]); jsonObject.addProperty("items", items.length); diff --git a/RebornCore/src/main/java/reborncore/common/crafting/serde/AbstractRecipeSerde.java b/RebornCore/src/main/java/reborncore/common/crafting/serde/AbstractRecipeSerde.java index ca524161d..67f27c922 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/serde/AbstractRecipeSerde.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/serde/AbstractRecipeSerde.java @@ -34,7 +34,7 @@ import net.minecraft.util.JsonHelper; import net.minecraft.util.registry.Registry; import reborncore.common.crafting.RebornRecipe; import reborncore.common.crafting.RecipeUtils; -import reborncore.common.crafting.ingredient.IngredientManager; +import reborncore.common.crafting.ingredient.IngredientFactory; import reborncore.common.crafting.ingredient.RebornIngredient; import reborncore.common.util.DefaultedListCollector; import reborncore.common.util.serialization.SerializationUtil; @@ -52,7 +52,7 @@ public abstract class AbstractRecipeSerde<R extends RebornRecipe> implements Rec protected List<RebornIngredient> getIngredients(JsonObject jsonObject) { return SerializationUtil.stream(JsonHelper.getArray(jsonObject, "ingredients")) - .map(IngredientManager::deserialize) + .map(IngredientFactory::deserialize) .collect(DefaultedListCollector.toList()); } @@ -63,7 +63,7 @@ public abstract class AbstractRecipeSerde<R extends RebornRecipe> implements Rec protected void writeIngredients(R recipe, JsonObject jsonObject, boolean networkSync) { final JsonArray ingredientsArray = new JsonArray(); - recipe.getRebornIngredients().stream().map(RebornIngredient::writeToSyncJson).forEach(ingredientsArray::add); + recipe.getRebornIngredients().stream().map(ingredient -> ingredient.toJson(networkSync)).forEach(ingredientsArray::add); jsonObject.add("ingredients", ingredientsArray); } diff --git a/RebornCore/src/main/java/reborncore/common/crafting/serde/RebornRecipeSerde.java b/RebornCore/src/main/java/reborncore/common/crafting/serde/RebornRecipeSerde.java index fd7843024..08c96cf66 100644 --- a/RebornCore/src/main/java/reborncore/common/crafting/serde/RebornRecipeSerde.java +++ b/RebornCore/src/main/java/reborncore/common/crafting/serde/RebornRecipeSerde.java @@ -54,7 +54,7 @@ public abstract class RebornRecipeSerde<R extends RebornRecipe> extends Abstract public final void toJson(R recipe, JsonObject jsonObject, boolean networkSync) { writePower(recipe, jsonObject); writeTime(recipe, jsonObject); - writeIngredients(recipe, jsonObject, true); + writeIngredients(recipe, jsonObject, networkSync); writeOutputs(recipe, jsonObject); collectJsonData(recipe, jsonObject, networkSync); diff --git a/src/datagen/groovy/techreborn/datagen/TechRebornDataGen.groovy b/src/datagen/groovy/techreborn/datagen/TechRebornDataGen.groovy index 99c4f11b5..83ee0f849 100644 --- a/src/datagen/groovy/techreborn/datagen/TechRebornDataGen.groovy +++ b/src/datagen/groovy/techreborn/datagen/TechRebornDataGen.groovy @@ -26,6 +26,7 @@ package techreborn.datagen import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator +import techreborn.datagen.recipes.machine.grinder.GrinderRecipesProvider import techreborn.datagen.recipes.smelting.SmeltingRecipesProvider import techreborn.datagen.recipes.crafting.CraftingRecipesProvider import techreborn.datagen.tags.TRItemTagProvider @@ -40,5 +41,7 @@ class TechRebornDataGen implements DataGeneratorEntrypoint { // tags before all else, very important!! fabricDataGenerator.addProvider(SmeltingRecipesProvider.&new) fabricDataGenerator.addProvider(CraftingRecipesProvider.&new) + + fabricDataGenerator.addProvider(GrinderRecipesProvider.&new) } } diff --git a/src/datagen/groovy/techreborn/datagen/recipes/TechRebornRecipesProvider.groovy b/src/datagen/groovy/techreborn/datagen/recipes/TechRebornRecipesProvider.groovy index 75cd024c6..e01b0acdb 100644 --- a/src/datagen/groovy/techreborn/datagen/recipes/TechRebornRecipesProvider.groovy +++ b/src/datagen/groovy/techreborn/datagen/recipes/TechRebornRecipesProvider.groovy @@ -32,6 +32,9 @@ import net.minecraft.item.ItemConvertible import net.minecraft.recipe.Ingredient import net.minecraft.tag.Tag import net.minecraft.util.Identifier +import techreborn.datagen.recipes.machine.MachineRecipeJsonFactory + +import techreborn.init.ModRecipes import java.util.function.Consumer @@ -120,6 +123,10 @@ abstract class TechRebornRecipesProvider extends FabricRecipesProvider { throw new IllegalArgumentException() } + def offerGrinderRecipe(@DelegatesTo(value = MachineRecipeJsonFactory.class, strategy = Closure.DELEGATE_FIRST) Closure closure) { + MachineRecipeJsonFactory.create(ModRecipes.GRINDER, closure).offerTo(exporter) + } + @Override protected Identifier getRecipeIdentifier(Identifier identifier) { return new Identifier("techreborn", super.getRecipeIdentifier(identifier).path) diff --git a/src/datagen/groovy/techreborn/datagen/recipes/machine/IngredientBuilder.groovy b/src/datagen/groovy/techreborn/datagen/recipes/machine/IngredientBuilder.groovy new file mode 100644 index 000000000..20159c902 --- /dev/null +++ b/src/datagen/groovy/techreborn/datagen/recipes/machine/IngredientBuilder.groovy @@ -0,0 +1,80 @@ +/* + * This file is part of TechReborn, licensed under the MIT License (MIT). + * + * Copyright (c) 2020 TechReborn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package techreborn.datagen.recipes.machine + +import net.minecraft.item.Item +import net.minecraft.item.ItemConvertible +import net.minecraft.item.ItemStack +import net.minecraft.tag.Tag +import reborncore.common.crafting.ingredient.RebornIngredient +import reborncore.common.crafting.ingredient.StackIngredient +import reborncore.common.crafting.ingredient.TagIngredient + +class IngredientBuilder { + private Tag.Identified<Item> tag + private List<ItemStack> stacks = new ArrayList<>() + + private IngredientBuilder() { + } + + static IngredientBuilder create() { + return new IngredientBuilder() + } + + RebornIngredient build() { + if (tag != null) { + if (!stacks.isEmpty()) { + throw new IllegalStateException("Cannot have ingredient with tag and stack inputs") + } + + return new TagIngredient(tag, getCount()) + } + + if (!stacks.isEmpty()) { + return new StackIngredient(stacks, getCount(), Optional.empty(), false) + } + + throw new IllegalStateException() + } + + def tag(Tag.Identified<Item> tag) { + this.tag = tag + return this + } + + def item(ItemConvertible itemConvertible) { + return stack(new ItemStack(itemConvertible.asItem())) + } + + def stack(ItemStack itemStack) { + stacks.add(itemStack) + return this + } + + + private Optional<Integer> getCount() { + return Optional.empty() + } +} diff --git a/src/datagen/groovy/techreborn/datagen/recipes/machine/MachineRecipeJsonFactory.groovy b/src/datagen/groovy/techreborn/datagen/recipes/machine/MachineRecipeJsonFactory.groovy new file mode 100644 index 000000000..14f9a0f50 --- /dev/null +++ b/src/datagen/groovy/techreborn/datagen/recipes/machine/MachineRecipeJsonFactory.groovy @@ -0,0 +1,213 @@ +/* + * This file is part of TechReborn, licensed under the MIT License (MIT). + * + * Copyright (c) 2020 TechReborn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package techreborn.datagen.recipes.machine + +import com.google.gson.JsonObject +import net.minecraft.data.server.recipe.RecipeJsonProvider +import net.minecraft.item.ItemConvertible +import net.minecraft.item.ItemStack +import net.minecraft.recipe.RecipeSerializer +import net.minecraft.tag.Tag +import net.minecraft.util.Identifier +import net.minecraft.util.registry.Registry +import reborncore.common.crafting.RebornRecipe +import reborncore.common.crafting.RebornRecipeType +import reborncore.common.crafting.ingredient.RebornIngredient + +import java.util.function.Consumer + +class MachineRecipeJsonFactory<R extends RebornRecipe> { + private final RebornRecipeType<R> type + + private final List<RebornIngredient> ingredients = new ArrayList<>() + private final List<ItemStack> outputs = new ArrayList<>() + private int power = -1 + private int time = -1 + private Identifier customId = null + + protected MachineRecipeJsonFactory(RebornRecipeType<R> type) { + this.type = type + } + + static <R extends RebornRecipe> MachineRecipeJsonFactory<R> create(RebornRecipeType<R> type) { + return new MachineRecipeJsonFactory<R>(type) + } + + static <R extends RebornRecipe> MachineRecipeJsonFactory<R> create(RebornRecipeType<R> type, @DelegatesTo(value = MachineRecipeJsonFactory.class, strategy = Closure.DELEGATE_FIRST) Closure closure) { + def factory = new MachineRecipeJsonFactory<R>(type) + closure.setDelegate(factory) + closure.call(factory) + return factory + } + + def ingredients(Object... objects) { + for (object in objects) { + if (object instanceof ItemConvertible) { + ingredient { + item object + } + } else if (object instanceof Tag.Identified) { + ingredient { + tag object + } + } else { + throw new UnsupportedOperationException() + } + } + + return this + } + + def ingredient(@DelegatesTo(value = IngredientBuilder.class, strategy = Closure.DELEGATE_FIRST) Closure closure) { + def builder = IngredientBuilder.create() + closure.setDelegate(builder) + closure.call(builder) + ingredients.add(builder.build()) + return this + } + + def outputs(Object... objects) { + for (object in objects) { + if (object instanceof ItemStack) { + output(object) + } else if (object instanceof ItemConvertible) { + output(new ItemStack(object.asItem())) + } + } + + return this + } + + def output(ItemStack stack) { + outputs.add(stack) + return this + } + + def power(int power) { + this.power = power + return this + } + + def time(int time) { + this.time = time + return this + } + + def id(Identifier identifier) { + this.customId = identifier + return this + } + + MachineRecipeJsonFactory id(String path) { + return id(new Identifier("techreborn", path)) + } + + /** + * Override this method to support custom recipe types. + */ + protected R createRecipe(Identifier identifier) { + return new RebornRecipe(type, identifier, ingredients, outputs, power, time) as R + } + + protected void validate() { + if (ingredients.isEmpty()) { + throw new IllegalStateException("recipe has no ingrendients") + } + + if (outputs.isEmpty()) { + throw new IllegalStateException("recipe has no outputs") + } + + if (power < 0) { + throw new IllegalStateException("recipe has no power value") + } + + if (time < 0) { + throw new IllegalStateException("recipe has no time value") + } + } + + void offerTo(Consumer<RecipeJsonProvider> exporter) { + validate() + exporter.accept(new MachineRecipeJsonProvider<R>(type, createRecipe(getIdentifier()))) + } + + def getIdentifier() { + if (customId) { + return customId + } + + if (outputs.size() < 1) { + throw new IllegalStateException("Recipe has no outputs") + } + + if (outputs.size() > 1) { + throw new IllegalStateException("Cannot compute default identifier for a recipe with more than one output. TODO might want to improve this?") + } + + def outputId = Registry.ITEM.getId(outputs[0].item) + return new Identifier("techreborn", "${type.name().path}/${outputId.path}") + } + + static class MachineRecipeJsonProvider<R extends RebornRecipe> implements RecipeJsonProvider { + private final RebornRecipeType<R> type + private final R recipe + + MachineRecipeJsonProvider(RebornRecipeType<R> type, R recipe) { + this.type = type + this.recipe = recipe + } + + @Override + JsonObject toJson() { + return type.toJson(recipe, false) + } + + @Override + Identifier getRecipeId() { + return recipe.id + } + + @Override + void serialize(JsonObject json) { + throw new UnsupportedOperationException() + } + + @Override + RecipeSerializer<?> getSerializer() { + throw new UnsupportedOperationException() + } + + @Override + JsonObject toAdvancementJson() { + return null + } + + @Override + Identifier getAdvancementId() { + return null + } + } +} diff --git a/src/datagen/groovy/techreborn/datagen/recipes/machine/grinder/GrinderRecipesProvider.groovy b/src/datagen/groovy/techreborn/datagen/recipes/machine/grinder/GrinderRecipesProvider.groovy new file mode 100644 index 000000000..9d48d6a6a --- /dev/null +++ b/src/datagen/groovy/techreborn/datagen/recipes/machine/grinder/GrinderRecipesProvider.groovy @@ -0,0 +1,46 @@ +/* + * This file is part of TechReborn, licensed under the MIT License (MIT). + * + * Copyright (c) 2020 TechReborn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package techreborn.datagen.recipes.machine.grinder + +import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator +import net.minecraft.item.Items +import techreborn.datagen.recipes.TechRebornRecipesProvider +import techreborn.init.TRContent + +class GrinderRecipesProvider extends TechRebornRecipesProvider { + GrinderRecipesProvider(FabricDataGenerator dataGenerator) { + super(dataGenerator) + } + + @Override + void generateRecipes() { +// offerGrinderRecipe { +// ingredients TRContent.ORES_TAG, Items.ACACIA_BOAT +// outputs Items.DIAMOND +// power 5 +// time 200 +// } + } +} \ No newline at end of file