diff --git a/GeneralMods/Revitalize/Framework/Enums/Enums.cs b/GeneralMods/Revitalize/Framework/Enums/Enums.cs index 80b4c76d..21e67fb0 100644 --- a/GeneralMods/Revitalize/Framework/Enums/Enums.cs +++ b/GeneralMods/Revitalize/Framework/Enums/Enums.cs @@ -35,11 +35,10 @@ namespace Revitalize.Framework Storage } - public enum LiquidInteractionType + public enum FluidInteractionType { None, - Produces, - Consumes, + Machine, Transfers, Storage } diff --git a/GeneralMods/Revitalize/Framework/Managers/FluidManagerV2.cs b/GeneralMods/Revitalize/Framework/Managers/FluidManagerV2.cs index e7c0d16f..9158f1af 100644 --- a/GeneralMods/Revitalize/Framework/Managers/FluidManagerV2.cs +++ b/GeneralMods/Revitalize/Framework/Managers/FluidManagerV2.cs @@ -250,19 +250,36 @@ namespace Revitalize.Framework.Managers public MachineFluidTank inputTank2; public MachineFluidTank outputTank; - public bool needsUpdate; + 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.needsUpdate = false; + this.requiresUpdate = false; + this.fluidInteractionType = Enums.FluidInteractionType.None; } /// @@ -271,7 +288,7 @@ namespace Revitalize.Framework.Managers /// /// /// Can both input tanks store the same Fluid? - public FluidManagerV2(int Capacity, bool OnlyOutput, bool AllowDoubleInput=false) + public FluidManagerV2(int Capacity, bool OnlyOutput, Enums.FluidInteractionType LiquidInteractionType, bool AllowDoubleInput=false) { if (OnlyOutput) { @@ -286,8 +303,10 @@ namespace Revitalize.Framework.Managers this.inputTank1 = new MachineFluidTank(Capacity); this.inputTank2 = new MachineFluidTank(Capacity); } + this.onlyOutput = OnlyOutput; this.allowDoubleInput = AllowDoubleInput; - this.needsUpdate = false; + this.requiresUpdate = false; + this.fluidInteractionType = LiquidInteractionType; } /// @@ -300,7 +319,7 @@ namespace Revitalize.Framework.Managers if (this.outputTank.CanRecieveThisFluid(L)) { this.outputTank.intakeFluid(L, Amount); - this.needsUpdate = true; + this.requiresUpdate = true; } } @@ -326,7 +345,7 @@ namespace Revitalize.Framework.Managers this.inputTank2.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; } - this.needsUpdate = true; + this.requiresUpdate = true; } else { @@ -336,7 +355,7 @@ namespace Revitalize.Framework.Managers int allowedAmount = this.inputTank1.remainingCapacity; this.inputTank1.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; - this.needsUpdate = true; + this.requiresUpdate = true; return; } if (this.inputTank2.CanRecieveThisFluid(L) && remainingAmount > 0 && this.inputTank1.DoesTankContainThisFluid(L) == false) @@ -344,7 +363,7 @@ namespace Revitalize.Framework.Managers int allowedAmount = this.inputTank2.remainingCapacity; this.inputTank2.intakeFluid(L, remainingAmount); remainingAmount -= allowedAmount; - this.needsUpdate = true; + this.requiresUpdate = true; return; } } @@ -367,14 +386,14 @@ namespace Revitalize.Framework.Managers { this.inputTank1.consumeFluid(requiredAmount); requiredAmount -= tank1Amount; - this.needsUpdate = true; + this.requiresUpdate = true; } if(tank2Amount>0 && requiredAmount > 0) { this.inputTank2.consumeFluid(requiredAmount); requiredAmount -= tank2Amount; - this.needsUpdate = true; + this.requiresUpdate = true; } //Consumes Fluid from both tanks if double input is enabled. Otherwise it only drains from the appropriate tank. } @@ -383,7 +402,7 @@ namespace Revitalize.Framework.Managers { this.outputTank.consumeFluid(Amount); if (this.outputTank.IsEmpty) this.outputTank.fluid = null; - this.needsUpdate = true; + this.requiresUpdate = true; } /// @@ -471,5 +490,21 @@ namespace Revitalize.Framework.Managers 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); + } } } diff --git a/GeneralMods/Revitalize/Framework/Objects/BasicItemInformation.cs b/GeneralMods/Revitalize/Framework/Objects/BasicItemInformation.cs index 8ab2f8c3..08e5f5b5 100644 --- a/GeneralMods/Revitalize/Framework/Objects/BasicItemInformation.cs +++ b/GeneralMods/Revitalize/Framework/Objects/BasicItemInformation.cs @@ -367,7 +367,7 @@ namespace Revitalize.Framework.Objects } } - public LiquidManagerV2 fluidManager; + public FluidManagerV2 fluidManager; [JsonIgnore] @@ -395,10 +395,10 @@ namespace Revitalize.Framework.Objects this.EnergyManager = new Energy.EnergyManager(); this._alwaysDrawAbovePlayer = false; this.ColorManager = new ColorManager(Enums.DyeBlendMode.Blend, 0.5f); - this.fluidManager = new LiquidManagerV2(); + this.fluidManager = new FluidManagerV2(); } - public BasicItemInformation(string name, string id, string description, string categoryName, Color categoryColor,int edibility, int fragility, bool isLamp, int price, bool canBeSetOutdoors, bool canBeSetIndoors, Texture2D texture, AnimationManager animationManager, Color drawColor, bool ignoreBoundingBox, InventoryManager Inventory, LightManager Lights,Energy.EnergyManager EnergyManager=null,bool AlwaysDrawAbovePlayer=false,NamedColor DyedColor=null, ColorManager ColorManager=null,LiquidManagerV2 LiquidManager=null) + public BasicItemInformation(string name, string id, string description, string categoryName, Color categoryColor,int edibility, int fragility, bool isLamp, int price, bool canBeSetOutdoors, bool canBeSetIndoors, Texture2D texture, AnimationManager animationManager, Color drawColor, bool ignoreBoundingBox, InventoryManager Inventory, LightManager Lights,Energy.EnergyManager EnergyManager=null,bool AlwaysDrawAbovePlayer=false,NamedColor DyedColor=null, ColorManager ColorManager=null,FluidManagerV2 FluidManager=null) { this.name = name; this.id = id; @@ -433,7 +433,7 @@ namespace Revitalize.Framework.Objects this.DyedColor = DyedColor ?? new NamedColor("", new Color(0, 0, 0, 0)); this.ColorManager = ColorManager ?? new ColorManager(Enums.DyeBlendMode.Blend, 0.5f); - this.fluidManager = LiquidManager ?? new LiquidManagerV2(); + this.fluidManager = FluidManager ?? new FluidManagerV2(); } /// @@ -451,12 +451,12 @@ namespace Revitalize.Framework.Objects /// public BasicItemInformation Copy() { - return new BasicItemInformation(this.name, this.id,this.description, this.categoryName, this.categoryColor, this.edibility, this.fragility, this.isLamp, this.price, this.canBeSetOutdoors, this.canBeSetIndoors, this.animationManager.getTexture(), this.animationManager, this.DrawColor, this.ignoreBoundingBox, this.inventory.Copy(), this._lightManager.Copy(),this.EnergyManager.Copy(),this.AlwaysDrawAbovePlayer,this.DyedColor,this.ColorManager); + return new BasicItemInformation(this.name, this.id,this.description, this.categoryName, this.categoryColor, this.edibility, this.fragility, this.isLamp, this.price, this.canBeSetOutdoors, this.canBeSetIndoors, this.animationManager.getTexture(), this.animationManager, this.DrawColor, this.ignoreBoundingBox, this.inventory.Copy(), this._lightManager.Copy(),this.EnergyManager.Copy(),this.AlwaysDrawAbovePlayer,this.DyedColor,this.ColorManager,this.fluidManager.Copy()); } public bool requiresSyncUpdate() { - return this.requiresUpdate || this.animationManagerRequiresUpdate() || this.inventoryManagerRequiresUpdate() || this.lightManagerRequiresUpdate() || this.energyManagerRequiresUpdate() || this.colorManagerRequiresUpdate(); + return this.requiresUpdate || this.animationManagerRequiresUpdate() || this.inventoryManagerRequiresUpdate() || this.lightManagerRequiresUpdate() || this.energyManagerRequiresUpdate() || this.colorManagerRequiresUpdate() || this.fluidManagerRequiresUpdate(); } public void forceUpdate() @@ -502,6 +502,12 @@ namespace Revitalize.Framework.Objects else return this._colorManager.requiresUpdate; } + private bool fluidManagerRequiresUpdate() + { + if (this.fluidManager == null) return false; + else return this.fluidManager.requiresUpdate; + } + public void cleanAfterUpdate() { this.requiresUpdate = false; diff --git a/GeneralMods/Revitalize/Framework/Objects/CustomObject.cs b/GeneralMods/Revitalize/Framework/Objects/CustomObject.cs index 1ba2ede8..75e48276 100644 --- a/GeneralMods/Revitalize/Framework/Objects/CustomObject.cs +++ b/GeneralMods/Revitalize/Framework/Objects/CustomObject.cs @@ -11,6 +11,7 @@ using StardewValley.Objects; using Revitalize.Framework.Utilities; using Revitalize.Framework.Energy; using Revitalize.Framework.Illuminate; +using Revitalize.Framework.Managers; namespace Revitalize.Framework.Objects { @@ -778,5 +779,15 @@ namespace Revitalize.Framework.Objects { this.info.inventory = Manager; } + + public virtual ref FluidManagerV2 GetFluidManager() + { + return ref this.info.fluidManager; + } + + public virtual void SetFluidManager(FluidManagerV2 FluidManager) + { + this.info.fluidManager = FluidManager; + } } } diff --git a/GeneralMods/Revitalize/Framework/Objects/MultiTiledComponent.cs b/GeneralMods/Revitalize/Framework/Objects/MultiTiledComponent.cs index e25f0024..d98e1afe 100644 --- a/GeneralMods/Revitalize/Framework/Objects/MultiTiledComponent.cs +++ b/GeneralMods/Revitalize/Framework/Objects/MultiTiledComponent.cs @@ -7,6 +7,7 @@ using Microsoft.Xna.Framework.Graphics; using Newtonsoft.Json; using PyTK.CustomElementHandler; using Revitalize.Framework.Energy; +using Revitalize.Framework.Managers; using Revitalize.Framework.Utilities; using StardewValley; using StardewValley.Objects; @@ -656,6 +657,160 @@ namespace Revitalize.Framework.Objects } + public override ref FluidManagerV2 GetFluidManager() + { + if (this.info == null || this.containerObject == null) + { + this.updateInfo(); + if (this.containerObject == null) return ref this.info.fluidManager; + return ref this.containerObject.info.fluidManager; + } + return ref this.containerObject.info.fluidManager; + } + + public override void SetFluidManager(FluidManagerV2 FluidManager) + { + this.info.fluidManager = FluidManager; + } + + + /// + /// Gets corresponding neighbor objects that can interact with fluid. + /// + /// + protected virtual List GetNeighboringFluidManagers() + { + Vector2 tileLocation = this.TileLocation; + List customObjects = new List(); + if (this.location != null) + { + for (int i = -1; i <= 1; i++) + { + for (int j = -1; j <= 1; j++) + { + if (i == j || i == (-j)) continue; + + Vector2 neighborTile = tileLocation + new Vector2(i, j); + if (this.location.isObjectAtTile((int)neighborTile.X, (int)neighborTile.Y)) + { + StardewValley.Object obj = this.location.getObjectAtTile((int)neighborTile.X, (int)neighborTile.Y); + if (obj is MultiTiledComponent) + { + if ((obj as MultiTiledComponent).GetFluidManager().InteractsWithFluids) + { + customObjects.Add((MultiTiledComponent)obj); + } + } + else continue; + } + } + } + } + return customObjects; + } + + /// + /// Searches a network of fluid managers to see if any of these fluid managers have an output tank with the corresponding fluid. + /// + /// + /// + protected virtual List FluidGraphSearchForFluidFromOutputTanks(Fluid L) + { + List fluidSources = new List(); + List searchedComponents = new List(); + List entitiesToSearch = new List(); + entitiesToSearch.AddRange(this.GetNeighboringFluidManagers()); + searchedComponents.Add(this); + while (entitiesToSearch.Count > 0) + { + MultiTiledComponent searchComponent = entitiesToSearch[0]; + entitiesToSearch.Remove(searchComponent); + if (searchedComponents.Contains(searchComponent)) + { + continue; + } + else + { + searchedComponents.Add(searchComponent); + entitiesToSearch.AddRange(searchComponent.GetNeighboringFluidManagers()); + + if (searchComponent.containerObject.info.fluidManager.doesThisOutputTankContainThisFluid(L)) + { + fluidSources.Add(searchComponent.containerObject); + } + } + + } + return fluidSources; + } + + protected virtual List FluidGraphSearchInputTanksThatCanAcceptThisFluid(Fluid L) + { + List fluidSources = new List(); + List searchedComponents = new List(); + List entitiesToSearch = new List(); + entitiesToSearch.AddRange(this.GetNeighboringFluidManagers()); + searchedComponents.Add(this); + while (entitiesToSearch.Count > 0) + { + MultiTiledComponent searchComponent = entitiesToSearch[0]; + entitiesToSearch.Remove(searchComponent); + if (searchedComponents.Contains(searchComponent)) + { + continue; + } + else + { + searchedComponents.Add(searchComponent); + entitiesToSearch.AddRange(searchComponent.GetNeighboringFluidManagers()); + + if (searchComponent.containerObject.info.fluidManager.canRecieveThisFluid(L)) + { + fluidSources.Add(searchComponent.containerObject); + } + } + + } + return fluidSources; + } + + /// + /// Searches for output tanks that have the corresponding fluid and tries to drain from them. + /// + /// + public void pullFluidFromNetworkOutputs(Fluid L) + { + List energySources = this.FluidGraphSearchForFluidFromOutputTanks(L); + + int index = 0; + + for (int i = 0; i < energySources.Count; i++) + { + FluidManagerV2 other = energySources[i].GetFluidManager(); + other.outputFluidToOtherSources(this.GetFluidManager()); + if (this.GetFluidManager().canRecieveThisFluid(L)==false) break; //Since we already check for valid tanks this will basically check again to see if the tanks are full. + } + } + + /// + /// Searches for output tanks that have the corresponding fluid and tries to drain from them. + /// + /// + /// + public void pullFluidFromNetworkOutputs(List FluidSources,Fluid L) + { + List energySources = FluidSources; + + int index = 0; + + for (int i = 0; i < energySources.Count; i++) + { + FluidManagerV2 other = energySources[i].GetFluidManager(); + other.outputFluidToOtherSources(this.GetFluidManager()); + if (this.GetFluidManager().canRecieveThisFluid(L) == false) break; //Since we already check for valid tanks this will basically check again to see if the tanks are full. + } + } + public override bool requiresUpdate() { if (this.info.requiresSyncUpdate() || this.containerObject.info.requiresSyncUpdate())