diff options
author | NotAPenguin <michiel.vandeginste@gmail.com> | 2024-09-02 23:17:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-02 23:17:17 +0200 |
commit | 1b820de08a05070909a267e17f033fcf58ac8710 (patch) | |
tree | 02831a025986a06b20f87e5bcc69d1e0c639a342 /src/main/java/gregtech/api/util/GTRecipeConstants.java | |
parent | afd3fd92b6a6ab9ab0d0dc3214e6bc8ff7a86c9b (diff) | |
download | GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.gz GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.bz2 GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.zip |
The Great Renaming (#3014)
* move kekztech to a single root dir
* move detrav to a single root dir
* move gtnh-lanthanides to a single root dir
* move tectech and delete some gross reflection in gt++
* remove more reflection inside gt5u
* delete more reflection in gt++
* fix imports
* move bartworks and bwcrossmod
* fix proxies
* move galactigreg and ggfab
* move gtneioreplugin
* try to fix gt++ bee loader
* apply the rename rules to BW
* apply rename rules to bwcrossmod
* apply rename rules to detrav scanner mod
* apply rename rules to galacticgreg
* apply rename rules to ggfab
* apply rename rules to goodgenerator
* apply rename rules to gtnh-lanthanides
* apply rename rules to gt++
* apply rename rules to kekztech
* apply rename rules to kubatech
* apply rename rules to tectech
* apply rename rules to gt
apply the rename rules to gt
* fix tt import
* fix mui hopefully
* fix coremod except intergalactic
* rename assline recipe class
* fix a class name i stumbled on
* rename StructureUtility to GTStructureUtility to prevent conflict with structurelib
* temporary rename of GTTooltipDataCache to old name
* fix gt client/server proxy names
Diffstat (limited to 'src/main/java/gregtech/api/util/GTRecipeConstants.java')
-rw-r--r-- | src/main/java/gregtech/api/util/GTRecipeConstants.java | 691 |
1 files changed, 691 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/util/GTRecipeConstants.java b/src/main/java/gregtech/api/util/GTRecipeConstants.java new file mode 100644 index 0000000000..82a477756a --- /dev/null +++ b/src/main/java/gregtech/api/util/GTRecipeConstants.java @@ -0,0 +1,691 @@ +package gregtech.api.util; + +import static gregtech.api.recipe.RecipeMaps.scannerFakeRecipes; +import static gregtech.api.util.GTRecipeMapUtil.convertCellToFluid; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Optional; + +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import cpw.mods.fml.common.registry.GameRegistry; +import gregtech.api.enums.GTValues; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.TierEU; +import gregtech.api.interfaces.IRecipeMap; +import gregtech.api.objects.ItemData; +import gregtech.api.recipe.RecipeCategories; +import gregtech.api.recipe.RecipeMaps; +import gregtech.api.recipe.RecipeMetadataKey; +import gregtech.api.recipe.metadata.SimpleRecipeMetadataKey; +import gregtech.common.items.IDMetaItem03; +import gregtech.common.items.MetaGeneratedItem03; +import gtnhlanth.common.item.ItemPhotolithographicMask; +import gtnhlanth.common.item.MaskList; +import gtnhlanth.common.register.LanthItemList; + +// this class is intended to be import-static-ed on every recipe script +// so take care to not put unrelated stuff here! +public class GTRecipeConstants { + + /** + * Set to true to signal the recipe require low gravity. do nothing if recipe set specialValue explicitly. Can + * coexist with CLEANROOM just fine + */ + public static final RecipeMetadataKey<Boolean> LOW_GRAVITY = SimpleRecipeMetadataKey + .create(Boolean.class, "low_gravity"); + /** + * Set to true to signal the recipe require cleanroom. do nothing if recipe set specialValue explicitly. Can coexist + * with LOW_GRAVITY just fine + */ + public static final RecipeMetadataKey<Boolean> CLEANROOM = SimpleRecipeMetadataKey + .create(Boolean.class, "cleanroom"); + /** + * Common additive to use in recipe, e.g. for PBF, this is coal amount. + */ + public static final RecipeMetadataKey<Integer> ADDITIVE_AMOUNT = SimpleRecipeMetadataKey + .create(Integer.class, "additives"); + /** + * Used for fusion reactor. Denotes ignition threshold. + */ + public static final RecipeMetadataKey<Integer> FUSION_THRESHOLD = SimpleRecipeMetadataKey + .create(Integer.class, "fusion_threshold"); + /** + * Research time in a scanner used in ticks. + */ + public static final RecipeMetadataKey<Integer> RESEARCH_TIME = SimpleRecipeMetadataKey + .create(Integer.class, "research_time"); + /** + * Fuel type. TODO should we use enum directly? + */ + public static final RecipeMetadataKey<Integer> FUEL_TYPE = SimpleRecipeMetadataKey + .create(Integer.class, "fuel_type"); + /** + * Fuel value. + */ + public static final RecipeMetadataKey<Integer> FUEL_VALUE = SimpleRecipeMetadataKey + .create(Integer.class, "fuel_value"); + /** + * Required heat for heating coil (Kelvin). + */ + public static final RecipeMetadataKey<Integer> COIL_HEAT = SimpleRecipeMetadataKey + .create(Integer.class, "coil_heat"); + /** + * Research item used by assline recipes. + */ + public static final RecipeMetadataKey<ItemStack> RESEARCH_ITEM = SimpleRecipeMetadataKey + .create(ItemStack.class, "research_item"); + /** + * For assembler. It accepts a single item as oredict. It looks like no one uses this anyway... + */ + public static final RecipeMetadataKey<Object> OREDICT_INPUT = SimpleRecipeMetadataKey + .create(Object.class, "oredict_input"); + /** + * Replicator output material. + */ + public static final RecipeMetadataKey<Materials> MATERIAL = SimpleRecipeMetadataKey + .create(Materials.class, "material"); + /** + * Marker for {@link #UniversalArcFurnace} to tell that the recipe belongs to recycling category. + */ + public static final RecipeMetadataKey<Boolean> RECYCLE = SimpleRecipeMetadataKey.create(Boolean.class, "recycle"); + /** + * For Microwave. + */ + public static final RecipeMetadataKey<Boolean> EXPLODE = SimpleRecipeMetadataKey.create(Boolean.class, "explode"); + /** + * For Microwave. + */ + public static final RecipeMetadataKey<Boolean> ON_FIRE = SimpleRecipeMetadataKey.create(Boolean.class, "on_fire"); + + /** + * Nano Forge Tier. + */ + public static final RecipeMetadataKey<Integer> NANO_FORGE_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "nano_forge_tier"); + + /** + * FOG Exotic recipe tier. + */ + public static final RecipeMetadataKey<Integer> FOG_EXOTIC_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "fog_exotic_tier"); + + /** + * FOG Plasma recipe tier. + */ + public static final RecipeMetadataKey<Integer> FOG_PLASMA_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "fog_plasma_tier"); + + /** + * DEFC Casing tier. + */ + public static final RecipeMetadataKey<Integer> DEFC_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "defc_casing_tier"); + + /** + * Chemplant Casing tier. Beware, codewise index starts at 0, but it is tier 1. + */ + public static final RecipeMetadataKey<Integer> CHEMPLANT_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "chemplant_casing_tier"); + + /** + * QFT Focus tier. + */ + public static final RecipeMetadataKey<Integer> QFT_FOCUS_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "qft_focus_tier"); + + /** + * Tier of advanced compression (HIP/black hole) + */ + public static final RecipeMetadataKey<Integer> COMPRESSION_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "compression"); + + /** + * Dissolution Tank Ratio. + */ + public static final RecipeMetadataKey<Integer> DISSOLUTION_TANK_RATIO = SimpleRecipeMetadataKey + .create(Integer.class, "dissolution_tank_ratio"); + + /** + * Duration in days for the RTG. + */ + public static final RecipeMetadataKey<Integer> RTG_DURATION_IN_DAYS = SimpleRecipeMetadataKey + .create(Integer.class, "rtg_duration_in_days"); + + /** + * Basic output for the Large Naquadah Generator. + */ + public static final RecipeMetadataKey<Integer> LNG_BASIC_OUTPUT = SimpleRecipeMetadataKey + .create(Integer.class, "lng_basic_output"); + + /** + * Coil tier for the Naquadah Fuel Refinery. + */ + public static final RecipeMetadataKey<Integer> NFR_COIL_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "nfr_coil_tier"); + + /** + * NKE range for the neutron activator. + */ + public static final RecipeMetadataKey<Integer> NKE_RANGE = SimpleRecipeMetadataKey + .create(Integer.class, "nke_range"); + /** + * Precise Assembler casing tier. + */ + public static final RecipeMetadataKey<Integer> PRECISE_ASSEMBLER_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "precise_assembler_casing_tier"); + /** + * CoAL casing tier. + */ + public static final RecipeMetadataKey<Integer> COAL_CASING_TIER = SimpleRecipeMetadataKey + .create(Integer.class, "coal_casing_tier"); + + /** + * LFTR output power. + */ + public static final RecipeMetadataKey<Integer> LFTR_OUTPUT_POWER = SimpleRecipeMetadataKey + .create(Integer.class, "lftr_output_power"); + + /** + * Research Station data. + */ + public static final RecipeMetadataKey<Integer> RESEARCH_STATION_DATA = SimpleRecipeMetadataKey + .create(Integer.class, "research_station_data"); + + /** + * glass tier required for the biovat recipes. + */ + public static final RecipeMetadataKey<Integer> SIEVERTS = SimpleRecipeMetadataKey.create(Integer.class, "sieverts"); + + public static final RecipeMetadataKey<Integer> DECAY_TICKS = SimpleRecipeMetadataKey + .create(Integer.class, "decay_ticks"); + + public static final RecipeMetadataKey<Boolean> NOBLE_GASES = SimpleRecipeMetadataKey + .create(Boolean.class, "noble_gases"); + + public static final RecipeMetadataKey<Boolean> ANAEROBE_GASES = SimpleRecipeMetadataKey + .create(Boolean.class, "anaerobe_gases"); + + public static final RecipeMetadataKey<Boolean> NO_GAS = SimpleRecipeMetadataKey.create(Boolean.class, "no_gas"); + + /** + * Add a arc furnace recipe. Adds to both normal arc furnace and plasma arc furnace. + * Will override the fluid input with oxygen/plasma for the respective recipe maps, so there is no point setting it. + */ + public static final IRecipeMap UniversalArcFurnace = IRecipeMap.newRecipeMap(builder -> { + if (!GTUtility.isArrayOfLength(builder.getItemInputsBasic(), 1) + || GTUtility.isArrayEmptyOrNull(builder.getItemOutputs())) return Collections.emptyList(); + int aDuration = builder.getDuration(); + if (aDuration <= 0) { + return Collections.emptyList(); + } + builder.duration(aDuration); + boolean recycle = builder.getMetadataOrDefault(RECYCLE, false); + Collection<GTRecipe> ret = new ArrayList<>(); + for (Materials mat : new Materials[] { Materials.Argon, Materials.Nitrogen }) { + int tPlasmaAmount = (int) Math.max(1L, aDuration / (mat.getMass() * 16L)); + GTRecipeBuilder plasmaBuilder = builder.copy() + .fluidInputs(mat.getPlasma(tPlasmaAmount)) + .fluidOutputs(mat.getGas(tPlasmaAmount)); + if (recycle) { + plasmaBuilder.recipeCategory(RecipeCategories.plasmaArcFurnaceRecycling); + } + ret.addAll(RecipeMaps.plasmaArcFurnaceRecipes.doAdd(plasmaBuilder)); + } + GTRecipeBuilder arcBuilder = builder.copy() + .fluidInputs(Materials.Oxygen.getGas(aDuration)); + if (recycle) { + arcBuilder.recipeCategory(RecipeCategories.arcFurnaceRecycling); + } + ret.addAll(RecipeMaps.arcFurnaceRecipes.doAdd(arcBuilder)); + return ret; + }); + + /** + * Add a chemical reactor recipe to both LCR and singleblocks. + */ + public static final IRecipeMap UniversalChemical = IRecipeMap.newRecipeMap(builder -> { + for (ItemStack input : builder.getItemInputsBasic()) { + // config >= 10 -> this is a special chemical recipe that output fluid/canned fluid variant. + // it doesn't belong to multiblocks + if (GTUtility.isAnyIntegratedCircuit(input) && input.getItemDamage() >= 10) { + return builder.addTo(RecipeMaps.chemicalReactorRecipes); + } + } + return GTUtility.concat( + builder.copy() + .addTo(RecipeMaps.chemicalReactorRecipes), + convertCellToFluid(builder, false) + // LCR does not need cleanroom. + .metadata(CLEANROOM, false) + .addTo(RecipeMaps.multiblockChemicalReactorRecipes)); + }); + + /** + * Adds an engraver recipe that might use purified water. Still added to the regular recipemap if it ends up not + * needing it. + */ + public static final IRecipeMap WaferEngravingRecipes = IRecipeMap.newRecipeMap(builder -> { + // spotless:off + enum Wafer{ + Naquadah, + Europium, + Americium, + // Beamline masks + MaskT1, + MaskT2, + MaskT3, + } + // spotless:on + // Find the wafer used + Wafer wafer = null; + ItemPhotolithographicMask t1Item = (ItemPhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK1); + ItemPhotolithographicMask t2Item = (ItemPhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK2); + ItemPhotolithographicMask t3Item = (ItemPhotolithographicMask) LanthItemList.maskMap.get(MaskList.BLANK3); + for (ItemStack input : builder.getItemInputsBasic()) { + if (input.getItem() instanceof MetaGeneratedItem03) { + int meta = input.getItemDamage() - 32000; + // Check if this input item is indicating a wafer recipe we want to modify + if (meta == IDMetaItem03.Circuit_Silicon_Wafer3.ID) wafer = Wafer.Naquadah; + else if (meta == IDMetaItem03.Circuit_Silicon_Wafer4.ID) wafer = Wafer.Europium; + else if (meta == IDMetaItem03.Circuit_Silicon_Wafer5.ID) wafer = Wafer.Americium; + } + + // Now look for beamline masks + if (input.getItem() instanceof ItemPhotolithographicMask mask) { + String spectrum = mask.getDescSpectrum(); + if (spectrum.equals(t1Item.getDescSpectrum())) wafer = Wafer.MaskT1; + else if (spectrum.equals(t2Item.getDescSpectrum())) wafer = Wafer.MaskT2; + else if (spectrum.equals(t3Item.getDescSpectrum())) wafer = Wafer.MaskT3; + } + + // Found a wafer, stop checking inputs + if (wafer != null) break; + } + + int recipeTime = builder.duration; + // Bonus for using purified water of a higher tier than necessary + int halfBoostedRecipeTime = (int) (recipeTime * 0.75); + int boostedRecipeTime = (int) (recipeTime * 0.5); + + // If this recipe does not use a wafer, exit without modifying it. + if (wafer == null) return builder.addTo(RecipeMaps.laserEngraverRecipes); + switch (wafer) { + case Naquadah -> { + ArrayList<ItemStack> items = new ArrayList<>(Arrays.asList(builder.getItemInputsBasic())); + ItemStack[] itemInputs = items.toArray(new ItemStack[] {}); + // Naquadah wafers can use grade 1-2 purified water for a bonus, otherwise use distilled so we don't + // have to + // deal with circuits + return GTUtility.concat( + builder.copy() + .itemInputs(itemInputs) + .fluidInputs(GTModHandler.getDistilledWater(100L)) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .itemInputs(itemInputs) + .fluidInputs(Materials.Grade1PurifiedWater.getFluid(100L)) + .duration(halfBoostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .itemInputs(itemInputs) + .fluidInputs(Materials.Grade2PurifiedWater.getFluid(100L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case Europium -> { + // Require purified water for europium wafers, at least grade 3 + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade3PurifiedWater.getFluid(100L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade4PurifiedWater.getFluid(100L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case Americium -> { + // Require purified water for americium wafers, at least grade 5 + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade5PurifiedWater.getFluid(100L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade6PurifiedWater.getFluid(100L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + // Masks require much more purified water because they can make many wafers at once + case MaskT1 -> { + // T1 masks require grade 1, 2 or 3 purified water + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade1PurifiedWater.getFluid(32000L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade2PurifiedWater.getFluid(32000L)) + .duration(halfBoostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade3PurifiedWater.getFluid(32000L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case MaskT2 -> { + // T2 masks require grade 4 or 5 purified water + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade4PurifiedWater.getFluid(32000L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade5PurifiedWater.getFluid(32000L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + case MaskT3 -> { + // T3 masks require grade 6, 7 or 8 purified water + return GTUtility.concat( + builder.copy() + .fluidInputs(Materials.Grade6PurifiedWater.getFluid(32000L)) + .duration(recipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade7PurifiedWater.getFluid(32000L)) + .duration(halfBoostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes), + builder.copy() + .fluidInputs(Materials.Grade8PurifiedWater.getFluid(32000L)) + .duration(boostedRecipeTime) + .addTo(RecipeMaps.laserEngraverRecipes)); + } + } + + throw new RuntimeException("Unreachable code reached in Laser Engraver Recipe Transformer"); + }); + + /** + * The one and only :tm: assline recipe adder. + * Uses {@link #RESEARCH_ITEM} metadata as research item, and {@link #RESEARCH_TIME} metadata as research time, unit + * in ticks. + */ + public static final IRecipeMap AssemblyLine = IRecipeMap.newRecipeMap(builder -> { + Optional<GTRecipe.GTRecipe_WithAlt> rr = builder.forceOreDictInput() + .validateInputCount(4, 16) + .validateOutputCount(1, 1) + .validateOutputFluidCount(-1, 0) + .validateInputFluidCount(1, 4) + .buildWithAlt(); + // noinspection SimplifyOptionalCallChains + if (!rr.isPresent()) return Collections.emptyList(); + GTRecipe.GTRecipe_WithAlt r = rr.get(); + ItemStack[][] mOreDictAlt = r.mOreDictAlt; + Object[] inputs = builder.getItemInputsOreDict(); + ItemStack aResearchItem = builder.getMetadata(RESEARCH_ITEM); + if (aResearchItem == null) { + return Collections.emptyList(); + } + ItemStack aOutput = r.mOutputs[0]; + int tPersistentHash = 1; + for (int i = 0, mOreDictAltLength = mOreDictAlt.length; i < mOreDictAltLength; i++) { + ItemStack[] alts = mOreDictAlt[i]; + Object input = inputs[i]; + if (input == null) { + GTLog.err.println( + "addAssemblingLineRecipe " + aResearchItem.getDisplayName() + + " --> " + + aOutput.getUnlocalizedName() + + " there is some null item in that recipe"); + } + if (input instanceof ItemStack) { + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash((ItemStack) input, true, false); + } else if (input instanceof ItemStack[]) { + for (ItemStack alt : ((ItemStack[]) input)) { + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(alt, true, false); + if (alt == null) { + GTLog.err.println( + "addAssemblingLineRecipe " + aResearchItem.getDisplayName() + + " --> " + + aOutput.getUnlocalizedName() + + " there is some null alt item in that recipe"); + } + } + tPersistentHash *= 31; + } else if (input instanceof Object[]objs) { + Arrays.sort( + alts, + Comparator + .<ItemStack, String>comparing(s -> GameRegistry.findUniqueIdentifierFor(s.getItem()).modId) + .thenComparing(s -> GameRegistry.findUniqueIdentifierFor(s.getItem()).name) + .thenComparingInt(Items.feather::getDamage) + .thenComparingInt(s -> s.stackSize)); + + tPersistentHash = tPersistentHash * 31 + (objs[0] == null ? "" : objs[0].toString()).hashCode(); + tPersistentHash = tPersistentHash * 31 + ((Number) objs[1]).intValue(); + } + } + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(aResearchItem, true, false); + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(aOutput, true, false); + for (FluidStack fluidInput : r.mFluidInputs) { + if (fluidInput == null) continue; + tPersistentHash = tPersistentHash * 31 + GTUtility.persistentHash(fluidInput, true, false); + } + int aResearchTime = builder.getMetadataOrDefault(RESEARCH_TIME, 0); + tPersistentHash = tPersistentHash * 31 + aResearchTime; + tPersistentHash = tPersistentHash * 31 + r.mDuration; + tPersistentHash = tPersistentHash * 31 + r.mEUt; + + GTRecipe.RecipeAssemblyLine tRecipe = new GTRecipe.RecipeAssemblyLine( + aResearchItem, + aResearchTime, + r.mInputs, + r.mFluidInputs, + aOutput, + r.mDuration, + r.mEUt, + r.mOreDictAlt); + tRecipe.setPersistentHash(tPersistentHash); + GTRecipe.RecipeAssemblyLine.sAssemblylineRecipes.add(tRecipe); + AssemblyLineUtils.addRecipeToCache(tRecipe); + + ItemStack writesDataStick = ItemList.Tool_DataStick.getWithName(1L, "Writes Research result"); + AssemblyLineUtils.setAssemblyLineRecipeOnDataStick(writesDataStick, tRecipe, false); + Collection<GTRecipe> ret = new ArrayList<>(3); + ret.addAll( + GTValues.RA.stdBuilder() + .itemInputs(aResearchItem) + .itemOutputs(aOutput) + .special(writesDataStick) + .duration(aResearchTime) + .eut(TierEU.RECIPE_LV) + .specialValue(-201) // means it's scanned + .noOptimize() + .ignoreCollision() + .fake() + .addTo(scannerFakeRecipes)); + + ItemStack readsDataStick = ItemList.Tool_DataStick.getWithName(1L, "Reads Research result"); + AssemblyLineUtils.setAssemblyLineRecipeOnDataStick(readsDataStick, tRecipe, false); + ret.add( + RecipeMaps.assemblylineVisualRecipes.addFakeRecipe( + false, + r.mInputs, + new ItemStack[] { aOutput }, + new ItemStack[] { readsDataStick }, + r.mFluidInputs, + null, + r.mDuration, + r.mEUt, + 0, + r.mOreDictAlt, + false)); + + return ret; + }); + + /** + * Adds an Electric Blast Furnace recipe that might use gas. + */ + public static final IRecipeMap BlastFurnaceWithGas = IRecipeMap.newRecipeMap(builder -> { + Collection<GTRecipe> ret = new ArrayList<>(); + int basicGasAmount = builder.getMetadataOrDefault(ADDITIVE_AMOUNT, 1000); + double durationBase = builder.getDuration(); + ArrayList<ItemStack> items = new ArrayList<>(Arrays.asList(builder.getItemInputsBasic())); + int circuitConfig = 1; + if (items.size() == 1) {// Set circuit config if it is a dust -> ingot recipe. + ItemData data = GTOreDictUnificator.getAssociation(items.get(0)); + if (data != null) { + OrePrefixes prefix = data.mPrefix; + if (OrePrefixes.dust.equals(prefix)) { + circuitConfig = 1; + } else if (OrePrefixes.dustSmall.equals(prefix)) { + circuitConfig = 4; + } else if (OrePrefixes.dustTiny.equals(prefix)) { + circuitConfig = 9; + } + } + } else { // Set circuit config if there is an integrated circuit + for (int i = 0; i < items.size(); i++) { + if (GTUtility.isAnyIntegratedCircuit(items.get(i))) { + circuitConfig = items.get(i) + .getItemDamage(); + items.remove(i--); + } + } + } + + if (builder.getMetadataOrDefault(NO_GAS, false)) { + items.add(GTUtility.getIntegratedCircuit(circuitConfig)); + ret.addAll( + builder.copy() + .itemInputs(items.toArray(new ItemStack[0])) + .fluidInputs() + .duration((int) Math.max(durationBase * 1.1, 1)) + .addTo(RecipeMaps.blastFurnaceRecipes)); + items.remove(items.size() - 1); + circuitConfig += 10; + } + + items.add(GTUtility.getIntegratedCircuit(circuitConfig)); + boolean nobleGases = builder.getMetadataOrDefault(NOBLE_GASES, false); + boolean anaerobeGases = builder.getMetadataOrDefault(ANAEROBE_GASES, false); + Collection<BlastFurnaceGasStat> gases = new ArrayList<>(); + + if (nobleGases && anaerobeGases) { + gases = BlastFurnaceGasStat.getNobleAndAnaerobeGases(); + } else if (nobleGases) { + gases = BlastFurnaceGasStat.getNobleGases(); + } else if (anaerobeGases) { + gases = BlastFurnaceGasStat.getAnaerobeGases(); + } + for (BlastFurnaceGasStat gas : gases) { + int gasAmount = (int) (gas.recipeConsumedAmountMultiplier * basicGasAmount); + int duration = (int) Math.max(gas.recipeTimeMultiplier * durationBase, 1); + ret.addAll( + builder.copy() + .itemInputs(items.toArray(new ItemStack[0])) + .fluidInputs(GTUtility.copyAmount(gasAmount, gas.gas)) + .duration(duration) + .addTo(RecipeMaps.blastFurnaceRecipes)); + } + return ret; + }); + + /** + * Just like any normal assembler recipe, however it accepts one input item to be oredicted. Pass in the item to + * oredict via {@link #OREDICT_INPUT}. It will be used along all other item inputs as input of this recipe. + */ + public static IRecipeMap AssemblerOD = IRecipeMap.newRecipeMap(builder -> { + Collection<GTRecipe> ret = new ArrayList<>(); + for (ItemStack input : GTOreDictUnificator.getOresImmutable(builder.getMetadata(OREDICT_INPUT))) { + ret.addAll( + builder.copy() + .itemInputs(GTRecipeMapUtil.appendArray(builder.getItemInputsBasic(), input)) + .addTo(RecipeMaps.assemblerRecipes)); + } + return ret; + }); + + /** + * A universal fuel adder. It's actually just a dispatcher towards all actual fuel recipe maps. + * Dispatch based on {@link #FUEL_TYPE}. Uses {@link #FUEL_VALUE} as fuel value. + * Can use {@link FuelType#ordinal()} as a human-readable form of what FUEL_TYPE should be. + * You can bypass this and add to relevant fuel maps directly if you wish. + */ + public static IRecipeMap Fuel = IRecipeMap.newRecipeMap(builder -> { + builder.validateInputCount(1, 1) + .validateNoInputFluid() + .validateOutputCount(-1, 1) + .validateNoOutputFluid(); + if (!builder.isValid()) return Collections.emptyList(); + Integer fuelType = builder.getMetadata(FUEL_TYPE); + if (fuelType == null) return Collections.emptyList(); + builder.metadata(FUEL_VALUE, builder.getMetadataOrDefault(FUEL_VALUE, 0)); + return FuelType.get(fuelType) + .getTarget() + .doAdd(builder); + }); + + public enum FuelType { + + // ORDER MATTERS. DO NOT INSERT ELEMENT BETWEEN EXISTING ONES + DieselFuel(RecipeMaps.dieselFuels), + GasTurbine(RecipeMaps.gasTurbineFuels), + // appears unused + HotFuel(RecipeMaps.hotFuels), + SemiFluid(RecipeMaps.denseLiquidFuels), + PlasmaTurbine(RecipeMaps.plasmaFuels), + Magic(RecipeMaps.magicFuels),; + + private static final FuelType[] VALUES = values(); + private final IRecipeMap target; + + FuelType(IRecipeMap target) { + this.target = target; + } + + public static FuelType get(int fuelType) { + if (fuelType < 0 || fuelType >= VALUES.length) return SemiFluid; + return VALUES[fuelType]; + } + + public IRecipeMap getTarget() { + return target; + } + } + + static { + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COIL_HEAT); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FUSION_THRESHOLD); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FUEL_VALUE); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NANO_FORGE_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FOG_EXOTIC_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(FOG_PLASMA_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DEFC_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(CHEMPLANT_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(QFT_FOCUS_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DISSOLUTION_TANK_RATIO); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(RTG_DURATION_IN_DAYS); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(LNG_BASIC_OUTPUT); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NFR_COIL_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(NKE_RANGE); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(PRECISE_ASSEMBLER_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COAL_CASING_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(COMPRESSION_TIER); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(RESEARCH_STATION_DATA); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(SIEVERTS); + GTRecipeMapUtil.SPECIAL_VALUE_ALIASES.add(DECAY_TICKS); + + } +} |