Fix barotrauma calculations

The math for our pressure damage (barotrauma) system is directly taken from TG. The constants are the same and the math is almost the same. However there are two errors.

1. Pressure damage started being applied within the WARNING bounds, rather than the HAZARD bounds. This means you started taking low pressure damage at 50 kPa instead of the intended 20 kPa, and also the HUD icon didn't show "danger" like it should even if you were already taking damage.

2. The calculations for high pressure damage were wrong. These are supposed to be linearly scaled, but the function was wrong so the scaling didn't actually work properly (especially when considering the fixed bounds above). This appears to be the case because the function was taken from an incorrect comment in the original source, rather than the real math.

Both of these issues are now fixed to match the TG behavior. Note that this somewhat nerfs pressure damage in non-extreme circumstances. e.g. a room at 40 kPa now gives NO pressure damage, whereas previously it would do full space damage.

The description of the pressure alerts is wrong for "low" severity, but I can't be arsed to fix that right now. Alerts don't have a way to change the description depending on severity...
This commit is contained in:
Pieter-Jan Briers
2024-03-17 22:37:28 +01:00
parent f259f2f3a2
commit b5138b245e
2 changed files with 52 additions and 57 deletions

View File

@@ -224,69 +224,64 @@ namespace Content.Server.Atmos.EntitySystems
pressure = MathF.Max(mixture.Pressure, 1f);
}
switch (pressure)
pressure = pressure switch
{
// Low pressure.
case <= Atmospherics.WarningLowPressure:
pressure = GetFeltLowPressure(uid, barotrauma, pressure);
// Adjust pressure based on equipment. Works differently depending on if it's "high" or "low".
<= Atmospherics.WarningLowPressure => GetFeltLowPressure(uid, barotrauma, pressure),
>= Atmospherics.WarningHighPressure => GetFeltHighPressure(uid, barotrauma, pressure),
_ => pressure
};
if (pressure > Atmospherics.WarningLowPressure)
goto default;
if (pressure <= Atmospherics.HazardLowPressure)
{
// Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear.
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * Atmospherics.LowPressureDamage, true, false);
// Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear.
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * Atmospherics.LowPressureDamage, true, false);
if (!barotrauma.TakingDamage)
{
barotrauma.TakingDamage = true;
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking low pressure damage");
}
if (!barotrauma.TakingDamage)
{
barotrauma.TakingDamage = true;
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking low pressure damage");
}
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 2);
}
else if (pressure >= Atmospherics.HazardHighPressure)
{
var damageScale = MathF.Min(((pressure / Atmospherics.HazardHighPressure) - 1) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage);
if (pressure <= Atmospherics.HazardLowPressure)
{
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 2);
// Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear.
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false);
if (!barotrauma.TakingDamage)
{
barotrauma.TakingDamage = true;
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage");
}
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2);
}
else
{
// Within safe pressure limits
if (barotrauma.TakingDamage)
{
barotrauma.TakingDamage = false;
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} stopped taking pressure damage");
}
// Set correct alert.
switch (pressure)
{
case <= Atmospherics.WarningLowPressure:
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 1);
break;
}
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 1);
break;
// High pressure.
case >= Atmospherics.WarningHighPressure:
pressure = GetFeltHighPressure(uid, barotrauma, pressure);
if (pressure < Atmospherics.WarningHighPressure)
goto default;
var damageScale = MathF.Min((pressure / Atmospherics.HazardHighPressure) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage);
// Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear.
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false);
if (!barotrauma.TakingDamage)
{
barotrauma.TakingDamage = true;
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage");
}
if (pressure >= Atmospherics.HazardHighPressure)
{
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2);
case >= Atmospherics.WarningHighPressure:
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 1);
break;
}
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 1);
break;
// Normal pressure.
default:
if (barotrauma.TakingDamage)
{
barotrauma.TakingDamage = false;
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} stopped taking pressure damage");
}
_alertsSystem.ClearAlertCategory(uid, AlertCategory.Pressure);
break;
default:
_alertsSystem.ClearAlertCategory(uid, AlertCategory.Pressure);
break;
}
}
}
}