using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework; namespace Revitalize.Framework.Managers { /// /// A Fluid used for various mod purposes. /// public class Fluid { /// /// The name of the Fluid. /// public string name; /// /// The color for the Fluid. /// public Color color; /// /// Constructor. /// public Fluid() { } /// /// Constructor. /// /// /// public Fluid(string Name, Color FluidColor) { this.name = Name; this.color = FluidColor; } /// /// Fluid comparison check to see if two Fluids are the same. /// /// /// public bool isFluidHomogenous(Fluid Other) { if (this.name.Equals(Other.name)) return true; return false; } /// /// Copys over the Fluid. /// /// public Fluid Copy() { return new Fluid(this.name, this.color); } } public class MachineFluidTank { /// /// The Fluid inside of the tank. /// public Fluid fluid; /// /// How much Fluid is inside the tank currently. /// public int amount; /// /// How much Fluid the tank can hold. /// public int capacity; /// /// The remaining capacity on the tank. /// public int remainingCapacity { get { return this.capacity - this.amount; } } /// /// Checks to see if this tank is full. /// public bool IsFull { get { return this.amount == this.capacity; } } /// /// Checks if there is fluid inside the tank. /// public bool IsEmpty { get { return this.amount == 0; } } public string getFluidDisplayString() { StringBuilder b = new StringBuilder(); if (this.fluid != null) { b.Append(this.fluid.name); b.Append(": "); } b.Append(this.amount); b.Append("/"); b.Append(this.capacity); return b.ToString(); } /// /// Constructor. /// public MachineFluidTank() { } /// /// Constructor. /// /// public MachineFluidTank(int Capacity) { this.capacity = Capacity; this.amount = 0; this.fluid = null; } /// /// Constructor. /// /// /// /// public MachineFluidTank(int Capacity, int Amount, Fluid Fluid) { this.capacity = Capacity; this.amount = Amount; this.fluid = Fluid; } /// /// Checks to see if this tank can recieve this Fluid. /// /// /// public bool CanRecieveThisFluid(Fluid L) { if (this.IsFull) return false; if (this.fluid == null) return true; if (this.fluid.isFluidHomogenous(L)) return true; if (this.IsEmpty) return true; else return false; } /// /// Takes in Fluid into this tank. /// /// /// public void intakeFluid(Fluid L, int Amount) { if (this.CanRecieveThisFluid(L)) { if (this.fluid == null) this.fluid = L.Copy(); int intakeAmount = Math.Min(this.remainingCapacity, Amount); this.amount = this.amount + intakeAmount; } else return; } /// /// Consumes, aka reduces the internal Fluid on this tank by the amount given or the amount remaining in the tank. /// /// public void consumeFluid(int Amount) { if (this.IsEmpty) return; if (this.fluid == null) return; int consumeAmount = Math.Min(this.amount, Amount); this.amount = this.amount - consumeAmount; if (this.amount <= 0) this.fluid = null; } /// /// Checks to see if this tank has enough /// /// /// /// public bool DoesThisTankHaveEnoughFluid(Fluid L, int Amount) { if (this.GetAmountOfFluidInThisTank(L) >= Amount) return true; return false; } /// /// Drains the tank completly /// public void emptyTank() { this.fluid = null; this.amount = 0; } /// /// Gets the amount of Fluid in this tank for the given Fluid. /// /// /// Returns 0 if the tank doesn't contain Fluid of the same type. Otherwise returns the amount stored in the tank. public int GetAmountOfFluidInThisTank(Fluid L) { if (this.fluid == null) return 0; if (this.fluid.isFluidHomogenous(L)) return this.amount; return 0; } /// /// Gets the amount of Fluid this take can take in in acordance with the parameter Fluid. /// /// /// public int GetAmountOfFluidThisTankCanReceieve(Fluid L) { if (this.fluid == null) return this.capacity; if (this.fluid.isFluidHomogenous(L)) return this.remainingCapacity; return 0; } /// /// Checks to see if this tank contains this Fluid at all. /// /// /// public bool DoesTankContainThisFluid(Fluid L) { if (this.fluid == null) return false; if (this.fluid.isFluidHomogenous(L)) return true; return false; } } public class FluidManagerV2 { public MachineFluidTank inputTank1; public MachineFluidTank inputTank2; public MachineFluidTank outputTank; public bool requiresUpdate; /// /// Does this machine allow the same fluid in both tanks? /// public bool allowDoubleInput; public bool onlyOutput; /// /// The capacity for the fluid tanks. /// public int tankCapacity; public Enums.FluidInteractionType fluidInteractionType; public bool InteractsWithFluids { get { return this.fluidInteractionType != Enums.FluidInteractionType.None; } } public FluidManagerV2() { this.inputTank1 = new MachineFluidTank(0); this.inputTank2 = new MachineFluidTank(0); this.outputTank = new MachineFluidTank(0); this.requiresUpdate = false; this.fluidInteractionType = Enums.FluidInteractionType.None; } /// /// Constructor. /// /// /// /// Can both input tanks store the same Fluid? public FluidManagerV2(int Capacity, bool OnlyOutput, Enums.FluidInteractionType LiquidInteractionType, bool AllowDoubleInput = false) { if (OnlyOutput) { this.outputTank = new MachineFluidTank(Capacity); this.inputTank1 = new MachineFluidTank(0); this.inputTank2 = new MachineFluidTank(0); } else { this.outputTank = new MachineFluidTank(Capacity); this.inputTank1 = new MachineFluidTank(Capacity); this.inputTank2 = new MachineFluidTank(Capacity); } this.onlyOutput = OnlyOutput; this.allowDoubleInput = AllowDoubleInput; this.requiresUpdate = false; this.fluidInteractionType = LiquidInteractionType; } /// /// Produces a given amount of Fluid and puts it into the output tank for this Fluid manager. /// /// /// public void produceFluid(Fluid L, int Amount) { if (this.outputTank.CanRecieveThisFluid(L)) { this.outputTank.intakeFluid(L, Amount); this.requiresUpdate = true; } } /// /// Intakes Fluid into the input takes on this Fluid manager. /// /// /// public void intakeFluid(Fluid L, int Amount) { int remainingAmount = Amount; if (this.allowDoubleInput) { if (this.inputTank1.CanRecieveThisFluid(L) && remainingAmount > 0) { int allowedAmount = this.inputTank1.remainingCapacity; this.inputTank1.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; } if (this.inputTank2.CanRecieveThisFluid(L) && remainingAmount > 0) { int allowedAmount = this.inputTank2.remainingCapacity; this.inputTank2.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; } this.requiresUpdate = true; } else { if (this.inputTank1.CanRecieveThisFluid(L) && remainingAmount > 0 && this.inputTank2.DoesTankContainThisFluid(L) == false) { int allowedAmount = this.inputTank1.remainingCapacity; this.inputTank1.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; this.requiresUpdate = true; return; } if (this.inputTank2.CanRecieveThisFluid(L) && remainingAmount > 0 && this.inputTank1.DoesTankContainThisFluid(L) == false) { int allowedAmount = this.inputTank2.remainingCapacity; this.inputTank2.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; this.requiresUpdate = true; return; } } } /// /// Consumes the Fluid in the input tanks. Mainly used for machine processing but shouldn't be drained outwards. /// /// /// public void consumeFluid(Fluid L, int Amount) { if (this.doTheInputTanksHaveEnoughFluid(L, Amount) == false) return; int requiredAmount = Amount; int tank1Amount = this.inputTank1.GetAmountOfFluidInThisTank(L); int tank2Amount = this.inputTank2.GetAmountOfFluidInThisTank(L); if (tank1Amount > 0 && requiredAmount > 0) { this.inputTank1.consumeFluid(requiredAmount); requiredAmount -= tank1Amount; this.requiresUpdate = true; } if (tank2Amount > 0 && requiredAmount > 0) { this.inputTank2.consumeFluid(requiredAmount); requiredAmount -= tank2Amount; this.requiresUpdate = true; } //Consumes Fluid from both tanks if double input is enabled. Otherwise it only drains from the appropriate tank. } public void drainOutputTank(int Amount) { this.outputTank.consumeFluid(Amount); if (this.outputTank.IsEmpty) this.outputTank.fluid = null; this.requiresUpdate = true; } /// /// Checks to see if the input tanks have enough Fluid combined to process the request. /// /// /// /// public bool doTheInputTanksHaveEnoughFluid(Fluid L, int Amount) { int tankTotals = this.inputTank1.GetAmountOfFluidInThisTank(L) + this.inputTank2.GetAmountOfFluidInThisTank(L); if (tankTotals >= Amount) return true; else return false; } /// /// Gets the total amount of Fluid that the input tanks can recieve /// /// /// public int getMaxAmountOfFluidIntakePossible(Fluid L) { if (this.allowDoubleInput) { int amount = 0; amount += this.inputTank1.GetAmountOfFluidThisTankCanReceieve(L); amount += this.inputTank2.GetAmountOfFluidThisTankCanReceieve(L); } else { if (this.inputTank1.CanRecieveThisFluid(L) && this.inputTank2.DoesTankContainThisFluid(L) == false) { return this.inputTank1.GetAmountOfFluidThisTankCanReceieve(L); } if (this.inputTank1.CanRecieveThisFluid(L) && this.inputTank2.DoesTankContainThisFluid(L) == false) { return this.inputTank2.GetAmountOfFluidThisTankCanReceieve(L); } } return 0; } /// /// Checks to see if the input tanks on this Fluid manager have the capacity to take in this Fluid at all. /// /// /// public bool canRecieveThisFluid(Fluid L) { if (L == null) return false; if (this.allowDoubleInput) { if (this.inputTank1.CanRecieveThisFluid(L) || this.inputTank2.CanRecieveThisFluid(L)) { return true; } } else { if (this.inputTank1.CanRecieveThisFluid(L) && this.inputTank2.DoesTankContainThisFluid(L) == false) { return false; } if (this.inputTank2.CanRecieveThisFluid(L) && this.inputTank1.DoesTankContainThisFluid(L) == false) { return true; } } return false; } /// /// Takes the fluid in this output tank and tries to transfer it to another Fluid manager who has an tank available. /// /// public void outputFluidToOtherSources(FluidManagerV2 Other) { if (this.outputTank.fluid == null) return; if (Other.canRecieveThisFluid(this.outputTank.fluid)) { int actualAmount = Math.Min(this.outputTank.amount, Other.getMaxAmountOfFluidIntakePossible(this.outputTank.fluid)); Other.intakeFluid(this.outputTank.fluid, actualAmount); this.drainOutputTank(actualAmount); } } /// /// Checks to see if this output tank has the corresponding fluid and if the amount is greater than 0. /// /// /// public bool doesThisOutputTankContainThisFluid(Fluid F) { if (this.outputTank.GetAmountOfFluidInThisTank(F) > 0) return true; else return false; } public FluidManagerV2 Copy() { return new FluidManagerV2(this.outputTank.capacity, this.onlyOutput, this.fluidInteractionType, this.allowDoubleInput); } } }