diff --git a/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs b/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs
new file mode 100644
index 0000000000..7c7b1e81e8
--- /dev/null
+++ b/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs
@@ -0,0 +1,11 @@
+namespace Content.Server.Temperature.Components;
+
+[RegisterComponent]
+public sealed partial class ContainerTemperatureComponent : Component
+{
+ [DataField]
+ public float? HeatDamageThreshold;
+
+ [DataField]
+ public float? ColdDamageThreshold;
+}
diff --git a/Content.Server/Temperature/Components/ContainerTemperatureDamageThresholdsComponent.cs b/Content.Server/Temperature/Components/ContainerTemperatureDamageThresholdsComponent.cs
deleted file mode 100644
index 024b8a013b..0000000000
--- a/Content.Server/Temperature/Components/ContainerTemperatureDamageThresholdsComponent.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Content.Server.Temperature.Components;
-
-[RegisterComponent]
-public sealed partial class ContainerTemperatureDamageThresholdsComponent: Component
-{
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public float? HeatDamageThreshold;
-
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public float? ColdDamageThreshold;
-}
diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs b/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs
new file mode 100644
index 0000000000..d436977daf
--- /dev/null
+++ b/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs
@@ -0,0 +1,279 @@
+using Content.Server.Administration.Logs;
+using Content.Server.Body.Components;
+using Content.Server.Temperature.Components;
+using Content.Shared.Alert;
+using Content.Shared.Damage.Components;
+using Content.Shared.Damage.Systems;
+using Content.Shared.Database;
+using Content.Shared.Rounding;
+using Content.Shared.Temperature;
+using Content.Shared.Temperature.Components;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Temperature.Systems;
+
+///
+/// Handles entities taking damage from being too hot or too cold.
+/// Also handles alerts relevant to the same.
+///
+public sealed partial class TemperatureSystem
+{
+ [Dependency] private readonly AlertsSystem _alerts = default!;
+ [Dependency] private readonly DamageableSystem _damageable = default!;
+ [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+
+ private EntityQuery _tempDamageQuery;
+ private EntityQuery _containerTemperatureQuery;
+ private EntityQuery _thermalRegulatorQuery;
+
+ ///
+ /// All the components that will have their damage updated at the end of the tick.
+ /// This is done because both AtmosExposed and Flammable call ChangeHeat in the same tick, meaning
+ /// that we need some mechanism to ensure it doesn't double-dip on damage for both calls.
+ ///
+ public HashSet> ShouldUpdateDamage = new();
+
+ ///
+ /// Alert prototype for Temperature.
+ ///
+ public static readonly ProtoId TemperatureAlertCategory = "Temperature";
+
+ ///
+ /// The maximum severity applicable to temperature alerts.
+ ///
+ public static readonly short MaxTemperatureAlertSeverity = 3;
+
+ ///
+ /// On a scale of 0. to 1. where 0. is the ideal temperature and 1. is a temperature damage threshold this is the point where the component starts raising temperature alerts.
+ ///
+ public static readonly float MinAlertTemperatureScale = 0.33f;
+
+ private void InitializeDamage()
+ {
+ SubscribeLocalEvent(ServerAlert);
+
+ SubscribeLocalEvent(EnqueueDamage);
+ SubscribeLocalEvent(OnUnpaused);
+
+ // Allows overriding thresholds based on the parent's thresholds.
+ SubscribeLocalEvent(OnParentChange);
+ SubscribeLocalEvent(OnParentThresholdStartup);
+ SubscribeLocalEvent(OnParentThresholdShutdown);
+
+ _tempDamageQuery = GetEntityQuery();
+ _containerTemperatureQuery = GetEntityQuery();
+ _thermalRegulatorQuery = GetEntityQuery();
+ }
+
+ private void UpdateDamage()
+ {
+ foreach (var entity in ShouldUpdateDamage)
+ {
+ if (Deleted(entity) || Paused(entity))
+ continue;
+
+ var deltaTime = _gameTiming.CurTime - entity.Comp.LastUpdate;
+ if (entity.Comp.TakingDamage && deltaTime < entity.Comp.UpdateInterval)
+ continue;
+
+ ChangeDamage(entity, deltaTime);
+ }
+
+ ShouldUpdateDamage.Clear();
+ }
+
+ private void ChangeDamage(Entity entity, TimeSpan deltaTime)
+ {
+ entity.Comp.LastUpdate = _gameTiming.CurTime;
+
+ if (!HasComp(entity) || !TemperatureQuery.TryComp(entity, out var temperature))
+ return;
+
+ // See this link for where the scaling func comes from:
+ // https://www.desmos.com/calculator/0vknqtdvq9
+ // Based on a logistic curve, which caps out at MaxDamage
+ var heatK = 0.005;
+ var a = 1;
+ var y = entity.Comp.DamageCap;
+ var c = y * 2;
+
+ var heatDamageThreshold = entity.Comp.ParentHeatDamageThreshold ?? entity.Comp.HeatDamageThreshold;
+ var coldDamageThreshold = entity.Comp.ParentColdDamageThreshold ?? entity.Comp.ColdDamageThreshold;
+
+ if (temperature.CurrentTemperature >= heatDamageThreshold)
+ {
+ if (!entity.Comp.TakingDamage)
+ {
+ _adminLogger.Add(LogType.Temperature, $"{ToPrettyString(entity):entity} started taking high temperature damage");
+ entity.Comp.TakingDamage = true;
+ }
+
+ var diff = Math.Abs(temperature.CurrentTemperature - heatDamageThreshold);
+ var tempDamage = c / (1 + a * Math.Pow(Math.E, -heatK * diff)) - y;
+ _damageable.TryChangeDamage(entity.Owner, entity.Comp.HeatDamage * tempDamage * deltaTime.TotalSeconds, ignoreResistances: true, interruptsDoAfters: false);
+ }
+ else if (temperature.CurrentTemperature <= coldDamageThreshold)
+ {
+ if (!entity.Comp.TakingDamage)
+ {
+ _adminLogger.Add(LogType.Temperature, $"{ToPrettyString(entity):entity} started taking low temperature damage");
+ entity.Comp.TakingDamage = true;
+ }
+
+ var diff = Math.Abs(temperature.CurrentTemperature - coldDamageThreshold);
+ var tempDamage =
+ Math.Sqrt(diff * (Math.Pow(entity.Comp.DamageCap.Double(), 2) / coldDamageThreshold));
+ _damageable.TryChangeDamage(entity.Owner, entity.Comp.ColdDamage * tempDamage * deltaTime.TotalSeconds, ignoreResistances: true, interruptsDoAfters: false);
+ }
+ else if (entity.Comp.TakingDamage)
+ {
+ _adminLogger.Add(LogType.Temperature, $"{ToPrettyString(entity):entity} stopped taking temperature damage");
+ entity.Comp.TakingDamage = false;
+ }
+ }
+
+ private void ServerAlert(Entity entity, ref OnTemperatureChangeEvent args)
+ {
+ ProtoId type;
+ float threshold;
+ float idealTemp;
+
+ if (!_tempDamageQuery.TryComp(entity, out var thresholds))
+ {
+ _alerts.ClearAlertCategory(entity.Owner, TemperatureAlertCategory);
+ return;
+ }
+
+ if (_thermalRegulatorQuery.TryComp(entity, out var regulator) &&
+ regulator.NormalBodyTemperature > thresholds.ColdDamageThreshold &&
+ regulator.NormalBodyTemperature < thresholds.HeatDamageThreshold)
+ {
+ idealTemp = regulator.NormalBodyTemperature;
+ }
+ else
+ {
+ idealTemp = (thresholds.ColdDamageThreshold + thresholds.HeatDamageThreshold) / 2;
+ }
+
+ if (args.CurrentTemperature <= idealTemp)
+ {
+ type = thresholds.ColdAlert;
+ threshold = thresholds.ColdDamageThreshold;
+ }
+ else
+ {
+ type = thresholds.HotAlert;
+ threshold = thresholds.HeatDamageThreshold;
+ }
+
+ // Calculates a scale where 0.0 is the ideal temperature and 1.0 is where temperature damage begins
+ // The cold and hot scales will differ in their range if the ideal temperature is not exactly halfway between the thresholds
+ var tempScale = (args.CurrentTemperature - idealTemp) / (threshold - idealTemp);
+ var alertLevel = (short)ContentHelpers.RoundToLevels(tempScale - MinAlertTemperatureScale, 1.00f - MinAlertTemperatureScale, MaxTemperatureAlertSeverity + 1);
+
+ if (alertLevel > 0)
+ _alerts.ShowAlert(entity.AsNullable(), type, alertLevel);
+ else
+ _alerts.ClearAlertCategory(entity.AsNullable(), TemperatureAlertCategory);
+ }
+
+ private void EnqueueDamage(Entity ent, ref OnTemperatureChangeEvent args)
+ {
+ if (ShouldUpdateDamage.Add(ent) && !ent.Comp.TakingDamage)
+ ent.Comp.LastUpdate = _gameTiming.CurTime;
+ }
+
+ private void OnUnpaused(Entity ent, ref EntityUnpausedEvent args)
+ {
+ ent.Comp.LastUpdate += args.PausedTime;
+ }
+
+ private void OnParentChange(Entity entity, ref EntParentChangedMessage args)
+ {
+ // We only need to update thresholds if the thresholds changed for the entity's ancestors.
+ var oldThresholds = args.OldParent != null
+ ? RecalculateParentThresholds(args.OldParent.Value)
+ : (null, null);
+ var xform = Transform(entity.Owner);
+ var newThresholds = RecalculateParentThresholds(xform.ParentUid);
+
+ if (oldThresholds != newThresholds)
+ RecursiveThresholdUpdate((entity, entity.Comp, xform));
+ }
+
+ private void OnParentThresholdStartup(Entity entity, ref ComponentStartup args)
+ {
+ RecursiveThresholdUpdate(entity.Owner);
+ }
+
+ private void OnParentThresholdShutdown(Entity entity, ref ComponentShutdown args)
+ {
+ RecursiveThresholdUpdate(entity.Owner);
+ }
+
+ ///
+ /// Recalculate and apply parent thresholds for the root entity and all its children.
+ ///
+ /// The root entity we're currently updating
+ private void RecursiveThresholdUpdate(Entity root)
+ {
+ RecalculateAndApplyParentThresholds(root);
+
+ var xform = root.Comp2 ?? Transform(root);
+ var enumerator = xform.ChildEnumerator;
+ while (enumerator.MoveNext(out var child))
+ {
+ RecursiveThresholdUpdate(child);
+ }
+ }
+
+ ///
+ /// Recalculate parent thresholds and apply them on the uid temperature component.
+ ///
+ /// The entity whose temperature damage thresholds we're updating
+ private void RecalculateAndApplyParentThresholds(Entity entity)
+ {
+ if (!_tempDamageQuery.Resolve(entity, ref entity.Comp, logMissing: false))
+ return;
+
+ var newThresholds = RecalculateParentThresholds(Transform(entity).ParentUid);
+ entity.Comp.ParentHeatDamageThreshold = newThresholds.Item1;
+ entity.Comp.ParentColdDamageThreshold = newThresholds.Item2;
+ }
+
+ ///
+ /// Recalculate Parent Heat/Cold DamageThreshold by recursively checking each ancestor and fetching the
+ /// maximum HeatDamageThreshold and the minimum ColdDamageThreshold if any exists (aka the best value for each).
+ ///
+ /// parent we start with
+ private (float?, float?) RecalculateParentThresholds(EntityUid initialParentUid)
+ {
+ // Recursively check parents for the best threshold available
+ var parentUid = initialParentUid;
+ float? newHeatThreshold = null;
+ float? newColdThreshold = null;
+ while (parentUid.IsValid())
+ {
+ if (_containerTemperatureQuery.TryComp(parentUid, out var newThresholds))
+ {
+ if (newThresholds.HeatDamageThreshold != null)
+ {
+ newHeatThreshold = Math.Max(newThresholds.HeatDamageThreshold.Value,
+ newHeatThreshold ?? 0);
+ }
+
+ if (newThresholds.ColdDamageThreshold != null)
+ {
+ newColdThreshold = Math.Min(newThresholds.ColdDamageThreshold.Value,
+ newColdThreshold ?? float.MaxValue);
+ }
+ }
+
+ parentUid = Transform(parentUid).ParentUid;
+ }
+
+ return (newHeatThreshold, newColdThreshold);
+ }
+}
diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.cs b/Content.Server/Temperature/Systems/TemperatureSystem.cs
index 928b6ae9b5..484912c780 100644
--- a/Content.Server/Temperature/Systems/TemperatureSystem.cs
+++ b/Content.Server/Temperature/Systems/TemperatureSystem.cs
@@ -1,64 +1,32 @@
-using System.Linq;
-using Content.Server.Administration.Logs;
using Content.Server.Atmos.EntitySystems;
-using Content.Server.Body.Components;
using Content.Server.Temperature.Components;
-using Content.Shared.Alert;
using Content.Shared.Atmos;
-using Content.Shared.Damage.Components;
-using Content.Shared.Damage.Systems;
-using Content.Shared.Database;
using Content.Shared.Inventory;
using Content.Shared.Rejuvenate;
using Content.Shared.Temperature;
-using Robust.Shared.Prototypes;
using Content.Shared.Projectiles;
using Content.Shared.Temperature.Components;
using Content.Shared.Temperature.Systems;
namespace Content.Server.Temperature.Systems;
-public sealed class TemperatureSystem : SharedTemperatureSystem
+public sealed partial class TemperatureSystem : SharedTemperatureSystem
{
- [Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
- [Dependency] private readonly DamageableSystem _damageable = default!;
- [Dependency] private readonly IAdminLogManager _adminLogger = default!;
- [Dependency] private readonly TemperatureSystem _temperature = default!;
-
- ///
- /// All the components that will have their damage updated at the end of the tick.
- /// This is done because both AtmosExposed and Flammable call ChangeHeat in the same tick, meaning
- /// that we need some mechanism to ensure it doesn't double dip on damage for both calls.
- ///
- public HashSet> ShouldUpdateDamage = new();
-
- public float UpdateInterval = 1.0f;
-
- private float _accumulatedFrametime;
-
- public static readonly ProtoId TemperatureAlertCategory = "Temperature";
public override void Initialize()
{
base.Initialize();
- SubscribeLocalEvent(EnqueueDamage);
SubscribeLocalEvent(OnAtmosExposedUpdate);
SubscribeLocalEvent(OnRejuvenate);
- SubscribeLocalEvent(ServerAlert);
Subs.SubscribeWithRelay(OnTemperatureChangeAttempt, held: false);
SubscribeLocalEvent(OnInit);
SubscribeLocalEvent(ChangeTemperatureOnCollide);
- // Allows overriding thresholds based on the parent's thresholds.
- SubscribeLocalEvent(OnParentChange);
- SubscribeLocalEvent(
- OnParentThresholdStartup);
- SubscribeLocalEvent(
- OnParentThresholdShutdown);
+ InitializeDamage();
}
public override void Update(float frameTime)
@@ -88,49 +56,23 @@ public sealed class TemperatureSystem : SharedTemperatureSystem
ForceChangeTemperature(uid, temp.CurrentTemperature - degrees, temp);
}
- UpdateDamage(frameTime);
- }
-
- private void UpdateDamage(float frameTime)
- {
- _accumulatedFrametime += frameTime;
-
- if (_accumulatedFrametime < UpdateInterval)
- return;
- _accumulatedFrametime -= UpdateInterval;
-
- if (!ShouldUpdateDamage.Any())
- return;
-
- foreach (var comp in ShouldUpdateDamage)
- {
- MetaDataComponent? metaData = null;
-
- var uid = comp.Owner;
- if (Deleted(uid, metaData) || Paused(uid, metaData))
- continue;
-
- ChangeDamage(uid, comp);
- }
-
- ShouldUpdateDamage.Clear();
+ UpdateDamage();
}
public void ForceChangeTemperature(EntityUid uid, float temp, TemperatureComponent? temperature = null)
{
- if (!Resolve(uid, ref temperature))
+ if (!TemperatureQuery.Resolve(uid, ref temperature))
return;
- float lastTemp = temperature.CurrentTemperature;
- float delta = temperature.CurrentTemperature - temp;
+ var lastTemp = temperature.CurrentTemperature;
+ var delta = temperature.CurrentTemperature - temp;
temperature.CurrentTemperature = temp;
- RaiseLocalEvent(uid, new OnTemperatureChangeEvent(temperature.CurrentTemperature, lastTemp, delta),
- true);
+ RaiseLocalEvent(uid, new OnTemperatureChangeEvent(temperature.CurrentTemperature, lastTemp, delta), broadcast: true);
}
public override void ChangeHeat(EntityUid uid, float heatAmount, bool ignoreHeatResistance = false, TemperatureComponent? temperature = null)
{
- if (!Resolve(uid, ref temperature, false))
+ if (!TemperatureQuery.Resolve(uid, ref temperature, false))
return;
if (!ignoreHeatResistance)
@@ -144,11 +86,10 @@ public sealed class TemperatureSystem : SharedTemperatureSystem
temperature.CurrentTemperature += heatAmount / GetHeatCapacity(uid, temperature);
float delta = temperature.CurrentTemperature - lastTemp;
- RaiseLocalEvent(uid, new OnTemperatureChangeEvent(temperature.CurrentTemperature, lastTemp, delta), true);
+ RaiseLocalEvent(uid, new OnTemperatureChangeEvent(temperature.CurrentTemperature, lastTemp, delta), broadcast: true);
}
- private void OnAtmosExposedUpdate(EntityUid uid, TemperatureComponent temperature,
- ref AtmosExposedUpdateEvent args)
+ private void OnAtmosExposedUpdate(EntityUid uid, TemperatureComponent temperature, ref AtmosExposedUpdateEvent args)
{
var transform = args.Transform;
@@ -158,17 +99,18 @@ public sealed class TemperatureSystem : SharedTemperatureSystem
var temperatureDelta = args.GasMixture.Temperature - temperature.CurrentTemperature;
var airHeatCapacity = _atmosphere.GetHeatCapacity(args.GasMixture, false);
var heatCapacity = GetHeatCapacity(uid, temperature);
+ // TODO ATMOS: This heat transfer formula is really really wrong, it needs to be pulled out. Pending on HeatContainers.
var heat = temperatureDelta * (airHeatCapacity * heatCapacity /
(airHeatCapacity + heatCapacity));
ChangeHeat(uid, heat * temperature.AtmosTemperatureTransferEfficiency, temperature: temperature);
}
- private void OnInit(EntityUid uid, InternalTemperatureComponent comp, MapInitEvent args)
+ private void OnInit(Entity entity, ref MapInitEvent args)
{
- if (!TryComp(uid, out var temp))
+ if (!TemperatureQuery.TryComp(entity, out var temp))
return;
- comp.Temperature = temp.CurrentTemperature;
+ entity.Comp.Temperature = temp.CurrentTemperature;
}
private void OnRejuvenate(EntityUid uid, TemperatureComponent comp, RejuvenateEvent args)
@@ -176,116 +118,6 @@ public sealed class TemperatureSystem : SharedTemperatureSystem
ForceChangeTemperature(uid, Atmospherics.T20C, comp);
}
- private void ServerAlert(EntityUid uid, AlertsComponent status, OnTemperatureChangeEvent args)
- {
- ProtoId type;
- float threshold;
- float idealTemp;
-
- if (!TryComp(uid, out var temperature))
- {
- _alerts.ClearAlertCategory(uid, TemperatureAlertCategory);
- return;
- }
-
- if (TryComp(uid, out var regulator) &&
- regulator.NormalBodyTemperature > temperature.ColdDamageThreshold &&
- regulator.NormalBodyTemperature < temperature.HeatDamageThreshold)
- {
- idealTemp = regulator.NormalBodyTemperature;
- }
- else
- {
- idealTemp = (temperature.ColdDamageThreshold + temperature.HeatDamageThreshold) / 2;
- }
-
- if (args.CurrentTemperature <= idealTemp)
- {
- type = temperature.ColdAlert;
- threshold = temperature.ColdDamageThreshold;
- }
- else
- {
- type = temperature.HotAlert;
- threshold = temperature.HeatDamageThreshold;
- }
-
- // Calculates a scale where 1.0 is the ideal temperature and 0.0 is where temperature damage begins
- // The cold and hot scales will differ in their range if the ideal temperature is not exactly halfway between the thresholds
- var tempScale = (args.CurrentTemperature - threshold) / (idealTemp - threshold);
- switch (tempScale)
- {
- case <= 0f:
- _alerts.ShowAlert(uid, type, 3);
- break;
-
- case <= 0.4f:
- _alerts.ShowAlert(uid, type, 2);
- break;
-
- case <= 0.66f:
- _alerts.ShowAlert(uid, type, 1);
- break;
-
- case > 0.66f:
- _alerts.ClearAlertCategory(uid, TemperatureAlertCategory);
- break;
- }
- }
-
- private void EnqueueDamage(Entity temperature, ref OnTemperatureChangeEvent args)
- {
- ShouldUpdateDamage.Add(temperature);
- }
-
- private void ChangeDamage(EntityUid uid, TemperatureComponent temperature)
- {
- if (!HasComp(uid))
- return;
-
- // See this link for where the scaling func comes from:
- // https://www.desmos.com/calculator/0vknqtdvq9
- // Based on a logistic curve, which caps out at MaxDamage
- var heatK = 0.005;
- var a = 1;
- var y = temperature.DamageCap;
- var c = y * 2;
-
- var heatDamageThreshold = temperature.ParentHeatDamageThreshold ?? temperature.HeatDamageThreshold;
- var coldDamageThreshold = temperature.ParentColdDamageThreshold ?? temperature.ColdDamageThreshold;
-
- if (temperature.CurrentTemperature >= heatDamageThreshold)
- {
- if (!temperature.TakingDamage)
- {
- _adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking high temperature damage");
- temperature.TakingDamage = true;
- }
-
- var diff = Math.Abs(temperature.CurrentTemperature - heatDamageThreshold);
- var tempDamage = c / (1 + a * Math.Pow(Math.E, -heatK * diff)) - y;
- _damageable.TryChangeDamage(uid, temperature.HeatDamage * tempDamage, ignoreResistances: true, interruptsDoAfters: false);
- }
- else if (temperature.CurrentTemperature <= coldDamageThreshold)
- {
- if (!temperature.TakingDamage)
- {
- _adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} started taking low temperature damage");
- temperature.TakingDamage = true;
- }
-
- var diff = Math.Abs(temperature.CurrentTemperature - coldDamageThreshold);
- var tempDamage =
- Math.Sqrt(diff * (Math.Pow(temperature.DamageCap.Double(), 2) / coldDamageThreshold));
- _damageable.TryChangeDamage(uid, temperature.ColdDamage * tempDamage, ignoreResistances: true, interruptsDoAfters: false);
- }
- else if (temperature.TakingDamage)
- {
- _adminLogger.Add(LogType.Temperature, $"{ToPrettyString(uid):entity} stopped taking temperature damage");
- temperature.TakingDamage = false;
- }
- }
-
private void OnTemperatureChangeAttempt(EntityUid uid, TemperatureProtectionComponent component, ModifyChangedTemperatureEvent args)
{
var coefficient = args.TemperatureDelta < 0
@@ -300,118 +132,6 @@ public sealed class TemperatureSystem : SharedTemperatureSystem
private void ChangeTemperatureOnCollide(Entity ent, ref ProjectileHitEvent args)
{
- _temperature.ChangeHeat(args.Target, ent.Comp.Heat, ent.Comp.IgnoreHeatResistance);// adjust the temperature
- }
-
- private void OnParentChange(EntityUid uid, TemperatureComponent component,
- ref EntParentChangedMessage args)
- {
- var temperatureQuery = GetEntityQuery();
- var transformQuery = GetEntityQuery();
- var thresholdsQuery = GetEntityQuery();
- // We only need to update thresholds if the thresholds changed for the entity's ancestors.
- var oldThresholds = args.OldParent != null
- ? RecalculateParentThresholds(args.OldParent.Value, transformQuery, thresholdsQuery)
- : (null, null);
- var newThresholds = RecalculateParentThresholds(transformQuery.GetComponent(uid).ParentUid, transformQuery, thresholdsQuery);
-
- if (oldThresholds != newThresholds)
- {
- RecursiveThresholdUpdate(uid, temperatureQuery, transformQuery, thresholdsQuery);
- }
- }
-
- private void OnParentThresholdStartup(EntityUid uid, ContainerTemperatureDamageThresholdsComponent component,
- ComponentStartup args)
- {
- RecursiveThresholdUpdate(uid, GetEntityQuery(), GetEntityQuery(),
- GetEntityQuery());
- }
-
- private void OnParentThresholdShutdown(EntityUid uid, ContainerTemperatureDamageThresholdsComponent component,
- ComponentShutdown args)
- {
- RecursiveThresholdUpdate(uid, GetEntityQuery(), GetEntityQuery(),
- GetEntityQuery());
- }
-
- ///
- /// Recalculate and apply parent thresholds for the root entity and all its descendant.
- ///
- ///
- ///
- ///
- ///
- private void RecursiveThresholdUpdate(EntityUid root, EntityQuery temperatureQuery,
- EntityQuery transformQuery,
- EntityQuery tempThresholdsQuery)
- {
- RecalculateAndApplyParentThresholds(root, temperatureQuery, transformQuery, tempThresholdsQuery);
-
- var enumerator = Transform(root).ChildEnumerator;
- while (enumerator.MoveNext(out var child))
- {
- RecursiveThresholdUpdate(child, temperatureQuery, transformQuery, tempThresholdsQuery);
- }
- }
-
- ///
- /// Recalculate parent thresholds and apply them on the uid temperature component.
- ///
- ///
- ///
- ///
- ///
- private void RecalculateAndApplyParentThresholds(EntityUid uid,
- EntityQuery temperatureQuery, EntityQuery transformQuery,
- EntityQuery tempThresholdsQuery)
- {
- if (!temperatureQuery.TryGetComponent(uid, out var temperature))
- {
- return;
- }
-
- var newThresholds = RecalculateParentThresholds(transformQuery.GetComponent(uid).ParentUid, transformQuery, tempThresholdsQuery);
- temperature.ParentHeatDamageThreshold = newThresholds.Item1;
- temperature.ParentColdDamageThreshold = newThresholds.Item2;
- }
-
- ///
- /// Recalculate Parent Heat/Cold DamageThreshold by recursively checking each ancestor and fetching the
- /// maximum HeatDamageThreshold and the minimum ColdDamageThreshold if any exists (aka the best value for each).
- ///
- ///
- ///
- ///
- private (float?, float?) RecalculateParentThresholds(
- EntityUid initialParentUid,
- EntityQuery transformQuery,
- EntityQuery tempThresholdsQuery)
- {
- // Recursively check parents for the best threshold available
- var parentUid = initialParentUid;
- float? newHeatThreshold = null;
- float? newColdThreshold = null;
- while (parentUid.IsValid())
- {
- if (tempThresholdsQuery.TryGetComponent(parentUid, out var newThresholds))
- {
- if (newThresholds.HeatDamageThreshold != null)
- {
- newHeatThreshold = Math.Max(newThresholds.HeatDamageThreshold.Value,
- newHeatThreshold ?? 0);
- }
-
- if (newThresholds.ColdDamageThreshold != null)
- {
- newColdThreshold = Math.Min(newThresholds.ColdDamageThreshold.Value,
- newColdThreshold ?? float.MaxValue);
- }
- }
-
- parentUid = transformQuery.GetComponent(parentUid).ParentUid;
- }
-
- return (newHeatThreshold, newColdThreshold);
+ ChangeHeat(args.Target, ent.Comp.Heat, ent.Comp.IgnoreHeatResistance);// adjust the temperature
}
}
diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs
index b4aee77cef..f39487bb24 100644
--- a/Content.Server/Zombies/ZombieSystem.Transform.cs
+++ b/Content.Server/Zombies/ZombieSystem.Transform.cs
@@ -242,7 +242,7 @@ public sealed partial class ZombieSystem
_mind.MakeSentient(target);
//Make the zombie not die in the cold. Good for space zombies
- if (TryComp(target, out var tempComp))
+ if (TryComp(target, out var tempComp))
tempComp.ColdDamage.ClampMax(0);
//Heals the zombie from all the damage it took while human
diff --git a/Content.Shared/Temperature/Components/TemperatureComponent.cs b/Content.Shared/Temperature/Components/TemperatureComponent.cs
index b73d1f77d1..fd79c4b4b2 100644
--- a/Content.Shared/Temperature/Components/TemperatureComponent.cs
+++ b/Content.Shared/Temperature/Components/TemperatureComponent.cs
@@ -1,15 +1,10 @@
-using Content.Shared.Alert;
using Content.Shared.Atmos;
-using Content.Shared.Damage;
-using Content.Shared.FixedPoint;
-using Robust.Shared.Prototypes;
namespace Content.Shared.Temperature.Components;
///
/// Handles changing temperature,
-/// informing others of the current temperature,
-/// and taking fire damage from high temperature.
+/// informing others of the current temperature.
///
[RegisterComponent]
public sealed partial class TemperatureComponent : Component
@@ -20,24 +15,6 @@ public sealed partial class TemperatureComponent : Component
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float CurrentTemperature = Atmospherics.T20C;
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public float HeatDamageThreshold = 360f;
-
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public float ColdDamageThreshold = 260f;
-
- ///
- /// Overrides HeatDamageThreshold if the entity's within a parent with the TemperatureDamageThresholdsComponent component.
- ///
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public float? ParentHeatDamageThreshold;
-
- ///
- /// Overrides ColdDamageThreshold if the entity's within a parent with the TemperatureDamageThresholdsComponent component.
- ///
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public float? ParentColdDamageThreshold;
-
///
/// Heat capacity per kg of mass.
///
@@ -49,31 +26,4 @@ public sealed partial class TemperatureComponent : Component
///
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float AtmosTemperatureTransferEfficiency = 0.1f;
-
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public DamageSpecifier ColdDamage = new();
-
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public DamageSpecifier HeatDamage = new();
-
- ///
- /// Temperature won't do more than this amount of damage per second.
- ///
- ///
- /// Okay it genuinely reaches this basically immediately for a plasma fire.
- ///
- [DataField, ViewVariables(VVAccess.ReadWrite)]
- public FixedPoint2 DamageCap = FixedPoint2.New(8);
-
- ///
- /// Used to keep track of when damage starts/stops. Useful for logs.
- ///
- [DataField]
- public bool TakingDamage;
-
- [DataField]
- public ProtoId HotAlert = "Hot";
-
- [DataField]
- public ProtoId ColdAlert = "Cold";
}
diff --git a/Content.Shared/Temperature/Components/TemperatureDamageComponent.cs b/Content.Shared/Temperature/Components/TemperatureDamageComponent.cs
new file mode 100644
index 0000000000..a9543e3046
--- /dev/null
+++ b/Content.Shared/Temperature/Components/TemperatureDamageComponent.cs
@@ -0,0 +1,94 @@
+using Content.Shared.Alert;
+using Content.Shared.Damage;
+using Content.Shared.FixedPoint;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Temperature.Components;
+
+///
+/// Handles taking damage from being excessively hot/cold.
+/// Also handles alerts about being too hot or too cold.
+///
+[RegisterComponent]
+public sealed partial class TemperatureDamageComponent : Component
+{
+ ///
+ /// The temperature above which the entity will start taking damage from being too hot.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float HeatDamageThreshold = 360f;
+
+ ///
+ /// The temperature below which the entity will start taking damage from being too cold.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float ColdDamageThreshold = 260f;
+
+ ///
+ /// Overrides HeatDamageThreshold if the entity's within a parent with the ContainerTemperatureDamageThresholdsComponent component.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float? ParentHeatDamageThreshold;
+
+ ///
+ /// Overrides ColdDamageThreshold if the entity's within a parent with the ContainerTemperatureDamageThresholdsComponent component.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float? ParentColdDamageThreshold;
+
+ ///
+ /// The base damage that this entity will take if it's too cold.
+ /// Will be scaled according to how cold it is.
+ /// The scaling maxes out at times this damage per second.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public DamageSpecifier ColdDamage = new();
+
+ ///
+ /// The base damage that this entity will take per second if it's too hot.
+ /// Will be scaled according to how hot it is.
+ /// The scaling maxes out at times this damage per second.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public DamageSpecifier HeatDamage = new();
+
+ ///
+ /// Temperature won't do more than this multiple of the base overheating/overcooling damage per seond.
+ ///
+ ///
+ /// Okay it genuinely reaches this basically immediately for a plasma fire.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public FixedPoint2 DamageCap = FixedPoint2.New(8);
+
+ ///
+ /// Used to keep track of when damage starts/stops. Useful for logs.
+ ///
+ [DataField]
+ public bool TakingDamage;
+
+ ///
+ /// The id of the alert thrown when the entity is too hot.
+ ///
+ [DataField]
+ public ProtoId HotAlert = "Hot";
+
+ ///
+ /// The id of the alert thrown when the entity is too cold.
+ ///
+ [DataField]
+ public ProtoId ColdAlert = "Cold";
+
+ ///
+ /// The last time this entity processed temperature damage.
+ ///
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
+ public TimeSpan LastUpdate;
+
+ ///
+ /// The time interval between temperature damage ticks for this entity.
+ ///
+ [DataField]
+ public TimeSpan UpdateInterval = TimeSpan.FromSeconds(1.0);
+}
diff --git a/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs b/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs
index 9561c6dfe1..216349d6f5 100644
--- a/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs
+++ b/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs
@@ -16,6 +16,8 @@ public abstract class SharedTemperatureSystem : EntitySystem
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
+ protected EntityQuery TemperatureQuery;
+
///
/// Band-aid for unpredicted atmos. Delays the application for a short period so that laggy clients can get the replicated temperature.
///
@@ -27,6 +29,8 @@ public abstract class SharedTemperatureSystem : EntitySystem
SubscribeLocalEvent(OnTemperatureChanged);
SubscribeLocalEvent(OnRefreshMovementSpeedModifiers);
+
+ TemperatureQuery = GetEntityQuery();
}
private void OnTemperatureChanged(Entity ent, ref OnTemperatureChangeEvent args)
@@ -87,7 +91,7 @@ public abstract class SharedTemperatureSystem : EntitySystem
public float GetHeatCapacity(EntityUid uid, TemperatureComponent? comp = null, PhysicsComponent? physics = null)
{
- if (!Resolve(uid, ref comp) || !Resolve(uid, ref physics, false) || physics.FixturesMass <= 0)
+ if (!TemperatureQuery.Resolve(uid, ref comp) || !Resolve(uid, ref physics, false) || physics.FixturesMass <= 0)
{
return Atmospherics.MinimumHeatCapacity;
}
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
index 3685f891b6..39c319f068 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
@@ -1610,10 +1610,11 @@
Slash: 5
Piercing: 4
- type: Temperature
- heatDamageThreshold: 360
- coldDamageThreshold: 285
currentTemperature: 310.15
specificHeat: 42
+ - type: TemperatureDamage
+ heatDamageThreshold: 360
+ coldDamageThreshold: 285
- type: Sprite
drawdepth: Mobs
layers:
@@ -2368,10 +2369,11 @@
factions:
- Passive
- type: Temperature
- heatDamageThreshold: 335
- coldDamageThreshold: 230
currentTemperature: 310.15
specificHeat: 46
+ - type: TemperatureDamage
+ heatDamageThreshold: 335
+ coldDamageThreshold: 230
coldDamage:
types:
Cold : 0.05 #per second, scales with temperature & other constants
@@ -3055,13 +3057,14 @@
damageContainer: BiologicalMetaphysical
damageModifierSet: Infernal
- type: Temperature
+ currentTemperature: 310.15
+ specificHeat: 42
+ - type: TemperatureDamage
heatDamageThreshold: 4000 #They come from hell, so..
coldDamageThreshold: 260
- currentTemperature: 310.15
coldDamage:
types:
Cold : 1 #per second, scales with temperature & other constants
- specificHeat: 42
heatDamage:
types:
Heat : 1 #per second, scales with temperature & other constants
@@ -3256,6 +3259,7 @@
Dead:
Base: spacecat_dead
- type: Temperature
+ - type: TemperatureDamage
heatDamageThreshold: 423
coldDamageThreshold: 0
- type: Tag
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml
index 1547e36339..1eb22649e7 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml
@@ -185,6 +185,7 @@
damage:
types: {}
- type: Temperature
+ - type: TemperatureDamage
heatDamageThreshold: 1200
- type: entity
id: MobCarpDungeon
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
index ccb5c3aebb..b6e53b794d 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
@@ -833,6 +833,7 @@
Bloodloss:
-0.8
- type: Temperature
+ - type: TemperatureDamage
heatDamageThreshold: 800
coldDamageThreshold: 0
- type: MeleeWeapon
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml
index 8f84e1496a..883103adcc 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml
@@ -36,10 +36,11 @@
60: Critical
125: Dead
- type: Temperature
- heatDamageThreshold: 360
- coldDamageThreshold: 285
currentTemperature: 310.15
specificHeat: 42
+ - type: TemperatureDamage
+ heatDamageThreshold: 360
+ coldDamageThreshold: 285
# Good eatin', you monster.
- type: Butcherable
butcheringType: Spike
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
index 7a51d257ef..e57e0d3d97 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
@@ -45,6 +45,7 @@
Quantity: 300
- type: CombatMode
- type: Temperature
+ - type: TemperatureDamage
heatDamageThreshold: 500
coldDamageThreshold: 0
- type: MeleeWeapon
@@ -512,6 +513,7 @@
sprite: Mobs/Effects/onfire.rsi
normalState: Mouse_burning
- type: Temperature
+ - type: TemperatureDamage
heatDamageThreshold: 500
coldDamageThreshold: 0
- type: Reactive
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
index 58e0088828..33653ed207 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
@@ -107,9 +107,10 @@
- type: TypingIndicator
proto: alien
- type: Temperature
+ currentTemperature: 310.15
+ - type: TemperatureDamage
heatDamageThreshold: 360
coldDamageThreshold: -150
- currentTemperature: 310.15
- type: Tag
tags:
- CannotSuicide
@@ -524,9 +525,10 @@
- type: TypingIndicator
proto: alien
- type: Temperature
+ currentTemperature: 310.15
+ - type: TemperatureDamage
heatDamageThreshold: 360
coldDamageThreshold: -150
- currentTemperature: 310.15
- type: NoSlip
- type: Perishable #Ummmm the acid kills a lot of the bacteria or something
molsPerSecondPerUnitMass: 0.0005
diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml
index 07bff11974..5aa7f05f0e 100644
--- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml
+++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml
@@ -109,6 +109,7 @@
- RadiationProtection
- Adrenaline
- type: Temperature
+ - type: TemperatureDamage
heatDamageThreshold: 2400
- type: Metabolizer
solutionOnBody: false
diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml
index a0ace57c47..4df9ddcaac 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/base.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml
@@ -239,10 +239,11 @@
- type: Blindable
# Other
- type: Temperature
- heatDamageThreshold: 325
- coldDamageThreshold: 260
currentTemperature: 310.15
specificHeat: 42
+ - type: TemperatureDamage
+ heatDamageThreshold: 325
+ coldDamageThreshold: 260
coldDamage:
types:
Cold: 0.1 #per second, scales with temperature & other constants
diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml
index 83031d61d9..6d7ba02f5f 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml
@@ -58,11 +58,12 @@
damage:
types:
Heat: 2.5 # moths burn more easily
- - type: Temperature # Moths hate the heat and thrive in the cold.
- heatDamageThreshold: 320
- coldDamageThreshold: 230
+ - type: Temperature
currentTemperature: 310.15
specificHeat: 46
+ - type: TemperatureDamage # Moths hate the heat and thrive in the cold.
+ heatDamageThreshold: 320
+ coldDamageThreshold: 230
coldDamage:
types:
Cold : 0.05 #per second, scales with temperature & other constants
diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml
index 67d0cfba80..55bb32e3a3 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml
@@ -54,10 +54,11 @@
types:
Slash: 5
- type: Temperature
- heatDamageThreshold: 400
- coldDamageThreshold: 285
currentTemperature: 310.15
specificHeat: 42
+ - type: TemperatureDamage
+ heatDamageThreshold: 400
+ coldDamageThreshold: 285
coldDamage:
types:
Cold : 0.1 #per second, scales with temperature & other constants
diff --git a/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml
index a80d20627f..535d3ba327 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/vulpkanin.yml
@@ -34,9 +34,10 @@
Piercing: 2
Slash: 3
- type: Temperature # Same as moth temperatures until below is solved.
+ specificHeat: 44
+ - type: TemperatureDamage
heatDamageThreshold: 320 # TODO: 315 when there is a way to make the temperature alert not blink to the side of the screen and disappear when you "sweat" at 39C.
coldDamageThreshold: 230 # TODO: 220 when the above is solved.
- specificHeat: 44
coldDamage:
types:
Cold: 0.05 # Per second, scales with temperature & other constants
diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml
index a21ca14c5d..26f9215247 100644
--- a/Resources/Prototypes/Entities/Mobs/base.yml
+++ b/Resources/Prototypes/Entities/Mobs/base.yml
@@ -169,13 +169,14 @@
components:
- type: AtmosExposed
- type: Temperature
+ currentTemperature: 310.15
+ specificHeat: 42
+ - type: TemperatureDamage
heatDamageThreshold: 325
coldDamageThreshold: 0
- currentTemperature: 310.15
coldDamage: #per second, scales with temperature & other constants
types:
Cold : 0.1
- specificHeat: 42
heatDamage: #per second, scales with temperature & other constants
types:
Heat : 1.5
@@ -204,10 +205,11 @@
normalBodyTemperature: 310.15
thermalRegulationTemperatureThreshold: 2
- type: Temperature
- heatDamageThreshold: 325
- coldDamageThreshold: 260
currentTemperature: 310.15
specificHeat: 42
+ - type: TemperatureDamage
+ heatDamageThreshold: 325
+ coldDamageThreshold: 260
coldDamage:
types:
Cold: 1 #per second, scales with temperature & other constants
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml
index 25e40d12dc..e19859f16e 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml
@@ -61,6 +61,13 @@
# all below are for egg cooking/exploding
- type: AtmosExposed
- type: Temperature
+ - type: TemperatureDamage
+ - type: InternalTemperature
+ # ~1mm shell and ~1cm of albumen
+ thickness: 0.011
+ area: 0.04
+ # conductivity of egg shell based on a paper from Romanoff and Romanoff (1949)
+ conductivity: 0.456
# Splat
- type: entity
@@ -128,3 +135,4 @@
- type: Temperature
# preserve temperature from the boiling step
currentTemperature: 344
+ - type: TemperatureDamage
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
index adc3b373d4..41c8f65885 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
@@ -42,6 +42,7 @@
- type: AtmosExposed
- type: Temperature
currentTemperature: 290
+ - type: TemperatureDamage
# required for cooking to work
- type: InternalTemperature
thickness: 0.02
diff --git a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml
index ccca7d1af1..514443f9a1 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml
@@ -45,6 +45,7 @@
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Temperature
+ - type: TemperatureDamage
heatDamage:
types:
Heat: 5
diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
index 157a9616ab..1f1b9a9c6a 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
@@ -56,6 +56,7 @@
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Temperature
+ - type: TemperatureDamage
heatDamage:
types:
Heat: 5
@@ -226,6 +227,7 @@
Cold: -1.0
Blunt: -0.5 # Needs to be balanced (approx 3x) with vacuum damage to stall but not kill Kudzu
- type: Temperature
+ - type: TemperatureDamage
heatDamage:
types:
Heat: 10
diff --git a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml
index e73d13e2cb..6e96dbbadc 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml
@@ -89,6 +89,7 @@
- type: AtmosExposed
- type: Temperature
currentTemperature: 290
+ - type: TemperatureDamage
- type: InternalTemperature
thickness: 0.02
area: 0.02
diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml
index d147417f9e..4d50a8b6ed 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml
@@ -111,7 +111,7 @@
- type: CryoPodAir
- type: Climbable # so that ejected bodies don't get stuck
vaultable: false
- - type: ContainerTemperatureDamageThresholds
+ - type: ContainerTemperature
coldDamageThreshold: 10
- type: GuideHelp
guides:
diff --git a/Resources/Prototypes/Entities/Structures/spider_web.yml b/Resources/Prototypes/Entities/Structures/spider_web.yml
index 73e5f5f032..b09e022a3b 100644
--- a/Resources/Prototypes/Entities/Structures/spider_web.yml
+++ b/Resources/Prototypes/Entities/Structures/spider_web.yml
@@ -24,6 +24,7 @@
- type: Damageable
damageModifierSet: Wood
- type: Temperature
+ - type: TemperatureDamage
heatDamage:
types:
Heat: 5