public void ExposeHotspot(Vector3Int position, float temperature, float volume) { if (hotspots.ContainsKey(position) && hotspots[position].Hotspot != null) { // TODO soh? hotspots[position].Hotspot.UpdateValues(volume * 25, temperature); } else { MetaDataNode node = metaDataLayer.Get(position); GasMix gasMix = node.GasMix; if (gasMix.GetMoles(Gas.Plasma) > 0.5 && gasMix.GetMoles(Gas.Oxygen) > 0.5 && temperature > Reactions.PLASMA_MINIMUM_BURN_TEMPERATURE) { // igniting Hotspot hotspot = new Hotspot(node, temperature, volume * 25); node.Hotspot = hotspot; hotspots[position] = node; } } if (hotspots.ContainsKey(position) && hotspots[position].Hotspot != null) { List <LivingHealthBehaviour> healths = matrix.Get <LivingHealthBehaviour>(position); foreach (LivingHealthBehaviour health in healths) { health.ApplyDamage(null, 1, DamageType.Burn); } } }
private float HandleBreathing(GasMix breathGasMix) { float oxygenPressure = breathGasMix.GetPressure(Gas.Oxygen); float oxygenUsed = 0; if (oxygenPressure < OXYGEN_SAFE_MIN) { if (Random.value < 0.2) { PostToChatMessage.Send("gasp", ChatChannel.Local); } if (oxygenPressure > 0) { float ratio = 1 - oxygenPressure / OXYGEN_SAFE_MIN; ApplyDamage(Mathf.Min(5 * ratio, 3), DamageType.Oxy); bloodSystem.OxygenLevel += 30 * ratio; oxygenUsed = breathGasMix.GetMoles(Gas.Oxygen) * ratio; } else { ApplyDamage(3, DamageType.Oxy); } } else { oxygenUsed = breathGasMix.GetMoles(Gas.Oxygen); bloodSystem.OxygenLevel += 30; } return(oxygenUsed); }
private float HandleBreathing(GasMix breathGasMix) { float oxygenPressure = breathGasMix.GetPressure(Gas.Oxygen); float oxygenUsed = 0; if (oxygenPressure < OXYGEN_SAFE_MIN) { if (Random.value < 0.1) { Chat.AddActionMsgToChat(gameObject, "You gasp for breath", $"{gameObject.name} gasps"); } if (oxygenPressure > 0) { float ratio = 1 - oxygenPressure / OXYGEN_SAFE_MIN; bloodSystem.OxygenDamage += 1 * ratio; oxygenUsed = breathGasMix.GetMoles(Gas.Oxygen) * ratio; } else { bloodSystem.OxygenDamage += 1; } IsSuffocating = true; } else { oxygenUsed = breathGasMix.GetMoles(Gas.Oxygen); IsSuffocating = false; bloodSystem.OxygenDamage -= 2.5f; breatheCooldown = 4; } return(oxygenUsed); }
private float HandleBreathing(GasMix breathGasMix) { float oxygenPressure = breathGasMix.GetPressure(Gas.Oxygen); float oxygenUsed = 0; if (oxygenPressure < OXYGEN_SAFE_MIN) { if (Random.value < 0.1) { PostToChatMessage.SendGasp(base.gameObject); } if (oxygenPressure > 0) { float ratio = 1 - oxygenPressure / OXYGEN_SAFE_MIN; bloodSystem.OxygenDamage += 1 * ratio; oxygenUsed = breathGasMix.GetMoles(Gas.Oxygen) * ratio; } else { bloodSystem.OxygenDamage += 1; } IsSuffocating = true; } else { oxygenUsed = breathGasMix.GetMoles(Gas.Oxygen); IsSuffocating = false; bloodSystem.OxygenDamage -= 2.5f; breatheCooldown = 4; } return(oxygenUsed); }
public void ExposeHotspot(Vector3Int localPosition, float temperature, float volume) { if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null) { // TODO soh? hotspots[localPosition].Hotspot.UpdateValues(volume * 25, temperature); } else { MetaDataNode node = metaDataLayer.Get(localPosition); GasMix gasMix = node.GasMix; if (gasMix.GetMoles(Gas.Plasma) > 0.5 && gasMix.GetMoles(Gas.Oxygen) > 0.5 && temperature > Reactions.PLASMA_MINIMUM_BURN_TEMPERATURE) { // igniting Hotspot hotspot = new Hotspot(node, temperature, volume * 25); node.Hotspot = hotspot; hotspots[localPosition] = node; } } if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null) { //expose everything on this tile Expose(localPosition, localPosition); //expose impassable things on the adjacent tile Expose(localPosition, localPosition + Vector3Int.right); Expose(localPosition, localPosition + Vector3Int.left); Expose(localPosition, localPosition + Vector3Int.up); Expose(localPosition, localPosition + Vector3Int.down); } }
public void ExposeHotspot(Vector3Int localPosition, float temperature, float volume) { if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null) { // TODO soh? hotspots[localPosition].Hotspot.UpdateValues(volume * 25, temperature); } else { Profiler.BeginSample("MarkForAddition"); MetaDataNode node = metaDataLayer.Get(localPosition); GasMix gasMix = node.GasMix; if (gasMix.GetMoles(Gas.Plasma) > 0.5 && gasMix.GetMoles(Gas.Oxygen) > 0.5 && temperature > Reactions.PlasmaMaintainFire) { // igniting //addition will be done later in Update hotspotsToAdd.Add(new Hotspot(node, temperature, volume * 25)); } Profiler.EndSample(); } if (hotspots.ContainsKey(localPosition) && hotspots[localPosition].Hotspot != null) { //expose everything on this tile Expose(localPosition, localPosition); //expose impassable things on the adjacent tile Expose(localPosition, localPosition + Vector3Int.right); Expose(localPosition, localPosition + Vector3Int.left); Expose(localPosition, localPosition + Vector3Int.up); Expose(localPosition, localPosition + Vector3Int.down); } }
/// <summary> /// Placeholder method to add some effects for breathing plasma. Eventually this behavior should be /// handled with interfaces we can implement so different species react differently. /// </summary> /// <param name="plasmaAmount"></param> private float HandleBreathingPlasma(GasMix gasMix) { float plasmaPressure = gasMix.GetPressure(Gas.Plasma); float plasmaConsumed = 0; plasmaConsumed = gasMix.GetMoles(Gas.Plasma) * AtmosConstants.BREATH_VOLUME; // there is some plasma in the ambient but it is still safe if (plasmaPressure <= PLASMA_SAFE_MAX && plasmaPressure > PLASMA_WARNING_LEVEL) { if (DMMath.Prob(90)) { return(plasmaConsumed); } // 10% chances of message var theirPronoun = gameObject.Player() != null ? gameObject.Player().Script.characterSettings.TheirPronoun(gameObject.Player().Script) : "its"; Chat.AddActionMsgToChat( gameObject, plasmaLowYouMessages.PickRandom(), string.Format( plasmaLowOthersMessages.PickRandom(), gameObject.ExpensiveName(), string.Format(plasmaLowOthersMessages.PickRandom(), gameObject.ExpensiveName(), theirPronoun)) ); } // enough plasma to be visible and damage us! else if (plasmaPressure > PLASMA_SAFE_MAX) { var plasmaDamage = (gasMix.GetMoles(Gas.Plasma) / PLASMA_SAFE_MAX) * 10; bloodSystem.ToxinLevel = Mathf.Clamp(bloodSystem.ToxinLevel + Mathf.Clamp(plasmaDamage, MIN_TOXIN_DMG, MAX_TOXIN_DMG), 0, 200); if (DMMath.Prob(90)) { return(plasmaConsumed); } // 10% chances of message var theirPronoun = gameObject.Player() != null ? gameObject.Player().Script.characterSettings.TheirPronoun(gameObject.Player().Script) : "its"; Chat.AddActionMsgToChat( gameObject, plasmaHighYouMessages.PickRandom(), string.Format(plasmaHighOthersMessages.PickRandom(), gameObject.ExpensiveName(), theirPronoun) ); } return(plasmaConsumed); }
public void React(GasMix gasMix, MetaDataNode node) { var oxyMoles = gasMix.GetMoles(Gas.Oxygen); gasMix.AddGas(Gas.Plasma, oxyMoles); gasMix.RemoveGas(Gas.Oxygen, oxyMoles); }
public void React(GasMix gasMix, Vector3 tilePos, Matrix matrix) { var oxyMoles = gasMix.GetMoles(Gas.Oxygen); gasMix.AddGas(Gas.Plasma, oxyMoles); gasMix.RemoveGas(Gas.Oxygen, oxyMoles); }
public void ExposeHotspot(Vector3Int position, float temperature, float volume) { if (hotspots.ContainsKey(position) && hotspots[position].Hotspot != null) { // TODO soh? hotspots[position].Hotspot.UpdateValues(volume * 25, temperature); } else { MetaDataNode node = metaDataLayer.Get(position); GasMix gasMix = node.Atmos; if (gasMix.GetMoles(Gas.Plasma) > 0.5 && gasMix.GetMoles(Gas.Oxygen) > 0.5 && temperature > Reactions.PLASMA_MINIMUM_BURN_TEMPERATURE) { // igniting Hotspot hotspot = new Hotspot(node, temperature, volume * 25); node.Hotspot = hotspot; hotspots[position] = node; } } }
private float HandleBreathing(GasMix gasMix) { float oxygenPressure = gasMix.GetPressure(Gas.Oxygen); float plasmaAmount = gasMix.GetMoles(Gas.Plasma); float oxygenUsed = 0; if (plasmaAmount > 0) { HandleBreathingPlasma(plasmaAmount); } if (oxygenPressure < OXYGEN_SAFE_MIN) { if (Random.value < 0.1) { Chat.AddActionMsgToChat(gameObject, "You gasp for breath", $"{gameObject.ExpensiveName()} gasps"); } if (oxygenPressure > 0) { float ratio = 1 - oxygenPressure / OXYGEN_SAFE_MIN; bloodSystem.OxygenDamage += 1 * ratio; oxygenUsed = gasMix.GetMoles(Gas.Oxygen) * ratio * AtmosConstants.BREATH_VOLUME; } else { bloodSystem.OxygenDamage += 1; } IsSuffocating = true; } else { oxygenUsed = gasMix.GetMoles(Gas.Oxygen) * AtmosConstants.BREATH_VOLUME; IsSuffocating = false; bloodSystem.OxygenDamage -= 2.5f; breatheCooldown = 4; } return(oxygenUsed); }
/// <summary> /// Pulls in the desired gas, as well as others, from the specified gas mix and adds them to the blood stream /// </summary> /// <param name="gasMix">The gas mix to breathe in from</param> /// <param name="blood">The blood to put gases into</param> /// <returns> True if breathGasMix was changed </returns> private bool BreatheIn(GasMix breathGasMix, ReagentMix blood, float efficiency) { if (RelatedPart.HealthMaster.RespiratorySystem.CanBreathAnywhere) { blood.Add(RelatedPart.requiredReagent, RelatedPart.bloodType.GetSpareGasCapacity(blood)); return(false); } ReagentMix toInhale = new ReagentMix(); var Available = RelatedPart.bloodType.GetGasCapacityOfnonMeanCarrier(blood); var TotalMoles = breathGasMix.Moles; ToxinBreathinCheck(breathGasMix); foreach (var gasValues in breathGasMix.GasData.GasesArray) { var gas = gasValues.GasSO; if (GAS2ReagentSingleton.Instance.DictionaryGasToReagent.ContainsKey(gas) == false) { continue; } // n = PV/RT float gasMoles = breathGasMix.GetMoles(gas); // Get as much as we need, or as much as in the lungs, whichever is lower Reagent gasReagent = GAS2ReagentSingleton.Instance.GetGasToReagent(gas); float molesRecieved = 0; if (gasReagent == RelatedPart.bloodType.CirculatedReagent) { molesRecieved = Mathf.Min(gasMoles, RelatedPart.bloodType.GetSpareGasCapacity(blood, gasReagent)); } else { if (gasMoles == 0) { molesRecieved = 0; } else { molesRecieved = Available / (TotalMoles / gasMoles); molesRecieved = Mathf.Min(molesRecieved, gasMoles); } } if (molesRecieved > 0) { toInhale.Add(gasReagent, molesRecieved * efficiency); } //TODO: Add pressureSafeMax check here, for hyperoxia } RelatedPart.HealthMaster.RespiratorySystem.GasExchangeToBlood(breathGasMix, blood, toInhale); // Counterintuitively, in humans respiration is stimulated by pressence of CO2 in the blood, not lack of oxygen // May want to change this code to reflect that in the future so people don't hyperventilate when they are on nitrous oxide var inGas = GAS2ReagentSingleton.Instance.GetGasToReagent(requiredGas); float bloodCap = RelatedPart.bloodType.GetGasCapacity(RelatedPart.BloodContainer.CurrentReagentMix); float foreignCap = RelatedPart.bloodType.GetGasCapacityForeign(RelatedPart.BloodContainer.CurrentReagentMix); float bloodSaturation = 0; if (bloodCap + foreignCap == 0) { bloodSaturation = 0; } else { var ratioNativeBlood = bloodCap / (bloodCap + foreignCap); bloodSaturation = RelatedPart.BloodContainer[RelatedPart.requiredReagent] * ratioNativeBlood / bloodCap; } if (bloodSaturation >= RelatedPart.HealthMaster.CirculatorySystem.BloodInfo.BLOOD_REAGENT_SATURATION_OKAY) { currentBreatheCooldown = breatheCooldown; //Slow breathing, we're all good RelatedPart.HealthMaster.HealthStateController.SetSuffocating(false); } else if (bloodSaturation <= RelatedPart.HealthMaster.CirculatorySystem.BloodInfo.BLOOD_REAGENT_SATURATION_BAD) { RelatedPart.HealthMaster.HealthStateController.SetSuffocating(true); if (Random.value < 0.2) { Chat.AddActionMsgToChat(RelatedPart.HealthMaster.gameObject, "You gasp for breath", $"{RelatedPart.HealthMaster.playerScript.visibleName} gasps"); } } //Debug.Log("Gas inhaled: " + toInhale.Total + " Saturation: " + saturation); return(toInhale.Total > 0); }
private bool HandleWearingGasMask(GasMix gasMix) { bool filtered = false; // if there is too much CO2 in the air if (gasMix.GetMoles(Gas.CarbonDioxide) >= 30) { GasMix gasMix2 = gasMix; gasMix2.RemoveGas(Gas.CarbonDioxide, 30); HandleBreathingCarbonDioxide(gasMix2); filtered = true; } // if there is too much plasma in the air if (gasMix.GetMoles(Gas.Plasma) >= 25) { GasMix gasMix2 = gasMix; gasMix2.RemoveGas(Gas.Plasma, 25); float plasmaBreathedWithMask = HandleBreathingPlasma(gasMix2); if (plasmaBreathedWithMask > 0) { gasMix.RemoveGas(Gas.Plasma, plasmaBreathedWithMask); registerTile.Matrix.MetaDataLayer.UpdateSystemsAt(registerTile.LocalPositionClient, SystemType.AtmosSystem); } filtered = true; } //if there's not enough to cause the plasma or CO2 warnings, skip the breathe messages if ((gasMix.GetMoles(Gas.Plasma) < PLASMA_WARNING_LEVEL && gasMix.GetMoles(Gas.Plasma) > 0) || (gasMix.GetMoles(Gas.CarbonDioxide) < CARBON_DIOXIDE_WARNING_LEVEL && gasMix.GetMoles(Gas.CarbonDioxide) > 0)) { return(true); } //if somehow both are 0 return false if (gasMix.GetMoles(Gas.Plasma) == 0 && gasMix.GetMoles(Gas.CarbonDioxide) == 0) { return(false); } if (DMMath.Prob(90)) { return(true); } if (!filtered) { // 10% chance of message var theirPronoun = gameObject.Player() != null ? gameObject.Player().Script.characterSettings.TheirPronoun(gameObject.Player().Script) : "its"; Chat.AddActionMsgToChat( gameObject, GasMaskFiltered.PickRandom(), string.Format( GasMaskFilteredOthers.PickRandom(), gameObject.ExpensiveName(), string.Format(plasmaLowOthersMessages.PickRandom(), gameObject.ExpensiveName(), theirPronoun)) ); return(true); } return(false); }
/// <summary> /// Pulls in the desired gas, as well as others, from the specified gas mix and adds them to the blood stream /// </summary> /// <param name="gasMix">The gas mix to breathe in from</param> /// <param name="blood">The blood to put gases into</param> /// <returns> True if breathGasMix was changed </returns> private bool BreatheIn(GasMix breathGasMix, ReagentMix blood, float efficiency) { if (RelatedPart.HealthMaster.RespiratorySystem.CanBreatheAnywhere) { blood.Add(RelatedPart.requiredReagent, RelatedPart.bloodType.GetSpareGasCapacity(blood)); return(false); } ReagentMix toInhale = new ReagentMix(); var Available = RelatedPart.bloodType.GetNormalGasCapacity(blood); ToxinBreathinCheck(breathGasMix); float PercentageCanTake = 1; if (breathGasMix.Moles != 0) { PercentageCanTake = LungSize / breathGasMix.Moles; } if (PercentageCanTake > 1) { PercentageCanTake = 1; } var PressureMultiplier = breathGasMix.Pressure / pressureSafeMin; if (PressureMultiplier > 1) { PressureMultiplier = 1; } var TotalMoles = breathGasMix.Moles * PercentageCanTake; lock (breathGasMix.GasData.GasesArray) //no Double lock { foreach (var gasValues in breathGasMix.GasData.GasesArray) { var gas = gasValues.GasSO; if (Gas.GasToReagent.TryGetValue(gas, out var gasReagent) == false) { continue; } // n = PV/RT float gasMoles = breathGasMix.GetMoles(gas) * PercentageCanTake; // Get as much as we need, or as much as in the lungs, whichever is lower float molesRecieved = 0; if (gasReagent == RelatedPart.bloodType.CirculatedReagent) { var PercentageMultiplier = (gasMoles / (TotalMoles)); molesRecieved = RelatedPart.bloodType.GetSpecialGasCapacity(blood) * PercentageMultiplier * PressureMultiplier; } else if (gasMoles != 0) { molesRecieved = (Available * (gasMoles / TotalMoles)) * PressureMultiplier; } if (molesRecieved > 0) { toInhale.Add(gasReagent, molesRecieved); } } } RelatedPart.HealthMaster.RespiratorySystem.GasExchangeToBlood(breathGasMix, blood, toInhale, LungSize); // Counterintuitively, in humans respiration is stimulated by pressence of CO2 in the blood, not lack of oxygen // May want to change this code to reflect that in the future so people don't hyperventilate when they are on nitrous oxide float bloodCap = RelatedPart.bloodType.GetNormalGasCapacity(RelatedPart.BloodContainer.CurrentReagentMix); var bloodSaturation = 0f; if (bloodCap > 0) { bloodSaturation = RelatedPart.BloodContainer[RelatedPart.requiredReagent] / bloodCap; } if (bloodSaturation >= RelatedPart.HealthMaster.CirculatorySystem.BloodInfo.BLOOD_REAGENT_SATURATION_OKAY) { currentBreatheCooldown = breatheCooldown; //Slow breathing, we're all good RelatedPart.HealthMaster.HealthStateController.SetSuffocating(false); } else if (bloodSaturation <= RelatedPart.HealthMaster.CirculatorySystem.BloodInfo.BLOOD_REAGENT_SATURATION_BAD) { RelatedPart.HealthMaster.HealthStateController.SetSuffocating(true); if (DMMath.Prob(20)) { Chat.AddActionMsgToChat(RelatedPart.HealthMaster.gameObject, "You gasp for breath!", $"{RelatedPart.HealthMaster.playerScript.visibleName} gasps!"); } } //Debug.Log("Gas inhaled: " + toInhale.Total + " Saturation: " + saturation); return(toInhale.Total > 0); }