diff --git a/src/main/java/gregtech/api/recipes/RecipeBuilder.java b/src/main/java/gregtech/api/recipes/RecipeBuilder.java index 8401101b205..d28e95d66c2 100644 --- a/src/main/java/gregtech/api/recipes/RecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/RecipeBuilder.java @@ -96,6 +96,7 @@ public class RecipeBuilder> { protected Map> ignoredBuildActions; private boolean withItemRecycling; + private boolean withFluidRecycling; protected RecipeBuilder() { this.inputs = new ArrayList<>(); @@ -142,6 +143,7 @@ protected RecipeBuilder(RecipeBuilder recipeBuilder) { this.ignoredBuildActions = new Object2ObjectOpenHashMap<>(recipeBuilder.ignoredBuildActions); } this.withItemRecycling = recipeBuilder.hasItemRecycling(); + this.withFluidRecycling = recipeBuilder.hasFluidRecycling(); } public R cleanroom(@Nullable CleanroomType cleanroom) { @@ -972,11 +974,28 @@ public R ignoreBuildAction(ResourceLocation buildActionName) { /** * Generate Recycling Data based on this recipe's Items */ - public R withRecycling() { + public R withItemRecycling() { this.withItemRecycling = true; return (R) this; } + /** + * Generate Recycling Data based on this recipe's Fluids + */ + public R withFluidRecycling() { + this.withFluidRecycling = true; + return (R) this; + } + + /** + * Generate Recycling Data based on this recipe's Items and Fluids + */ + public R withFullRecycling() { + this.withItemRecycling = true; + this.withFluidRecycling = true; + return (R) this; + } + public ValidationResult build() { EnumValidationResult result = recipePropertyStorageErrored ? EnumValidationResult.INVALID : validate(); return ValidationResult.newResult(result, new Recipe(inputs, outputs, @@ -1084,12 +1103,24 @@ public void buildAndRegister() { buildAction.getValue().accept((R) this); } } + if (hasItemRecycling()) { - // ignore input fluids for item-only recycling - ItemStack outputStack = getOutputs().get(0); - RecyclingData data = RecyclingHandler.getRecyclingIngredients(getInputs(), outputStack.getCount()); + RecyclingData data; + if (hasFluidRecycling()) { + data = RecyclingHandler.getRecyclingIngredients(getOutputs().get(0).getCount(), + getInputs(), getFluidInputs()); + } else { + data = RecyclingHandler.getRecyclingIngredients(getOutputs().get(0).getCount(), + getInputs(), null); + } if (data != null) { - GregTechAPI.RECYCLING_MANAGER.registerRecyclingData(outputStack, data); + GregTechAPI.RECYCLING_MANAGER.registerRecyclingData(getOutputs().get(0), data); + } + } else if (hasFluidRecycling()) { + RecyclingData data = RecyclingHandler.getRecyclingIngredients(getOutputs().get(0).getCount(), + null, getFluidInputs()); + if (data != null) { + GregTechAPI.RECYCLING_MANAGER.registerRecyclingData(getOutputs().get(0), data); } } @@ -1177,6 +1208,10 @@ public boolean hasItemRecycling() { return withItemRecycling; } + public boolean hasFluidRecycling() { + return withFluidRecycling; + } + @Override public String toString() { return new ToStringBuilder(this) @@ -1193,6 +1228,8 @@ public String toString() { .append("cleanroom", getCleanroom()) .append("dimensions", getDimensionIDs().toString()) .append("dimensions_blocked", getBlockedDimensionIDs().toString()) + .append("itemRecycling", withItemRecycling) + .append("fluidRecycling", withFluidRecycling) .append("recipeStatus", recipeStatus) .append("ignoresBuildActions", ignoresAllBuildActions()) .append("ignoredBuildActions", getIgnoredBuildActions()) diff --git a/src/main/java/gregtech/api/recipes/RecyclingHandler.java b/src/main/java/gregtech/api/recipes/RecyclingHandler.java index 8fa5f401da7..e510f36a148 100644 --- a/src/main/java/gregtech/api/recipes/RecyclingHandler.java +++ b/src/main/java/gregtech/api/recipes/RecyclingHandler.java @@ -1,12 +1,15 @@ package gregtech.api.recipes; +import gregtech.api.GTValues; import gregtech.api.GregTechAPI; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.items.toolitem.ToolHelper; import gregtech.api.recipes.ingredients.GTRecipeInput; +import gregtech.api.unification.FluidUnifier; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.MarkerMaterial; import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.PropertyKey; import gregtech.api.unification.ore.OrePrefix; import gregtech.api.unification.stack.MaterialStack; import gregtech.api.unification.stack.RecyclingData; @@ -15,6 +18,7 @@ import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; @@ -81,20 +85,46 @@ public class RecyclingHandler { .collect(Collectors.toList())); } - public static @Nullable RecyclingData getRecyclingIngredients(List inputs, int outputCount) { + public static @Nullable RecyclingData getRecyclingIngredients(int outputCount, + @Nullable List itemInputs, + @Nullable List fluidInputs) { Object2LongMap materialStacksExploded = new Object2LongOpenHashMap<>(); - for (GTRecipeInput input : inputs) { - if (input == null || input.isNonConsumable()) continue; - ItemStack[] inputStacks = input.getInputStacks(); - if (inputStacks == null || inputStacks.length == 0) continue; - ItemStack inputStack = inputStacks[0]; - addItemStackToMaterialStacks(inputStack, materialStacksExploded, inputStack.getCount()); + if (itemInputs != null) { + populateExplodedMaterialStacks(materialStacksExploded, itemInputs); + } + if (fluidInputs != null) { + populateExplodedMaterialStacks(materialStacksExploded, fluidInputs); } - return new RecyclingData(materialStacksExploded.entrySet().stream() + if (materialStacksExploded.isEmpty()) { + return null; + } + + var materialStacks = materialStacksExploded.entrySet().stream() .map(e -> new MaterialStack(e.getKey(), e.getValue() / outputCount)) .sorted(Comparator.comparingLong(m -> -m.amount)) - .collect(Collectors.toList())); + .collect(Collectors.toList()); + return new RecyclingData(materialStacks); + } + + private static void populateExplodedMaterialStacks(@NotNull Object2LongMap materialStacksExploded, + @NotNull List inputs) { + for (GTRecipeInput input : inputs) { + if (input == null || input.isNonConsumable()) { + continue; + } + + ItemStack[] inputStacks = input.getInputStacks(); + if (inputStacks == null) { + FluidStack fluidStack = input.getInputFluidStack(); + if (fluidStack != null && fluidStack.amount > 0) { + addFluidStackToMaterialStacks(fluidStack, materialStacksExploded); + } + } else if (inputStacks.length != 0) { + ItemStack inputStack = inputStacks[0]; + addItemStackToMaterialStacks(inputStack, materialStacksExploded, inputStack.getCount()); + } + } } private static void addItemStackToMaterialStacks(@NotNull ItemStack itemStack, @@ -126,6 +156,22 @@ private static void addItemStackToMaterialStacks(@NotNull ItemStack itemStack, } } + private static void addFluidStackToMaterialStacks(@NotNull FluidStack fluidStack, + @NotNull Object2LongMap materialStacksExploded) { + Material material = FluidUnifier.getMaterialFromFluid(fluidStack.getFluid()); + if (material == null) { + return; + } + + // must be a solid with a fluid + if (!material.hasProperty(PropertyKey.DUST)) { + return; + } + + long amount = GTValues.M * fluidStack.amount / GTValues.L; + addMaterialStack(materialStacksExploded, 1, new MaterialStack(material, amount)); + } + /** * Adds a MaterialStack to a map of {@code } * diff --git a/src/main/java/gregtech/loaders/recipe/ComponentRecipes.java b/src/main/java/gregtech/loaders/recipe/ComponentRecipes.java index bf192e6c60f..fbc71eb81d9 100644 --- a/src/main/java/gregtech/loaders/recipe/ComponentRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/ComponentRecipes.java @@ -399,7 +399,7 @@ public static void register() { .outputs(FLUID_REGULATOR_LV.getStackForm()) .EUt(VA[LV]) .duration(400) - .withRecycling() + .withItemRecycling() .buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -409,7 +409,7 @@ public static void register() { .outputs(FLUID_REGULATOR_MV.getStackForm()) .EUt(VA[MV]) .duration(350) - .withRecycling() + .withItemRecycling() .buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -419,7 +419,7 @@ public static void register() { .outputs(FLUID_REGULATOR_HV.getStackForm()) .EUt(VA[HV]) .duration(300) - .withRecycling() + .withItemRecycling() .buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -429,7 +429,7 @@ public static void register() { .outputs(FLUID_REGULATOR_EV.getStackForm()) .EUt(VA[EV]) .duration(250) - .withRecycling() + .withItemRecycling() .buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -439,7 +439,7 @@ public static void register() { .outputs(FLUID_REGULATOR_IV.getStackForm()) .EUt(VA[IV]) .duration(200) - .withRecycling() + .withItemRecycling() .buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() diff --git a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java index d5bedf439e2..1274eae216f 100644 --- a/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MetaTileEntityMachineRecipeLoader.java @@ -1346,7 +1346,7 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me .fluidInputs(Polybenzimidazole.getFluid(pbiAmount)) .circuitMeta(1) .output(inputBus) - .withRecycling() + .withItemRecycling() .duration(300).EUt(VA[Math.min(GTValues.UV, tier)]).buildAndRegister(); ASSEMBLER_RECIPES.recipeBuilder() @@ -1355,7 +1355,7 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me .fluidInputs(Polybenzimidazole.getFluid(pbiAmount)) .circuitMeta(2) .output(outputBus) - .withRecycling() + .withItemRecycling() .duration(300).EUt(VA[Math.min(GTValues.UV, tier)]).buildAndRegister(); }