private bool Breathe(IGasMixContainer node) { breatheCooldown--; //not timebased, but tickbased if (breatheCooldown > 0) { return(false); } // if no internal breathing is possible, get the from the surroundings IGasMixContainer container = GetInternalGasMix() ?? node; GasMix gasMix = container.GasMix; GasMix breathGasMix = gasMix.RemoveVolume(AtmosConstants.BREATH_VOLUME, true); float oxygenUsed = HandleBreathing(breathGasMix); if (oxygenUsed > 0) { breathGasMix.RemoveGas(Gas.Oxygen, oxygenUsed); node.GasMix.AddGas(Gas.CarbonDioxide, oxygenUsed); registerTile.Matrix.MetaDataLayer.UpdateSystemsAt(registerTile.LocalPositionClient); } gasMix += breathGasMix; container.GasMix = gasMix; return(oxygenUsed > 0); }
/// <summary> /// Performs the action of breathing, expelling waste products from the used blood pool and refreshing /// the desired blood reagent (ie oxygen) /// </summary> /// <param name="node">The gas node at this lung's position</param> /// <returns>True if gas was exchanged</returns> public bool TryBreathing(IGasMixContainer node, float efficiency) { //Base effeciency is a little strong on the lungs //efficiency = (1 + efficiency) / 2; //Breathing is not timebased, but tick based, it will be slow when the blood has all the oxygen it needs //and will speed up if more oxygen is needed currentBreatheCooldown--; if (currentBreatheCooldown > 0) { return(false); } if (healthMaster.CirculatorySystem.UsedBloodPool[bloodType] == 0) { return(false); //No point breathing if we dont have blood. } // Try to get internal breathing if possible, otherwise get from the surroundings IGasMixContainer container = healthMaster.RespiratorySystem.GetInternalGasMix() ?? node; ReagentMix AvailableBlood = healthMaster.CirculatorySystem.UsedBloodPool.Take(healthMaster.CirculatorySystem.UsedBloodPool.Total); bool tryExhale = BreatheOut(container.GasMix, AvailableBlood, efficiency); bool tryInhale = BreatheIn(container.GasMix, AvailableBlood, efficiency); healthMaster.CirculatorySystem.ReadyBloodPool.Add(AvailableBlood); return(tryExhale || tryInhale); }
/// <summary> /// Performs the action of breathing, expelling waste products from the used blood pool and refreshing /// the desired blood reagent (ie oxygen) /// </summary> /// <param name="node">The gas node at this lung's position</param> /// <returns>True if gas was exchanged</returns> public bool TryBreathing(IGasMixContainer node, float efficiency) { //Base effeciency is a little strong on the lungs //efficiency = (1 + efficiency) / 2; //Breathing is not timebased, but tick based, it will be slow when the blood has all the oxygen it needs //and will speed up if more oxygen is needed currentBreatheCooldown--; if (currentBreatheCooldown > 0) { return(false); } if (RelatedPart.HealthMaster.CirculatorySystem.BloodPool[RelatedPart.bloodType] == 0) { return(false); //No point breathing if we dont have blood. } // Try to get internal breathing if possible, otherwise get from the surroundings IGasMixContainer container = RelatedPart.HealthMaster.RespiratorySystem.GetInternalGasMix(); var gasMixSink = node.GasMix; // Where to dump lung exhaust if (container == null) { // Could be in a container that has an internal gas mix, else use the tile's gas mix. var parentContainer = RelatedPart.HealthMaster.ObjectBehaviour.parentContainer; if (parentContainer != null && parentContainer.TryGetComponent <GasContainer>(out var gasContainer)) { container = gasContainer; gasMixSink = container.GasMix; } else { container = node; } } if (efficiency > 1) { efficiency = 1; } ReagentMix AvailableBlood = RelatedPart.HealthMaster.CirculatorySystem.BloodPool.Take( (RelatedPart.HealthMaster.CirculatorySystem.BloodPool.Total * efficiency) / 2f); bool tryExhale = BreatheOut(gasMixSink, AvailableBlood); bool tryInhale = BreatheIn(container.GasMix, AvailableBlood, efficiency); RelatedPart.HealthMaster.CirculatorySystem.BloodPool.Add(AvailableBlood); return(tryExhale || tryInhale); }
private bool Breathe(IGasMixContainer node) { breatheCooldown--; //not timebased, but tickbased if (breatheCooldown > 0) { return(false); } // if no internal breathing is possible, get the from the surroundings IGasMixContainer container = GetInternalGasMix() ?? node; GasMix gasMix = container.GasMix; float plasmaConsumed = 0; bool carbonDioxideInhaled = false; bool gasFiltered = false; float oxygenUsed = HandleBreathingOxygen(gasMix); if (isWearingGasMask()) { gasFiltered = HandleWearingGasMask(gasMix); } if (gasFiltered == false) { plasmaConsumed = HandleBreathingPlasma(gasMix); carbonDioxideInhaled = HandleBreathingCarbonDioxide(gasMix); } if (oxygenUsed > 0) { gasMix.RemoveGas(Gas.Oxygen, oxygenUsed); node.GasMix.AddGas(Gas.CarbonDioxide, oxygenUsed); registerTile.Matrix.MetaDataLayer.UpdateSystemsAt(registerTile.LocalPositionClient, SystemType.AtmosSystem); } if (plasmaConsumed > 0) { gasMix.RemoveGas(Gas.Plasma, plasmaConsumed); registerTile.Matrix.MetaDataLayer.UpdateSystemsAt(registerTile.LocalPositionClient, SystemType.AtmosSystem); } if (oxygenUsed > 0 || plasmaConsumed > 0 || carbonDioxideInhaled) { return(true); } return(false); }
private bool Breathe(IGasMixContainer node) { // if no internal breathing is possible, get the from the surroundings IGasMixContainer container = GetInternalGasMix() ?? node; GasMix gasMix = container.GasMix; GasMix breathGasMix = gasMix.RemoveVolume(AtmosConstants.BREATH_VOLUME, true); float oxygenUsed = HandleBreathing(breathGasMix); if (oxygenUsed > 0) { breathGasMix.RemoveGas(Gas.Oxygen, oxygenUsed); breathGasMix.AddGas(Gas.CarbonDioxide, oxygenUsed); } gasMix += breathGasMix; container.GasMix = gasMix; return(oxygenUsed > 0); }