From: Menshin Date: Sun, 30 Apr 2023 17:58:26 +0000 (+0200) Subject: Cached barotrauma resistance and immunity values instead of computing them each Updat... X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=76903dd1453b55fdfe2bb0cc68f8258fa9093207;p=space-station-14.git Cached barotrauma resistance and immunity values instead of computing them each Update() (#15055) --- diff --git a/Content.Server/Atmos/Components/BarotraumaComponent.cs b/Content.Server/Atmos/Components/BarotraumaComponent.cs index 0d0c1c89b4..1a9f8c04f7 100644 --- a/Content.Server/Atmos/Components/BarotraumaComponent.cs +++ b/Content.Server/Atmos/Components/BarotraumaComponent.cs @@ -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. /// [DataField("protectionSlots")] - public List ProtectionSlots = new() { "head", "outerClothing" }; + public List ProtectionSlots = new() { "head", "outerClothing" }; + + /// + /// Cached pressure protection values + /// + [ViewVariables] + public float HighPressureMultiplier = 1f; + [ViewVariables] + public float HighPressureModifier = 0f; + [ViewVariables] + public float LowPressureMultiplier = 1f; + [ViewVariables] + public float LowPressureModifier = 0f; + + /// + /// Whether the entity is immuned to pressure (i.e possess the PressureImmunity component) + /// + [ViewVariables] + public bool HasImmunity = false; + } } diff --git a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs index 15401aa5d1..1b3e1b07a6 100644 --- a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs +++ b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs @@ -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(OnHighPressureEvent); - SubscribeLocalEvent(OnLowPressureEvent); - - SubscribeLocalEvent(OnHighPressureImmuneEvent); - SubscribeLocalEvent(OnLowPressureImmuneEvent); + SubscribeLocalEvent(OnPressureProtectionEquipped); + SubscribeLocalEvent(OnPressureProtectionUnequipped); + SubscribeLocalEvent(OnUpdateResistance); + SubscribeLocalEvent(OnUpdateResistance); + SubscribeLocalEvent(OnPressureImmuneInit); + SubscribeLocalEvent(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(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(uid, out var barotrauma)) + { + barotrauma.HasImmunity = false; + } } - /// - /// Completely prevent high pressure damage + /// Generic method for updating resistance on component Lifestage events /// - private void OnHighPressureImmuneEvent(EntityUid uid, PressureImmunityComponent component, HighPressureEvent args) + private void OnUpdateResistance(EntityUid uid, PressureProtectionComponent pressureProtection, EntityEventArgs args) { - args.Multiplier = 0; + if (TryComp(uid, out var barotrauma)) + { + UpdateCachedResistances(uid, barotrauma); + } } - /// - /// Completely prevent low pressure damage - /// - 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(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(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) + /// + /// 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. + /// + 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(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) + /// + /// Returns adjusted pressure after having applied resistances from equipment and innate (if any), to check against a low pressure hazard threshold + /// + 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); + /// + /// Returns adjusted pressure after having applied resistances from equipment and innate (if any), to check against a high pressure hazard threshold + /// + 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);