public static bool Prefix(float dt, ValveBase __instance, float ___currentFlow, int ___outputCell, int ___inputCell, HandleVector <int> .Handle ___flowAccumulator) { ConduitFlow flowManager = Conduit.GetFlowManager(__instance.conduitType); if (!flowManager.HasConduit(___inputCell) || !flowManager.HasConduit(___outputCell)) { __instance.UpdateAnim(); } else { ConduitFlow.ConduitContents input_content = flowManager.GetConduit(___inputCell).GetContents(flowManager); ConduitFlow.ConduitContents output_content = flowManager.GetConduit(___outputCell).GetContents(flowManager); float mass_input = Mathf.Min(input_content.mass, ___currentFlow * dt); float mass_output = output_content.mass; float mass_limit = Mathf.Max(___currentFlow - mass_output, 0); // mass on output cannot exceed flow setting mass_input = Mathf.Min(mass_input, mass_limit); // set new input mass if (mass_input > 0f) { float disease_percent = mass_input / input_content.mass; int disease_count = (int)(disease_percent * input_content.diseaseCount); float mass_moved = flowManager.AddElement(___outputCell, input_content.element, mass_input, input_content.temperature, input_content.diseaseIdx, disease_count); Game.Instance.accumulators.Accumulate(___flowAccumulator, mass_moved); if (mass_moved > 0f) { flowManager.RemoveElement(___inputCell, mass_moved); } } __instance.UpdateAnim(); } return(false); }
protected override void ConduitUpdate(float dt) { this.currentValue = 0; // spawn code should never toggle as it crashes on load if (dt < 0) { return; } int cell = Grid.PosToCell(this); ConduitFlow flowManager = Conduit.GetFlowManager(this.conduitType); if (flowManager.HasConduit(cell)) { if (flowManager != null) { var conduit = flowManager.GetConduit(cell); var lastFlow = conduit.GetLastFlowInfo(flowManager); if (lastFlow.direction != ConduitFlow.FlowDirections.None) { this.currentValue = (lastFlow.contents.mass) * 1000; } } } if (this.activateAboveThreshold) { // Empty is always false if (this.currentValue <= 0f) { if (base.IsSwitchedOn) { this.Toggle(); } return; } // Full is always true if (this.currentValue >= this.max) { if (!base.IsSwitchedOn) { this.Toggle(); } return; } if ((this.currentValue > this.threshold && !base.IsSwitchedOn) || (this.currentValue <= this.threshold && base.IsSwitchedOn)) { this.Toggle(); } } else if ((this.currentValue > this.threshold && base.IsSwitchedOn) || (this.currentValue <= this.threshold && !base.IsSwitchedOn)) { this.Toggle(); } }
private void ConduitUpdate(float dt) { ConduitFlow flowManager = Conduit.GetFlowManager(this.conduitType); if (!flowManager.HasConduit(this.inputCell) || !flowManager.HasConduit(this.outputCell)) { this.UpdateAnim(); } else { ConduitFlow.ConduitContents input_content = flowManager.GetConduit(this.inputCell).GetContents(flowManager); ConduitFlow.ConduitContents output_content = flowManager.GetConduit(this.outputCell).GetContents(flowManager); float mass_input = Mathf.Min(input_content.mass, this.CurrentFlow * dt); float mass_output = output_content.mass; if (limitPressure) { float mass_limit = Mathf.Max(this.CurrentFlow - mass_output, 0); // mass on output cannot exceed flow setting mass_input = Mathf.Min(mass_input, mass_limit); // set new input mass } if (mass_input > 0f) { float disease_percent = mass_input / input_content.mass; int disease_count = (int)(disease_percent * input_content.diseaseCount); float mass_moved = flowManager.AddElement(this.outputCell, input_content.element, mass_input, input_content.temperature, input_content.diseaseIdx, disease_count); Game.Instance.accumulators.Accumulate(this.flowAccumulator, mass_moved); if (mass_moved > 0f) { flowManager.RemoveElement(this.inputCell, mass_moved); } } this.UpdateAnim(); } }
private void ConduitUpdate(float dt) { //If the building is broken, nothing normally stops it from operating! if (gameObject.GetComponent <BuildingHP>().HitPoints == 0) { return; } ConduitFlow manager = Conduit.GetFlowManager(valveBase.conduitType); ConduitFlow.Conduit inputConduit = manager.GetConduit(InputCell); ConduitFlow.Conduit outputConduit = manager.GetConduit(OutputCell); if (!manager.HasConduit(InputCell) || !manager.HasConduit(OutputCell)) { valveBase.UpdateAnim(); } else { ConduitFlow.ConduitContents inputContents = inputConduit.GetContents(manager); if (!bufferMode) { float valveFlow = valveBase.CurrentFlow * dt; float maxFlow; float temp; SimHashes element; byte diseaseIdx; float ratio; int disease_count; bool fromStorage = false; Tag storedTag = Tag.Invalid; if (!storage.IsEmpty()) { //If there is still mass within the storage but we are not in buffer mode, take nothing in until the storage is emptied! (while still following the limit mode settings) fromStorage = true; GameObject item = storage.items.FirstOrDefault(); PrimaryElement storedPrimary = item.GetComponent <PrimaryElement>(); maxFlow = Mathf.Min(valveFlow, storedPrimary.Mass); element = storedPrimary.ElementID; temp = storedPrimary.Temperature; diseaseIdx = storedPrimary.DiseaseIdx; ratio = maxFlow / storedPrimary.Mass; disease_count = (int)(ratio * (float)storedPrimary.DiseaseCount); storedTag = storedPrimary.Element.tag; } else { maxFlow = Mathf.Min(inputContents.mass, valveBase.CurrentFlow * dt); element = inputContents.element; temp = inputContents.temperature; diseaseIdx = inputContents.diseaseIdx; ratio = maxFlow / inputContents.mass; disease_count = (int)(ratio * (float)inputContents.diseaseCount); } if (maxFlow > 0f) { float movableMass = manager.AddElement(OutputCell, element, maxFlow, temp, diseaseIdx, disease_count); Game.Instance.accumulators.Accumulate(flowAccumulator, movableMass); if (movableMass > 0f) { //If we took the mass from storage, make sure we use the right function if (!fromStorage) { manager.RemoveElement(InputCell, movableMass); } else { storage.ConsumeIgnoringDisease(storedTag, movableMass); } } } } else { float availableInput = inputContents.mass; GameObject storedItem = storage.items.FirstOrDefault(); Element storedElement = storedItem?.GetComponent <PrimaryElement>().Element; float storedMass = storedItem != null?storedItem.GetComponent <PrimaryElement>().Mass : 0f; float maxOutputCapacity = Integration.GetMaxCapacityAt(OutputCell, valveBase.conduitType); //Override the set current flow if the output pipe cannot support a flow that large. This prevents the valve from storing, for example, 3KG, when it can only output 1KG at a time. float minimumOutput = Mathf.Min(maxOutputCapacity, valveBase.CurrentFlow); storage.capacityKg = maxOutputCapacity; float movableToStorage = Mathf.Min(availableInput, storage.RemainingCapacity()); if (movableToStorage > 0f) { Element inputElement = ElementLoader.FindElementByHash(inputContents.element); float ratio = movableToStorage / inputContents.mass; int transferredDisease = (int)((float)inputContents.diseaseCount * ratio); if (inputElement == storedElement || storedItem == null) { if (valveBase.conduitType == ConduitType.Gas) { storage.AddGasChunk(inputContents.element, movableToStorage, inputContents.temperature, inputContents.diseaseIdx, transferredDisease, false); } else { storage.AddLiquid(inputContents.element, movableToStorage, inputContents.temperature, inputContents.diseaseIdx, transferredDisease, false); } storedMass += movableToStorage; if (storedItem == null) { storedElement = inputElement; } } else { //The input has a different element than what is in storage! Deal damage and remove however much mass attempted to flow into the valve. Trigger(-794517298, new BuildingHP.DamageSourceInfo { damage = 1, source = STRINGS.BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT, popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT }); SimMessages.AddRemoveSubstance(Grid.PosToCell(base.transform.GetPosition()), inputContents.element, CellEventLogger.Instance.ConduitConsumerWrongElement, movableToStorage, inputContents.temperature, inputContents.diseaseIdx, transferredDisease); } manager.RemoveElement(InputCell, movableToStorage); } ConduitFlow.ConduitContents outputContents = outputConduit.GetContents(manager); float initialOutputMass = outputContents.mass; Element outputElement = ElementLoader.FindElementByHash(outputContents.element); //If we can create a packet of at least size CurrentFlow, including if we combined the valve's output into what is already in the output conduit //Debug.Log($"[TogglableValve] InitialOut: {initialOutputMass}, StoredMass: {storedMass}, MinimumOutput: {minimumOutput}, MaxOutputCapacity: {maxOutputCapacity}, AvailableInput: {availableInput}, MovableToStorage: {movableToStorage}"); if (initialOutputMass + storedMass >= minimumOutput && (storedElement == outputElement || outputElement == null || outputElement.id == SimHashes.Vacuum)) { float movableToOut = Mathf.Min(storedMass, maxOutputCapacity - initialOutputMass); if (movableToOut > 0f) { PrimaryElement storedPrimary = storage.items.FirstOrDefault()?.GetComponent <PrimaryElement>(); float ratio = movableToOut / storedMass; int transferredDisease = (int)((float)storedPrimary.DiseaseCount * ratio); float totalMovedOut = manager.AddElement(OutputCell, storedPrimary.ElementID, storedMass, storedPrimary.Temperature, storedPrimary.DiseaseIdx, transferredDisease); Game.Instance.accumulators.Accumulate(flowAccumulator, totalMovedOut); if (totalMovedOut > 0f) { storage.ConsumeIgnoringDisease(storedPrimary.Element.tag, totalMovedOut); } } } } valveBase.UpdateAnim(); } }
private static bool Prefix(ValveBase __instance, float dt) { Debug.Log(" === ValveBase.ConduitUpdate(" + dt + ") Prefix " + __instance.conduitType); if (__instance.conduitType != (ConduitType)100 && __instance.conduitType != (ConduitType)101) { return(true); } FieldInfo fi1 = AccessTools.Field(typeof(ValveBase), "inputCell"); FieldInfo fi2 = AccessTools.Field(typeof(ValveBase), "outputCell"); FieldInfo fi3 = AccessTools.Field(typeof(ValveBase), "flowAccumulator"); //Debug.Log("ConduitUpdate " + dt); ConduitFlow flowManager = Conduit.GetFlowManager(__instance.conduitType); ConduitFlow.Conduit conduit = flowManager.GetConduit((int)fi1.GetValue(__instance)); if (!flowManager.HasConduit((int)fi1.GetValue(__instance)) || !flowManager.HasConduit((int)fi2.GetValue(__instance))) { __instance.UpdateAnim(); } if ((int)fi1.GetValue(__instance) > 0 && flowManager.HasConduit((int)fi1.GetValue(__instance)) && ((int)fi2.GetValue(__instance) > 0 && !flowManager.HasConduit((int)fi2.GetValue(__instance)))) { ConduitFlow.ConduitContents contents = conduit.GetContents(flowManager); //float num = Mathf.Min(contents.mass, this.currentFlow * dt); FieldInfo fi = AccessTools.Field(typeof(ValveBase), "currentFlow"); //float num = Mathf.Min(contents.mass, (float)fi.GetValue(this) * dt); float num = Mathf.Min(contents.mass, 10f * dt); Debug.Log("ConduitUpdate " + num); if (num > 0f) { float num2 = num / contents.mass; int disease_count = (int)(num2 * (float)contents.diseaseCount); Debug.Log("List " + num); LiquidWarpData.LiquidPackets.Add(new PacketData((int)__instance.conduitType, (float)fi.GetValue(__instance), (int)fi2.GetValue(__instance), contents.element, num, contents.temperature, contents.diseaseIdx, disease_count)); //float num3 = flowManager.AddElement(this.outputCell, contents.element, num, contents.temperature, contents.diseaseIdx, disease_count); //Game.Instance.accumulators.Accumulate(this.flowAccumulator, num3); //float num3 = Mathf.Min(num, 10f - contents.mass); float num3 = num; if (num3 > 0f) { flowManager.RemoveElement((int)fi1.GetValue(__instance), num3); } } __instance.UpdateAnim(); return(false); } if ((int)fi2.GetValue(__instance) > 0 && flowManager.HasConduit((int)fi2.GetValue(__instance))) { ConduitFlow.Conduit conduitO = flowManager.GetConduit((int)fi2.GetValue(__instance)); FieldInfo fi = AccessTools.Field(typeof(ValveBase), "currentFlow"); PacketData toRemove = null; foreach (PacketData packet in LiquidWarpData.LiquidPackets) { Debug.Log("currentFlow = " + (float)fi.GetValue(__instance) + ", packet.currentFlow = " + packet.current_flow); if ((float)fi.GetValue(__instance) == packet.current_flow && (int)__instance.conduitType == packet.content_type) { float num3 = flowManager.AddElement((int)fi2.GetValue(__instance), packet.element, packet.mass, packet.temperature, packet.disease_idx, packet.disease_count); Debug.Log("Adding Element to pipe: " + packet.mass + "," + num3); Game.Instance.accumulators.Accumulate((HandleVector <int> .Handle)fi3.GetValue(__instance), num3); toRemove = packet; break; } } if (toRemove != null) { LiquidWarpData.LiquidPackets.Remove(toRemove); toRemove = null; } __instance.UpdateAnim(); return(false); } return(false); }