Esempio n. 1
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);
        }