Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 42 additions & 5 deletions src/main/java/gregtech/api/recipes/RecipeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public class RecipeBuilder<R extends RecipeBuilder<R>> {
protected Map<ResourceLocation, RecipeBuildAction<R>> ignoredBuildActions;

private boolean withItemRecycling;
private boolean withFluidRecycling;

protected RecipeBuilder() {
this.inputs = new ArrayList<>();
Expand Down Expand Up @@ -142,6 +143,7 @@ protected RecipeBuilder(RecipeBuilder<R> recipeBuilder) {
this.ignoredBuildActions = new Object2ObjectOpenHashMap<>(recipeBuilder.ignoredBuildActions);
}
this.withItemRecycling = recipeBuilder.hasItemRecycling();
this.withFluidRecycling = recipeBuilder.hasFluidRecycling();
}

public R cleanroom(@Nullable CleanroomType cleanroom) {
Expand Down Expand Up @@ -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<Recipe> build() {
EnumValidationResult result = recipePropertyStorageErrored ? EnumValidationResult.INVALID : validate();
return ValidationResult.newResult(result, new Recipe(inputs, outputs,
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -1177,6 +1208,10 @@ public boolean hasItemRecycling() {
return withItemRecycling;
}

public boolean hasFluidRecycling() {
return withFluidRecycling;
}

@Override
public String toString() {
return new ToStringBuilder(this)
Expand All @@ -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())
Expand Down
64 changes: 55 additions & 9 deletions src/main/java/gregtech/api/recipes/RecyclingHandler.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -81,20 +85,46 @@ public class RecyclingHandler {
.collect(Collectors.toList()));
}

public static @Nullable RecyclingData getRecyclingIngredients(List<GTRecipeInput> inputs, int outputCount) {
public static @Nullable RecyclingData getRecyclingIngredients(int outputCount,
@Nullable List<GTRecipeInput> itemInputs,
@Nullable List<GTRecipeInput> fluidInputs) {
Object2LongMap<Material> 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<Material> materialStacksExploded,
@NotNull List<GTRecipeInput> 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,
Expand Down Expand Up @@ -126,6 +156,22 @@ private static void addItemStackToMaterialStacks(@NotNull ItemStack itemStack,
}
}

private static void addFluidStackToMaterialStacks(@NotNull FluidStack fluidStack,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to check that the fluid stack is also a Fluid GT Material, and not a Gas or a plasma GT Fluid Material?

@NotNull Object2LongMap<Material> 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 <Material, Quantity>}
*
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/gregtech/loaders/recipe/ComponentRecipes.java
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public static void register() {
.outputs(FLUID_REGULATOR_LV.getStackForm())
.EUt(VA[LV])
.duration(400)
.withRecycling()
.withItemRecycling()
.buildAndRegister();

ASSEMBLER_RECIPES.recipeBuilder()
Expand All @@ -409,7 +409,7 @@ public static void register() {
.outputs(FLUID_REGULATOR_MV.getStackForm())
.EUt(VA[MV])
.duration(350)
.withRecycling()
.withItemRecycling()
.buildAndRegister();

ASSEMBLER_RECIPES.recipeBuilder()
Expand All @@ -419,7 +419,7 @@ public static void register() {
.outputs(FLUID_REGULATOR_HV.getStackForm())
.EUt(VA[HV])
.duration(300)
.withRecycling()
.withItemRecycling()
.buildAndRegister();

ASSEMBLER_RECIPES.recipeBuilder()
Expand All @@ -429,7 +429,7 @@ public static void register() {
.outputs(FLUID_REGULATOR_EV.getStackForm())
.EUt(VA[EV])
.duration(250)
.withRecycling()
.withItemRecycling()
.buildAndRegister();

ASSEMBLER_RECIPES.recipeBuilder()
Expand All @@ -439,7 +439,7 @@ public static void register() {
.outputs(FLUID_REGULATOR_IV.getStackForm())
.EUt(VA[IV])
.duration(200)
.withRecycling()
.withItemRecycling()
.buildAndRegister();

ASSEMBLER_RECIPES.recipeBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -1355,7 +1355,7 @@ private static void registerHatchBusRecipe(int tier, MetaTileEntity inputBus, Me
.fluidInputs(Polybenzimidazole.getFluid(pbiAmount))
.circuitMeta(2)
.output(outputBus)
.withRecycling()
.withItemRecycling()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these two not using withFullRecycling? Since there is the items and the fluids

.duration(300).EUt(VA[Math.min(GTValues.UV, tier)]).buildAndRegister();
}

Expand Down
Loading