233 lines
7 KiB
Java
233 lines
7 KiB
Java
package resonantinduction.mechanical.fluid.network;
|
|
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraftforge.fluids.Fluid;
|
|
import net.minecraftforge.fluids.FluidStack;
|
|
|
|
import com.builtbroken.common.Pair;
|
|
import com.builtbroken.common.Triple;
|
|
|
|
/**
|
|
* Used to store more complex info, than A + B = C, on two FluidStack mixing behavior
|
|
*
|
|
* @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
|
|
{
|
|
/** 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
|
|
{
|
|
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 */
|
|
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
|
|
* work
|
|
*
|
|
* @param receiving - receiving object that is waiting to be mixed
|
|
* @param input - object being added to the receiving object
|
|
* @param output - result of mixing the object together. Can be anything but not all
|
|
* machines using this will respect all output types
|
|
*/
|
|
public SimpleFluidRecipe(Object receiving, Object input, Object output)
|
|
{
|
|
this.recipeObjectA = receiving;
|
|
this.recipeObjectB = input;
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Can the mixing be complete in anyway. Does a basic volume check but does not check for
|
|
* volume wasted in mixing
|
|
*
|
|
* @param receiving - Object stored and waiting for mixing
|
|
* @param input - Object being added to the receiving object
|
|
* @return true if the process can be completed
|
|
*/
|
|
public boolean canComplete(Object receiving, Object input)
|
|
{
|
|
int countReceiving = 0;
|
|
int countInput = 0;
|
|
float percent = 0;
|
|
if (receiving != null && input != null && recipeObjectA.equals(receiving) && recipeObjectB.equals(input))
|
|
{
|
|
countReceiving = this.getObjectVolume(receiving);
|
|
countInput = this.getObjectVolume(input);
|
|
if (countReceiving > 0 && countInput > 0)
|
|
{
|
|
float per = countInput / countReceiving;
|
|
float per2 = countReceiving / countInput;
|
|
percent = per > per2 ? per2 : per;
|
|
if (percent >= this.mixingPercentMin)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public int getObjectVolume(Object object)
|
|
{
|
|
int volume = 0;
|
|
if (object instanceof Item)
|
|
{
|
|
volume = 1;
|
|
}
|
|
else if (object instanceof ItemStack)
|
|
{
|
|
volume = ((ItemStack) object).stackSize;
|
|
}
|
|
else if (object instanceof FluidStack)
|
|
{
|
|
volume = ((FluidStack) object).amount;
|
|
}
|
|
else if (object instanceof Fluid)
|
|
{
|
|
volume = 1;
|
|
}
|
|
|
|
return volume;
|
|
}
|
|
|
|
/**
|
|
* @param receiving - Object receiving an input object for mixing
|
|
* @param input - Object being added to the receiving object
|
|
* @return Triple containing values of mixing. Complex way to handle it, and may be replaced
|
|
* later, However to prevent 4 different methods be created for mixing this is the best
|
|
* output design. As well this doesn't consume the object but does the calculations of the
|
|
* recipe out at the given object volumes
|
|
*
|
|
* First value is amount of the first object used. Second value is the amount of the second
|
|
* object used. Third value Pair containing object output then amount of output
|
|
*/
|
|
public Triple<Integer, Integer, Pair<Object, Integer>> mix(Object receiving, Object input)
|
|
{
|
|
if (this.canComplete(receiving, input))
|
|
{
|
|
// Collect volume of each input object
|
|
int volumeReceiving = this.getObjectVolume(receiving);
|
|
int volumeInput = this.getObjectVolume(input);
|
|
int volAUsed, volBUsed;
|
|
|
|
// check if there is enough to mix even once
|
|
if (volumeReceiving > this.ratioOfA && volumeInput > this.ratioOfB)
|
|
{
|
|
// Collect ratio of each
|
|
int ratioA = (volumeReceiving / this.ratioOfA);
|
|
int ratioB = (volumeInput / this.ratioOfB);
|
|
|
|
// Take the least ratio value and multiply it by the ratio of the output
|
|
int outputVolume = ratioA > ratioB ? ratioB * this.ratioOfC : ratioA * this.ratioOfC;
|
|
|
|
volAUsed = (outputVolume / this.ratioOfC) * this.ratioOfA;
|
|
volBUsed = (outputVolume / this.ratioOfC) * this.ratioOfB;
|
|
return new Triple<Integer, Integer, Pair<Object, Integer>>(volAUsed, volBUsed, new Pair<Object, Integer>(this.recipeObjectC, outputVolume));
|
|
}
|
|
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
{
|
|
public int numberOfSteps;
|
|
public SimpleFluidRecipe[] stepArray;
|
|
|
|
public ComplexFluidRecipe(int numberOfSteps)
|
|
{
|
|
this.numberOfSteps = numberOfSteps;
|
|
this.stepArray = new SimpleFluidRecipe[this.numberOfSteps];
|
|
}
|
|
|
|
public ComplexFluidRecipe createStep(int step, SimpleFluidRecipe stepRecipe)
|
|
{
|
|
if (step < numberOfSteps)
|
|
{
|
|
stepArray[step] = stepRecipe;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public boolean canCompleteStep(int step, Object receiving, Object input)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|