From c39cdc15a1419fa285f3a7a8bcfe6f1e2168fb20 Mon Sep 17 00:00:00 2001 From: DarkGuardsman Date: Fri, 13 Sep 2013 01:10:13 -0400 Subject: [PATCH] More work on Fluid crafting system --- .../network/fluid/FluidCraftingHandler.java | 197 ++++++++++++++++++ .../network/fluid/FluidNetworkHelper.java | 154 -------------- .../core/network/fluid/FluidRecipeInfo.java | 71 +++++-- 3 files changed, 256 insertions(+), 166 deletions(-) diff --git a/src/dark/core/network/fluid/FluidCraftingHandler.java b/src/dark/core/network/fluid/FluidCraftingHandler.java index afe9b76d5..130e75c04 100644 --- a/src/dark/core/network/fluid/FluidCraftingHandler.java +++ b/src/dark/core/network/fluid/FluidCraftingHandler.java @@ -1,14 +1,211 @@ package dark.core.network.fluid; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; +import dark.core.network.fluid.FluidRecipeInfo.SimpleFluidRecipe; +import dark.core.prefab.helpers.FluidHelper; +import dark.core.prefab.helpers.Pair; +import dark.core.prefab.helpers.Triple; + /** Handles all kinds of process involving mixing Fluids with other fluids and/or Items, Blocks, * ItemStack, or Liquids * * @author DarkGuardsman */ public class FluidCraftingHandler { + /** Map of results of two different liquids merging */ + public static HashMap, Object> fluidMergeResults = new HashMap, Object>(); + + static + { + registerRecipe(FluidRegistry.LAVA, FluidRegistry.WATER, Block.obsidian); + registerRecipe(FluidRegistry.WATER, FluidRegistry.LAVA, Block.cobblestone); + } + + public static void registerRecipe(Object a, Object b, Object c) + { + if (a != null && b != null && c != null) + { + registerFluidRecipe(new SimpleFluidRecipe(a, b, c)); + } + } + + public static void registerFluidRecipe(SimpleFluidRecipe recipe) + { + if (recipe != null && recipe.recipeObjectA != null && recipe.recipeObjectB != null && recipe.recipeObjectC != null) + { + if (!fluidMergeResults.containsKey(new Pair(recipe.recipeObjectA, recipe.recipeObjectB))) + { + fluidMergeResults.put(new Pair(recipe.recipeObjectA, recipe.recipeObjectB), recipe); + } + if (recipe.canBeReversed) + { + if (!fluidMergeResults.containsKey(new Pair(recipe.recipeObjectB, recipe.recipeObjectA))) + { + fluidMergeResults.put(new Pair(recipe.recipeObjectB, recipe.recipeObjectA), recipe); + } + } + } + } public static void loadPotionRecipes() { //TODO load the process by which a potion would be created threw fliud crafting } + + /** Merges two fluids together that don't result in damage to the network */ + public static FluidStack mergeFluidStacks(FluidStack stackOne, FluidStack stackTwo) + { + FluidStack resultStack = null; + + if (stackTwo != null && stackOne != null && stackOne.isFluidEqual(stackTwo)) + { + resultStack = stackOne.copy(); + resultStack.amount += stackTwo.amount; + } + else if (stackOne == null && stackTwo != null) + { + resultStack = stackTwo.copy(); + } + else if (stackOne != null && stackTwo == null) + { + resultStack = stackOne.copy(); + } + else if (stackTwo != null && stackOne != null && !stackOne.isFluidEqual(stackTwo)) + { + Object result = fluidMergeResults.get(new Pair(stackOne.getFluid(), stackTwo.getFluid())); + /* Try to merge fluids by mod defined rules first */ + if (result != null) + { + if (result instanceof Fluid) + { + resultStack = new FluidStack(((Fluid) result).getID(), stackOne.amount + stackTwo.amount); + } + else if (result instanceof FluidStack) + { + resultStack = ((FluidStack) result).copy(); + resultStack.amount = stackOne.amount + stackTwo.amount; + } + else if (result instanceof String && ((String) result).startsWith("Liquid:")) + { + resultStack = new FluidStack(FluidRegistry.getFluid(((String) result).replace("Liquid:", "")), stackOne.amount + stackTwo.amount); + } + else if (result instanceof SimpleFluidRecipe) + { + Triple> re = ((SimpleFluidRecipe) result).mix(stackOne, stackTwo); + if (re.getC().getKey() instanceof FluidStack) + { + resultStack = FluidHelper.getStack((FluidStack) re.getC().getKey(), re.getC().getValue()); + } + else if (re.getC().getKey() instanceof FluidStack) + { + resultStack = new FluidStack((Fluid) re.getC().getKey(), re.getC().getValue()); + } + } + } + if (resultStack == null) + { + Fluid waste = FluidRegistry.getFluid("waste"); + if (waste == null) + { + System.out.println("[FluidNetworkHelper] Attempted to merge two fluids into a waste fluid stack but Forge fluid registry return null for waste. Possible that waste fluid was disabled or not registered correctly."); + return null; + } + /* If both liquids are waste then copy fluidStack lists then merge */ + if (stackTwo.fluidID == waste.getID() && stackOne.fluidID == waste.getID()) + { + List stacks = new ArrayList(); + stacks.addAll(getStacksFromWaste(stackOne.copy())); + stacks.addAll(getStacksFromWaste(stackTwo.copy())); + resultStack = createNewWasteStack(stacks.toArray(new FluidStack[stacks.size()])); + } + else + { + resultStack = createNewWasteStack(stackOne.copy(), stackTwo.copy()); + } + } + } + return resultStack; + } + + /** Gets the fluidStacks that make up a waste FluidStack */ + public static List getStacksFromWaste(FluidStack wasteStack) + { + List stacks = new ArrayList(); + if (wasteStack.fluidID == FluidRegistry.getFluidID("waste")) + { + for (int i = 1; i <= wasteStack.tag.getInteger("liquids"); i++) + { + FluidStack readStack = FluidStack.loadFluidStackFromNBT(wasteStack.tag.getCompoundTag("Liquid" + i)); + if (readStack != null) + { + stacks.add(readStack); + } + } + } + return stacks; + } + + /** Creates a new waste stack from the listed fluidStacks */ + public static FluidStack createNewWasteStack(FluidStack... liquids) + { + FluidStack stack = new FluidStack(FluidRegistry.getFluid("waste"), 0); + stack.tag = new NBTTagCompound(); + if (liquids != null) + { + int count = 0; + for (int i = 0; i < liquids.length; i++) + { + if (liquids[i] != null) + { + if (!liquids[i].getFluid().equals(stack.getFluid())) + { + count++; + stack.tag.setCompoundTag("Liquids" + count, liquids[i].writeToNBT(new NBTTagCompound())); + stack.amount += liquids[i].amount; + } + else + { + for (FluidStack loadStack : getStacksFromWaste(liquids[i])) + { + count++; + stack.tag.setCompoundTag("Liquids" + count, loadStack.writeToNBT(new NBTTagCompound())); + stack.amount += loadStack.amount; + } + } + } + } + stack.tag.setInteger("liquids", count); + } + return stack; + } + + /** Gets the result of the merge of the two fluids, order of merge does matter and will produce + * different results. + * + * @param stackOne - Receiving fluid, eg the one that is not moving + * @param stackTwo - Flowing fluid, eg the one moving into the first fluid + * @return Object result of the merge, can be anything from string, ItemStack, Item, Block, or + * enum action */ + public static Object getMergeResult(FluidStack stackOne, FluidStack stackTwo) + { + FluidStack sampleStackOne, sampleStackTwo; + if (stackOne != null && stackTwo != null && !stackOne.equals(stackTwo)) + { + sampleStackOne = FluidHelper.getStack(stackOne, 1); + sampleStackTwo = FluidHelper.getStack(stackTwo, 1); + if (fluidMergeResults.containsKey(new Pair(sampleStackOne, sampleStackTwo))) + { + return fluidMergeResults.get(new Pair(sampleStackOne, sampleStackTwo)); + } + } + return null; + } } diff --git a/src/dark/core/network/fluid/FluidNetworkHelper.java b/src/dark/core/network/fluid/FluidNetworkHelper.java index 354890d78..121cf7df9 100644 --- a/src/dark/core/network/fluid/FluidNetworkHelper.java +++ b/src/dark/core/network/fluid/FluidNetworkHelper.java @@ -1,32 +1,14 @@ package dark.core.network.fluid; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import net.minecraft.block.Block; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.ForgeDirection; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; import universalelectricity.core.vector.Vector3; import universalelectricity.core.vector.VectorHelper; import dark.api.parts.INetworkPart; -import dark.core.prefab.helpers.Pair; import dark.core.prefab.tilenetwork.NetworkTileEntities; public class FluidNetworkHelper { - /** Map of results of two different liquids merging */ - public static HashMap, Object> fluidMergeResults = new HashMap, Object>(); - - static - { - fluidMergeResults.put(new Pair(FluidRegistry.WATER, FluidRegistry.LAVA), Block.obsidian); - fluidMergeResults.put(new Pair(FluidRegistry.LAVA, FluidRegistry.WATER), Block.cobblestone); - } /** Invalidates a TileEntity that is part of a fluid network */ public static void invalidate(TileEntity tileEntity) @@ -48,140 +30,4 @@ public class FluidNetworkHelper } } - /** Merges two fluids together that don't result in damage to the network */ - public static FluidStack mergeFluidStacks(FluidStack stackOne, FluidStack stackTwo) - { - FluidStack resultStack = null; - - if (stackTwo != null && stackOne != null && stackOne.isFluidEqual(stackTwo)) - { - resultStack = stackOne.copy(); - resultStack.amount += stackTwo.amount; - } - else if (stackOne == null && stackTwo != null) - { - resultStack = stackTwo.copy(); - } - else if (stackOne != null && stackTwo == null) - { - resultStack = stackOne.copy(); - } - else if (stackTwo != null && stackOne != null && !stackOne.isFluidEqual(stackTwo)) - { - /* Try to merge fluids by mod defined rules first */ - if (fluidMergeResults.containsKey(new Pair(stackOne.getFluid(), stackTwo.getFluid()))) - { - Object result = fluidMergeResults.get(new Pair(stackOne.getFluid(), stackTwo.getFluid())); - if (result instanceof Fluid) - { - resultStack = new FluidStack(((Fluid) result).getID(), stackOne.amount + stackTwo.amount); - } - else if (result instanceof FluidStack) - { - resultStack = ((FluidStack) result).copy(); - resultStack.amount = stackOne.amount + stackTwo.amount; - } - else if (result instanceof String && ((String) result).startsWith("Liquid:")) - { - resultStack = new FluidStack(FluidRegistry.getFluid(((String) result).replace("Liquid:", "")), stackOne.amount + stackTwo.amount); - } - } - if (resultStack == null) - { - Fluid waste = FluidRegistry.getFluid("waste"); - if (waste == null) - { - System.out.println("[FluidNetworkHelper] Attempted to merge two fluids into a waste fluid stack but Forge fluid registry return null for waste. Possible that waste fluid was disabled or not registered correctly."); - return null; - } - /* If both liquids are waste then copy fluidStack lists then merge */ - if (stackTwo.fluidID == waste.getID() && stackOne.fluidID == waste.getID()) - { - List stacks = new ArrayList(); - stacks.addAll(getStacksFromWaste(stackOne.copy())); - stacks.addAll(getStacksFromWaste(stackTwo.copy())); - resultStack = createNewWasteStack(stacks.toArray(new FluidStack[stacks.size()])); - } - else - { - resultStack = createNewWasteStack(stackOne.copy(), stackTwo.copy()); - } - } - } - return resultStack; - } - - /** Gets the fluidStacks that make up a waste FluidStack */ - public static List getStacksFromWaste(FluidStack wasteStack) - { - List stacks = new ArrayList(); - if (wasteStack.fluidID == FluidRegistry.getFluidID("waste")) - { - for (int i = 1; i <= wasteStack.tag.getInteger("liquids"); i++) - { - FluidStack readStack = FluidStack.loadFluidStackFromNBT(wasteStack.tag.getCompoundTag("Liquid" + i)); - if (readStack != null) - { - stacks.add(readStack); - } - } - } - return stacks; - } - - /** Creates a new waste stack from the listed fluidStacks */ - public static FluidStack createNewWasteStack(FluidStack... liquids) - { - FluidStack stack = new FluidStack(FluidRegistry.getFluid("waste"), 0); - stack.tag = new NBTTagCompound(); - if (liquids != null) - { - int count = 0; - for (int i = 0; i < liquids.length; i++) - { - if (liquids[i] != null) - { - if (!liquids[i].getFluid().equals(stack.getFluid())) - { - count++; - stack.tag.setCompoundTag("Liquids" + count, liquids[i].writeToNBT(new NBTTagCompound())); - stack.amount += liquids[i].amount; - } - else - { - for (FluidStack loadStack : getStacksFromWaste(liquids[i])) - { - count++; - stack.tag.setCompoundTag("Liquids" + count, loadStack.writeToNBT(new NBTTagCompound())); - stack.amount += loadStack.amount; - } - } - } - } - stack.tag.setInteger("liquids", count); - } - return stack; - } - - /** Gets the result of the merge of the two fluids, order of merge does matter and will produce - * diffrent results. - * - * @param stackOne - Receiving fluid, eg the one that is not moving - * @param stackTwo - Flowing fluid, eg the one moving into the first fluid - * @return Object result of the merge, can be anything from string, ItemStack, Item, Block, or - * enum action */ - public static Object getMergeResult(FluidStack stackOne, FluidStack stackTwo) - { - if (stackOne != null && stackTwo != null && !stackOne.equals(stackTwo)) - { - if (fluidMergeResults.containsKey(new Pair(stackOne.getFluid(), stackTwo.getFluid()))) - { - //TODO add volume calculation too see if merge can happen resulting in one liquid just vanishing - //Case 100mb of fuel 10000mb of lava will result in fuel being consumed with no major results - return fluidMergeResults.get(new Pair(stackOne.getFluid(), stackTwo.getFluid())); - } - } - return null; - } - } diff --git a/src/dark/core/network/fluid/FluidRecipeInfo.java b/src/dark/core/network/fluid/FluidRecipeInfo.java index 02b4020bf..8a1520e11 100644 --- a/src/dark/core/network/fluid/FluidRecipeInfo.java +++ b/src/dark/core/network/fluid/FluidRecipeInfo.java @@ -12,20 +12,43 @@ import dark.core.prefab.helpers.Triple; * @author DarkGuardsman */ public class FluidRecipeInfo { + /** A + Energy = C, simple recipe designed to tell a boiler like machine how to handle input to + * output process */ public static class BoilingFluidRecipe { - Object boiledObject; - Object boiledResult; + /** Unboiled object */ + public Object boiledObject; + /** Boiled object */ + public Object boiledResult; + /** In kelvin tempature units only */ + public float heatLevel = 0; + /** Energy in jouls need to turn convert A to B */ + public float energyPerMb = 1; + + public BoilingFluidRecipe(Object unboiled, Object boiled, float boilingTempature, float energyPerUnitBoiled) + { + this.boiledObject = unboiled; + this.boiledResult = boiled; + this.heatLevel = boilingTempature; + this.energyPerMb = energyPerUnitBoiled; + } + + @Override + public String toString() + { + return "[BoilingFluidRecipe] UnboiledObject: " + (this.boiledObject != null ? this.boiledObject.toString() : "null") + " | BoiledObject: " + (this.boiledResult != null ? this.boiledResult.toString() : "null") + " | BoilingTemp: " + this.heatLevel + "k | EnergyPerUnit: " + this.energyPerMb + "j"; + } } /** Basic A + B = C recipe result that should involve fluids but can be used as a 2 item crafting * system if needed */ public static class SimpleFluidRecipe { - Object recipeObjectA, recipeObjectB, recipeObjectC; - int ratioOfA = 1, ratioOfB = 1, ratioOfC = 1; + public Object recipeObjectA, recipeObjectB, recipeObjectC; + public int ratioOfA = 1, ratioOfB = 1, ratioOfC = 1; /** Size compared to the largest volume that the smallest volume can be */ - float mixingPercentMin = .1f; + public float mixingPercentMin = .1f; + public boolean canBeReversed = false; /** receiving & input object must be either be an instance of a class extending Item, * ItemStack, Block, Fluid, FluidStack, or OreNames. Anything else and the mixing will never @@ -42,6 +65,20 @@ public class FluidRecipeInfo this.recipeObjectC = output; } + public SimpleFluidRecipe setRatio(int receivingVolume, int inputVolume, int result) + { + this.ratioOfA = receivingVolume; + this.ratioOfB = inputVolume; + this.ratioOfC = result; + return this; + } + + public SimpleFluidRecipe setIsReversable(boolean canBeReversed) + { + this.canBeReversed = canBeReversed; + return this; + } + public Object getResult() { return this.recipeObjectC; @@ -137,12 +174,13 @@ public class FluidRecipeInfo } } - /** Stores the list of process need to complete a long step process of creating a complex fluid - * based mixing recipe */ + /** Stores the list of processes needed to complete a fluid recipe that require more than one + * step to complete. Only used by brewing factories, and is suggest too still register result as + * a SimpleFluidRecipe unless the result can't be stored or moved easily. */ public static class ComplexFluidRecipe { - int numberOfSteps; - SimpleFluidRecipe[] stepArray; + public int numberOfSteps; + public SimpleFluidRecipe[] stepArray; public ComplexFluidRecipe(int numberOfSteps) { @@ -154,18 +192,27 @@ public class FluidRecipeInfo { if (step < numberOfSteps) { - + stepArray[step] = stepRecipe; } return this; } public boolean canCompleteStep(int step, Object receiving, Object input) { - if (step < numberOfSteps) + if (this.getStep(step) != null) { - + return this.getStep(step).canComplete(receiving, input); } return false; } + + public SimpleFluidRecipe getStep(int step) + { + if (step < numberOfSteps) + { + return stepArray[step]; + } + return null; + } } }