From 601f4a4cd200161c223b78a1828e00049d756032 Mon Sep 17 00:00:00 2001 From: D-Cysteine <54219287+D-Cysteine@users.noreply.github.com> Date: Tue, 27 Dec 2022 16:39:21 -0700 Subject: [PATCH] Make Ore Processing Diagram chemical bath recipe handler handle any input fluid amount (#15) * Make Ore Processing Diagram chemical bath recipe handler handle any input fluid amount * Make Ore Processing Diagram chemical bath recipe handler handle any input fluid amount + Fluid amounts were previously hard-coded: 1000 for mercury, and 100 for sodium persulfate * Fixes GTNewHorizons/GT-New-Horizons-Modpack#11842 * Update build.gradle Co-authored-by: Martin Robertz --- build.gradle | 2 +- .../oreprocessing/DiagramBuilder.java | 9 +- .../oreprocessing/RecipeHandler.java | 101 ++++++++++++------ 3 files changed, 75 insertions(+), 37 deletions(-) diff --git a/build.gradle b/build.gradle index c09bee2..19d365b 100644 --- a/build.gradle +++ b/build.gradle @@ -34,7 +34,7 @@ buildscript { } } dependencies { - classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.7' + classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.13' } } diff --git a/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/DiagramBuilder.java b/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/DiagramBuilder.java index b78d94f..efc0823 100644 --- a/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/DiagramBuilder.java +++ b/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/DiagramBuilder.java @@ -296,20 +296,21 @@ private Optional handleRecipes( private void handleChemicalBathFluid( RecipeHandler.ChemicalBathFluid chemicalBathFluid, ItemComponent input, Layout.SlotGroupKey key) { - Optional> outputsOptional = + Optional recipeOptional = recipeHandler.getUniqueChemicalBathOutput(chemicalBathFluid, input); - if (!outputsOptional.isPresent()) { + if (!recipeOptional.isPresent()) { return; } - DisplayComponent fluid = chemicalBathFluid.fluid; + DisplayComponent fluid = DisplayComponent.builder(chemicalBathFluid.fluid) + .setStackSize(recipeOptional.get().inputFluidAmount()).build(); Optional fluidDisplayItem = GregTechFluidDictUtil.getDisplayItem(fluid.component()) .map( itemComponent -> fluid.toBuilder().setComponent(itemComponent).build()); - List outputs = new ArrayList<>(outputsOptional.get()); + List outputs = new ArrayList<>(recipeOptional.get().outputs()); ComponentTransformer.removeComponent(outputs, STONE_DUST); if (outputs.size() == 0) { Logger.GREGTECH_5_ORE_PROCESSING.warn( diff --git a/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/RecipeHandler.java b/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/RecipeHandler.java index abd91fa..956d52c 100644 --- a/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/RecipeHandler.java +++ b/src/main/java/com/github/dcysteine/neicustomdiagram/generators/gregtech5/oreprocessing/RecipeHandler.java @@ -5,6 +5,7 @@ import com.github.dcysteine.neicustomdiagram.main.Logger; import com.github.dcysteine.neicustomdiagram.util.gregtech5.GregTechOreDictUtil; import com.github.dcysteine.neicustomdiagram.util.gregtech5.GregTechRecipeUtil; +import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -50,22 +51,23 @@ enum RecipeMap { } } - /** Enum containing fluids that we will look up crushed ore recipes for in the chemical bath. */ + /** + * Enum containing fluids that we will look up crushed ore recipes for in the chemical bath. + * + *

These are the GregTech display item stack, and so are {@link ItemComponent}s rather than + * {@code FluidComponent}s. + */ enum ChemicalBathFluid { - MERCURY( - DisplayComponent.builder(GT_Utility.getFluidDisplayStack(Materials.Mercury.mFluid)) - .setStackSize(1000) - .build()), + MERCURY(ItemComponent.create(GT_Utility.getFluidDisplayStack(Materials.Mercury.mFluid))), SODIUM_PERSULFATE( - DisplayComponent.builder( - GT_Utility.getFluidDisplayStack(Materials.SodiumPersulfate.mFluid)) - .setStackSize(100) - .build()); + ItemComponent.create( + GT_Utility.getFluidDisplayStack( + Materials.SodiumPersulfate.mFluid))); - final DisplayComponent fluid; + final ItemComponent fluid; - ChemicalBathFluid(DisplayComponent fluid) { + ChemicalBathFluid(ItemComponent fluid) { this.fluid = fluid; } @@ -73,15 +75,33 @@ enum ChemicalBathFluid { * Note that the keys are GregTech fluid display items, not fluids. This is for convenience, * because {@link GregTechRecipeUtil} returns GregTech fluid display items (when possible). */ - static final ImmutableMap VALUES_MAP = + static final ImmutableMap VALUES_MAP = ImmutableMap.copyOf( Arrays.stream(values()) .collect(Collectors.toMap(c -> c.fluid, Function.identity()))); } + /** + * Helper class containing the input fluid amount, as well as the recipe outputs. + * + *

This class is stored in {@code chemicalBathFluidData} below. Unlike {@code recipeData}, we + * cannot just map to {@code ImmutableList}, because we must also store the + * additional information of how much of the chemical bath fluid is required as input. + */ + @AutoValue + public abstract static class ChemicalBathFluidRecipe { + public static ChemicalBathFluidRecipe create( + int inputFluidAmount, ImmutableList outputs) { + return new AutoValue_RecipeHandler_ChemicalBathFluidRecipe(inputFluidAmount, outputs); + } + + public abstract int inputFluidAmount(); + public abstract ImmutableList outputs(); + } + /** * Map of recipe type to multimap. The multimaps are maps of input {@link ItemComponent}s to - * lists of {@code DisplayComponent}s representing the outputs for each recipe for that input. + * lists of {@link DisplayComponent}s representing the outputs for each recipe for that input. * *

We usually don't look up recipe outputs by fluid, so fluid inputs will be skipped when * building this data. We have separate data structures for the few fluid lookups that we do. @@ -90,12 +110,12 @@ enum ChemicalBathFluid { SetMultimap>> recipeData; /** - * Map of fluid to multimap. The multimaps are maps of input {@link ItemComponent}s to lists of - * {@code DisplayComponent}s representing the outputs for each chemical bath recipe for that - * fluid and input fluid and item. + * Map of fluid to multimap. The multimaps are maps of input {@link ItemComponent}s to + * {@link ChemicalBathFluidRecipe}s containing the input fluid amount, as well as the chemical + * bath recipe outputs, for the given chemical bath fluid and input item. */ private final EnumMap>> chemicalBathFluidData; + SetMultimap> chemicalBathFluidData; /** Map of smelting input to smelting output. */ private final Map furnaceData; @@ -123,6 +143,7 @@ void initialize() { ImmutableList.copyOf(GregTechRecipeUtil.buildComponentsFromOutputs(recipe)); Optional chemicalBathFluidOptional = Optional.empty(); + int inputFluidAmount = 0; if (recipeMap == RecipeMap.CHEMICAL_BATH) { List fluidInputs = GregTechRecipeUtil.buildComponents(recipe.mFluidInputs); @@ -134,10 +155,20 @@ void initialize() { GregTechRecipeUtil.buildComponentsFromInputs(recipe), GregTechRecipeUtil.buildComponentsFromOutputs(recipe)); } else { - chemicalBathFluidOptional = - Optional.ofNullable( - ChemicalBathFluid.VALUES_MAP.get( - Iterables.getOnlyElement(fluidInputs))); + DisplayComponent inputFluid = Iterables.getOnlyElement(fluidInputs); + + if (inputFluid.stackSize().isPresent()) { + chemicalBathFluidOptional = + Optional.ofNullable( + ChemicalBathFluid.VALUES_MAP.get( + inputFluid.component())); + inputFluidAmount = inputFluid.stackSize().get(); + } else { + Logger.GREGTECH_5_ORE_PROCESSING.warn( + "Found chemical bath recipe missing input fluid stack size:\n[{}]\n ->\n[{}]", + GregTechRecipeUtil.buildComponentsFromInputs(recipe), + GregTechRecipeUtil.buildComponentsFromOutputs(recipe)); + } } } @@ -150,18 +181,24 @@ void initialize() { ItemComponent.create(GT_OreDictUnificator.get_nocopy(itemStack)); multimap.put(itemComponent, outputs); + // Need an effectively final variable here so that we can reference it within + // the lambda. + final int finalInputFluidAmount = inputFluidAmount; chemicalBathFluidOptional.ifPresent( chemicalBathFluid -> chemicalBathFluidData.get(chemicalBathFluid) - .put(itemComponent, outputs)); + .put( + itemComponent, + ChemicalBathFluidRecipe.create( + finalInputFluidAmount, outputs))); } } } - ((Map) FurnaceRecipes.smelting().getSmeltingList()).entrySet() + ((Map) FurnaceRecipes.smelting().getSmeltingList()) .forEach( - entry -> furnaceData.put( - ItemComponent.create(entry.getKey()), - ItemComponent.create(entry.getValue()))); + (key, value) -> + furnaceData.put( + ItemComponent.create(key), ItemComponent.create(value))); } /** The returned set is immutable! */ @@ -195,15 +232,15 @@ Optional> getUniqueRecipeOutput( } /** - * Returns the unique recipe output for chemical bath recipes including - * {@code chemicalBathFluid} and {@code input}, or empty optional if there were zero such - * recipes, or if there were multiple recipes with differing outputs. + * Returns the recipe data for chemical bath recipes including {@code chemicalBathFluid} and + * {@code input}, or empty optional if there were zero such recipes, or if there were multiple + * recipes with differing outputs or input fluid amount. * - *

Also will log each case where multiple differing recipe outputs were found. + *

Also will log each case where multiple differing recipes were found. */ - Optional> getUniqueChemicalBathOutput( + Optional getUniqueChemicalBathOutput( ChemicalBathFluid chemicalBathFluid, ItemComponent input) { - Set> outputs = + Set outputs = chemicalBathFluidData.get(chemicalBathFluid).get(input); if (outputs.size() > 1) { Logger.GREGTECH_5_ORE_PROCESSING.warn(