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
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)
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);