public override void OnAddedToScene(object source) { base.OnAddedToScene(source); MyPlanets.Register(this); MyGravityProviderSystem.AddNaturalGravityProvider(Components.Get <MyGravityProviderComponent>()); MyOxygenProviderSystem.AddOxygenGenerator(this); }
public override void OnRemovedFromScene(object source) { base.OnRemovedFromScene(source); MyPlanets.UnRegister(this); MyGravityProviderSystem.RemoveNaturalGravityProvider(Components.Get <MyGravityProviderComponent>()); MyOxygenProviderSystem.RemoveOxygenGenerator(this); }
public override void OnRemovedFromScene(object source) { base.OnRemovedFromScene(source); MyPlanets.UnRegister(this); MyGravityProviderSystem.RemovePlanet(this); MyOxygenProviderSystem.RemoveOxygenGenerator(this); }
public override void OnAddedToScene(object source) { base.OnAddedToScene(source); MyPlanets.Register(this); MyGravityProviderSystem.AddPlanet(this); MyOxygenProviderSystem.AddOxygenGenerator(this); }
private bool IsInOxygen() { // we cannot use cached value from update100: // example: character leaves enviroment with oxygen and enters void, realistic sound (sound in void) should be played // ...but cached MySession.LocalCharacter.OxygenComponent.EnvironmentOxygenLevel can be still on full level! if (MySession.Static.LocalCharacter == null) { return(false); } float oxygenOnPlayerPos = MyOxygenProviderSystem.GetOxygenInPoint(MySession.Static.LocalCharacter.PositionComp.GetPosition()); return(oxygenOnPlayerPos > 0.1f); }
protected override void Closing() { base.Closing(); MyGravityProviderSystem.RemovePlanet(this); MyOxygenProviderSystem.RemoveOxygenGenerator(this); if (m_physicsShapes != null) { foreach (var voxelMap in m_physicsShapes) { voxelMap.Value.Close(); } } }
void DrainFromRoom(float amount) { if (amount == 0f || !IsDepressurizing) { return; } Debug.Assert(IsDepressurizing, "Vent asked to depressurize when it is supposed to pressurize"); Debug.Assert(amount >= 0f); var oxygenBlock = GetOxygenBlock(); float oxygenInRoom = oxygenBlock.Room == null ? 0f : (float)oxygenBlock.Room.OxygenAmount; if (oxygenBlock.Room == null) { return; } if (oxygenBlock.Room.IsPressurized) { SourceComp.SetRemainingCapacityByType(m_oxygenGasId, oxygenInRoom); oxygenBlock.Room.OxygenAmount -= amount; if (oxygenBlock.Room.OxygenAmount < 0f) { oxygenBlock.Room.OxygenAmount = 0f; } } //Take from environment else { float oxygenInEnvironment = MyOxygenProviderSystem.GetOxygenInPoint(WorldMatrix.Translation) != 0 ? BlockDefinition.VentilationCapacityPerSecond * 100 : 0f; SourceComp.SetRemainingCapacityByType(m_oxygenGasId, oxygenInEnvironment); m_producedSinceLastUpdate = true; } if (amount > 0)//some oxygen were vented { m_producedSinceLastUpdate = true; if (amount > 1)//enough oxygen were vented for sound and effects { m_playVentEffect = true; if (m_effect == null)//create air vent effect { CreateEffect(); } } } m_nextGasTransfer = 0f; }
public void Init(MyPlanetInitArguments arguments) { if (MyFakes.ENABLE_PLANETS == false) { throw new PlanetsNotEnabledException(); } m_planetInitValues = arguments; m_hasSpawningMaterial = arguments.Storage.DataProvider.HasMaterialSpawningFlora(); base.Init(m_planetInitValues.StorageName, m_planetInitValues.Storage, m_planetInitValues.PositionMinCorner); NeedsUpdate |= MyEntityUpdateEnum.EACH_100TH_FRAME | MyEntityUpdateEnum.BEFORE_NEXT_FRAME; m_storage.RangeChanged += storage_RangeChangedPlanet; if (Physics != null) { Physics.Enabled = false; Physics.Close(); Physics = null; } Vector3I storageSize = m_planetInitValues.Storage.Size; m_numCells = new Vector3I(storageSize.X / PHYSICS_SECTOR_SIZE_METERS, storageSize.Y / PHYSICS_SECTOR_SIZE_METERS, storageSize.Z / PHYSICS_SECTOR_SIZE_METERS); m_numCells -= 1; StorageName = m_planetInitValues.StorageName; m_storageMax = m_planetInitValues.Storage.Size; MyGravityProviderSystem.AddPlanet(this); MyOxygenProviderSystem.AddOxygenGenerator(this); if (m_planetInitValues.MarkAreaEmpty) { MyProceduralWorldGenerator.Static.MarkEmptyArea(PositionComp.GetPosition()); } }
void IMyOxygenProducer.Produce(float amount) { if (amount == 0f || !IsDepressurizing) { return; } Debug.Assert(CanVent, "Vent asked to depressurize when it is unable to do so"); Debug.Assert(IsDepressurizing, "Vent asked to depressurize when it is supposed to pressurize"); Debug.Assert(amount >= 0f); var oxygenBlock = GetOxygenBlock(); if (oxygenBlock.Room == null) { return; } if (oxygenBlock.Room.IsPressurized) { oxygenBlock.Room.OxygenAmount -= amount; if (oxygenBlock.Room.OxygenAmount < 0f) { oxygenBlock.Room.OxygenAmount = 0f; } if (amount > 0) { m_producedSinceLastUpdate = true; } } else { //Take from environment, nothing to do Debug.Assert(MyOxygenProviderSystem.GetOxygenInPoint(WorldMatrix.Translation) > 0f); m_producedSinceLastUpdate = true; } }
public override void UpdateAfterSimulation100() { base.UpdateAfterSimulation100(); if (Sync.IsServer && IsWorking) { UpdateActions(); } if (m_playVentEffect == false) { if (m_effect != null) { m_effect.Stop(); m_effect = null; } } m_isProducing = m_producedSinceLastUpdate; m_producedSinceLastUpdate = false; m_playVentEffect = false; var block = GetOxygenBlock(); int sourceUpdateFrames = (MySession.Static.GameplayFrameCounter - m_lastOutputUpdateTime); int sinkUpdateFrames = (MySession.Static.GameplayFrameCounter - m_lastInputUpdateTime); m_lastOutputUpdateTime = MySession.Static.GameplayFrameCounter; m_lastInputUpdateTime = MySession.Static.GameplayFrameCounter; float gasInput = GasInputPerUpdate * sinkUpdateFrames; float gasOutput = GasOutputPerUpdate * sourceUpdateFrames; float totalTransfer = gasInput - gasOutput + m_nextGasTransfer; if (totalTransfer != 0f) { Transfer(totalTransfer); } SourceComp.SetRemainingCapacityByType(m_oxygenGasId, (float)(block.Room != null && block.Room.IsPressurized ? block.Room.OxygenAmount : (MyOxygenProviderSystem.GetOxygenInPoint(WorldMatrix.Translation) != 0 ? BlockDefinition.VentilationCapacityPerSecond * 100 : 0f))); ResourceSink.Update(); UpdateTexts(); UpdateEmissivity(); if (MyFakes.ENABLE_OXYGEN_SOUNDS) { UpdateSound(); } }
protected override void Closing() { base.Closing(); MyGravityProviderSystem.RemovePlanet(this); MyOxygenProviderSystem.RemoveOxygenGenerator(this); }
private void UpdateOxygen() { // Try to find grids that might contain oxygen var entities = new List <MyEntity>(); var aabb = Character.PositionComp.WorldAABB; MyGamePruningStructure.GetAllTopMostEntitiesInBox(ref aabb, entities); bool lowOxygenDamage = MySession.Static.Settings.EnableOxygen; bool noOxygenDamage = MySession.Static.Settings.EnableOxygen; bool isInEnvironment = true; EnvironmentOxygenLevel = MyOxygenProviderSystem.GetOxygenInPoint(Character.PositionComp.GetPosition()); bool oxygenReplenished = false; if (Sync.IsServer) { if (MySession.Static.Settings.EnableOxygen) { float oxygenInput = CharacterGasSink.CurrentInputByType(OxygenId); if (oxygenInput > 0 && !Definition.NeedsOxygen) { var oxygenInputPer100Frames = oxygenInput * 100f / MyEngineConstants.UPDATE_STEPS_PER_SECOND; SuitOxygenAmount += oxygenInputPer100Frames; if (oxygenInputPer100Frames >= Definition.OxygenConsumption) { oxygenReplenished = true; noOxygenDamage = false; lowOxygenDamage = false; } } } foreach (GasData gasInfo in m_storedGases) { float gasInputPer100Frames = Math.Min(gasInfo.Throughput, CharacterGasSink.CurrentInputByType(gasInfo.Id)) * 100f / MyEngineConstants.UPDATE_STEPS_PER_SECOND; float gasOutputPer100Frames = Math.Min(gasInfo.Throughput, CharacterGasSource.CurrentOutputByType(gasInfo.Id)) * 100f / MyEngineConstants.UPDATE_STEPS_PER_SECOND; TransferSuitGas(gasInfo.Id, gasInputPer100Frames, gasOutputPer100Frames); m_gasOutputTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; } } if (MySession.Static.Settings.EnableOxygen) { var cockpit = Character.Parent as MyCockpit; if (cockpit != null && cockpit.BlockDefinition.IsPressurized) { if (Sync.IsServer && MySession.Static.SurvivalMode && !oxygenReplenished) { if (!Definition.NeedsOxygen) { if (cockpit.OxygenAmount >= Definition.OxygenConsumption) { cockpit.OxygenAmount -= Definition.OxygenConsumption; noOxygenDamage = false; lowOxygenDamage = false; } else if (m_suitOxygenAmount >= Definition.OxygenConsumption) { m_suitOxygenAmount -= Definition.OxygenConsumption; noOxygenDamage = false; lowOxygenDamage = false; } } else if (Definition.NeedsOxygen) { if (cockpit.OxygenFillLevel > 0f) { if (cockpit.OxygenAmount >= Definition.OxygenConsumption) { cockpit.OxygenAmount -= Definition.OxygenConsumption; noOxygenDamage = false; lowOxygenDamage = false; } } } } EnvironmentOxygenLevel = cockpit.OxygenFillLevel; isInEnvironment = false; } else { Vector3D pos = Character.GetHeadMatrix(true, true, false, true).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.GasSystem.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; if (!oxygenReplenished) { 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 == Character) { 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; } CharacterGasSink.Update(); // Cannot early exit before calculations because of UI if (!Sync.IsServer || MySession.Static.CreativeMode || !MySession.Static.Settings.EnableOxygen) { return; } //Try to refill the suit from bottles in inventory if (SuitOxygenLevel < 0.3f && !Definition.NeedsOxygen) { var items = Character.Inventory.GetItems(); bool bottlesUsed = false; foreach (var item in items) { var oxygenContainer = item.Content as MyObjectBuilder_GasContainerObject; if (oxygenContainer != null) { if (oxygenContainer.GasLevel == 0f) { continue; } var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(oxygenContainer) as MyOxygenContainerDefinition; if (physicalItem.StoredGasId != OxygenId) { continue; } float oxygenAmount = oxygenContainer.GasLevel * physicalItem.Capacity; float transferredAmount = Math.Min(oxygenAmount, SuitOxygenAmountMissing); oxygenContainer.GasLevel = (oxygenAmount - transferredAmount) / physicalItem.Capacity; if (oxygenContainer.GasLevel < 0f) { oxygenContainer.GasLevel = 0f; } if (oxygenContainer.GasLevel > 1f) { Debug.Fail("Incorrect value"); } Character.Inventory.UpdateGasAmount(); bottlesUsed = true; SuitOxygenAmount += transferredAmount; if (SuitOxygenLevel == 1f) { break; } } } if (bottlesUsed) { if (MySession.LocalCharacter == Character) { ShowRefillFromBottleNotification(); } else { Character.SyncObject.SendRefillFromBottle(); } } } foreach (var gasInfo in m_storedGases) { if (gasInfo.FillLevel < 0.3f) // Get rid of the specific oxygen version of this { var items = Character.Inventory.GetItems(); bool bottlesUsed = false; foreach (var item in items) { var gasContainer = item.Content as MyObjectBuilder_GasContainerObject; if (gasContainer != null) { if (gasContainer.GasLevel == 0f) { continue; } var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(gasContainer) as MyOxygenContainerDefinition; if (physicalItem.StoredGasId != gasInfo.Id) { continue; } float gasAmount = gasContainer.GasLevel * physicalItem.Capacity; float transferredAmount = Math.Min(gasAmount, (1f - gasInfo.FillLevel) * gasInfo.MaxCapacity); gasContainer.GasLevel = Math.Max((gasAmount - transferredAmount) / physicalItem.Capacity, 0f); if (gasContainer.GasLevel > 1f) { Debug.Fail("Incorrect value"); } Character.Inventory.UpdateGasAmount(); bottlesUsed = true; gasInfo.FillLevel = Math.Min(gasInfo.FillLevel + transferredAmount / gasInfo.MaxCapacity, 1f); if (gasInfo.FillLevel == 1f) { break; } } } if (bottlesUsed) { if (MySession.LocalCharacter == Character) { ShowRefillFromBottleNotification(); } else { Character.SyncObject.SendRefillFromBottle(); } } } } // No oxygen found in room, try to get it from suit if (noOxygenDamage || lowOxygenDamage) { if (!Definition.NeedsOxygen && m_suitOxygenAmount > Definition.OxygenConsumption) { if (!oxygenReplenished) { 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) { Character.DoDamage(Definition.DamageAmountAtZeroPressure, MyDamageType.LowPressure, true); } else if (lowOxygenDamage) { Character.DoDamage(1f, MyDamageType.Asphyxia, true); } Character.SyncObject.UpdateOxygen(SuitOxygenAmount); }
private void UpdateOxygen() { MyOxygenRoom room; List <MyEntity> result = new List <MyEntity>(); BoundingBoxD worldAABB = base.Character.PositionComp.WorldAABB; bool enableOxygen = MySession.Static.Settings.EnableOxygen; bool noOxygenDamage = MySession.Static.Settings.EnableOxygen; bool isInEnvironment = true; bool flag4 = false; if (!Sync.IsServer) { goto TR_000A; } else { base.Character.EnvironmentOxygenLevelSync.Value = MyOxygenProviderSystem.GetOxygenInPoint(base.Character.PositionComp.GetPosition()); base.Character.OxygenLevelAtCharacterLocation.Value = base.Character.EnvironmentOxygenLevel; room = null; if (!MySession.Static.Settings.EnableOxygen) { goto TR_000C; } else { GasData data; if (this.TryGetGasData(OxygenId, out data)) { float num = (MySession.Static.GameplayFrameCounter - data.LastOutputTime) * 0.01666667f; flag4 = (this.CharacterGasSink.CurrentInputByType(OxygenId) * num) > this.Definition.OxygenConsumption; if (flag4) { noOxygenDamage = false; enableOxygen = false; } } MyCockpit parent = base.Character.Parent as MyCockpit; bool flag5 = false; if ((parent != null) && parent.BlockDefinition.IsPressurized) { if ((!this.HelmetEnabled && (MySession.Static.SurvivalMode && !flag4)) && (parent.OxygenAmount >= (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier))) { parent.OxygenAmount -= this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier; noOxygenDamage = false; enableOxygen = false; } base.Character.EnvironmentOxygenLevelSync.Value = parent.OxygenFillLevel; isInEnvironment = false; flag5 = true; } if (!flag5 || (MyFakes.ENABLE_NEW_SOUNDS && MySession.Static.Settings.RealisticSound)) { base.Character.OxygenSourceGridEntityId.Value = 0L; Vector3D center = base.Character.PositionComp.WorldAABB.Center; MyGamePruningStructure.GetTopMostEntitiesInBox(ref worldAABB, result, MyEntityQueryType.Both); using (List <MyEntity> .Enumerator enumerator = result.GetEnumerator()) { while (true) { while (true) { if (enumerator.MoveNext()) { MyCubeGrid current = enumerator.Current as MyCubeGrid; if (current == null) { continue; } if (current.GridSystems.GasSystem == null) { continue; } MyOxygenBlock safeOxygenBlock = current.GridSystems.GasSystem.GetSafeOxygenBlock(center); if (safeOxygenBlock == null) { continue; } if (safeOxygenBlock.Room == null) { continue; } room = safeOxygenBlock.Room; if ((room.OxygenLevel(current.GridSize) > this.Definition.PressureLevelForLowDamage) && !this.HelmetEnabled) { enableOxygen = false; } if (!room.IsAirtight) { float environmentOxygen = room.EnvironmentOxygen; base.Character.OxygenLevelAtCharacterLocation.Value = environmentOxygen; if (flag5) { break; } base.Character.EnvironmentOxygenLevelSync.Value = environmentOxygen; if (this.HelmetEnabled) { break; } if (base.Character.EnvironmentOxygenLevelSync.Value <= (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier)) { break; } noOxygenDamage = false; } else { float num2 = room.OxygenLevel(current.GridSize); if (!flag5) { base.Character.EnvironmentOxygenLevelSync.Value = num2; } base.Character.OxygenLevelAtCharacterLocation.Value = num2; base.Character.OxygenSourceGridEntityId.Value = current.EntityId; if (room.OxygenAmount <= (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier)) { break; } if (!this.HelmetEnabled) { noOxygenDamage = false; safeOxygenBlock.PreviousOxygenAmount = safeOxygenBlock.OxygenAmount() - (this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier); safeOxygenBlock.OxygenChangeTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; if (!flag4) { room.OxygenAmount -= this.Definition.OxygenConsumption * this.Definition.OxygenConsumptionMultiplier; } } } goto TR_000D; } else { goto TR_000D; } break; } isInEnvironment = false; } } } } } goto TR_000D; TR_000A: this.CharacterGasSink.Update(); if (Sync.IsServer && !MySession.Static.CreativeMode) { this.RefillSuitGassesFromBottles(); if (MySession.Static.Settings.EnableOxygen) { this.UpdateSuitOxygen(enableOxygen, noOxygenDamage, isInEnvironment); } foreach (GasData data2 in this.m_storedGases) { base.Character.UpdateStoredGas(data2.Id, data2.FillLevel); } } return; TR_000C: this.UpdateGassesFillLevelsAndAmounts(room); goto TR_000A; TR_000D: this.m_oldSuitOxygenLevel = this.SuitOxygenLevel; goto TR_000C; }
private void UpdateOxygen() { // Try to find grids that might contain oxygen var entities = new List <MyEntity>(); var aabb = Character.PositionComp.WorldAABB; bool lowOxygenDamage = MySession.Static.Settings.EnableOxygen; bool noOxygenDamage = MySession.Static.Settings.EnableOxygen; bool isInEnvironment = true; bool oxygenReplenished = false; EnvironmentOxygenLevel = MyOxygenProviderSystem.GetOxygenInPoint(Character.PositionComp.GetPosition()); OxygenLevelAtCharacterLocation = EnvironmentOxygenLevel; if (Sync.IsServer) { // Check for possibility that we are replenishing oxygen if (MySession.Static.Settings.EnableOxygen) { GasData oxygenData; if (TryGetGasData(OxygenId, out oxygenData)) { float timeSinceLastUpdateSeconds = (MySession.Static.GameplayFrameCounter - oxygenData.LastOutputTime) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; oxygenReplenished = CharacterGasSink.CurrentInputByType(OxygenId) * timeSinceLastUpdateSeconds > Definition.OxygenConsumption; if (oxygenReplenished) { noOxygenDamage = false; lowOxygenDamage = false; } } } // Update Gases fill levels and capacity amounts foreach (GasData gasInfo in m_storedGases) { var timeSinceLastOutputSeconds = (MySession.Static.GameplayFrameCounter - gasInfo.LastOutputTime) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; var timeSinceLastInputSeconds = (MySession.Static.GameplayFrameCounter - gasInfo.LastInputTime) * VRage.Game.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS; gasInfo.LastOutputTime = MySession.Static.GameplayFrameCounter; gasInfo.LastInputTime = MySession.Static.GameplayFrameCounter; float gasOutputAmount = CharacterGasSource.CurrentOutputByType(gasInfo.Id) * timeSinceLastOutputSeconds; float gasInputAmount = CharacterGasSink.CurrentInputByType(gasInfo.Id) * timeSinceLastInputSeconds; // Values that are not in distribution system yet and happend to inc/dec between updates float outTransfer = -MathHelper.Clamp(gasInfo.NextGasTransfer, float.NegativeInfinity, 0f); float inTransfer = MathHelper.Clamp(gasInfo.NextGasTransfer, 0f, float.PositiveInfinity); gasInfo.NextGasTransfer = 0f; TransferSuitGas(ref gasInfo.Id, gasInputAmount + inTransfer, gasOutputAmount + outTransfer); } } if (MySession.Static.Settings.EnableOxygen) { var cockpit = Character.Parent as MyCockpit; bool OxygenFromCockpit = false; if (cockpit != null && cockpit.BlockDefinition.IsPressurized) { if (Sync.IsServer && MySession.Static.SurvivalMode && !oxygenReplenished) { // Character is in pressurized room if (!HelmetEnabled) { if (cockpit.OxygenFillLevel > 0f) { if (cockpit.OxygenAmount >= Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { cockpit.OxygenAmount -= Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier; noOxygenDamage = false; lowOxygenDamage = false; } } } } EnvironmentOxygenLevel = cockpit.OxygenFillLevel; isInEnvironment = false; OxygenFromCockpit = true; } if (OxygenFromCockpit == false || (MyFakes.ENABLE_NEW_SOUNDS && MySession.Static.Settings.RealisticSound)) { OxygenSourceGrid = null; Vector3D pos = Character.GetHeadMatrix(true, true, false, true).Translation; MyGamePruningStructure.GetTopMostEntitiesInBox(ref aabb, entities); 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 && grid.GridSystems.GasSystem != null) { var oxygenBlock = grid.GridSystems.GasSystem.GetSafeOxygenBlock(pos); if (oxygenBlock.Room != null) { if (oxygenBlock.Room.OxygenLevel(grid.GridSize) > Definition.PressureLevelForLowDamage) { if (!HelmetEnabled) { lowOxygenDamage = false; } } if (oxygenBlock.Room.IsPressurized) { float oxygen = oxygenBlock.Room.OxygenLevel(grid.GridSize); if (!OxygenFromCockpit) { EnvironmentOxygenLevel = oxygen; } OxygenLevelAtCharacterLocation = oxygen; OxygenSourceGrid = grid; if (oxygenBlock.Room.OxygenAmount > Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { if (!HelmetEnabled) { noOxygenDamage = false; oxygenBlock.PreviousOxygenAmount = oxygenBlock.OxygenAmount() - Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier; oxygenBlock.OxygenChangeTime = MySandboxGame.TotalGamePlayTimeInMilliseconds; if (!oxygenReplenished) { oxygenBlock.Room.OxygenAmount -= Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier; } } break; } } else { float oxygen = oxygenBlock.Room.EnvironmentOxygen; OxygenLevelAtCharacterLocation = oxygen; if (!OxygenFromCockpit) { EnvironmentOxygenLevel = oxygen; if (!HelmetEnabled && EnvironmentOxygenLevel > Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { noOxygenDamage = false; break; } } } isInEnvironment = false; } } } } if (MySession.Static.LocalCharacter == Character) { 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; } CharacterGasSink.Update(); // Cannot early exit before calculations because of UI if (!Sync.IsServer || MySession.Static.CreativeMode || !MySession.Static.Settings.EnableOxygen) { return; } foreach (var gasInfo in m_storedGases) { if (gasInfo.FillLevel < GAS_REFILL_RATION) // Get rid of the specific oxygen version of this { if (gasInfo.NextGasRefill == -1) { gasInfo.NextGasRefill = MySandboxGame.TotalGamePlayTimeInMilliseconds + m_gasRefillInterval * 1000; } if (MySandboxGame.TotalGamePlayTimeInMilliseconds < gasInfo.NextGasRefill) { continue; } gasInfo.NextGasRefill = -1; var items = Character.GetInventory().GetItems(); bool bottlesUsed = false; foreach (var item in items) { var gasContainer = item.Content as MyObjectBuilder_GasContainerObject; if (gasContainer != null) { if (gasContainer.GasLevel == 0f) { continue; } var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(gasContainer) as MyOxygenContainerDefinition; if (physicalItem.StoredGasId != gasInfo.Id) { continue; } float gasAmount = gasContainer.GasLevel * physicalItem.Capacity; float transferredAmount = Math.Min(gasAmount, (1f - gasInfo.FillLevel) * gasInfo.MaxCapacity); gasContainer.GasLevel = Math.Max((gasAmount - transferredAmount) / physicalItem.Capacity, 0f); if (gasContainer.GasLevel > 1f) { Debug.Fail("Incorrect value"); } Character.GetInventory().UpdateGasAmount(); bottlesUsed = true; TransferSuitGas(ref gasInfo.Id, transferredAmount, 0); if (gasInfo.FillLevel == 1f) { break; } } } if (bottlesUsed) { if (MySession.Static.LocalCharacter == Character) { ShowRefillFromBottleNotification(gasInfo.Id); } else { Character.SendRefillFromBottle(gasInfo.Id); } } var jetpack = Character.JetpackComp; if (jetpack != null && jetpack.TurnedOn && jetpack.FuelDefinition != null && jetpack.FuelDefinition.Id == gasInfo.Id && gasInfo.FillLevel <= 0 && (Character.ControllerInfo.Controller != null && MySession.Static.IsAdminModeEnabled(Character.ControllerInfo.Controller.Player.Id.SteamId) == false || (MySession.Static.LocalCharacter != Character && Sync.IsServer == false))) { jetpack.SwitchThrusts(); } } else { gasInfo.NextGasRefill = -1; } } // No oxygen or low oxygen found in room, try to get it from suit if (MySession.Static.Settings.EnableOxygen) { if (noOxygenDamage || lowOxygenDamage) { if (HelmetEnabled && SuitOxygenAmount > Definition.OxygenConsumption * Definition.OxygenConsumptionMultiplier) { noOxygenDamage = false; lowOxygenDamage = false; } if (isInEnvironment && !HelmetEnabled) { if (EnvironmentOxygenLevel > Definition.PressureLevelForLowDamage) { lowOxygenDamage = false; } if (EnvironmentOxygenLevel > 0f) { noOxygenDamage = false; } } } m_oldSuitOxygenLevel = SuitOxygenLevel; if (noOxygenDamage) { Character.DoDamage(Definition.DamageAmountAtZeroPressure, MyDamageType.LowPressure, true); } else if (lowOxygenDamage) { Character.DoDamage(1f, MyDamageType.Asphyxia, true); } } Character.UpdateOxygen(SuitOxygenAmount); foreach (var gasInfo in m_storedGases) { Character.UpdateStoredGas(gasInfo.Id, gasInfo.FillLevel); } }
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); }