protected virtual void ConduitUpdate(float dt) { if (!SkipSetOperational) { this.operational.SetFlag(PortConduitDispenserBase.outputConduitFlag, this.IsConnected); } if (this.operational.IsOperational || this.alwaysDispense) { PrimaryElement primaryElement = this.FindSuitableElement(); if (primaryElement != null) { primaryElement.KeepZeroMassObject = true; ConduitFlow conduitManager = this.GetConduitManager(); float num = conduitManager.AddElement(this.utilityCell, primaryElement.ElementID, primaryElement.Mass, primaryElement.Temperature, primaryElement.DiseaseIdx, primaryElement.DiseaseCount); if (num > 0f) { float num2 = num / primaryElement.Mass; int num3 = (int)(num2 * (float)primaryElement.DiseaseCount); primaryElement.ModifyDiseaseCount(-num3, "CustomConduitDispenser.ConduitUpdate"); primaryElement.Mass -= num; base.Trigger(-1697596308, primaryElement.gameObject); } } } }
private void ConduitUpdate(float dt) { ConduitFlow flowManager = Conduit.GetFlowManager(portInfo.conduitType); if (flowManager.HasConduit(inputCell)) { ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell); if (!(contents.mass <= 0f)) { int cell = outputCell; ConduitFlow.ConduitContents contents2 = flowManager.GetContents(cell); if (contents2.mass > 0f) { cell = secondaryOutput.Cell; contents2 = flowManager.GetContents(cell); } if (contents2.mass <= 0f) { float num = flowManager.AddElement(cell, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); if (num > 0f) { flowManager.RemoveElement(inputCell, num); } } } } }
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); }
private void UpdateState(float dt) { bool value = consumer.IsSatisfied; envTemp = 0f; cellCount = 0; if ((UnityEngine.Object)occupyArea != (UnityEngine.Object)null && (UnityEngine.Object)base.gameObject != (UnityEngine.Object)null) { occupyArea.TestArea(Grid.PosToCell(base.gameObject), this, UpdateStateCb); envTemp /= (float)cellCount; } lastEnvTemp = envTemp; List <GameObject> items = storage.items; for (int i = 0; i < items.Count; i++) { PrimaryElement component = items[i].GetComponent <PrimaryElement>(); if (component.Mass > 0f && (!isLiquidConditioner || !component.Element.IsGas) && (isLiquidConditioner || !component.Element.IsLiquid)) { value = true; lastGasTemp = component.Temperature; float num = component.Temperature + temperatureDelta; if (num < 1f) { num = 1f; lowTempLag = Mathf.Min(lowTempLag + dt / 5f, 1f); } else { lowTempLag = Mathf.Min(lowTempLag - dt / 5f, 0f); } ConduitFlow conduitFlow = (!isLiquidConditioner) ? Game.Instance.gasConduitFlow : Game.Instance.liquidConduitFlow; float num2 = conduitFlow.AddElement(cooledAirOutputCell, component.ElementID, component.Mass, num, component.DiseaseIdx, component.DiseaseCount); component.KeepZeroMassObject = true; float num3 = num2 / component.Mass; int num4 = (int)((float)component.DiseaseCount * num3); component.Mass -= num2; component.ModifyDiseaseCount(-num4, "AirConditioner.UpdateState"); float num5 = num - component.Temperature; float num6 = num5 * component.Element.specificHeatCapacity * num2; float display_dt = (!(lastSampleTime > 0f)) ? 1f : (Time.time - lastSampleTime); lastSampleTime = Time.time; GameComps.StructureTemperatures.ProduceEnergy(structureTemperature, 0f - num6, BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, display_dt); break; } } if (Time.time - lastSampleTime > 2f) { GameComps.StructureTemperatures.ProduceEnergy(structureTemperature, 0f, BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, Time.time - lastSampleTime); lastSampleTime = Time.time; } operational.SetActive(value, false); UpdateStatus(); }
private void OnConduitTick(float dt) { bool value = false; if (this.operational.IsOperational) { ConduitFlow gasFlow = Conduit.GetFlowManager(this.portInfo.conduitType); ConduitFlow.ConduitContents contentsI1 = gasFlow.GetContents(this.inputCell1); ConduitFlow.ConduitContents contentsI2 = gasFlow.GetContents(this.inputCell2); //Debug.Log("contentsI1.mass: " + contentsI1.mass); //Debug.Log("contentsI2.mass: " + contentsI2.mass); //int num = (contents.element != this.filteredElem) ? this.outputCell : this.filteredCell; ConduitFlow.ConduitContents contentsO = gasFlow.GetContents(this.outputCell); if (contentsI1.element != SimHashes.Hydrogen || contentsI2.element != SimHashes.Oxygen) { base.Trigger((int)GameHashes.DoBuildingDamage, new BuildingHP.DamageSourceInfo { damage = 1, source = STRINGS.BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT, popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT }); gasFlow.RemoveElement(this.inputCell1, 0.111999989f); gasFlow.RemoveElement(this.inputCell2, 0.888f); } else { if (contentsI1.mass > 0.111999989f && contentsI2.mass > 0.888f && contentsO.mass <= 0f) { value = true; //float num2 = flowManager.AddElement(num, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); float outputTemperature = contentsI1.temperature * 0.111999989f + contentsI2.temperature * 0.888f; //Debug.Log("outputTemperature: " + outputTemperature); ConduitFlow liquidFlow = Conduit.GetFlowManager(ConduitType.Liquid); float num2 = liquidFlow.AddElement(this.outputCell, SimHashes.Water, 1f, outputTemperature, contentsI1.diseaseIdx, 0); if (num2 > 0f) { gasFlow.RemoveElement(this.inputCell1, 0.111999989f); gasFlow.RemoveElement(this.inputCell2, 0.888f); } } } } this.operational.SetActive(value, false); }
private void ConduitUpdate(float dt) { ConduitFlow flowManager = Conduit.GetFlowManager(type); if (flowManager.HasConduit(inputCell)) { ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell); if (contents.mass > 0f) { float num = flowManager.AddElement(outputCell, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); if (num > 0f) { flowManager.RemoveElement(inputCell, num); Game.Instance.accumulators.Accumulate(accumulator, contents.mass); } } } }
private void OnConduitTick(float dt) { bool value = false; if (this.operational.IsOperational) { ConduitFlow flowManager = Conduit.GetFlowManager(this.portInfo.conduitType); ConduitFlow.ConduitContents contents = flowManager.GetContents(this.inputCell); //int num = (contents.element != this.filteredElem) ? this.outputCell : this.filteredCell; ConduitFlow.ConduitContents contentsO = flowManager.GetContents(this.outputCell); ConduitFlow.ConduitContents contents2 = flowManager.GetContents(this.sInputCell); if (contents.mass > 0.111999989f && contents2.mass > 0.888f && contentsO.mass <= 0f) { if (contents.element != SimHashes.Hydrogen || contents2.element != SimHashes.Oxygen) { base.Trigger(-794517298, new BuildingHP.DamageSourceInfo { damage = 1, source = STRINGS.BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT, popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT }); flowManager.RemoveElement(this.inputCell, 0.111999989f); flowManager.RemoveElement(this.sInputCell, 0.888f); } else { value = true; //float num2 = flowManager.AddElement(num, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); float num2 = flowManager.AddElement(this.outputCell, SimHashes.Steam, 1f, 523.15f, contents.diseaseIdx, 0); if (num2 > 0f) { flowManager.RemoveElement(this.inputCell, 0.111999989f); flowManager.RemoveElement(this.sInputCell, 0.888f); } } } } this.operational.SetActive(value, false); }
private void ConduitUpdate(float dt) { operational.SetFlag(outputConduitFlag, IsConnected); if (operational.IsOperational || alwaysDispense) { PrimaryElement primaryElement = FindSuitableElement(); if ((Object)primaryElement != (Object)null) { primaryElement.KeepZeroMassObject = true; ConduitFlow conduitManager = GetConduitManager(); float num = conduitManager.AddElement(utilityCell, primaryElement.ElementID, primaryElement.Mass, primaryElement.Temperature, primaryElement.DiseaseIdx, primaryElement.DiseaseCount); if (num > 0f) { float num2 = num / primaryElement.Mass; int num3 = (int)(num2 * (float)primaryElement.DiseaseCount); primaryElement.ModifyDiseaseCount(-num3, "ConduitDispenser.ConduitUpdate"); primaryElement.Mass -= num; Trigger(-1697596308, primaryElement.gameObject); } } } }
private void OnConduitTick(float dt) { bool value = false; UpdateConduitBlockedStatus(); if (operational.IsOperational) { ConduitFlow flowManager = Conduit.GetFlowManager(portInfo.conduitType); ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell); int num = (contents.element != filteredElem) ? outputCell : filteredCell; ConduitFlow.ConduitContents contents2 = flowManager.GetContents(num); if (contents.mass > 0f && contents2.mass <= 0f) { value = true; float num2 = flowManager.AddElement(num, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); if (num2 > 0f) { flowManager.RemoveElement(inputCell, num2); } } } operational.SetActive(value, false); }
//Since our input/output ports are inert, we must define the behavior of the ports ourself. //float dt is the amount of time that has passed. typically not used as far as i am aware, likely always just 1 (1 second) private void OnConduitTick(float dt) { //The ConduitFlow task is an overarching flow manager for a specific conduit type. If our bridge is a liquid bridge, we will get the liquid manager. ConduitFlow flowManager = Conduit.GetFlowManager(conduitType); //If there is a pipe connected to the location of the input port, and a pipe connected to the location of the output port if (flowManager.HasConduit(inputPort.GetPortCell()) && flowManager.HasConduit(outputPort.GetPortCell())) { //Get the contents of the input pipe ConduitFlow.ConduitContents contents = flowManager.GetContents(inputPort.GetPortCell()); if (contents.mass > 0f) { //The AddElement method will attempt to move as much fluid from the input to the output as it can, and will return the amount successfully moved (if any). //This method also handles things such as merging disease amounts and temperature based on how much is moved float amountMOved = flowManager.AddElement(outputPort.GetPortCell(), contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); if (amountMOved > 0f) { //RemoveElement, similar to AddElement, automatically reduces the disease count (if any germs are present) flowManager.RemoveElement(inputPort.GetPortCell(), amountMOved); } } } }
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 void ConvertMass() { float filterAmt = 0; List <GameObject> items = this.storage.items; PrimaryElement elem = null; foreach (GameObject item in items) { elem = item.GetComponent <PrimaryElement>(); if (elem.ElementID == SimHashes.BleachStone) { filterAmt += elem.Mass; } } if (filterAmt <= 0) { return; } float maxGerms = Mathf.Min(GERMS_PER_KG * MAX_KG_PER_SEC, (int)(filterAmt * GERMS_PER_KG)); float removedAmount = 0; ConduitFlow flowManager = Conduit.GetFlowManager(ConduitType.Liquid); if (!flowManager.HasConduit(inCell) || !flowManager.HasConduit(outCell)) { return; } foreach (GameObject item in items) { elem = item.GetComponent <PrimaryElement>(); if (elem.Element.IsLiquid) { float mass = Mathf.Min(10f, elem.Mass); float disease = elem.DiseaseCount / elem.Mass * mass; if (elem.DiseaseIdx == Byte.MaxValue) { disease = 0; } if (disease > maxGerms) { mass = mass * maxGerms / disease; disease = maxGerms; } float trueMass = flowManager.AddElement(outCell, elem.ElementID, mass, elem.Temperature, Byte.MaxValue, 0); if (trueMass < mass) { disease = disease * trueMass / mass; mass = trueMass; } elem.Mass -= mass; elem.ModifyDiseaseCount(-(int)disease, ""); removedAmount = disease; Game.Instance.accumulators.Accumulate(fluidProcessedLastTick, mass); if (mass > 0) { break; } } } if (removedAmount > 0) { float removal = (float)removedAmount / GERMS_PER_KG; storage.ConsumeIgnoringDisease(ElementLoader.FindElementByHash(filterIn).tag, removal); Game.Instance.accumulators.Accumulate(filterConsumedLastTick, removal); if (EMIT_CHLORINE) { float addition = (float)removedAmount / GERMS_PER_KG; Element elementByHash = ElementLoader.FindElementByHash(filterOut); Vector3 outVector3 = new Vector3(this.transform.GetPosition().x, this.transform.GetPosition().y, 0.0f); int outCell = Grid.PosToCell(outVector3); SimMessages.AddRemoveSubstance(outCell, filterOut, CellEventLogger.Instance.OxygenModifierSimUpdate, addition, 273.15f + 45f, Byte.MaxValue, 0); } } //TODO: find out what the nice name is this.storage.Trigger(-1697596308, (object)this.gameObject); }
public static void RequestFluidFromChannel(ValveBase requestor, int channelNo) { Logger.LogFormat("==Entry WarpSpaceManager.RequestFluidFromChannel(requestor={0}, channelNo={1})", requestor.GetInstanceID(), channelNo); try { ConduitFlow flowManager = null; if (requestor.conduitType == LiquidWarpConfig.CONDUIT_TYPE) { flowManager = Conduit.GetFlowManager(ConduitType.Liquid); } else if (requestor.conduitType == GasWarpConfig.CONDUIT_TYPE) { flowManager = Conduit.GetFlowManager(ConduitType.Gas); } else { Logger.Log("unable to determine correct ConduitType."); return; } ValveChannels channels = getChannelsForConduitType(requestor.conduitType); ValvesList providers; if (!channels.TryGetValue(channelNo, out providers) || (providers.Count == 0)) { Logger.LogFormat("No providers for channel {0} found.", channelNo); return; } ValveBase provider = providers.getNext(); ValveBase start = provider; if (null == provider) { Logger.Log("You should never see this message! provider is null"); return; } int toCell = (int)valveBaseOutputCellFieldInfo.GetValue(requestor); ConduitFlow.ConduitContents requestorContents = flowManager.GetContents(toCell); // Fill input cell from various providers, in case when provider's conduit is not full do { Logger.LogFormat("Trying to request from valveBase {0}", provider.GetInstanceID()); int fromCell = (int)valveBaseInputCellFieldInfo.GetValue(provider); if (provider != requestor && flowManager.HasConduit(fromCell)) { ConduitFlow.ConduitContents providerContents = flowManager.GetContents(fromCell); float addedMass = flowManager.AddElement(toCell, providerContents.element, providerContents.mass, providerContents.temperature, providerContents.diseaseIdx, providerContents.diseaseCount); Game.Instance.accumulators.Accumulate(provider.AccumulatorHandle, addedMass); if (addedMass > 0f) { Logger.LogFormat("Adding Element to cell: requestor={0} provider={1} actually added mass={2}, element type={3}", requestor.GetInstanceID(), provider.GetInstanceID(), addedMass, providerContents.element); flowManager.RemoveElement(fromCell, addedMass); Game.Instance.accumulators.Accumulate(requestor.AccumulatorHandle, addedMass); } } if (flowManager.IsConduitFull(toCell)) { break; } provider = providers.getNext(); } while (provider != start); } catch (Exception ex) { Logger.LogFormat("Exception in WarpSpaceManager.RequestFluidFromChannel: {0}\n{1}", ex.Message, ex.StackTrace); } Logger.Log("==Exit WarpSpaceManager.RequestFluidFromChannel"); }
private void ConvertMass() { SimUtil.DiseaseInfo diseaseInfo = SimUtil.DiseaseInfo.Invalid; diseaseInfo.idx = byte.MaxValue; diseaseInfo.count = 0; float speedMultiplier = GetSpeedMultiplier(); // Accumulators float oxygenMass = 0f; float hydrogenMass = 0f; float bleachStoneMass = 0f; float totalConsumedAmount = 0f; float waterConsumptionRate = Config.waterConsumptionRate * speedMultiplier; Tag dirtyWaterTag = SimHashes.DirtyWater.CreateTag(); Tag saltWaterTag = SimHashes.SaltWater.CreateTag(); Tag brineTag = SimHashes.Brine.CreateTag(); bool isDirty = false; for (int i = 0; i < storage.items.Count; i++) { GameObject storageItem = storage.items[i]; if (storageItem != null && storageItem.HasTag(GameTags.AnyWater)) { PrimaryElement element = storageItem.GetComponent <PrimaryElement>(); //element.KeepZeroMassObject = true; float consumedAmount = Mathf.Min(waterConsumptionRate, element.Mass); float consumedPercentage = consumedAmount / element.Mass; int diseaseCount = (int)(consumedPercentage * element.DiseaseCount); element.Mass -= consumedAmount; element.ModifyDiseaseCount(-diseaseCount, "IndustrialElectrolyzer.ConvertMass"); if (storageItem.HasTag(saltWaterTag)) { // 93% H2O oxygenMass += consumedAmount * Config.saltWater2WaterRatio * Config.water2OxygenRatio; hydrogenMass += consumedAmount * Config.saltWater2WaterRatio * Config.water2HydrogenRatio; // 7% NaCl bleachStoneMass += consumedAmount * Config.saltWater2SaltRatio * Config.salt2BleachStoneRatio; } else if (storageItem.HasTag(brineTag)) { // 70% H2O oxygenMass += consumedAmount * Config.brine2WaterRatio * Config.water2OxygenRatio; hydrogenMass += consumedAmount * Config.brine2WaterRatio * Config.water2HydrogenRatio; // 30% NaCl bleachStoneMass += consumedAmount * Config.brine2SaltRatio * Config.salt2BleachStoneRatio; } else { oxygenMass += consumedAmount * Config.water2OxygenRatio; hydrogenMass += consumedAmount * Config.water2HydrogenRatio; } totalConsumedAmount += consumedAmount; if (storageItem.HasTag(dirtyWaterTag) && consumedAmount > EPSILON) { isDirty = true; } diseaseInfo = SimUtil.CalculateFinalDiseaseInfo(diseaseInfo.idx, diseaseInfo.count, element.DiseaseIdx, element.DiseaseCount); waterConsumptionRate -= consumedAmount; if (waterConsumptionRate <= 0f) { Debug.Assert(waterConsumptionRate <= 0f); break; } } } float temperature = GetComponent <PrimaryElement>().Temperature; if (onConvertMass != null && totalConsumedAmount > EPSILON) { onConvertMass(totalConsumedAmount); } ConduitFlow gasFlowManager = Conduit.GetFlowManager(portInfo.conduitType); SimHashes oxygenHash = isDirty ? SimHashes.ContaminatedOxygen : SimHashes.Oxygen; float oxygenGenerated = gasFlowManager.AddElement(oxygenOutputCell, oxygenHash, oxygenMass * speedMultiplier, Mathf.Max(Config.oxygenTemperature, temperature), diseaseInfo.idx, diseaseInfo.count / 2); ReportManager.Instance.ReportValue(ReportManager.ReportType.OxygenCreated, oxygenGenerated, gameObject.GetProperName()); Game.Instance.accumulators.Accumulate(OxygenAccumulator, oxygenGenerated); float hydrogenGenerated = gasFlowManager.AddElement(hydrogenOutputCell, SimHashes.Hydrogen, hydrogenMass * speedMultiplier, Mathf.Max(Config.hydrogenTemperature, temperature), diseaseInfo.idx, diseaseInfo.count / 2); Game.Instance.accumulators.Accumulate(HydrogenAccumulator, hydrogenGenerated); if (bleachStoneMass > EPSILON) { Element bleachStone = ElementLoader.FindElementByHash(SimHashes.BleachStone); Vector3 position = building.GetRotatedOffset(new CellOffset(1, 0)).ToVector3() + new Vector3(.5f, .5f, .0f) + transform.position; UnityEngine.Debug.Log("[AE] transform is at " + transform.position); UnityEngine.Debug.Log("[AE] exit is at " + position); bleachStone.substance.SpawnResource(position, bleachStoneMass, temperature, diseaseInfo.idx, diseaseInfo.count); } storage.Trigger((int)GameHashes.OnStorageChange, gameObject); }
public void UpdateState(float dt) { bool isSatisfied = this.consumer.IsSatisfied; this.envTemp = 0f; this.cellCount = 0; if (this.occupyArea != null && base.gameObject != null) { this.occupyArea.TestArea(Grid.PosToCell(base.gameObject), this, AdvancedAirConditioner.UpdateStateCbDelegate); this.envTemp /= (float)this.cellCount; } _lastEnvTemp(this, this.envTemp); //this.lastEnvTemp = this.envTemp; List <GameObject> items = this.storage.items; for (int i = 0; i < items.Count; i++) { PrimaryElement element = items[i].GetComponent <PrimaryElement>(); if (element.Mass > 0f && (!isLiquidConditioner && element.Element.IsGas || isLiquidConditioner && element.Element.IsLiquid)) { isSatisfied = true; _lastGasTemp(this, element.Temperature); //this.lastGasTemp = storage.Temperature; float temperatureNew = element.Temperature + this.temperatureDelta; if (this.useTarget) { temperatureNew = this.targetTemperature; //# } if (temperatureNew < 1f) { temperatureNew = 1f; this.lowTempLag = Mathf.Min(this.lowTempLag + dt / 5f, 1f); } else { this.lowTempLag = Mathf.Min(this.lowTempLag - dt / 5f, 0f); } _lowTempLag(this, this.lowTempLag); ConduitFlow conduit = this.isLiquidConditioner ? Game.Instance.liquidConduitFlow : Game.Instance.gasConduitFlow; float mass_max = element.Mass; float temperatureCooled = temperatureNew - element.Temperature; if (this.useMassReduction) { // mass cannot be greater than the pipe size minus pipe content //mass_max = Math.Min(mass_max, this.consumer.consumptionRate - conduit.GetContents(this.cooledAirOutputCell).mass); // max of mass that could be moved with the DPUMax float mass_DPU = this.DPUMax / (temperatureCooled * element.Element.specificHeatCapacity); mass_max = Math.Min(mass_max, mass_DPU); } float mass_output = conduit.AddElement(this.cooledAirOutputCell, element.ElementID, mass_max, temperatureNew, element.DiseaseIdx, element.DiseaseCount); element.KeepZeroMassObject = true; float diseasePercent = mass_output / element.Mass; int diseaseCount = (int)((float)element.DiseaseCount * diseasePercent); element.Mass -= mass_output; element.ModifyDiseaseCount(-diseaseCount, "AirConditioner.UpdateState"); float DPU_removed = temperatureCooled * element.Element.specificHeatCapacity * mass_output; float display_dt = (this.lastSampleTime > 0f) ? (Time.time - this.lastSampleTime) : 1f; this.lastSampleTime = Time.time; GameComps.StructureTemperatures.ProduceEnergy(this.structureTemperature, -DPU_removed, STRINGS.BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, display_dt); break; } } if (Time.time - this.lastSampleTime > 2f) { GameComps.StructureTemperatures.ProduceEnergy(this.structureTemperature, 0f, STRINGS.BUILDING.STATUSITEMS.OPERATINGENERGY.PIPECONTENTS_TRANSFER, Time.time - this.lastSampleTime); this.lastSampleTime = Time.time; } this.operational.SetActive(isSatisfied, false); this.Trigger((int)GameHashes.ActiveChanged, this); //this.UpdateStatus(); }
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); }
private void ConduitUpdate(float dt) { ConduitFlow flowManager = Conduit.GetFlowManager(type); if (!flowManager.HasConduit(inputCell)) { return; } if (IsOperational) { ConduitFlow.ConduitContents contents = flowManager.GetContents(inputCell); if (contents.mass <= 0.0) { return; } ConduitFlow.ConduitContents contentOutput1 = flowManager.GetContents(outputCell); ConduitFlow.ConduitContents contentOutput2 = flowManager.GetContents(secondaryOutputCell); var maxMass = Traverse.Create(flowManager).Field("MaxMass").GetValue <float>(); //type == ConduitType.Liquid ? 10f : 1f; var halfMass = contents.mass / 2f; var willFitInOutput1 = maxMass - contentOutput1.mass; var willFitInOutput2 = maxMass - contentOutput2.mass; float delta1 = 0; float delta2 = 0; if (Math.Abs(willFitInOutput1) < 0.001f && Math.Abs(willFitInOutput2) < 0.001f) { //do nothing } else if (!flowManager.HasConduit(secondaryOutputCell)) { delta1 = flowManager.AddElement(outputCell, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); } else if (!flowManager.HasConduit(outputCell)) { delta2 = flowManager.AddElement(secondaryOutputCell, contents.element, contents.mass, contents.temperature, contents.diseaseIdx, contents.diseaseCount); } else if (willFitInOutput1 >= halfMass && willFitInOutput2 >= halfMass) { delta1 = flowManager.AddElement(outputCell, contents.element, halfMass, contents.temperature, contents.diseaseIdx, contents.diseaseCount / 2); delta2 = flowManager.AddElement(secondaryOutputCell, contents.element, halfMass, contents.temperature, contents.diseaseIdx, contents.diseaseCount / 2); } else if (willFitInOutput1 < halfMass) { var overflowOutput1 = halfMass - willFitInOutput1; var ratio = (halfMass - overflowOutput1) / halfMass; delta1 = flowManager.AddElement(outputCell, contents.element, halfMass - overflowOutput1, contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * ratio)); delta2 = flowManager.AddElement(secondaryOutputCell, contents.element, halfMass + overflowOutput1, contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * (1f / ratio))); } else { var overflowOutput2 = halfMass - willFitInOutput2; var ratio = (halfMass - overflowOutput2) / halfMass; delta1 = flowManager.AddElement(secondaryOutputCell, contents.element, halfMass - overflowOutput2, contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * ratio)); delta2 = flowManager.AddElement(outputCell, contents.element, halfMass + overflowOutput2, contents.temperature, contents.diseaseIdx, (int)((contents.diseaseCount / 2f) * (1f / ratio))); } flowManager.RemoveElement(inputCell, delta1); flowManager.RemoveElement(inputCell, delta2); Game.Instance.accumulators.Accumulate(accumulator, contents.mass); } }
protected override void ConduitTick(float delta) { UpdateConduitBlockedStatus(); bool dispensed = false; if (!operational.IsOperational && !AlwaysDispense) { return; } foreach (GameObject item in storage.items) { if (item.GetComponent <PrimaryElement>()?.Element.id == SimHashes.Water) { item.AddOrGet <Pickupable>(); } } PrimaryElement element = FindSuitableElement(); if (element != null) { element.KeepZeroMassObject = true; IConduitFlow iConduitManager = GetConduitManager(); if (iConduitManager == null) { Debug.LogError($"[MultiIO] OutputPort.ConduitTick(): iConduitManager is null"); } //Solid Conduits do not use the same kind of flow manager, so the code must be separated if (ConduitType == ConduitType.Solid) { SolidConduitFlow solidManager = iConduitManager as SolidConduitFlow; if (solidManager == null) { Debug.LogError($"[MultiIO] OutputPort.ConduitTick(): solidManager is null"); } //Solid conveyor only needs to take elements with a Pikcupable component. The only difference between Water and Bottled Water is a Pikcupable component. Pickupable pickup = element.gameObject.GetComponent <Pickupable>(); if (pickup == null) { return; } if (pickup.PrimaryElement.Mass > SolidOutputMax) { pickup = pickup.Take(SolidOutputMax); } solidManager.AddPickupable(portCell, pickup); dispensed = true; } else if (ConduitType == ConduitType.Liquid || ConduitType == ConduitType.Gas) { ConduitFlow conduitManager = iConduitManager as ConduitFlow; if (conduitManager == null) { Debug.LogError($"[MutiIO] OutputPort.ConduitTick(): conduitManager is null"); return; } float amountMoved = conduitManager.AddElement(portCell, element.ElementID, element.Mass, element.Temperature, element.DiseaseIdx, element.DiseaseCount); if (amountMoved > 0f) { float movedRatio = amountMoved / element.Mass; int movedDisease = (int)(movedRatio * (float)element.DiseaseCount); element.ModifyDiseaseCount(-movedDisease, "ConduitDispenser.ConduitUpdate"); element.Mass -= amountMoved; _parent.Trigger((int)GameHashes.OnStorageChange, element.gameObject); dispensed = true; } } } isDispensing = dispensed; }