diff options
author | Glease <4586901+Glease@users.noreply.github.com> | 2023-04-02 00:02:47 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-01 18:02:47 +0200 |
commit | 6b77557e0e87cf5afd9ebd3985323ff1249e615c (patch) | |
tree | 36474042ef39f863aedc007eab81a9b09cc7aa78 /src/main/java/gregtech/api/util/GT_RecipeMapUtil.java | |
parent | 655cc902d3df19a1ac2bfaa38cc928ed629d0171 (diff) | |
download | GT5-Unofficial-6b77557e0e87cf5afd9ebd3985323ff1249e615c.tar.gz GT5-Unofficial-6b77557e0e87cf5afd9ebd3985323ff1249e615c.tar.bz2 GT5-Unofficial-6b77557e0e87cf5afd9ebd3985323ff1249e615c.zip |
Recipe Adder v2 (#1770)
* add everything
* fixes
* migrate plasma forge recipes
* syntax update
* make chances array length differ a fatal error
* time constants + long eut overload
* migrate extruder recipes
* migrate electromagnetic separator recipes
* migrate wiremill recipes
* migrate forming press recipes
* migrate bender recipes
* add doc to clarify the three itemInputs
* migrate alloy smelter recipes
* migrate arc furnace recipes
* added ModIDs enum
* sort ModIDs
* migrate autoclave recipes
* migrated some assembler recipes
* split a bit more assembler recipes
* migrate canner recipes
* migrate brewing recipes
* ic2 mod check in canner recipes
* use some loops to reduce the amount of recipes to migrate
* add requested helper methods
* migrate vacuum freezer recipes
* migrate thermal centrifuge recipes
* format smelter recipes only, doesn't go through normal GT recipe
* migrated slicer recipes
* migrated sifter recipes
* Use proper enum now
* remove more constants
* cleaning cutting recipes before migration
* remove tons of dead commented recipes
* migrate pyrolyse recipes
* use ModIDs enum more
* migrate printer recipes
* add a less confusing way to specify value of specialItem
* migrate pulverizer recipes
* less confusing special item specification
* even more ModIDs enum usage
* fix auto * import confusing Minecraft enum value with Minecraft client object
* migrated blast furnace recipes
* migrated Centrifuge recipes
* migrated assembler recipes
* migrated implosion compressor recipes
* migrated extractor recipes
* migrated mixer recipes
* remove useless code
* mgrate universal chemical recipes
* refactor chemical recipes
* migrate single block only chem reactor recipes
* migrate chem reactor recipes
* reworked circuit assembler recipes before migrating them
* migrated circuit assembler recipes
* fix merge conflict for assembler recipes
* remove leftover of the merge conflicts
* fix weird translation glitch
* example of assembly line recipe using RA2
* bugfixes for assline
* remove specialValue usage in blast furnace recipes
* fix more bugs
* add nooptimize to where it make sense
* add recipe descriptions
* Materials.Superconductor -> Materials.SuperconductorUHV
* remove useless Object creations
* remove explicit long casts
* migrate assemblyline recipes
* migrate chemical bath recipes
* migrate compressor recipes
* move smelting recipe where it belongs
* migrated cutting machine recipes
* migrated fermenter recipes (unhide alcohol)
* remove explicit long casts
* migrate fluid canner recipes
* migrate fluid heater recipes
* migrated fusion recipes
* migrated lathe recipes
* migrated laser engraver recipes
* migrated packager recipes
* migrated forge hammer recipes
* migrated TPM recipes
* exit early and reduced indents
* migrated fluid extractor recipes
* migrated fluid solidifier recipes
* migrated electrolyzer recipes
* migrated crop processing recipes
* migrated default polymerization recipes
* migrate distillery recipes
* migrate matter amplifier recipes
* add metadata identifier for fusion ignition threshold
* migrate fuel recipes
* update bs
(cherry picked from commit c2d931c9b6caa0376e9d50591894cd849021104d)
* spotless
(cherry picked from commit 1060f5357fb95e28bfae1f052025f55dabc21a0f)
* guard against null itemstacks
* wrong translation
* fix empty arrays being accessed
* add 0 duration and 0 EU/t for fuel recipes
* fix typo in matter amplifier recipes
* spotless apply
---------
Co-authored-by: boubou19 <miisterunknown@gmail.com>
Co-authored-by: Martin Robertz <dream-master@gmx.net>
Diffstat (limited to 'src/main/java/gregtech/api/util/GT_RecipeMapUtil.java')
-rw-r--r-- | src/main/java/gregtech/api/util/GT_RecipeMapUtil.java | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java b/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java new file mode 100644 index 0000000000..7bb02a5681 --- /dev/null +++ b/src/main/java/gregtech/api/util/GT_RecipeMapUtil.java @@ -0,0 +1,196 @@ +package gregtech.api.util; + +import static gregtech.api.util.GT_Config.getStackConfigName; +import static gregtech.api.util.GT_Utility.isArrayEmptyOrNull; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import cpw.mods.fml.common.Loader; +import gregtech.api.interfaces.IGT_RecipeMap; + +/** + * Define helpers useful in the creation of recipe maps. + */ +// Do not place arbitrary stuff here! These are all statically imported in GT_Recipe.java file. +public class GT_RecipeMapUtil { + + public static final Function<GT_Recipe, GT_Recipe> ALL_FAKE_RECIPE = r -> { + r.mFakeRecipe = true; + return r; + }; + + public static final Function<GT_Recipe, String> FIRST_FLUID_INPUT = r -> isArrayEmptyOrNull(r.mFluidInputs) ? null + : r.mFluidInputs[0].getFluid().getName(); + public static final Function<GT_Recipe, String> FIRST_FLUID_OUTPUT = r -> isArrayEmptyOrNull(r.mFluidInputs) ? null + : r.mFluidOutputs[0].getFluid().getName(); + public static final Function<GT_Recipe, String> FIRST_FLUIDSTACK_INPUT = r -> isArrayEmptyOrNull(r.mFluidInputs) + ? null + : r.mFluidInputs[0].getUnlocalizedName(); + public static final Function<GT_Recipe, String> FIRST_FLUIDSTACK_OUTPUT = r -> isArrayEmptyOrNull(r.mFluidOutputs) + ? null + : r.mFluidOutputs[0].getUnlocalizedName(); + public static final Function<GT_Recipe, String> FIRST_ITEM_INPUT = r -> isArrayEmptyOrNull(r.mInputs) ? null + : getStackConfigName(r.mInputs[0]); + public static final Function<GT_Recipe, String> FIRST_ITEM_OUTPUT = r -> isArrayEmptyOrNull(r.mOutputs) ? null + : getStackConfigName(r.mOutputs[0]); + public static final Function<GT_Recipe, String> FIRST_ITEM_OR_FLUID_INPUT = r -> isArrayEmptyOrNull(r.mInputs) + ? isArrayEmptyOrNull(r.mFluidInputs) ? null : r.mFluidInputs[0].getFluid().getName() + : getStackConfigName(r.mInputs[0]); + public static final Function<GT_Recipe, String> FIRST_ITEM_OR_FLUID_OUTPUT = r -> isArrayEmptyOrNull(r.mOutputs) + ? isArrayEmptyOrNull(r.mFluidOutputs) ? null : r.mFluidOutputs[0].getFluid().getName() + : getStackConfigName(r.mOutputs[0]); + private static final Map<String, IGT_RecipeMap> addonRecipeMaps = new HashMap<>(); + private static final Multimap<String, Consumer<IGT_RecipeMap>> delayedActions = ArrayListMultimap.create(); + + public static final Set<GT_RecipeBuilder.MetadataIdentifier<Integer>> SPECIAL_VALUE_ALIASES = new HashSet<>(); + + public static <T> T[] appendArray(T[] arr, T val) { + T[] newArr = Arrays.copyOf(arr, arr.length + 1); + newArr[arr.length] = val; + return newArr; + } + + public static GT_RecipeTemplate asTemplate(GT_Recipe r) { + return asTemplate(r, false); + } + + public static GT_RecipeTemplate asTemplate(GT_Recipe r, boolean includeTemplate) { + return new GT_RecipeTemplate(r, includeTemplate); + } + + public static List<GT_Recipe> buildRecipeForMultiblock(GT_RecipeBuilder b) { + List<ItemStack> itemInputs = new ArrayList<>(Arrays.asList(b.getItemInputsBasic())); + List<ItemStack> itemOutputs = new ArrayList<>(Arrays.asList(b.getItemOutputs())); + List<FluidStack> fluidInputs = new ArrayList<>(Arrays.asList(b.getFluidInputs())); + List<FluidStack> fluidOutputs = new ArrayList<>(Arrays.asList(b.getFluidOutputs())); + cellToFluid(itemInputs, fluidInputs, true); + cellToFluid(itemInputs, fluidInputs, false); + return buildOrEmpty( + b.itemInputs(itemInputs.toArray(new ItemStack[0])).itemOutputs(itemOutputs.toArray(new ItemStack[0])) + .fluidInputs(fluidInputs.toArray(new FluidStack[0])) + .fluidOutputs(fluidOutputs.toArray(new FluidStack[0]))); + } + + public static List<GT_Recipe> buildRecipeForMultiblockNoCircuit(GT_RecipeBuilder b) { + List<ItemStack> itemInputs = new ArrayList<>(Arrays.asList(b.getItemInputsBasic())); + List<ItemStack> itemOutputs = new ArrayList<>(Arrays.asList(b.getItemOutputs())); + List<FluidStack> fluidInputs = new ArrayList<>(Arrays.asList(b.getFluidInputs())); + List<FluidStack> fluidOutputs = new ArrayList<>(Arrays.asList(b.getFluidOutputs())); + cellToFluid(itemInputs, fluidInputs, false); + cellToFluid(itemInputs, fluidInputs, false); + return buildOrEmpty( + b.itemInputs(itemInputs.toArray(new ItemStack[0])).itemOutputs(itemOutputs.toArray(new ItemStack[0])) + .fluidInputs(fluidInputs.toArray(new FluidStack[0])) + .fluidOutputs(fluidOutputs.toArray(new FluidStack[0]))); + } + + private static void cellToFluid(List<ItemStack> items, List<FluidStack> fluids, boolean removeIntegratedCircuit) { + for (ListIterator<ItemStack> iterator = items.listIterator(items.size()); iterator.hasPrevious();) { + ItemStack item = iterator.previous(); + if (GT_Utility.getFluidForFilledItem(item, true) != null || GT_Utility.isCellEmpty(item) + || (removeIntegratedCircuit && GT_Utility.isAnyIntegratedCircuit(item))) { + fluids.add(GT_Utility.convertCellToFluid(item)); + iterator.remove(); + } + } + } + + public static List<GT_Recipe> buildOrEmpty(GT_RecipeBuilder builder) { + return builder.build().map(Collections::singletonList).orElse(Collections.emptyList()); + } + + /** + * Register a recipe map as part of your mod's public API under your modid and your given identifier. + * + * @param identifier + * @param recipeMap + * @param dependencies fully qualified identifier of dependent recipe maps. scheduler will only add recipes to one + * of the dependent recipe maps and this recipe map concurrently, guaranteeing thread safety. + * Currently unused, but you are advised to fill them, so that when The Day (tm) comes we don't + * end up with a bunch of weird concurrency bugs. + */ + public static void registerRecipeMap(String identifier, IGT_RecipeMap recipeMap, + RecipeMapDependency... dependencies) { + String modId = Loader.instance().activeModContainer().getModId(); + if ("gregtech".equals(modId)) throw new IllegalStateException( + "do not register recipe map under the name of gregtech! do it in your own preinit!"); + String id = modId + "@" + identifier; + addonRecipeMaps.put(id, recipeMap); + for (Consumer<IGT_RecipeMap> action : delayedActions.get(id)) { + action.accept(recipeMap); + } + } + + /** + * Use this to register recipes for a recipe map in addon not present at compile time. + * <p> + * Do not use this for recipes maps already in {@link GT_RecipeConstants}. None of them will be available via this + * interface! + * + * @param identifier recipe map id + * @param registerAction DO NOT ADD RECIPES TO MAPS OTHER THAN THE ONE PASSED TO YOU. DO NOT DO ANYTHING OTHER THAN + * ADDING RECIPES TO THIS R + */ + public static void registerRecipesFor(String modid, String identifier, Consumer<IGT_RecipeMap> registerAction) { + String id = modid + "@" + identifier; + IGT_RecipeMap map = addonRecipeMaps.get(id); + if (map == null) delayedActions.put(id, registerAction); + else registerAction.accept(map); + } + + public static final class GT_RecipeTemplate { + + private final GT_Recipe template; + private final List<GT_Recipe> derivatives = new ArrayList<>(); + + private GT_RecipeTemplate(GT_Recipe template, boolean includeTemplate) { + this.template = template; + if (includeTemplate) derivatives.add(template); + } + + public GT_Recipe derive() { + GT_Recipe derived = template.copyShallow(); + derivatives.add(derived); + return derived; + } + + public List<GT_Recipe> getAll() { + // fix shallow references + Set<Object> references = Collections.newSetFromMap(new IdentityHashMap<>()); + for (GT_Recipe r : derivatives) { + if (!references.add(r.mInputs)) r.mInputs = r.mInputs.clone(); + if (!references.add(r.mOutputs)) r.mOutputs = r.mOutputs.clone(); + if (!references.add(r.mFluidInputs)) r.mFluidInputs = r.mFluidInputs.clone(); + if (!references.add(r.mFluidOutputs)) r.mFluidOutputs = r.mFluidOutputs.clone(); + } + return derivatives; + } + } + + public static final class RecipeMapDependency { + + private final IGT_RecipeMap obj; + private final String id; + + public RecipeMapDependency(IGT_RecipeMap obj, String id) { + this.obj = obj; + this.id = id; + } + + public static RecipeMapDependency create(String id) { + return new RecipeMapDependency(null, id); + } + + public static RecipeMapDependency create(IGT_RecipeMap obj) { + return new RecipeMapDependency(obj, null); + } + } +} |