Cached barotrauma resistance and immunity values instead of computing them each Update() (#15055)
This commit is contained in:
@@ -27,5 +27,24 @@ namespace Content.Server.Atmos.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("protectionSlots")]
|
[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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Content.Shared.Damage;
|
|||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Inventory.Events;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.EntitySystems
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
@@ -23,124 +24,136 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<PressureProtectionComponent, HighPressureEvent>(OnHighPressureEvent);
|
SubscribeLocalEvent<PressureProtectionComponent, GotEquippedEvent>(OnPressureProtectionEquipped);
|
||||||
SubscribeLocalEvent<PressureProtectionComponent, LowPressureEvent>(OnLowPressureEvent);
|
SubscribeLocalEvent<PressureProtectionComponent, GotUnequippedEvent>(OnPressureProtectionUnequipped);
|
||||||
|
SubscribeLocalEvent<PressureProtectionComponent, ComponentInit>(OnUpdateResistance);
|
||||||
SubscribeLocalEvent<PressureImmunityComponent, HighPressureEvent>(OnHighPressureImmuneEvent);
|
SubscribeLocalEvent<PressureProtectionComponent, ComponentRemove>(OnUpdateResistance);
|
||||||
SubscribeLocalEvent<PressureImmunityComponent, LowPressureEvent>(OnLowPressureImmuneEvent);
|
|
||||||
|
|
||||||
|
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;
|
if (TryComp<BarotraumaComponent>(uid, out var barotrauma))
|
||||||
args.Multiplier *= component.HighPressureMultiplier;
|
{
|
||||||
|
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;
|
if (TryComp<BarotraumaComponent>(uid, out var barotrauma))
|
||||||
args.Multiplier *= component.LowPressureMultiplier;
|
{
|
||||||
|
barotrauma.HasImmunity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Completely prevent high pressure damage
|
|
||||||
/// </summary>
|
|
||||||
private void OnHighPressureImmuneEvent(EntityUid uid, PressureImmunityComponent component, HighPressureEvent args)
|
|
||||||
{
|
|
||||||
args.Multiplier = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Completely prevent low pressure damage
|
/// Generic method for updating resistance on component Lifestage events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnLowPressureImmuneEvent(EntityUid uid, PressureImmunityComponent component, LowPressureEvent args)
|
private void OnUpdateResistance(EntityUid uid, PressureProtectionComponent pressureProtection, EntityEventArgs args)
|
||||||
{
|
{
|
||||||
args.Modifier = 100;
|
if (TryComp<BarotraumaComponent>(uid, out var barotrauma))
|
||||||
args.Multiplier = 10000;
|
{
|
||||||
|
UpdateCachedResistances(uid, barotrauma);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetFeltLowPressure(EntityUid uid, BarotraumaComponent baro, float environmentPressure)
|
private void OnPressureProtectionEquipped(EntityUid uid, PressureProtectionComponent pressureProtection, GotEquippedEvent args)
|
||||||
{
|
{
|
||||||
var modifier = float.MaxValue;
|
if (TryComp<BarotraumaComponent>(args.Equipee, out var barotrauma) && barotrauma.ProtectionSlots.Contains(args.Slot))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
modifier = 0;
|
UpdateCachedResistances(args.Equipee, barotrauma);
|
||||||
multiplier = 1;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, check if for protective equipment
|
private void OnPressureProtectionUnequipped(EntityUid uid, PressureProtectionComponent pressureProtection, GotUnequippedEvent args)
|
||||||
foreach (var slot in baro.ProtectionSlots)
|
{
|
||||||
|
if (TryComp<BarotraumaComponent>(args.Equipee, out var barotrauma) && barotrauma.ProtectionSlots.Contains(args.Slot))
|
||||||
|
{
|
||||||
|
UpdateCachedResistances(args.Equipee, barotrauma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 (!TryComp(uid, out InventoryComponent? inv) || !TryComp(uid, out ContainerManagerComponent? contMan))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var hPModifier = float.MinValue;
|
||||||
|
var hPMultiplier = float.MinValue;
|
||||||
|
var lPModifier = float.MaxValue;
|
||||||
|
var lPMultiplier = float.MaxValue;
|
||||||
|
|
||||||
|
foreach (var slot in barotrauma.ProtectionSlots)
|
||||||
{
|
{
|
||||||
if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan)
|
if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan)
|
||||||
|| !TryComp(equipment, out PressureProtectionComponent? protection))
|
|| !TryComp(equipment, out PressureProtectionComponent? protection))
|
||||||
{
|
{
|
||||||
// Missing protection, skin is exposed.
|
// Missing protection, skin is exposed.
|
||||||
modifier = 0;
|
hPModifier = 0f;
|
||||||
multiplier = 1;
|
hPMultiplier = 1f;
|
||||||
|
lPModifier = 0f;
|
||||||
|
lPMultiplier = 1f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier = Math.Min(protection.LowPressureModifier, modifier);
|
// The entity is as protected as its weakest part protection
|
||||||
multiplier = Math.Min(protection.LowPressureMultiplier, multiplier);
|
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.
|
barotrauma.HighPressureModifier = hPModifier;
|
||||||
var lowPressureEvent = new LowPressureEvent(environmentPressure);
|
barotrauma.HighPressureMultiplier = hPMultiplier;
|
||||||
RaiseLocalEvent(uid, lowPressureEvent);
|
barotrauma.LowPressureModifier = lPModifier;
|
||||||
|
barotrauma.LowPressureMultiplier = lPMultiplier;
|
||||||
return (environmentPressure + modifier + lowPressureEvent.Modifier)
|
|
||||||
* (multiplier * lowPressureEvent.Multiplier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetFeltHighPressure(EntityUid uid, BarotraumaComponent baro, float environmentPressure)
|
// any innate pressure resistance ?
|
||||||
|
if (TryComp<PressureProtectionComponent>(uid, out var innatePressureProtection))
|
||||||
{
|
{
|
||||||
var modifier = float.MinValue;
|
barotrauma.HighPressureModifier += innatePressureProtection.HighPressureModifier;
|
||||||
var multiplier = float.MinValue;
|
barotrauma.HighPressureMultiplier *= innatePressureProtection.HighPressureMultiplier;
|
||||||
|
barotrauma.LowPressureModifier += innatePressureProtection.LowPressureModifier;
|
||||||
TryComp(uid, out InventoryComponent? inv);
|
barotrauma.LowPressureMultiplier *= innatePressureProtection.LowPressureMultiplier;
|
||||||
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)
|
|
||||||
{
|
|
||||||
modifier = 0;
|
|
||||||
multiplier = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, check if for protective equipment
|
/// <summary>
|
||||||
foreach (var slot in baro.ProtectionSlots)
|
/// 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)
|
||||||
{
|
{
|
||||||
if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan)
|
if (barotrauma.HasImmunity)
|
||||||
|| !TryComp(equipment, out PressureProtectionComponent? protection))
|
|
||||||
{
|
{
|
||||||
// Missing protection, skin is exposed.
|
return Atmospherics.OneAtmosphere;
|
||||||
modifier = 0;
|
|
||||||
multiplier = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier = Math.Max(protection.HighPressureModifier, modifier);
|
return (environmentPressure + barotrauma.LowPressureModifier) * (barotrauma.LowPressureMultiplier);
|
||||||
multiplier = Math.Max(protection.HighPressureMultiplier, multiplier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then apply any generic, non-clothing related modifiers.
|
/// <summary>
|
||||||
var highPressureEvent = new HighPressureEvent(environmentPressure);
|
/// Returns adjusted pressure after having applied resistances from equipment and innate (if any), to check against a high pressure hazard threshold
|
||||||
RaiseLocalEvent(uid, highPressureEvent);
|
/// </summary>
|
||||||
|
public float GetFeltHighPressure(EntityUid uid, BarotraumaComponent barotrauma, float environmentPressure)
|
||||||
|
{
|
||||||
|
if (barotrauma.HasImmunity)
|
||||||
|
{
|
||||||
|
return Atmospherics.OneAtmosphere;
|
||||||
|
}
|
||||||
|
|
||||||
return (environmentPressure + modifier + highPressureEvent.Modifier)
|
return (environmentPressure + barotrauma.HighPressureModifier) * (barotrauma.HighPressureMultiplier);
|
||||||
* (multiplier * highPressureEvent.Multiplier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
|
|||||||
Reference in New Issue
Block a user