diff --git a/src/main/java/gregtech/api/interfaces/IRecipeMap.java b/src/main/java/gregtech/api/interfaces/IRecipeMap.java
index c6184bee342..412778d2ccc 100644
--- a/src/main/java/gregtech/api/interfaces/IRecipeMap.java
+++ b/src/main/java/gregtech/api/interfaces/IRecipeMap.java
@@ -16,19 +16,6 @@
*/
public interface IRecipeMap {
- /**
- * Add a downstream recipe map that will get to handle the original builder.
- *
- * Downstream recipe maps got passed the recipe builder after parent recipe map is done with its business. Notice
- * at this time the original recipe builder might be modified by the parent recipe map in some form, but it will
- * remain as valid.
- *
- * A downstream will only be invoked if parent recipe map added something.
- *
- * @param downstream the downstream recipe map to add
- */
- void addDownstream(IRecipeMap downstream);
-
/**
* Actually add the recipe represented by the builder. CAN modify the builder's internal states!!!
*/
@@ -38,8 +25,6 @@ public interface IRecipeMap {
/**
* Return a variant of this recipe map that will perform a deep copy on input recipe builder before doing anything
* to it.
- *
- * The returned recipe map will not have any downstreams, but can accept new downstreams.
*/
default IRecipeMap deepCopyInput() {
return newRecipeMap(b -> doAdd(b.copy()));
@@ -48,13 +33,6 @@ default IRecipeMap deepCopyInput() {
static IRecipeMap newRecipeMap(Function super GTRecipeBuilder, Collection> func) {
return new IRecipeMap() {
- private final Collection downstreams = new ArrayList<>();
-
- @Override
- public void addDownstream(IRecipeMap downstream) {
- downstreams.add(downstream);
- }
-
@Nonnull
@Override
public Collection doAdd(GTRecipeBuilder builder) {
@@ -62,11 +40,6 @@ public Collection doAdd(GTRecipeBuilder builder) {
Collection out = func.apply(builder);
ret.add(out);
builder.clearInvalid();
- if (!out.isEmpty()) {
- for (IRecipeMap downstream : downstreams) {
- ret.add(downstream.doAdd(builder));
- }
- }
return GTUtility.concat(ret);
}
};
diff --git a/src/main/java/gregtech/api/recipe/RecipeMap.java b/src/main/java/gregtech/api/recipe/RecipeMap.java
index 9fb504c0a47..2cb839bf739 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMap.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMap.java
@@ -6,6 +6,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -107,9 +108,20 @@ public int getAmperage() {
return frontend.getUIProperties().amperage;
}
- @Override
- public void addDownstream(IRecipeMap downstream) {
- backend.addDownstream(downstream);
+ /**
+ * Callback called before the recipe builder emits recipes. Can edit this builder to change this recipe, or
+ * use this information to add recipes elsewhere.
+ */
+ public void appendBuilderTransformer(Consumer super GTRecipeBuilder> builderTransformer) {
+ backend.properties.appendBuilderTransformer(builderTransformer);
+ }
+
+ /**
+ * Callback called after the recipe builder emits recipes, but before it is added to the map. Can edit this recipe
+ * for this map, or use this information to add recipes elsewhere.
+ */
+ public void appendRecipeTransformer(Consumer super GTRecipe> recipeTransformer) {
+ backend.properties.appendRecipeTransformer(recipeTransformer);
}
// region add recipe
diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBackend.java b/src/main/java/gregtech/api/recipe/RecipeMapBackend.java
index 8c23e2bfb9a..70d36b933e6 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMapBackend.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMapBackend.java
@@ -11,7 +11,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
@@ -31,7 +30,6 @@
import com.google.common.collect.SetMultimap;
import gregtech.api.GregTechAPI;
-import gregtech.api.interfaces.IRecipeMap;
import gregtech.api.objects.GTItemStack;
import gregtech.api.util.GTOreDictUnificator;
import gregtech.api.util.GTRecipe;
@@ -65,11 +63,6 @@ public class RecipeMapBackend {
*/
private final Map> recipesByCategory = new HashMap<>();
- /**
- * List of recipemaps that also receive recipe addition from this backend.
- */
- private final List downstreams = new ArrayList<>(0);
-
/**
* All the properties specific to this backend.
*/
@@ -171,6 +164,7 @@ protected GTRecipe addToItemMap(GTRecipe recipe) {
* Builds recipe from supplied recipe builder and adds it.
*/
protected Collection doAdd(GTRecipeBuilder builder) {
+ properties.transformBuilder(builder);
Iterable extends GTRecipe> recipes = properties.recipeEmitter.apply(builder);
Collection ret = new ArrayList<>();
for (GTRecipe recipe : recipes) {
@@ -182,13 +176,7 @@ protected Collection doAdd(GTRecipeBuilder builder) {
handleInvalidRecipeLowFluids();
return Collections.emptyList();
}
- if (properties.recipeTransformer != null) {
- recipe = properties.recipeTransformer.apply(recipe);
- }
- if (recipe == null) {
- handleInvalidRecipe();
- continue;
- }
+ properties.transformRecipe(recipe);
if (builder.isCheckForCollision() && ENABLE_COLLISION_CHECK && checkCollision(recipe)) {
handleCollision(recipe);
continue;
@@ -199,12 +187,6 @@ protected Collection doAdd(GTRecipeBuilder builder) {
}
ret.add(compileRecipe(recipe));
}
- if (!ret.isEmpty()) {
- builder.clearInvalid();
- for (IRecipeMap downstream : downstreams) {
- downstream.doAdd(builder);
- }
- }
return ret;
}
@@ -243,10 +225,6 @@ private void handleCollision(GTRecipe recipe) {
handleRecipeCollision(errorInfo.toString());
}
- void addDownstream(IRecipeMap downstream) {
- downstreams.add(downstream);
- }
-
/**
* Removes supplied recipes from recipe list. Do not use unless absolute necessity!
*/
diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java b/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java
index 47c400a3dd6..2333db2ae60 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMapBackendProperties.java
@@ -1,5 +1,6 @@
package gregtech.api.recipe;
+import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nullable;
@@ -46,16 +47,16 @@ static RecipeMapBackendPropertiesBuilder builder() {
*/
public final Function super GTRecipeBuilder, ? extends Iterable extends GTRecipe>> recipeEmitter;
- /**
- * Runs a custom hook on all recipes added via builder.
- */
@Nullable
- public final Function super GTRecipe, ? extends GTRecipe> recipeTransformer;
+ private Consumer super GTRecipeBuilder> builderTransformer;
+ @Nullable
+ private Consumer super GTRecipe> recipeTransformer;
RecipeMapBackendProperties(int minItemInputs, int minFluidInputs, boolean specialSlotSensitive,
boolean disableOptimize,
Function super GTRecipeBuilder, ? extends Iterable extends GTRecipe>> recipeEmitter,
- @Nullable Function super GTRecipe, ? extends GTRecipe> recipeTransformer) {
+ @Nullable Consumer super GTRecipeBuilder> builderTransformer,
+ @Nullable Consumer super GTRecipe> recipeTransformer) {
if (minItemInputs < 0 || minFluidInputs < 0) {
throw new IllegalArgumentException("minItemInputs and minFluidInputs cannot be negative");
}
@@ -64,6 +65,43 @@ static RecipeMapBackendPropertiesBuilder builder() {
this.specialSlotSensitive = specialSlotSensitive;
this.disableOptimize = disableOptimize;
this.recipeEmitter = recipeEmitter;
+ this.builderTransformer = builderTransformer;
this.recipeTransformer = recipeTransformer;
}
+
+ public void appendBuilderTransformer(Consumer super GTRecipeBuilder> builderTransformer) {
+ if (this.builderTransformer == null) {
+ this.builderTransformer = builderTransformer;
+ } else {
+ Consumer super GTRecipeBuilder> t = this.builderTransformer;
+ this.builderTransformer = b -> {
+ t.accept(b);
+ builderTransformer.accept(b);
+ };
+ }
+ }
+
+ public void appendRecipeTransformer(Consumer super GTRecipe> recipeTransformer) {
+ if (this.recipeTransformer == null) {
+ this.recipeTransformer = recipeTransformer;
+ } else {
+ Consumer super GTRecipe> t = this.recipeTransformer;
+ this.recipeTransformer = r -> {
+ t.accept(r);
+ recipeTransformer.accept(r);
+ };
+ }
+ }
+
+ public void transformBuilder(GTRecipeBuilder builder) {
+ if (builderTransformer != null) {
+ builderTransformer.accept(builder);
+ }
+ }
+
+ public void transformRecipe(GTRecipe recipe) {
+ if (recipeTransformer != null) {
+ recipeTransformer.accept(recipe);
+ }
+ }
}
diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java b/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java
index aad0748fa91..d77396a09e6 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMapBackendPropertiesBuilder.java
@@ -2,9 +2,9 @@
import static gregtech.api.util.GTRecipeMapUtil.buildOrEmpty;
+import java.util.function.Consumer;
import java.util.function.Function;
-import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import com.google.common.collect.Iterables;
@@ -28,10 +28,9 @@ public final class RecipeMapBackendPropertiesBuilder {
private boolean disableOptimize;
+ private Consumer super GTRecipeBuilder> builderTransformer;
private Function super GTRecipeBuilder, ? extends Iterable extends GTRecipe>> recipeEmitter = this::defaultBuildRecipe;
-
- @Nullable
- private Function super GTRecipe, ? extends GTRecipe> recipeTransformer;
+ private Consumer super GTRecipe> recipeTransformer;
RecipeMapBackendPropertiesBuilder() {}
@@ -42,6 +41,7 @@ RecipeMapBackendProperties build() {
specialSlotSensitive,
disableOptimize,
recipeEmitter,
+ builderTransformer,
recipeTransformer);
}
@@ -78,15 +78,16 @@ public RecipeMapBackendPropertiesBuilder combineRecipeEmitter(
return recipeEmitter(b -> Iterables.concat(cur.apply(b), func.apply(b)));
}
- public RecipeMapBackendPropertiesBuilder recipeTransformer(
- Function super GTRecipe, ? extends GTRecipe> recipeTransformer) {
- this.recipeTransformer = recipeTransformer;
- return this;
- }
-
- public RecipeMapBackendPropertiesBuilder chainRecipeTransformer(
- Function super GTRecipe, ? extends GTRecipe> func) {
- this.recipeTransformer = this.recipeTransformer == null ? func : this.recipeTransformer.andThen(func);
+ public RecipeMapBackendPropertiesBuilder builderTransformer(Consumer super GTRecipeBuilder> builderTransformer) {
+ if (this.builderTransformer == null) {
+ this.builderTransformer = builderTransformer;
+ } else {
+ Consumer super GTRecipeBuilder> t = this.builderTransformer;
+ this.builderTransformer = b -> {
+ t.accept(b);
+ builderTransformer.accept(b);
+ };
+ }
return this;
}
@@ -102,4 +103,17 @@ private Iterable extends GTRecipe> defaultBuildRecipe(GTRecipeBuilder builder)
private static GTRecipeBuilder copy(GTRecipeBuilder original, GTRecipeBuilder b) {
return b == original ? b.copy() : b;
}
+
+ public RecipeMapBackendPropertiesBuilder recipeTransformer(Consumer super GTRecipe> recipeTransformer) {
+ if (this.recipeTransformer == null) {
+ this.recipeTransformer = recipeTransformer;
+ } else {
+ Consumer super GTRecipe> t = this.recipeTransformer;
+ this.recipeTransformer = r -> {
+ t.accept(r);
+ recipeTransformer.accept(r);
+ };
+ }
+ return this;
+ }
}
diff --git a/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java b/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java
index ee8953570a8..1c6b49164bd 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMapBuilder.java
@@ -118,6 +118,16 @@ public RecipeMapBuilder disableOptimize() {
return this;
}
+ /**
+ * Transformer which allows you to modify the recipe builder before it emits recipes.
+ *
+ * Allows modification of the builder to modify this recipe, or adding recipes to other places based on the builder.
+ */
+ public RecipeMapBuilder builderTransformer(Consumer super GTRecipeBuilder> builderTransformer) {
+ backendPropertiesBuilder.builderTransformer(builderTransformer);
+ return this;
+ }
+
/**
* Changes how recipes are emitted by a particular recipe builder. Can emit multiple recipe per builder.
*/
@@ -164,54 +174,15 @@ public RecipeMapBuilder combineRecipeEmitterSingle(
}
/**
- * Runs a custom hook on all recipes added via builder. For more complicated behavior,
- * use {@link #recipeEmitter}.
- *
- * Recipes added via one of the overloads of addRecipe will NOT be affected by this function.
+ * Transformer which allows for modification of a recipe after it is "finalized" but before it is added to the map.
+ *
+ * Allows modification of the recipe to change this map's recipe, or add this recipe copied and/or edited elsewhere.
*/
- public RecipeMapBuilder recipeTransformer(Function super GTRecipe, ? extends GTRecipe> recipeTransformer) {
+ public RecipeMapBuilder recipeTransformer(Consumer super GTRecipe> recipeTransformer) {
backendPropertiesBuilder.recipeTransformer(recipeTransformer);
return this;
}
- /**
- * Runs a custom hook on all recipes added via builder. For more complicated behavior,
- * use {@link #recipeEmitter}.
- *
- * Recipes added via one of the overloads of addRecipe will NOT be affected by this function.
- */
- public RecipeMapBuilder recipeTransformer(Consumer recipeTransformer) {
- return recipeTransformer(withIdentityReturn(recipeTransformer));
- }
-
- /**
- * Runs a custom hook on all recipes added via builder. For more complicated behavior,
- * use {@link #recipeEmitter}.
- *
- * Recipes added via one of the overloads of addRecipe will NOT be affected by this function.
- *
- * Unlike {@link #recipeTransformer(Function)}, this one will not replace the existing special handler.
- * The supplied function will be given the output of existing handler when a recipe is added.
- */
- public RecipeMapBuilder chainRecipeTransformer(
- Function super GTRecipe, ? extends GTRecipe> recipeTransformer) {
- backendPropertiesBuilder.chainRecipeTransformer(recipeTransformer);
- return this;
- }
-
- /**
- * Runs a custom hook on all recipes added via builder. For more complicated behavior,
- * use {@link #recipeEmitter}.
- *
- * Recipes added via one of the overloads of addRecipe will NOT be affected by this function.
- *
- * Unlike {@link #recipeTransformer(Function)}, this one will not replace the existing special handler.
- * The supplied function will be given the output of existing handler when a recipe is added.
- */
- public RecipeMapBuilder chainRecipeTransformer(Consumer recipeTransformer) {
- return chainRecipeTransformer(withIdentityReturn(recipeTransformer));
- }
-
// endregion
// region frontend UI properties
diff --git a/src/main/java/gregtech/api/recipe/RecipeMaps.java b/src/main/java/gregtech/api/recipe/RecipeMaps.java
index d6cbe5bdcf1..125f1c45bb0 100644
--- a/src/main/java/gregtech/api/recipe/RecipeMaps.java
+++ b/src/main/java/gregtech/api/recipe/RecipeMaps.java
@@ -44,7 +44,6 @@
import gregtech.api.enums.OrePrefixes;
import gregtech.api.enums.TierEU;
import gregtech.api.gui.modularui.GTUITextures;
-import gregtech.api.interfaces.IRecipeMap;
import gregtech.api.objects.ItemData;
import gregtech.api.recipe.maps.AssemblerBackend;
import gregtech.api.recipe.maps.AssemblyLineFrontend;
@@ -478,6 +477,12 @@ public final class RecipeMaps {
.maxIO(0, 0, 1, 1)
.minInputs(0, 1)
.progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE)
+ .builderTransformer(
+ b -> b.copy()
+ .special(BioItemList.getPetriDish(BioCultureLoader.generalPurposeFermentingBacteria))
+ .metadata(GLASS, 3)
+ .eut(b.getEUt())
+ .addTo(BartWorksRecipeMaps.bacterialVatRecipes))
.build();
public static final RecipeMap fluidSolidifierRecipes = RecipeMapBuilder
.of("gt.recipe.fluidsolidifier")
@@ -745,6 +750,11 @@ public final class RecipeMaps {
.setInputs(input, GTModHandler.getIC2Item("industrialTnt", tITNT, null));
return coll.getAll();
})
+ .builderTransformer(
+ b -> b.copy()
+ .duration(1 * TICK)
+ .eut(TierEU.RECIPE_UEV)
+ .addTo(BartWorksRecipeMaps.electricImplosionCompressorRecipes))
.build();
public static final RecipeMap vacuumFreezerRecipes = RecipeMapBuilder
.of("gt.recipe.vacuumfreezer")
@@ -1033,6 +1043,17 @@ && isArrayEmptyOrNull(b.getFluidOutputs())
public static final RecipeMap dieselFuels = RecipeMapBuilder
.of("gt.recipe.dieselgeneratorfuel", FuelBackend::new)
.maxIO(1, 1, 0, 0)
+ .builderTransformer(b -> {
+ b.copy()
+ .build()
+ .ifPresent(
+ r -> RecipeMaps.largeBoilerFakeFuels.getBackend()
+ .addDieselRecipe(r));
+ if (b.getMetadataOrDefault(FUEL_VALUE, 0) >= 1500) {
+ b.copy()
+ .addTo(RecipeMaps.extremeDieselFuels);
+ }
+ })
.neiSpecialInfoFormatter(FuelSpecialValueFormatter.INSTANCE)
.build();
public static final RecipeMap extremeDieselFuels = RecipeMapBuilder
@@ -1053,6 +1074,12 @@ && isArrayEmptyOrNull(b.getFluidOutputs())
public static final RecipeMap denseLiquidFuels = RecipeMapBuilder
.of("gt.recipe.semifluidboilerfuels", FuelBackend::new)
.maxIO(1, 1, 0, 0)
+ .builderTransformer(
+ b -> b.copy()
+ .build()
+ .ifPresent(
+ r -> RecipeMaps.largeBoilerFakeFuels.getBackend()
+ .addDenseLiquidRecipe(r)))
.disableRegisterNEI()
.build();
public static final RecipeMap plasmaFuels = RecipeMapBuilder
@@ -1216,40 +1243,4 @@ && isArrayEmptyOrNull(b.getFluidOutputs())
.neiRecipeBackgroundSize(170, 60)
.neiHandlerInfo(builder -> builder.setDisplayStack(GTModHandler.getIC2Item("nuclearReactor", 1, null)))
.build();
-
- static {
- RecipeMaps.dieselFuels.addDownstream(
- IRecipeMap.newRecipeMap(
- b -> b.build()
- .map(
- r -> RecipeMaps.largeBoilerFakeFuels.getBackend()
- .addDieselRecipe(r))
- .map(Collections::singletonList)
- .orElse(Collections.emptyList())));
- RecipeMaps.dieselFuels.addDownstream(IRecipeMap.newRecipeMap(b -> {
- if (b.getMetadataOrDefault(FUEL_VALUE, 0) < 1500) return Collections.emptyList();
- return b.addTo(RecipeMaps.extremeDieselFuels);
- }));
- RecipeMaps.denseLiquidFuels.addDownstream(
- IRecipeMap.newRecipeMap(
- b -> b.build()
- .map(
- r -> RecipeMaps.largeBoilerFakeFuels.getBackend()
- .addDenseLiquidRecipe(r))
- .map(Collections::singletonList)
- .orElse(Collections.emptyList())));
- RecipeMaps.fermentingRecipes.addDownstream(
- IRecipeMap.newRecipeMap(
- b -> BartWorksRecipeMaps.bacterialVatRecipes.doAdd(
- b.copy()
- .special(BioItemList.getPetriDish(BioCultureLoader.generalPurposeFermentingBacteria))
- .metadata(GLASS, 3)
- .eut(b.getEUt()))));
- RecipeMaps.implosionRecipes.addDownstream(
- IRecipeMap.newRecipeMap(
- b -> BartWorksRecipeMaps.electricImplosionCompressorRecipes.doAdd(
- b.copy()
- .duration(1 * TICK)
- .eut(TierEU.RECIPE_UEV))));
- }
}