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 liquid used for various mod purposes. /// public class Liquid { /// /// The name of the liquid. /// public string name; /// /// The color for the liquid. /// public Color color; /// /// Constructor. /// public Liquid() { } /// /// Constructor. /// /// /// public Liquid(string Name, Color LiquidColor) { this.name = Name; this.color = LiquidColor; } /// /// Liquid comparison check to see if two liquids are the same. /// /// /// public bool isLiquidHomogenous(Liquid Other) { if (this.name.Equals(Other.name)) return true; return false; } /// /// Copys over the liquid. /// /// public Liquid Copy() { return new Liquid(this.name, this.color); } } public class MachineLiquidTank { /// /// The liquid inside of the tank. /// public Liquid liquid; /// /// How much liquid is inside the tank currently. /// public int amount; /// /// How much liquid 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; } } /// /// Constructor. /// public MachineLiquidTank() { } /// /// Constructor. /// /// public MachineLiquidTank(int Capacity) { this.capacity = Capacity; this.amount = 0; this.liquid = null; } /// /// Constructor. /// /// /// /// public MachineLiquidTank(int Capacity, int Amount, Liquid Liquid) { this.capacity = Capacity; this.amount = Amount; this.liquid = Liquid; } /// /// Checks to see if this tank can recieve this liquid. /// /// /// public bool CanRecieveThisLiquid(Liquid L) { if (this.IsFull) return false; if (this.liquid == null) return true; if (this.liquid.isLiquidHomogenous(L)) return true; if (this.IsEmpty) return true; else return false; } /// /// Takes in liquid into this tank. /// /// /// public void intakeLiquid(Liquid L, int Amount) { if (this.CanRecieveThisLiquid(L)) { if (this.liquid == null) this.liquid = L.Copy(); else { int intakeAmount=Math.Min(this.remainingCapacity, Amount); this.amount = this.amount + intakeAmount; } } else return; } /// /// Consumes, aka reduces the internal liquid on this tank by the amount given or the amount remaining in the tank. /// /// public void consumeLiquid(int Amount) { if (this.IsEmpty) return; if (this.liquid == null) return; int consumeAmount = Math.Min(this.amount, Amount); this.amount = this.amount - consumeAmount; if (this.amount <= 0) this.liquid = null; } /// /// Checks to see if this tank has enough /// /// /// /// public bool DoesThisTankHaveEnoughLiquid(Liquid L, int Amount) { if (this.GetAmountOfLiquidInThisTank(L) >= Amount) return true; return false; } /// /// Drains the tank completly /// public void emptyTank() { this.liquid = null; this.amount = 0; } /// /// Gets the amount of liquid in this tank for the given liquid. /// /// /// Returns 0 if the tank doesn't contain liquid of the same type. Otherwise returns the amount stored in the tank. public int GetAmountOfLiquidInThisTank(Liquid L) { if (this.liquid == null) return 0; if (this.liquid.isLiquidHomogenous(L)) return this.amount; return 0; } /// /// Gets the amount of liquid this take can take in in acordance with the parameter liquid. /// /// /// public int GetAmountOfLiquidThisTankCanReceieve(Liquid L) { if (this.liquid == null) return this.capacity; if (this.liquid.isLiquidHomogenous(L)) return this.remainingCapacity; return 0; } /// /// Checks to see if this tank contains this liquid at all. /// /// /// public bool DoesTankContainThisLiquid(Liquid L) { if (this.liquid == null) return false; if (this.liquid.isLiquidHomogenous(L)) return true; return false; } } public class LiquidManagerV2 { public MachineLiquidTank inputTank1; public MachineLiquidTank inputTank2; public MachineLiquidTank outputTank; public bool needsUpdate; /// /// Does this machine allow the same fluid in both tanks? /// public bool allowDoubleInput; public LiquidManagerV2() { this.inputTank1 = new MachineLiquidTank(0); this.inputTank2 = new MachineLiquidTank(0); this.outputTank = new MachineLiquidTank(0); this.needsUpdate = false; } /// /// Constructor. /// /// /// /// Can both input tanks store the same liquid? public LiquidManagerV2(int Capacity, bool OnlyOutput, bool AllowDoubleInput=false) { if (OnlyOutput) { this.outputTank = new MachineLiquidTank(Capacity); this.inputTank1 = new MachineLiquidTank(0); this.inputTank2 = new MachineLiquidTank(0); } else { this.outputTank = new MachineLiquidTank(Capacity); this.inputTank1 = new MachineLiquidTank(Capacity); this.inputTank2 = new MachineLiquidTank(Capacity); } this.allowDoubleInput = AllowDoubleInput; this.needsUpdate = false; } /// /// Produces a given amount of liquid and puts it into the output tank for this liquid manager. /// /// /// public void produceLiquid(Liquid L, int Amount) { if (this.outputTank.CanRecieveThisLiquid(L)) { this.outputTank.intakeLiquid(L, Amount); this.needsUpdate = true; } } /// /// Intakes liquid into the input takes on this liquid manager. /// /// /// public void intakeLiquid(Liquid L, int Amount) { int remainingAmount = Amount; if (this.allowDoubleInput) { if (this.inputTank1.CanRecieveThisLiquid(L) && remainingAmount>0) { int allowedAmount = this.inputTank1.remainingCapacity; this.inputTank1.intakeLiquid(L, remainingAmount); remainingAmount -= allowedAmount; } if (this.inputTank2.CanRecieveThisLiquid(L)&& remainingAmount>0) { int allowedAmount = this.inputTank2.remainingCapacity; this.inputTank2.intakeLiquid(L, remainingAmount); remainingAmount -= allowedAmount; } this.needsUpdate = true; } else { if (this.inputTank1.CanRecieveThisLiquid(L) && remainingAmount > 0 && this.inputTank2.DoesTankContainThisLiquid(L)==false) { int allowedAmount = this.inputTank1.remainingCapacity; this.inputTank1.intakeLiquid(L, remainingAmount); remainingAmount -= allowedAmount; this.needsUpdate = true; return; } if (this.inputTank2.CanRecieveThisLiquid(L) && remainingAmount > 0 && this.inputTank1.DoesTankContainThisLiquid(L) == false) { int allowedAmount = this.inputTank2.remainingCapacity; this.inputTank2.intakeLiquid(L, remainingAmount); remainingAmount -= allowedAmount; this.needsUpdate = true; return; } } } /// /// Consumes the liquid in the input tanks. Mainly used for machine processing but shouldn't be drained outwards. /// /// /// public void consumeLiquid(Liquid L, int Amount) { if (this.doTheInputTanksHaveEnoughLiquid(L, Amount) == false) return; int requiredAmount = Amount; int tank1Amount = this.inputTank1.GetAmountOfLiquidInThisTank(L); int tank2Amount= this.inputTank2.GetAmountOfLiquidInThisTank(L); if (tank1Amount > 0 && requiredAmount>0) { this.inputTank1.consumeLiquid(requiredAmount); requiredAmount -= tank1Amount; this.needsUpdate = true; } if(tank2Amount>0 && requiredAmount > 0) { this.inputTank2.consumeLiquid(requiredAmount); requiredAmount -= tank2Amount; this.needsUpdate = true; } //Consumes liquid from both tanks if double input is enabled. Otherwise it only drains from the appropriate tank. } public void drainOutputTank(int Amount) { this.outputTank.consumeLiquid(Amount); if (this.outputTank.IsEmpty) this.outputTank.liquid = null; this.needsUpdate = true; } /// /// Checks to see if the input tanks have enough liquid combined to process the request. /// /// /// /// public bool doTheInputTanksHaveEnoughLiquid(Liquid L, int Amount) { int tankTotals = this.inputTank1.GetAmountOfLiquidInThisTank(L) + this.inputTank2.GetAmountOfLiquidInThisTank(L); if (tankTotals >= Amount) return true; else return false; } /// /// Gets the total amount of liquid that the input tanks can recieve /// /// /// public int getMaxAmountOfLiquidIntakePossible(Liquid L) { if (this.allowDoubleInput) { int amount = 0; amount += this.inputTank1.GetAmountOfLiquidThisTankCanReceieve(L); amount += this.inputTank2.GetAmountOfLiquidThisTankCanReceieve(L); } else { if(this.inputTank1.CanRecieveThisLiquid(L) && this.inputTank2.DoesTankContainThisLiquid(L) == false) { return this.inputTank1.GetAmountOfLiquidThisTankCanReceieve(L); } if (this.inputTank1.CanRecieveThisLiquid(L) && this.inputTank2.DoesTankContainThisLiquid(L) == false) { return this.inputTank2.GetAmountOfLiquidThisTankCanReceieve(L); } } return 0; } /// /// Checks to see if the input tanks on this liquid manager have the capacity to take in this liquid at all. /// /// /// public bool canRecieveThisLiquid(Liquid L) { if (L == null) return false; if (this.allowDoubleInput) { if (this.inputTank1.CanRecieveThisLiquid(L) || this.inputTank2.CanRecieveThisLiquid(L)) { return true; } } else { if (this.inputTank1.CanRecieveThisLiquid(L) && this.inputTank2.DoesTankContainThisLiquid(L) == false) { return false; } if (this.inputTank2.CanRecieveThisLiquid(L) && this.inputTank1.DoesTankContainThisLiquid(L) == false) { return true; } } return false; } /// /// Takes the fluid in this output tank and tries to transfer it to another liquid manager who has an tank available. /// /// public void outputLiquidToOtherSources(LiquidManagerV2 Other) { if (this.outputTank.liquid == null) return; if (Other.canRecieveThisLiquid(this.outputTank.liquid)) { int actualAmount = Math.Min(this.outputTank.amount, Other.getMaxAmountOfLiquidIntakePossible(this.outputTank.liquid)); Other.intakeLiquid(this.outputTank.liquid,actualAmount); this.drainOutputTank(actualAmount); } } } }