Beispiel #1
0
        public override void OnAddedToScene(object source)
        {
            base.OnAddedToScene(source);

            MyPlanets.Register(this);

            MyGravityProviderSystem.AddNaturalGravityProvider(Components.Get <MyGravityProviderComponent>());
            MyOxygenProviderSystem.AddOxygenGenerator(this);
        }
Beispiel #2
0
        public override void OnRemovedFromScene(object source)
        {
            base.OnRemovedFromScene(source);

            MyPlanets.UnRegister(this);

            MyGravityProviderSystem.RemoveNaturalGravityProvider(Components.Get <MyGravityProviderComponent>());
            MyOxygenProviderSystem.RemoveOxygenGenerator(this);
        }
Beispiel #3
0
        public override void OnRemovedFromScene(object source)
        {
            base.OnRemovedFromScene(source);

            MyPlanets.UnRegister(this);

            MyGravityProviderSystem.RemovePlanet(this);
            MyOxygenProviderSystem.RemoveOxygenGenerator(this);
        }
Beispiel #4
0
        public override void OnAddedToScene(object source)
        {
            base.OnAddedToScene(source);

            MyPlanets.Register(this);

            MyGravityProviderSystem.AddPlanet(this);
            MyOxygenProviderSystem.AddOxygenGenerator(this);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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;
        }
Beispiel #8
0
        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());
            }
        }
Beispiel #9
0
        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;
            }
        }
Beispiel #10
0
        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();
            }
        }
Beispiel #11
0
 protected override void Closing()
 {
     base.Closing();
     MyGravityProviderSystem.RemovePlanet(this);
     MyOxygenProviderSystem.RemoveOxygenGenerator(this);
 }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #15
0
        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);
        }