diff --git a/changelog b/changelog index 087101ec0..8778e076f 100644 --- a/changelog +++ b/changelog @@ -19,6 +19,8 @@ * Similar to soil sand, entities will sink in taint and get slowed down * The sludge consumeth * `enableGuns` config option now applies to SEDNA system guns, simply canceling all gun-related keybinds +* Cinnabar dust, if registered by another mod, can now be acidized into cinnabar using hydrogen peroxide +* Copper wires, like AA and gold, can now be welded into dense wires ## Fixed * Fixed animation error on the MAS-36 diff --git a/gradle.properties b/gradle.properties index 68fe9efe2..57936ce9d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,7 @@ credits=HbMinecraft,\ \ MellowArpeggiation (new animation system, turbine sounds, sound fixes, industrial lights, better particle diodes),\ \ Pheo (textures, various machines, models, weapons),\ \ Vær (gas centrifuges, better worldgen, ZIRNOX, CP-1 parts, starter guide, new cyclotron, weapon animations),\ + \ UFFR (RTG pellets, guns, casings, euphemium capacitor, nucleartech.wiki),\ \ LePeep (coilgun model, BDCL QC),\ \ Adam29 (liquid petroleum, ethanol, electric furnace),\ \ Pvndols (thorium fuel recipe, gas turbine),\ @@ -33,7 +34,6 @@ credits=HbMinecraft,\ \ Maksymisio (polish localization)\ \ el3ctro4ndre (italian localization),\ \ Pu-238 (Tom impact effects),\ - \ UFFR (RTG pellets, guns, casings, euphemium capacitor),\ \ Frooz (gun models),\ \ VT-6/24 (models, textures),\ \ Nos (models),\ diff --git a/src/main/java/api/hbm/recipe/IRecipeRegisterListener.java b/src/main/java/api/hbm/recipe/IRecipeRegisterListener.java new file mode 100644 index 000000000..14832ec3a --- /dev/null +++ b/src/main/java/api/hbm/recipe/IRecipeRegisterListener.java @@ -0,0 +1,13 @@ +package api.hbm.recipe; + +public interface IRecipeRegisterListener { + + /** + * Called during SerializableRecipe.initialize(), after the defaults are loaded but before the template is written. + * Due to the way the recipes are handled, calling it once is not enough, it has to be called once for every SerializableRecipe + * instance handled, therefore the load operation passes the type name of the recipe, so that the listeners know what type of recipe + * to register at that point. Note that the actual SerializableRecipe instance is irrelevant, since recipes are static anyway, + * and direct tampering with SerializableRecipes is not recommended. + */ + public void onRecipeLoad(String recipeClassName); +} diff --git a/src/main/java/api/hbm/recipe/package-info.java b/src/main/java/api/hbm/recipe/package-info.java new file mode 100644 index 000000000..53e838a43 --- /dev/null +++ b/src/main/java/api/hbm/recipe/package-info.java @@ -0,0 +1,17 @@ +package api.hbm.recipe; + +/* + +Quick guide on how to make robust and safe recipe integration: +* Implement IRecipeRegisterListener, the resulting class will handle all recipes, and the onRecipeLoad method is called every time the SerializableRecipe system updates +* Register your IRecipeRegisterListener using CompatExternal.registerRecipeRegisterListener, this has to happen before the SerializableRecipe initializes, doing this during PreInit should be safe +* In your IRecipeRegisterListener, check the supplied recipe type string (which will be the class name of the SerializableRecipe currently being registered) and register your custom recipes accordingly using CompatRecipeRegistry + +Explanation: +* Order of operations is important for the recipes to work, if recipes are loaded outside the scope of SerializableRecipe.initialize, they will not work correctly +* If recipes are registered before the init, they are deleted, if they are registered after the init, they will not be part of the config template file, and get deleted when running /ntmreload +* Machines change all the time, so the recipe classes should not be considered API, since the compat would break immediately if a machine is changed or removed +* CompatRecipeRegistry promises to never change its method signatures, and have solid sanity checking when recipes are registered, allowing it to make the bst of whatever data is thrown at it +* Using this dedicated registry class means that even if a machine is changed or removed, the recipes will continue to work to the best of its abilities + +*/ \ No newline at end of file diff --git a/src/main/java/com/hbm/inventory/recipes/ArcWelderRecipes.java b/src/main/java/com/hbm/inventory/recipes/ArcWelderRecipes.java index 2dacf92dd..669a4bde2 100644 --- a/src/main/java/com/hbm/inventory/recipes/ArcWelderRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/ArcWelderRecipes.java @@ -46,6 +46,8 @@ public class ArcWelderRecipes extends SerializableRecipe { new OreDictStack(ANY_BISMOIDBRONZE.plateCast(), 2), new OreDictStack(CMB.plateWelded(), 1), new ComparableStack(ModItems.ingot_cft))); //Dense Wires + recipes.add(new ArcWelderRecipe(new ItemStack(ModItems.wire_dense, 1, Mats.MAT_COPPER.id), 100, 10_000L, + new OreDictStack(CU.wireFine(), 8))); recipes.add(new ArcWelderRecipe(new ItemStack(ModItems.wire_dense, 1, Mats.MAT_ALLOY.id), 100, 10_000L, new OreDictStack(ALLOY.wireFine(), 8))); recipes.add(new ArcWelderRecipe(new ItemStack(ModItems.wire_dense, 1, Mats.MAT_GOLD.id), 100, 10_000L, diff --git a/src/main/java/com/hbm/inventory/recipes/BlastFurnaceRecipes.java b/src/main/java/com/hbm/inventory/recipes/BlastFurnaceRecipes.java index af7032305..1a7599b5d 100644 --- a/src/main/java/com/hbm/inventory/recipes/BlastFurnaceRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/BlastFurnaceRecipes.java @@ -77,7 +77,7 @@ public class BlastFurnaceRecipes extends SerializableRecipe { hiddenRecipes.add(new ComparableStack(ModItems.meteorite_sword_alloyed)); } - private static void addRecipe(Object in1, Object in2, ItemStack out) { + public static void addRecipe(Object in1, Object in2, ItemStack out) { if(in1 instanceof Item) in1 = new ComparableStack((Item) in1); if(in1 instanceof Block) in1 = new ComparableStack((Block) in1); diff --git a/src/main/java/com/hbm/inventory/recipes/BreederRecipes.java b/src/main/java/com/hbm/inventory/recipes/BreederRecipes.java index 7503b3dec..1ff4b65fb 100644 --- a/src/main/java/com/hbm/inventory/recipes/BreederRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/BreederRecipes.java @@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack; public class BreederRecipes extends SerializableRecipe { - private static HashMap recipes = new HashMap(); + public static HashMap recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/CentrifugeRecipes.java b/src/main/java/com/hbm/inventory/recipes/CentrifugeRecipes.java index 641008670..027efb67d 100644 --- a/src/main/java/com/hbm/inventory/recipes/CentrifugeRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/CentrifugeRecipes.java @@ -43,7 +43,7 @@ import net.minecraftforge.oredict.OreDictionary; public class CentrifugeRecipes extends SerializableRecipe { - private static HashMap recipes = new HashMap(); + public static HashMap recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java b/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java index 5331f09d4..7a44817d3 100644 --- a/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/ChemplantRecipes.java @@ -38,7 +38,7 @@ public class ChemplantRecipes extends SerializableRecipe { @Override public void registerDefaults() { - //6-30, formerly oil cracking, coal liquefaction and solidifciation + //6-30, formerly oil cracking, coal liquefaction and solidification registerOtherOil(); recipes.add(new ChemRecipe(36, "COOLANT", 50) diff --git a/src/main/java/com/hbm/inventory/recipes/CokerRecipes.java b/src/main/java/com/hbm/inventory/recipes/CokerRecipes.java index ce4c4dfb5..32f1bbd6a 100644 --- a/src/main/java/com/hbm/inventory/recipes/CokerRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/CokerRecipes.java @@ -25,7 +25,7 @@ import net.minecraft.item.ItemStack; public class CokerRecipes extends SerializableRecipe { - private static HashMap> recipes = new HashMap(); + public static HashMap> recipes = new HashMap(); @Override public void registerDefaults() { @@ -68,7 +68,7 @@ public class CokerRecipes extends SerializableRecipe { registerRecipe(VITRIOL, 4000, new ItemStack(ModItems.powder_iron), new FluidStack(SULFURIC_ACID, 500)); } - private static void registerAuto(FluidType fluid, FluidType type) { + public static void registerAuto(FluidType fluid, FluidType type) { registerSFAuto(fluid, 820_000L, DictFrame.fromOne(ModItems.coke, EnumCokeType.PETROLEUM), type); //3200 burntime * 1.25 burntime bonus * 200 TU/t + 20000TU per operation } private static void registerSFAuto(FluidType fluid, long tuPerSF, ItemStack fuel, FluidType type) { diff --git a/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java b/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java index 5698426dc..58cc7784a 100644 --- a/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/CombinationRecipes.java @@ -34,7 +34,7 @@ import net.minecraft.item.ItemStack; public class CombinationRecipes extends SerializableRecipe { - private static HashMap> recipes = new HashMap(); + public static HashMap> recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/CrackingRecipes.java b/src/main/java/com/hbm/inventory/recipes/CrackingRecipes.java index 7bfe680ec..b66cf903d 100644 --- a/src/main/java/com/hbm/inventory/recipes/CrackingRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/CrackingRecipes.java @@ -36,7 +36,7 @@ public class CrackingRecipes extends SerializableRecipe { public static final int xyl_crack_aroma = 80; public static final int xyl_crack_petro = 20; - private static Map> cracking = new HashMap(); + public static Map> cracking = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/CrystallizerRecipes.java b/src/main/java/com/hbm/inventory/recipes/CrystallizerRecipes.java index 6d12d8124..e4b8907ba 100644 --- a/src/main/java/com/hbm/inventory/recipes/CrystallizerRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/CrystallizerRecipes.java @@ -235,6 +235,12 @@ public class CrystallizerRecipes extends SerializableRecipe { registerRecipe(P_WHITE.dust(), new CrystallizerRecipe(new ItemStack(ModItems.ingot_phosphorus), utilityTime), new FluidStack(Fluids.AROMATICS, 50)); } + /// COMPAT CINNABAR DUST /// + List dustCinnabar = OreDictionary.getOres(CINNABAR.dust()); + if(dustCinnabar != null && !dustCinnabar.isEmpty()) { + registerRecipe(CINNABAR.dust(), new CrystallizerRecipe(new ItemStack(ModItems.cinnebar), utilityTime), new FluidStack(Fluids.PEROXIDE, 50)); + } + if(!IMCCrystallizer.buffer.isEmpty()) { recipes.putAll(IMCCrystallizer.buffer); MainRegistry.logger.info("Fetched " + IMCCrystallizer.buffer.size() + " IMC crystallizer recipes!"); diff --git a/src/main/java/com/hbm/inventory/recipes/FractionRecipes.java b/src/main/java/com/hbm/inventory/recipes/FractionRecipes.java index 93e932ef3..dda69009f 100644 --- a/src/main/java/com/hbm/inventory/recipes/FractionRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/FractionRecipes.java @@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack; public class FractionRecipes extends SerializableRecipe { - private static Map> fractions = new HashMap(); + public static Map> fractions = new HashMap(); @Override public void registerDefaults() { @@ -40,8 +40,8 @@ public class FractionRecipes extends SerializableRecipe { fractions.put(Fluids.OIL_COKER, new Pair(new FluidStack(Fluids.CRACKOIL, 30), new FluidStack(Fluids.HEATINGOIL, 70))); fractions.put(Fluids.NAPHTHA_COKER, new Pair(new FluidStack(Fluids.NAPHTHA_CRACK, 75), new FluidStack(Fluids.LIGHTOIL_CRACK, 25))); fractions.put(Fluids.GAS_COKER, new Pair(new FluidStack(Fluids.AROMATICS, 25), new FluidStack(Fluids.CARBONDIOXIDE, 75))); - fractions.put(Fluids.CHLOROCALCITE_MIX, new Pair(new FluidStack(Fluids.CHLOROCALCITE_CLEANED, 50), new FluidStack(Fluids.COLLOID, 50))); - fractions.put(Fluids.BAUXITE_SOLUTION, new Pair(new FluidStack(Fluids.REDMUD, 50), new FluidStack(Fluids.SODIUM_ALUMINATE, 50))); + fractions.put(Fluids.CHLOROCALCITE_MIX, new Pair(new FluidStack(Fluids.CHLOROCALCITE_CLEANED, 50), new FluidStack(Fluids.COLLOID, 50))); + fractions.put(Fluids.BAUXITE_SOLUTION, new Pair(new FluidStack(Fluids.REDMUD, 50), new FluidStack(Fluids.SODIUM_ALUMINATE, 50))); } public static Pair getFractions(FluidType oil) { diff --git a/src/main/java/com/hbm/inventory/recipes/HadronRecipes.java b/src/main/java/com/hbm/inventory/recipes/HadronRecipes.java index 0d2c443e1..d2cccc339 100644 --- a/src/main/java/com/hbm/inventory/recipes/HadronRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/HadronRecipes.java @@ -14,7 +14,7 @@ import com.hbm.tileentity.machine.TileEntityHadron.EnumHadronState; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -public class HadronRecipes extends SerializableRecipe { +@Deprecated public class HadronRecipes extends SerializableRecipe { /* * Since we're dealing with like 10 or so recipes, using a HashMap (or to combine two keys, a HashMap *in* a HashMap) diff --git a/src/main/java/com/hbm/inventory/recipes/HydrotreatingRecipes.java b/src/main/java/com/hbm/inventory/recipes/HydrotreatingRecipes.java index 620d5b490..46f5b2e11 100644 --- a/src/main/java/com/hbm/inventory/recipes/HydrotreatingRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/HydrotreatingRecipes.java @@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack; public class HydrotreatingRecipes extends SerializableRecipe { - private static HashMap> recipes = new HashMap(); + public static HashMap> recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java b/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java index feb244d49..ed171ee75 100644 --- a/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/LiquefactionRecipes.java @@ -27,7 +27,7 @@ import net.minecraftforge.oredict.OreDictionary; public class LiquefactionRecipes extends SerializableRecipe { - private static HashMap recipes = new HashMap(); + public static HashMap recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/PyroOvenRecipes.java b/src/main/java/com/hbm/inventory/recipes/PyroOvenRecipes.java index 616adb05e..1cb68724a 100644 --- a/src/main/java/com/hbm/inventory/recipes/PyroOvenRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/PyroOvenRecipes.java @@ -124,7 +124,7 @@ public class PyroOvenRecipes extends SerializableRecipe { .out(new FluidStack(Fluids.HYDROGEN, 8_000)).out(new ItemStack(ModItems.ingot_graphite, 1))); } - private static void registerSFAuto(FluidType fluid) { + public static void registerSFAuto(FluidType fluid) { registerSFAuto(fluid, 1_440_000L, ModItems.solid_fuel); //3200 burntime * 1.5 burntime bonus * 300 TU/t } private static void registerSFAuto(FluidType fluid, long tuPerSF, Item fuel) { diff --git a/src/main/java/com/hbm/inventory/recipes/ReformingRecipes.java b/src/main/java/com/hbm/inventory/recipes/ReformingRecipes.java index ce8b44627..d728bb2de 100644 --- a/src/main/java/com/hbm/inventory/recipes/ReformingRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/ReformingRecipes.java @@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack; public class ReformingRecipes extends SerializableRecipe { - private static HashMap> recipes = new HashMap(); + public static HashMap> recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/SolidificationRecipes.java b/src/main/java/com/hbm/inventory/recipes/SolidificationRecipes.java index f3fc6a15d..4e7aed3ad 100644 --- a/src/main/java/com/hbm/inventory/recipes/SolidificationRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/SolidificationRecipes.java @@ -56,7 +56,7 @@ public class SolidificationRecipes extends SerializableRecipe { //aromatics can be idfk wax or soap or sth, perhaps artificial lubricant? //on that note, add more leaded variants - private static HashMap> recipes = new HashMap(); + public static HashMap> recipes = new HashMap(); @Override public void registerDefaults() { diff --git a/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java b/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java index 47b60d9e2..b30c58bee 100644 --- a/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/anvil/AnvilRecipes.java @@ -38,8 +38,8 @@ import net.minecraftforge.oredict.OreDictionary; public class AnvilRecipes extends SerializableRecipe { - private static List smithingRecipes = new ArrayList(); - private static List constructionRecipes = new ArrayList(); + public static List smithingRecipes = new ArrayList(); + public static List constructionRecipes = new ArrayList(); public static void register() { registerSmithing(); diff --git a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java index 02db7b389..753fb048f 100644 --- a/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java +++ b/src/main/java/com/hbm/inventory/recipes/loader/SerializableRecipe.java @@ -29,14 +29,16 @@ import com.hbm.items.ModItems; import com.hbm.main.MainRegistry; import com.hbm.util.Tuple.Pair; +import api.hbm.recipe.IRecipeRegisterListener; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; //the anti-spaghetti. this class provides so much functionality and saves so much time, i just love you, SerializableRecipe <3 -public abstract class SerializableRecipe { //TODO: #1969 +public abstract class SerializableRecipe { public static final Gson gson = new Gson(); public static List recipeHandlers = new ArrayList(); + public static List additionalListeners = new ArrayList(); public boolean modified = false; @@ -114,6 +116,10 @@ public abstract class SerializableRecipe { //TODO: #1969 MainRegistry.logger.info("No recipe file found, registering defaults for " + recipe.getFileName()); recipe.registerDefaults(); + for(IRecipeRegisterListener listener : additionalListeners) { + listener.onRecipeLoad(recipe.getClass().getSimpleName()); + } + File recTemplate = new File(recDir.getAbsolutePath() + File.separatorChar + "_" + recipe.getFileName()); MainRegistry.logger.info("Writing template file " + recTemplate.getName()); recipe.writeTemplateFile(recTemplate); diff --git a/src/main/java/com/hbm/util/CompatExternal.java b/src/main/java/com/hbm/util/CompatExternal.java index 2a7f1177c..4105a1482 100644 --- a/src/main/java/com/hbm/util/CompatExternal.java +++ b/src/main/java/com/hbm/util/CompatExternal.java @@ -10,11 +10,14 @@ import java.util.function.Consumer; import api.hbm.energymk2.IEnergyHandlerMK2; import api.hbm.energymk2.IEnergyReceiverMK2; import api.hbm.fluid.IFluidUser; +import api.hbm.recipe.IRecipeRegisterListener; + import com.hbm.blocks.BlockDummyable; import com.hbm.entity.missile.EntityMissileCustom; import com.hbm.explosion.ExplosionNukeSmall; import com.hbm.inventory.fluid.FluidType; import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.inventory.recipes.loader.SerializableRecipe; import com.hbm.items.weapon.ItemCustomMissilePart.WarheadType; import com.hbm.tileentity.machine.TileEntityDummy; import com.hbm.tileentity.turret.TileEntityTurretSentry; @@ -186,6 +189,15 @@ public class CompatExternal { public static void setWarheadLabel(WarheadType type, String label) { type.labelCustom = label; } public static void setWarheadImpact(WarheadType type, Consumer impact) { type.impactCustom = impact; } public static void setWarheadUpdate(WarheadType type, Consumer update) { type.updateCustom = update; } + + /** + * Registers an IRecipeRegisterListener to the recipe system. The listener is called every time a SerializableRecipe instance has its recipes loaded, before the + * config files are written, but after the defaults are initialized. + * @param listener + */ + public static void registerRecipeRegisterListener(IRecipeRegisterListener listener) { + SerializableRecipe.additionalListeners.add(listener); + } public static void compatExamples() { // Makes all cows be targeted by turrets if player mode is active in addition to the existing rules. Applies to all entities that inherit EntityCow. diff --git a/src/main/java/com/hbm/util/CompatRecipeRegistry.java b/src/main/java/com/hbm/util/CompatRecipeRegistry.java new file mode 100644 index 000000000..b4f27c3e4 --- /dev/null +++ b/src/main/java/com/hbm/util/CompatRecipeRegistry.java @@ -0,0 +1,264 @@ +package com.hbm.util; + +import java.util.Arrays; + +import com.hbm.interfaces.Untested; +import com.hbm.inventory.FluidStack; +import com.hbm.inventory.RecipesCommon.*; +import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.material.Mats.MaterialStack; +import com.hbm.inventory.recipes.*; +import com.hbm.inventory.recipes.AmmoPressRecipes.AmmoPressRecipe; +import com.hbm.inventory.recipes.ArcFurnaceRecipes.ArcFurnaceRecipe; +import com.hbm.inventory.recipes.ArcWelderRecipes.ArcWelderRecipe; +import com.hbm.inventory.recipes.BreederRecipes.BreederRecipe; +import com.hbm.inventory.recipes.CrucibleRecipes.CrucibleRecipe; +import com.hbm.inventory.recipes.CrystallizerRecipes.CrystallizerRecipe; +import com.hbm.inventory.recipes.ElectrolyserFluidRecipes.ElectrolysisRecipe; +import com.hbm.inventory.recipes.ElectrolyserMetalRecipes.ElectrolysisMetalRecipe; +import com.hbm.inventory.recipes.ExposureChamberRecipes.ExposureChamberRecipe; +import com.hbm.inventory.recipes.ParticleAcceleratorRecipes.ParticleAcceleratorRecipe; +import com.hbm.inventory.recipes.PedestalRecipes.PedestalExtraCondition; +import com.hbm.inventory.recipes.PedestalRecipes.PedestalRecipe; +import com.hbm.inventory.recipes.PyroOvenRecipes.PyroOvenRecipe; +import com.hbm.inventory.recipes.RotaryFurnaceRecipes.RotaryFurnaceRecipe; +import com.hbm.inventory.recipes.ChemplantRecipes.ChemRecipe; +import com.hbm.inventory.recipes.CompressorRecipes.CompressorRecipe; +import com.hbm.inventory.recipes.SolderingRecipes.SolderingRecipe; +import com.hbm.inventory.recipes.anvil.AnvilRecipes; +import com.hbm.inventory.recipes.anvil.AnvilRecipes.AnvilConstructionRecipe; +import com.hbm.inventory.recipes.anvil.AnvilRecipes.AnvilOutput; +import com.hbm.inventory.recipes.anvil.AnvilRecipes.OverlayType; +import com.hbm.items.machine.ItemStamp.StampType; +import com.hbm.util.Tuple.Pair; +import com.hbm.util.Tuple.Triplet; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +/** + * Public methods for registering recipes. Method signature should never change, only the body to reflect any changes to recipes/machines themselves. + * Recipe creation is either 1:1 with the original SerializableRecipe or even simpler (in the case of the compressor, two FluidStacks instead of a ton of loose numbers). + * Call these with a registered IRecipeRegisterListener, otherwise the recipe loading/reloading will break the custom recipes. + * @author hbm + */ +@Untested +public class CompatRecipeRegistry { + + public static void registerPress(StampType stamp, AStack input, ItemStack output) { + PressRecipes.recipes.put(new Pair(input, stamp), output); + } + + /** Same loose rules as BlastFurnaceRecipes, valid inputs are Items, Blocks, ItemStacks, ComparableStacks, Strings (for oredict) and DictFrames */ + public static void registerBlastFurnace(Object[] inputs, ItemStack output) { + if(inputs.length != 2) return; + BlastFurnaceRecipes.addRecipe(inputs[0], inputs[1], output); + } + + public static void registerShredder(AStack input, ItemStack output) { + for(ItemStack allItems : input.extractForNEI()) { + ComparableStack comp = new ComparableStack(allItems); + ShredderRecipes.shredderRecipes.put(comp, output); + } + } + + /** Items should strictly be categorized as pcb, topping or solder. An item that is used as a topping in one recipe should not be a pcb in another. + * This is because the soldering station's item IO will automatically place items based on this category, and having items in more than one category would break it. */ + public static void registerSoldering(ItemStack output, int time, long power, FluidStack fluid, AStack[] toppings, AStack[] pcb, AStack[] solder) { + SolderingRecipes.recipes.add(new SolderingRecipe(output, time, power, fluid, copyFirst(toppings, 3), copyFirst(pcb, 2), copyFirst(solder, 1))); + } + + /** Chemplant recipes need unique IDs, game will crash when an ID collision is detected! */ + public static void registerChemplant(int id, String name, int duration, AStack[] inputItems, FluidStack[] inputFluids, ItemStack[] outputItems, FluidStack[] outputFluids) { + ChemRecipe recipe = new ChemRecipe(id, name, duration); + if(inputItems != null) recipe.inputItems(copyFirst(inputItems, 4)); + if(inputFluids != null) recipe.inputFluids(copyFirst(inputFluids, 2)); + if(outputItems != null) recipe.outputItems(copyFirst(outputItems, 4)); + if(outputFluids != null) recipe.outputFluids(copyFirst(outputFluids, 2)); + ChemplantRecipes.recipes.add(recipe); + } + + /** Either solid or liquid output can be null */ + public static void registerCombination(AStack input, ItemStack output, FluidStack fluid) { + if(output == null && fluid == null) return; + Object o = input instanceof OreDictStack ? ((OreDictStack) input).name : input; + CombinationRecipes.recipes.put(o, new Pair(output, fluid)); + } + + /** Crucible recipes need unique IDs, game will crash when an ID collision is detected! */ + public static void registerCrucible(int index, String name, int frequency, ItemStack icon, MaterialStack[] input, MaterialStack[] output) { + CrucibleRecipe recipe = new CrucibleRecipe(index, name, frequency, icon).inputs(input).outputs(output); + CrucibleRecipes.recipes.add(recipe); + } + + public static void registerCentrifuge(AStack input, ItemStack[] outputs) { + CentrifugeRecipes.recipes.put(input, copyFirst(outputs, 4)); + } + + public static void registerCrystallizer(AStack input, ItemStack output, int time, float productivity, FluidStack fluid) { + CrystallizerRecipe recipe = new CrystallizerRecipe(output, time).prod(productivity); + CrystallizerRecipes.registerRecipe(input instanceof OreDictStack ? ((OreDictStack) input).name : input, recipe, fluid); + } + + /** Fractions always use 100mB of input fluid per operation. None of the outputs can be null. */ + public static void registerFraction(FluidType input, FluidStack[] output) { + if(output.length != 2) return; + FractionRecipes.fractions.put(input, new Pair(output[0], output[1])); + } + + /** Cracking always uses 100mB of input fluid and 200mB of steam per operation. None of the outputs can be null. */ + public static void registerCracking(FluidType input, FluidStack[] output) { + if(output.length != 2) return; + CrackingRecipes.cracking.put(input, new Pair(output[0], output[1])); + } + + /** Reforming always uses 100mB of input fluid per operation. None of the outputs can be null. */ + public static void registerReforming(FluidType input, FluidStack[] output) { + output = copyFirst(output, 3); + if(output.length < 3) return; + ReformingRecipes.recipes.put(input, new Triplet(output[0], output[1], output[2])); + } + + /** Hydrotreating always uses 100mB of input fluid per operation. None of the outputs can be null. */ + public static void registerHydrotreating(FluidType input, FluidStack hydrogen, FluidStack[] output) { + output = copyFirst(output, 2); + if(output.length < 2) return; + HydrotreatingRecipes.recipes.put(input, new Triplet(hydrogen, output[0], output[1])); + } + + public static void registerLiquefaction(AStack input, FluidStack output) { + LiquefactionRecipes.recipes.put(input instanceof OreDictStack ? ((OreDictStack) input).name : input, output); + } + + public static void registerSolidifying(FluidStack input, ItemStack output) { + SolidificationRecipes.recipes.put(input.type, new Pair(input.fill, output)); + } + + public static void registerCoker(FluidStack input, ItemStack output, FluidStack fluid) { + CokerRecipes.recipes.put(input.type, new Triplet(input.fill, output, fluid)); + } + + /** Registers a coker recipe based on the standardized fluid to coke values */ + public static void registerCokerAuto(FluidType input, FluidType output) { + CokerRecipes.registerAuto(input, output); + } + + public static void registerPyro(FluidStack inputFluid, AStack inputItem, FluidStack outputFluid, ItemStack outputItem, int duration) { + PyroOvenRecipes.recipes.add(new PyroOvenRecipe(duration).in(inputFluid).in(inputItem).out(outputFluid).out(outputItem)); + } + + /** Registers a pyro oven recipe based on the standardized fluid to solid fuel values */ + public static void registerPyroAuto(FluidType input) { + PyroOvenRecipes.registerSFAuto(input); + } + + /** Breeding reactor does not handle OreDictStacks */ + public static void registerBreeder(ComparableStack input, ItemStack output, int flux) { + BreederRecipes.recipes.put(input, new BreederRecipe(output, flux)); + } + + public static void registerCyclotron(ComparableStack box, AStack target, ItemStack output, int antimatter) { + CyclotronRecipes.recipes.put(new Pair(box, target), new Pair(output, antimatter)); + } + + /** Fuel pools do not handle OreDictStacks */ + public static void registerFuelPool(ComparableStack input, ItemStack output) { + FuelPoolRecipes.recipes.put(input, output); + } + + //TBI mixer + + public static void registerOutgasser(AStack input, ItemStack output, FluidStack fluid) { + OutgasserRecipes.recipes.put(input, new Pair(output, fluid)); + } + + public static void registerCompressor(FluidStack input, FluidStack output, int time) { + CompressorRecipes.recipes.put(new Pair(input.type, input.pressure), new CompressorRecipe(input.fill, output, time)); + } + + /** Byproduct array can be null, fluid output length must be 2 */ + public static void registerElectrolyzerFluid(FluidStack input, FluidStack[] output, ItemStack[] byproduct, int time) { + output = copyFirst(output, 2); + if(output.length < 2) return; + if(byproduct != null) byproduct = copyFirst(byproduct, 3); + + ElectrolyserFluidRecipes.recipes.put(input.type, new ElectrolysisRecipe(input.fill, output[0], output[1], time, byproduct)); + } + + /** Output array length must be 2, outputs can be null. Byproduct array can be null. */ + public static void registerElectrolyzerMetal(AStack input, MaterialStack[] output, ItemStack[] byproduct, int time) { + output = copyFirst(output, 2); + if(byproduct != null) byproduct = copyFirst(byproduct, 6); + + ElectrolyserMetalRecipes.recipes.put(input, new ElectrolysisMetalRecipe(output[0], output[1], time, byproduct)); + } + + public static void registerArcWelder(ItemStack output, int time, long power, FluidStack fluid, AStack[] inputs) { + ArcWelderRecipes.recipes.add(new ArcWelderRecipe(output, time, power, fluid, copyFirst(inputs, 3))); + } + + public static void registerRotaryFurnace(MaterialStack output, int time, int steam, FluidStack fluid, AStack[] inputs) { + RotaryFurnaceRecipes.recipes.add(new RotaryFurnaceRecipe(output, time, steam, fluid, copyFirst(inputs, 3))); + } + + /** Particles will always perform 8 recipes */ + public static void registerExposureChamber(AStack particle, AStack input, ItemStack output) { + ExposureChamberRecipes.recipes.add(new ExposureChamberRecipe(particle, input, output)); + } + + /** Input needs two AStacks, output can take 1-2 ItemStacks. If the same recipe with different + * momentum should yield different results, register the lower momentum recipes first. */ + public static void registerParticleAccelerator(AStack[] input, int momentum, ItemStack[] output) { + input = copyFirst(input, 2); + if(input.length < 2) return; + output = copyFirst(output, 2); + if(output.length < 1) return; + ParticleAcceleratorRecipes.recipes.add(new ParticleAcceleratorRecipe(input[0], input[1], momentum, output[0], output.length > 1 ? output[1] : null)); + } + + public static void registerAmmoPress(ItemStack output, AStack[] input) { + if(input.length != 9) return; + AmmoPressRecipes.recipes.add(new AmmoPressRecipe(output, input)); + } + + public static void registerAssembler(ItemStack output, AStack[] input, int time) { + AssemblerRecipes.makeRecipe(new ComparableStack(output), copyFirst(input, 12), time); + } + + /** Registers an assembler recipe but with the template only being obtainable via the specified folders */ + public static void registerAssembler(ItemStack output, AStack[] input, int time, Item... folder) { + AssemblerRecipes.makeRecipe(new ComparableStack(output), copyFirst(input, 12), time, folder); + } + + public static void registerAnvilConstruction(AStack[] input, AnvilOutput[] output, int tier, int overlayIndex) { + AnvilRecipes.constructionRecipes.add(new AnvilConstructionRecipe(input, output).setTier(tier).setOverlay(EnumUtil.grabEnumSafely(OverlayType.class, overlayIndex))); + } + + public static void registerAnvilConstruction(AStack[] input, AnvilOutput[] output, int tierLower, int tierUpper, int overlayIndex) { + AnvilRecipes.constructionRecipes.add(new AnvilConstructionRecipe(input, output).setTierRange(tierLower, tierUpper).setOverlay(EnumUtil.grabEnumSafely(OverlayType.class, overlayIndex))); + } + + public static void registerPedestal(ItemStack output, AStack[] input) { + registerPedestal(output, input, 0); + } + + public static void registerPedestal(ItemStack output, AStack[] input, int condition) { + input = copyFirst(input, 9); + if(input.length < 9) return; + PedestalRecipes.recipes.add(new PedestalRecipe(output, input).extra(EnumUtil.grabEnumSafely(PedestalExtraCondition.class, condition))); + } + + /** Either output or fluid can be null */ + public static void registerArcFurnace(AStack input, ItemStack output, MaterialStack fluid) { + if(output == null && fluid == null) return; + ArcFurnaceRecipes.recipeList.add(new Pair(input, new ArcFurnaceRecipe().solid(output).fluid(fluid))); + } + + ///////////////////////////////////////////////////////////////////////////////////////// + + /** If the supplied array exceeds the specified length, creates a copy and trunkates the array. Otherwise, returns the original array */ + private static T[] copyFirst(T[] array, int amount) { + if(array.length <= amount) return array; + return Arrays.copyOf(array, amount); + } +}