private void UpdateOxygen() { if (!MySession.Static.Settings.EnableOxygen) { return; } // Try to find grids that might contain oxygen var entities = new List <MyEntity>(); var aabb = PositionComp.WorldAABB; MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref aabb, entities); bool lowOxygenDamage = true; bool noOxygenDamage = true; bool isInEnvironment = true; EnvironmentOxygenLevel = MyOxygenProviderSystem.GetOxygenInPoint(PositionComp.GetPosition()); var cockpit = Parent as MyCockpit; if (cockpit != null && cockpit.BlockDefinition.IsPressurized) { if (Sync.IsServer && MySession.Static.SurvivalMode) { if (!Definition.NeedsOxygen && m_suitOxygenAmount > Definition.OxygenConsumption) { m_suitOxygenAmount -= Definition.OxygenConsumption; if (m_suitOxygenAmount < 0f) { m_suitOxygenAmount = 0f; } } if (cockpit.OxygenLevel > 0f) { if (Definition.NeedsOxygen) { if (cockpit.OxygenAmount >= Definition.OxygenConsumption) { cockpit.OxygenAmount -= Definition.OxygenConsumption; noOxygenDamage = false; lowOxygenDamage = false; } } else { float oxygenTransferred = Math.Min(SuitOxygenAmountMissing, cockpit.OxygenAmount); oxygenTransferred = Math.Min(oxygenTransferred, MyOxygenConstants.OXYGEN_REGEN_PER_SECOND); cockpit.OxygenAmount -= oxygenTransferred; SuitOxygenAmount += oxygenTransferred; noOxygenDamage = false; lowOxygenDamage = false; } } } EnvironmentOxygenLevel = cockpit.OxygenLevel; isInEnvironment = false; } else { Vector3D pos = PositionComp.WorldMatrix.Translation; if (m_headBoneIndex != -1) { pos = (BoneAbsoluteTransforms[m_headBoneIndex] * WorldMatrix).Translation; } foreach (var entity in entities) { var grid = entity as MyCubeGrid; // Oxygen can be present on small grids as well because of mods if (grid != null) { var oxygenBlock = grid.GridSystems.OxygenSystem.GetSafeOxygenBlock(pos); if (oxygenBlock.Room != null) { if (oxygenBlock.Room.OxygenLevel(grid.GridSize) > Definition.PressureLevelForLowDamage) { if (Definition.NeedsOxygen) { lowOxygenDamage = false; } } if (oxygenBlock.Room.IsPressurized) { EnvironmentOxygenLevel = oxygenBlock.Room.OxygenLevel(grid.GridSize); if (oxygenBlock.Room.OxygenAmount > Definition.OxygenConsumption) { if (Definition.NeedsOxygen) { noOxygenDamage = false; oxygenBlock.PreviousOxygenAmount = oxygenBlock.OxygenAmount() - Definition.OxygenConsumption; oxygenBlock.OxygenChangeTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; oxygenBlock.Room.OxygenAmount -= Definition.OxygenConsumption; } break; } } else { EnvironmentOxygenLevel = oxygenBlock.Room.EnvironmentOxygen; if (EnvironmentOxygenLevel > Definition.OxygenConsumption) { if (Definition.NeedsOxygen) { noOxygenDamage = false; } break; } } isInEnvironment = false; } } } } if (MySession.LocalCharacter == this) { if (m_oldSuitOxygenLevel >= 0.25f && SuitOxygenLevel < 0.25f) { MyHud.Notifications.Add(m_lowOxygenNotification); } else if (m_oldSuitOxygenLevel >= 0.05f && SuitOxygenLevel < 0.05f) { MyHud.Notifications.Add(m_criticalOxygenNotification); } } m_oldSuitOxygenLevel = SuitOxygenLevel; // Cannot early exit before calculations because of UI if (!Sync.IsServer || MySession.Static.CreativeMode) { return; } //TODO(AF) change this to a constant //Try to refill the suit from bottles in inventory if (SuitOxygenLevel < 0.3f && !Definition.NeedsOxygen) { var items = Inventory.GetItems(); bool bottlesUsed = false; foreach (var item in items) { var oxygenContainer = item.Content as MyObjectBuilder_OxygenContainerObject; if (oxygenContainer != null) { if (oxygenContainer.OxygenLevel == 0f) { continue; } var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(oxygenContainer) as MyOxygenContainerDefinition; float oxygenAmount = oxygenContainer.OxygenLevel * physicalItem.Capacity; float transferredAmount = Math.Min(oxygenAmount, SuitOxygenAmountMissing); oxygenContainer.OxygenLevel = (oxygenAmount - transferredAmount) / physicalItem.Capacity; if (oxygenContainer.OxygenLevel < 0f) { oxygenContainer.OxygenLevel = 0f; } if (oxygenContainer.OxygenLevel > 1f) { Debug.Fail("Incorrect value"); } Inventory.UpdateOxygenAmount(); Inventory.SyncOxygenContainerLevel(item.ItemId, oxygenContainer.OxygenLevel); bottlesUsed = true; SuitOxygenAmount += transferredAmount; if (SuitOxygenLevel == 1f) { break; } } } if (bottlesUsed) { if (MySession.LocalCharacter == this) { ShowRefillFromBottleNotification(); } else { SyncObject.SendRefillFromBottle(); } } } // No oxygen found in room, try to get it from suit if (noOxygenDamage || lowOxygenDamage) { if (!Definition.NeedsOxygen && m_suitOxygenAmount > Definition.OxygenConsumption) { m_suitOxygenAmount -= Definition.OxygenConsumption; if (m_suitOxygenAmount < 0f) { m_suitOxygenAmount = 0f; } noOxygenDamage = false; lowOxygenDamage = false; } if (isInEnvironment) { if (EnvironmentOxygenLevel > Definition.PressureLevelForLowDamage) { lowOxygenDamage = false; } if (EnvironmentOxygenLevel > 0f) { noOxygenDamage = false; } } } if (noOxygenDamage) { DoDamage(Definition.DamageAmountAtZeroPressure, MyDamageType.LowPressure, true); } else if (lowOxygenDamage) { DoDamage(1f, MyDamageType.Asphyxia, true); } SyncObject.UpdateOxygen(SuitOxygenAmount); }