]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Cached barotrauma resistance and immunity values instead of computing them each Updat...
authorMenshin <Menshin@users.noreply.github.com>
Sun, 30 Apr 2023 17:58:26 +0000 (19:58 +0200)
committerGitHub <noreply@github.com>
Sun, 30 Apr 2023 17:58:26 +0000 (03:58 +1000)
Content.Server/Atmos/Components/BarotraumaComponent.cs
Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs

index 0d0c1c89b49f160f9a2093a6e65505c4658fbf83..1a9f8c04f762202f361a174840496018587f3554 100644 (file)
@@ -26,6 +26,25 @@ namespace Content.Server.Atmos.Components
         ///     These are the inventory slots that are checked for pressure protection. If a slot is missing protection, no protection is applied.
         /// </summary>
         [DataField("protectionSlots")]
-        public List<string> ProtectionSlots = new() { "head", "outerClothing" }; 
+        public List<string> ProtectionSlots = new() { "head", "outerClothing" };
+
+        /// <summary>
+        /// Cached pressure protection values
+        /// </summary>
+        [ViewVariables]
+        public float HighPressureMultiplier = 1f;
+        [ViewVariables]
+        public float HighPressureModifier = 0f;
+        [ViewVariables]
+        public float LowPressureMultiplier = 1f;
+        [ViewVariables]
+        public float LowPressureModifier = 0f;
+
+        /// <summary>
+        /// Whether the entity is immuned to pressure (i.e possess the PressureImmunity component)
+        /// </summary>
+        [ViewVariables]
+        public bool HasImmunity = false;
+
     }
 }
index 15401aa5d198ff2118bdcec204be1bff8b0d8742..1b3e1b07a6fcabb6ae4455f1c8a02114574b9de9 100644 (file)
@@ -6,6 +6,7 @@ using Content.Shared.Damage;
 using Content.Shared.Database;
 using Content.Shared.FixedPoint;
 using Content.Shared.Inventory;
+using Content.Shared.Inventory.Events;
 using Robust.Shared.Containers;
 
 namespace Content.Server.Atmos.EntitySystems
@@ -23,124 +24,136 @@ namespace Content.Server.Atmos.EntitySystems
 
         public override void Initialize()
         {
-            SubscribeLocalEvent<PressureProtectionComponent, HighPressureEvent>(OnHighPressureEvent);
-            SubscribeLocalEvent<PressureProtectionComponent, LowPressureEvent>(OnLowPressureEvent);
-
-            SubscribeLocalEvent<PressureImmunityComponent, HighPressureEvent>(OnHighPressureImmuneEvent);
-            SubscribeLocalEvent<PressureImmunityComponent, LowPressureEvent>(OnLowPressureImmuneEvent);
+            SubscribeLocalEvent<PressureProtectionComponent, GotEquippedEvent>(OnPressureProtectionEquipped);
+            SubscribeLocalEvent<PressureProtectionComponent, GotUnequippedEvent>(OnPressureProtectionUnequipped);
+            SubscribeLocalEvent<PressureProtectionComponent, ComponentInit>(OnUpdateResistance);
+            SubscribeLocalEvent<PressureProtectionComponent, ComponentRemove>(OnUpdateResistance);
 
+            SubscribeLocalEvent<PressureImmunityComponent, ComponentInit>(OnPressureImmuneInit);
+            SubscribeLocalEvent<PressureImmunityComponent, ComponentRemove>(OnPressureImmuneRemove);
         }
 
-        private void OnHighPressureEvent(EntityUid uid, PressureProtectionComponent component, HighPressureEvent args)
+        private void OnPressureImmuneInit(EntityUid uid, PressureImmunityComponent pressureImmunity, ComponentInit args)
         {
-            args.Modifier += component.HighPressureModifier;
-            args.Multiplier *= component.HighPressureMultiplier;
+            if (TryComp<BarotraumaComponent>(uid, out var barotrauma))
+            {
+                barotrauma.HasImmunity = true;
+            }
         }
 
-        private void OnLowPressureEvent(EntityUid uid, PressureProtectionComponent component, LowPressureEvent args)
+        private void OnPressureImmuneRemove(EntityUid uid, PressureImmunityComponent pressureImmunity, ComponentRemove args)
         {
-            args.Modifier += component.LowPressureModifier;
-            args.Multiplier *= component.LowPressureMultiplier;
+            if (TryComp<BarotraumaComponent>(uid, out var barotrauma))
+            {
+                barotrauma.HasImmunity = false;
+            }
         }
 
-
         /// <summary>
-        /// Completely prevent high pressure damage
+        /// Generic method for updating resistance on component Lifestage events
         /// </summary>
-        private void OnHighPressureImmuneEvent(EntityUid uid, PressureImmunityComponent component, HighPressureEvent args)
+        private void OnUpdateResistance(EntityUid uid, PressureProtectionComponent pressureProtection, EntityEventArgs args)
         {
-            args.Multiplier = 0;
+            if (TryComp<BarotraumaComponent>(uid, out var barotrauma))
+            {
+                UpdateCachedResistances(uid, barotrauma);
+            }
         }
 
-        /// <summary>
-        /// Completely prevent low pressure damage
-        /// </summary>
-        private void OnLowPressureImmuneEvent(EntityUid uid, PressureImmunityComponent component, LowPressureEvent args)
+        private void OnPressureProtectionEquipped(EntityUid uid, PressureProtectionComponent pressureProtection, GotEquippedEvent args)
         {
-            args.Modifier = 100;
-            args.Multiplier = 10000;
+            if (TryComp<BarotraumaComponent>(args.Equipee, out var barotrauma) && barotrauma.ProtectionSlots.Contains(args.Slot))
+            {
+                UpdateCachedResistances(args.Equipee, barotrauma);
+            }
         }
 
-        public float GetFeltLowPressure(EntityUid uid, BarotraumaComponent baro, float environmentPressure)
+        private void OnPressureProtectionUnequipped(EntityUid uid, PressureProtectionComponent pressureProtection, GotUnequippedEvent args)
         {
-            var modifier = float.MaxValue;
-            var multiplier = float.MaxValue;
-
-            TryComp(uid, out InventoryComponent? inv);
-            TryComp(uid, out ContainerManagerComponent? contMan);
-
-            // TODO: cache this & update when equipment changes?
-            // This continuously raises events for every player in space.
-
-            if (baro.ProtectionSlots.Count == 0)
+            if (TryComp<BarotraumaComponent>(args.Equipee, out var barotrauma) && barotrauma.ProtectionSlots.Contains(args.Slot))
             {
-                modifier = 0;
-                multiplier = 1;
+                UpdateCachedResistances(args.Equipee, barotrauma);
             }
+        }
 
-            // First, check if for protective equipment
-            foreach (var slot in baro.ProtectionSlots)
+        /// <summary>
+        /// Computes the pressure resistance for the entity coming from the equipment and any innate resistance.
+        /// The ProtectionSlots field of the Barotrauma component specifies which parts must be protected for the protection to have any effet.
+        /// </summary>
+        private void UpdateCachedResistances(EntityUid uid, BarotraumaComponent barotrauma)
+        {
+
+            if (barotrauma.ProtectionSlots.Count != 0)
             {
-                if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan)
-                    || ! TryComp(equipment, out PressureProtectionComponent? protection))
+                if (!TryComp(uid, out InventoryComponent? inv) || !TryComp(uid, out ContainerManagerComponent? contMan))
                 {
-                    // Missing protection, skin is exposed.
-                    modifier = 0;
-                    multiplier = 1;
-                    break;
+                    return;
                 }
+                var hPModifier = float.MinValue;
+                var hPMultiplier = float.MinValue;
+                var lPModifier = float.MaxValue;
+                var lPMultiplier = float.MaxValue;
 
-                modifier = Math.Min(protection.LowPressureModifier, modifier);
-                multiplier = Math.Min(protection.LowPressureMultiplier, multiplier);
-            }
+                foreach (var slot in barotrauma.ProtectionSlots)
+                {
+                    if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan)
+                        || !TryComp(equipment, out PressureProtectionComponent? protection))
+                    {
+                        // Missing protection, skin is exposed.
+                        hPModifier = 0f;
+                        hPMultiplier = 1f;
+                        lPModifier = 0f;
+                        lPMultiplier = 1f;
+                        break;
+                    }
+
+                    // The entity is as protected as its weakest part protection
+                    hPModifier = Math.Max(hPModifier, protection.HighPressureModifier);
+                    hPMultiplier = Math.Max(hPMultiplier, protection.HighPressureMultiplier);
+                    lPModifier = Math.Min(lPModifier, protection.LowPressureModifier);
+                    lPMultiplier = Math.Min(lPMultiplier, protection.LowPressureMultiplier);
+                }
 
-            // Then apply any generic, non-clothing related modifiers.
-            var lowPressureEvent = new LowPressureEvent(environmentPressure);
-            RaiseLocalEvent(uid, lowPressureEvent);
+                barotrauma.HighPressureModifier = hPModifier;
+                barotrauma.HighPressureMultiplier = hPMultiplier;
+                barotrauma.LowPressureModifier = lPModifier;
+                barotrauma.LowPressureMultiplier = lPMultiplier;
+            }
 
-            return (environmentPressure + modifier + lowPressureEvent.Modifier)
-                   * (multiplier * lowPressureEvent.Multiplier);
+            // any innate pressure resistance ?
+            if (TryComp<PressureProtectionComponent>(uid, out var innatePressureProtection))
+            {
+                barotrauma.HighPressureModifier += innatePressureProtection.HighPressureModifier;
+                barotrauma.HighPressureMultiplier *= innatePressureProtection.HighPressureMultiplier;
+                barotrauma.LowPressureModifier += innatePressureProtection.LowPressureModifier;
+                barotrauma.LowPressureMultiplier *= innatePressureProtection.LowPressureMultiplier;
+            }
         }
 
-        public float GetFeltHighPressure(EntityUid uid, BarotraumaComponent baro, float environmentPressure)
+        /// <summary>
+        /// Returns adjusted pressure after having applied resistances from equipment and innate (if any), to check against a low pressure hazard threshold
+        /// </summary>
+        public float GetFeltLowPressure(EntityUid uid, BarotraumaComponent barotrauma, float environmentPressure)
         {
-            var modifier = float.MinValue;
-            var multiplier = float.MinValue;
-
-            TryComp(uid, out InventoryComponent? inv);
-            TryComp(uid, out ContainerManagerComponent? contMan);
-
-            // TODO: cache this & update when equipment changes?
-            // Not as import and as low-pressure, but probably still useful.
-
-            if (baro.ProtectionSlots.Count == 0)
+            if (barotrauma.HasImmunity)
             {
-                modifier = 0;
-                multiplier = 1;
+                return Atmospherics.OneAtmosphere;
             }
 
-            // First, check if for protective equipment
-            foreach (var slot in baro.ProtectionSlots)
-            {
-                if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan)
-                    || !TryComp(equipment, out PressureProtectionComponent? protection))
-                {
-                    // Missing protection, skin is exposed.
-                    modifier = 0;
-                    multiplier = 1;
-                    break;
-                }
+            return (environmentPressure + barotrauma.LowPressureModifier) * (barotrauma.LowPressureMultiplier);
+        }
 
-                modifier = Math.Max(protection.HighPressureModifier, modifier);
-                multiplier = Math.Max(protection.HighPressureMultiplier, multiplier);
+        /// <summary>
+        /// Returns adjusted pressure after having applied resistances from equipment and innate (if any), to check against a high pressure hazard threshold
+        /// </summary>
+        public float GetFeltHighPressure(EntityUid uid, BarotraumaComponent barotrauma, float environmentPressure)
+        {
+            if (barotrauma.HasImmunity)
+            {
+                return Atmospherics.OneAtmosphere;
             }
 
-            // Then apply any generic, non-clothing related modifiers.
-            var highPressureEvent = new HighPressureEvent(environmentPressure);
-            RaiseLocalEvent(uid, highPressureEvent);
-
-            return (environmentPressure + modifier + highPressureEvent.Modifier)
-                   * (multiplier * highPressureEvent.Multiplier);
+            return (environmentPressure + barotrauma.HighPressureModifier) * (barotrauma.HighPressureMultiplier);
         }
 
         public override void Update(float frameTime)
@@ -203,7 +216,7 @@ namespace Content.Server.Atmos.EntitySystems
                     case >= Atmospherics.WarningHighPressure:
                         pressure = GetFeltHighPressure(uid, barotrauma, pressure);
 
-                        if(pressure < Atmospherics.WarningHighPressure)
+                        if (pressure < Atmospherics.WarningHighPressure)
                             goto default;
 
                         var damageScale = MathF.Min((pressure / Atmospherics.HazardHighPressure) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage);