using System; using Content.Server.Alert; using Content.Shared.Alert; using Content.Shared.Atmos; using Content.Shared.Damage; using Robust.Shared.GameObjects; using Robust.Shared.Physics; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; using Robust.Shared.IoC; using Robust.Shared.Prototypes; namespace Content.Server.Temperature.Components { /// /// Handles changing temperature, /// informing others of the current temperature, /// and taking fire damage from high temperature. /// [RegisterComponent] public class TemperatureComponent : Component { /// public override string Name => "Temperature"; [DataField("heatDamageThreshold")] private float _heatDamageThreshold = default; [DataField("coldDamageThreshold")] private float _coldDamageThreshold = default; [DataField("tempDamageCoefficient")] private float _tempDamageCoefficient = 1; [DataField("currentTemperature")] public float CurrentTemperature { get; set; } = Atmospherics.T20C; [DataField("specificHeat")] private float _specificHeat = Atmospherics.MinimumHeatCapacity; [ViewVariables] public float HeatDamageThreshold => _heatDamageThreshold; [ViewVariables] public float ColdDamageThreshold => _coldDamageThreshold; [ViewVariables] public float TempDamageCoefficient => _tempDamageCoefficient; [ViewVariables] public float SpecificHeat => _specificHeat; [ViewVariables] public float HeatCapacity { get { if (Owner.TryGetComponent(out var physics)) { return SpecificHeat * physics.Mass; } return Atmospherics.MinimumHeatCapacity; } } [DataField("coldDamage", required: true)] [ViewVariables(VVAccess.ReadWrite)] public DamageSpecifier ColdDamage = default!; [DataField("heatDamage", required: true)] [ViewVariables(VVAccess.ReadWrite)] public DamageSpecifier HeatDamage = default!; public void Update() { if (Owner.TryGetComponent(out ServerAlertsComponent? status)) { switch (CurrentTemperature) { // Cold strong. case <= 260: status.ShowAlert(AlertType.Cold, 3); break; // Cold mild. case <= 280 and > 260: status.ShowAlert(AlertType.Cold, 2); break; // Cold weak. case <= 292 and > 280: status.ShowAlert(AlertType.Cold, 1); break; // Safe. case <= 327 and > 292: status.ClearAlertCategory(AlertCategory.Temperature); break; // Heat weak. case <= 335 and > 327: status.ShowAlert(AlertType.Hot, 1); break; // Heat mild. case <= 345 and > 335: status.ShowAlert(AlertType.Hot, 2); break; // Heat strong. case > 345: status.ShowAlert(AlertType.Hot, 3); break; } } if (!Owner.HasComponent()) return; if (CurrentTemperature >= _heatDamageThreshold) { int tempDamage = (int) Math.Floor((CurrentTemperature - _heatDamageThreshold) * _tempDamageCoefficient); EntitySystem.Get().TryChangeDamage(Owner.Uid, HeatDamage * tempDamage); } else if (CurrentTemperature <= _coldDamageThreshold) { int tempDamage = (int) Math.Floor((_coldDamageThreshold - CurrentTemperature) * _tempDamageCoefficient); EntitySystem.Get().TryChangeDamage(Owner.Uid, ColdDamage * tempDamage); } } /// /// Forcefully give heat to this component /// /// public void ReceiveHeat(float heatAmount) { CurrentTemperature += heatAmount / HeatCapacity; } /// /// Forcefully remove heat from this component /// /// public void RemoveHeat(float heatAmount) { CurrentTemperature -= heatAmount / HeatCapacity; } } }