diff --git a/Content.Client/IgnoredComponents.cs b/Content.Client/IgnoredComponents.cs
index af320568fa..7dea6c8738 100644
--- a/Content.Client/IgnoredComponents.cs
+++ b/Content.Client/IgnoredComponents.cs
@@ -12,6 +12,7 @@
"CloningPod",
"Destructible",
"Temperature",
+ "AtmosExposed",
"Explosive",
"OnUseTimerTrigger",
"ToolboxElectricalFill",
diff --git a/Content.Server/Atmos/AtmosHelpers.cs b/Content.Server/Atmos/AtmosHelpers.cs
index 4e0d313d89..e7e8371804 100644
--- a/Content.Server/Atmos/AtmosHelpers.cs
+++ b/Content.Server/Atmos/AtmosHelpers.cs
@@ -19,9 +19,9 @@ namespace Content.Server.Atmos
return gridAtmos?.GetTile(coordinates);
}
- public static GasMixture? GetTileAir(this EntityCoordinates coordinates)
+ public static GasMixture? GetTileAir(this EntityCoordinates coordinates, IEntityManager? entityManager = null)
{
- return coordinates.GetTileAtmosphere()?.Air;
+ return coordinates.GetTileAtmosphere(entityManager)?.Air;
}
public static bool TryGetTileAtmosphere(this EntityCoordinates coordinates, [MaybeNullWhen(false)] out TileAtmosphere atmosphere)
@@ -30,10 +30,10 @@ namespace Content.Server.Atmos
return !Equals(atmosphere = coordinates.GetTileAtmosphere()!, default);
}
- public static bool TryGetTileAir(this EntityCoordinates coordinates, [MaybeNullWhen(false)] out GasMixture air)
+ public static bool TryGetTileAir(this EntityCoordinates coordinates, [MaybeNullWhen(false)] out GasMixture air, IEntityManager? entityManager = null)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
- return !Equals(air = coordinates.GetTileAir()!, default);
+ return !Equals(air = coordinates.GetTileAir(entityManager)!, default);
}
public static TileAtmosphere? GetTileAtmosphere(this MapIndices indices, GridId gridId)
diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs
index 04186e3686..6b11195176 100644
--- a/Content.Server/Atmos/TileAtmosphere.cs
+++ b/Content.Server/Atmos/TileAtmosphere.cs
@@ -48,7 +48,7 @@ namespace Content.Server.Atmos
public int AtmosCooldown { get; set; } = 0;
[ViewVariables]
- private float _temperature = Atmospherics.T20C;
+ public float Temperature {get; private set; } = Atmospherics.T20C;
[ViewVariables]
private float _temperatureArchived = Atmospherics.T20C;
@@ -132,7 +132,7 @@ namespace Content.Server.Atmos
{
Air?.Archive();
_archivedCycle = fireCount;
- _temperatureArchived = _temperature;
+ _temperatureArchived = Temperature;
}
public void HotspotExpose(float exposedTemperature, float exposedVolume, bool soh = false)
@@ -869,10 +869,10 @@ namespace Content.Server.Atmos
// Conduct with air on my tile if I have it
if (!BlocksAir)
{
- _temperature = Air.TemperatureShare(ThermalConductivity, _temperature, HeatCapacity);
+ Temperature = Air.TemperatureShare(ThermalConductivity, Temperature, HeatCapacity);
}
- FinishSuperconduction(BlocksAir ? _temperature : Air.Temperature);
+ FinishSuperconduction(BlocksAir ? Temperature : Air.Temperature);
}
private void FinishSuperconduction(float temperature)
@@ -897,7 +897,7 @@ namespace Content.Server.Atmos
other.TemperatureShareMutualSolid(this, ThermalConductivity);
}
- TemperatureExpose(null, _temperature, _gridAtmosphereComponent.GetVolumeForCells(1));
+ TemperatureExpose(null, Temperature, _gridAtmosphereComponent.GetVolumeForCells(1));
return;
}
@@ -915,8 +915,8 @@ namespace Content.Server.Atmos
private void TemperatureShareOpenToSolid(TileAtmosphere other)
{
- other._temperature =
- Air.TemperatureShare(other.ThermalConductivity, other._temperature, other.HeatCapacity);
+ other.Temperature =
+ Air.TemperatureShare(other.ThermalConductivity, other.Temperature, other.HeatCapacity);
}
private void TemperatureShareMutualSolid(TileAtmosphere other, float conductionCoefficient)
@@ -928,15 +928,15 @@ namespace Content.Server.Atmos
var heat = conductionCoefficient * deltaTemperature *
(HeatCapacity * other.HeatCapacity / (HeatCapacity + other.HeatCapacity));
- _temperature -= heat / HeatCapacity;
- other._temperature += heat / other.HeatCapacity;
+ Temperature -= heat / HeatCapacity;
+ other.Temperature += heat / other.HeatCapacity;
}
}
public void RadiateToSpace()
{
// Considering 0ºC as the break even point for radiation in and out.
- if (_temperature > Atmospherics.T0C)
+ if (Temperature > Atmospherics.T0C)
{
// Hardcoded space temperature.
var deltaTemperature = (_temperatureArchived - Atmospherics.TCMB);
@@ -945,7 +945,7 @@ namespace Content.Server.Atmos
var heat = ThermalConductivity * deltaTemperature * (HeatCapacity *
Atmospherics.HeatCapacityVacuum / (HeatCapacity + Atmospherics.HeatCapacityVacuum));
- _temperature -= heat;
+ Temperature -= heat;
}
}
}
diff --git a/Content.Server/GameObjects/Components/Atmos/AtmosExposedComponent.cs b/Content.Server/GameObjects/Components/Atmos/AtmosExposedComponent.cs
new file mode 100644
index 0000000000..f5bfde7271
--- /dev/null
+++ b/Content.Server/GameObjects/Components/Atmos/AtmosExposedComponent.cs
@@ -0,0 +1,38 @@
+using Content.Server.Atmos;
+using Content.Server.GameObjects.Components.Temperature;
+using Content.Shared.Atmos;
+using Robust.Shared.GameObjects;
+
+namespace Content.Server.GameObjects.Components.Atmos
+{
+ ///
+ /// Represents that entity can be exposed to Atmo
+ ///
+ [RegisterComponent]
+ public class AtmosExposedComponent
+ : Component
+ {
+ public override string Name => "AtmosExposed";
+
+ public void Update(TileAtmosphere tile, float timeDelta)
+ {
+ if (Owner.TryGetComponent(out var temperatureComponent))
+ {
+ if (tile.Air != null)
+ {
+ var temperatureDelta = tile.Air.Temperature - temperatureComponent.CurrentTemperature;
+ var heat = temperatureDelta * (tile.Air.HeatCapacity * temperatureComponent.HeatCapacity / (tile.Air.HeatCapacity + temperatureComponent.HeatCapacity));
+ temperatureComponent.ReceiveHeat(heat);
+ }
+ temperatureComponent.Update();
+ }
+
+ if (Owner.TryGetComponent(out var barotraumaComponent))
+ {
+ barotraumaComponent.Update(tile.Air?.Pressure ?? 0);
+ }
+
+ }
+
+ }
+}
diff --git a/Content.Server/GameObjects/Components/Atmos/BarotraumaComponent.cs b/Content.Server/GameObjects/Components/Atmos/BarotraumaComponent.cs
index d877165791..249df1639f 100644
--- a/Content.Server/GameObjects/Components/Atmos/BarotraumaComponent.cs
+++ b/Content.Server/GameObjects/Components/Atmos/BarotraumaComponent.cs
@@ -1,14 +1,12 @@
using System;
using System.Runtime.CompilerServices;
using Content.Server.GameObjects.Components.Mobs;
-using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects;
using Content.Shared.Atmos;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Mobs;
using Robust.Shared.GameObjects;
-using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
namespace Content.Server.GameObjects.Components.Atmos
@@ -19,21 +17,14 @@ namespace Content.Server.GameObjects.Components.Atmos
[RegisterComponent]
public class BarotraumaComponent : Component
{
- [Robust.Shared.IoC.Dependency] private readonly IEntityManager _entityManager = default!;
-
public override string Name => "Barotrauma";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Update(float frameTime)
+ public void Update(float airPressure)
{
if (!Owner.TryGetComponent(out IDamageableComponent damageable)) return;
Owner.TryGetComponent(out ServerStatusEffectsComponent status);
- var coordinates = Owner.Transform.Coordinates;
- var gridAtmos = EntitySystem.Get().GetGridAtmosphere(coordinates.GetGridId(_entityManager));
- var tile = gridAtmos?.GetTile(coordinates);
-
- var pressure = 1f;
var highPressureMultiplier = 1f;
var lowPressureMultiplier = 1f;
@@ -43,8 +34,7 @@ namespace Content.Server.GameObjects.Components.Atmos
lowPressureMultiplier *= protection.LowPressureMultiplier;
}
- if (tile?.Air != null)
- pressure = MathF.Max(tile.Air.Pressure, 1f);
+ var pressure = MathF.Max(airPressure, 1f);
switch (pressure)
{
diff --git a/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs b/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs
index d9c1051e27..45fb5e2e11 100644
--- a/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs
+++ b/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs
@@ -2,15 +2,20 @@
using System.Collections.Generic;
using System.Linq;
using Content.Server.Atmos;
-using Content.Server.GameObjects.Components.Atmos;
using Content.Server.GameObjects.Components.Body.Circulatory;
+using Content.Server.GameObjects.Components.Temperature;
+using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.Chemistry;
-using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
+using Content.Shared.GameObjects.EntitySystems;
+using Content.Shared.Interfaces;
using Content.Shared.Interfaces.Chemistry;
using Robust.Shared.GameObjects;
+using Robust.Shared.GameObjects.Systems;
+using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
+using Robust.Shared.Localization;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
@@ -21,11 +26,16 @@ namespace Content.Server.GameObjects.Components.Metabolism
public class MetabolismComponent : Component
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IEntityManager _entityManager = default!;
+
public override string Name => "Metabolism";
private float _accumulatedFrameTime;
+ private bool _isShivering;
+ private bool _isSweating;
+
[ViewVariables(VVAccess.ReadWrite)] private int _suffocationDamage;
[ViewVariables] public Dictionary NeedsGases { get; set; }
@@ -34,6 +44,47 @@ namespace Content.Server.GameObjects.Components.Metabolism
[ViewVariables] public Dictionary DeficitGases { get; set; }
+ ///
+ /// Heat generated due to metabolism. It's generated via metabolism
+ ///
+ [ViewVariables]
+ public float MetabolismHeat { get; private set; }
+
+ ///
+ /// Heat output via radiation.
+ ///
+ [ViewVariables]
+ public float RadiatedHeat { get; private set; }
+
+ ///
+ /// Maximum heat regulated via sweat
+ ///
+ [ViewVariables]
+ public float SweatHeatRegulation { get; private set; }
+
+ ///
+ /// Maximum heat regulated via shivering
+ ///
+ [ViewVariables]
+ public float ShiveringHeatRegulation { get; private set; }
+
+ ///
+ /// Amount of heat regulation that represents thermal regulation processes not
+ /// explicitly coded.
+ ///
+ public float ImplicitHeatRegulation { get; private set; }
+
+ ///
+ /// Normal body temperature
+ ///
+ [ViewVariables]
+ public float NormalBodyTemperature { get; private set; }
+
+ ///
+ /// Deviation from normal temperature for body to start thermal regulation
+ ///
+ public float ThermalRegulationTemperatureThreshold { get; private set; }
+
[ViewVariables] public bool Suffocating => SuffocatingPercentage() > 0;
public override void ExposeData(ObjectSerializer serializer)
@@ -43,6 +94,14 @@ namespace Content.Server.GameObjects.Components.Metabolism
serializer.DataField(this, b => b.NeedsGases, "needsGases", new Dictionary());
serializer.DataField(this, b => b.ProducesGases, "producesGases", new Dictionary());
serializer.DataField(this, b => b.DeficitGases, "deficitGases", new Dictionary());
+ serializer.DataField(this, b => b.MetabolismHeat, "metabolismHeat", 0);
+ serializer.DataField(this, b => b.RadiatedHeat, "radiatedHeat", 0);
+ serializer.DataField(this, b => b.SweatHeatRegulation, "sweatHeatRegulation", 0);
+ serializer.DataField(this, b => b.ShiveringHeatRegulation, "shiveringHeatRegulation", 0);
+ serializer.DataField(this, b => b.ImplicitHeatRegulation, "implicitHeatRegulation", 0);
+ serializer.DataField(this, b => b.NormalBodyTemperature, "normalBodyTemperature", 0);
+ serializer.DataField(this, b => b.ThermalRegulationTemperatureThreshold,
+ "thermalRegulationTemperatureThreshold", 0);
serializer.DataField(ref _suffocationDamage, "suffocationDamage", 1);
}
@@ -152,6 +211,76 @@ namespace Content.Server.GameObjects.Components.Metabolism
ClampDeficit();
}
+ ///
+ /// Process thermal regulation
+ ///
+ ///
+ private void ProcessThermalRegulation(float frameTime)
+ {
+ if (!Owner.TryGetComponent(out TemperatureComponent temperatureComponent)) return;
+ temperatureComponent.ReceiveHeat(MetabolismHeat);
+ temperatureComponent.RemoveHeat(RadiatedHeat);
+
+ // implicit heat regulation
+ var tempDiff = Math.Abs(temperatureComponent.CurrentTemperature - NormalBodyTemperature);
+ var targetHeat = tempDiff * temperatureComponent.HeatCapacity;
+ if (temperatureComponent.CurrentTemperature > NormalBodyTemperature)
+ {
+ temperatureComponent.RemoveHeat(Math.Min(targetHeat, ImplicitHeatRegulation));
+ }
+ else
+ {
+ temperatureComponent.ReceiveHeat(Math.Min(targetHeat, ImplicitHeatRegulation));
+ }
+
+ // recalc difference and target heat
+ tempDiff = Math.Abs(temperatureComponent.CurrentTemperature - NormalBodyTemperature);
+ targetHeat = tempDiff * temperatureComponent.HeatCapacity;
+
+ // if body temperature is not within comfortable, thermal regulation
+ // processes starts
+ if (tempDiff < ThermalRegulationTemperatureThreshold)
+ {
+ if (_isShivering || _isSweating)
+ {
+ Owner.PopupMessage(Loc.GetString("You feel comfortable"));
+ }
+
+ _isShivering = false;
+ _isSweating = false;
+ return;
+ }
+
+
+ if (temperatureComponent.CurrentTemperature > NormalBodyTemperature)
+ {
+ if (!ActionBlockerSystem.CanSweat(Owner)) return;
+ if (!_isSweating)
+ {
+ Owner.PopupMessage(Loc.GetString("You are sweating"));
+ _isSweating = true;
+ }
+
+ // creadth: sweating does not help in airless environment
+ if (Owner.Transform.Coordinates.TryGetTileAir(out _, _entityManager))
+ {
+ temperatureComponent.RemoveHeat(Math.Min(targetHeat, SweatHeatRegulation));
+ }
+ }
+ else
+ {
+ if (!ActionBlockerSystem.CanShiver(Owner)) return;
+ if (!_isShivering)
+ {
+ Owner.PopupMessage(Loc.GetString("You are shivering"));
+ _isShivering = true;
+ }
+
+ temperatureComponent.ReceiveHeat(Math.Min(targetHeat, ShiveringHeatRegulation));
+ }
+ }
+
+
///
/// Loops through each reagent in _internalSolution,
/// and calls for each of them.
@@ -196,6 +325,12 @@ namespace Content.Server.GameObjects.Components.Metabolism
///
public void Update(float frameTime)
{
+ if (!Owner.TryGetComponent(out var damageable) ||
+ damageable.CurrentDamageState == DamageState.Dead)
+ {
+ return;
+ }
+
_accumulatedFrameTime += frameTime;
if (_accumulatedFrameTime < 1)
@@ -207,9 +342,9 @@ namespace Content.Server.GameObjects.Components.Metabolism
ProcessGases(frameTime);
ProcessNutrients(frameTime);
+ ProcessThermalRegulation(frameTime);
- if (Suffocating &&
- Owner.TryGetComponent(out IDamageableComponent damageable))
+ if (Suffocating)
{
// damageable.ChangeDamage(DamageClass.Airloss, _suffocationDamage, false);
}
diff --git a/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs b/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs
index 3c80f17bca..4828df6dee 100644
--- a/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs
+++ b/Content.Server/GameObjects/Components/Temperature/TemperatureComponent.cs
@@ -1,61 +1,103 @@
using System;
+using System.Diagnostics;
+using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.Maths;
using Robust.Shared.GameObjects;
+using Robust.Shared.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Temperature
{
- public interface ITemperatureComponent : IComponent
- {
- float CurrentTemperature { get; }
- }
-
///
/// Handles changing temperature,
/// informing others of the current temperature,
/// and taking fire damage from high temperature.
///
[RegisterComponent]
- public class TemperatureComponent : Component, ITemperatureComponent
+ public class TemperatureComponent : Component
{
///
public override string Name => "Temperature";
- //TODO: should be programmatic instead of how it currently is
- [ViewVariables] public float CurrentTemperature { get; private set; } = PhysicalConstants.ZERO_CELCIUS;
+ [ViewVariables] public float CurrentTemperature { get => _currentTemperature; set => _currentTemperature = value; }
- float _fireDamageThreshold = 0;
- float _fireDamageCoefficient = 1;
+ [ViewVariables] public float HeatDamageThreshold => _heatDamageThreshold;
+ [ViewVariables] public float ColdDamageThreshold => _coldDamageThreshold;
+ [ViewVariables] public float TempDamageCoefficient => _tempDamageCoefficient;
+ [ViewVariables] public float HeatCapacity {
+ get
+ {
+ if (Owner.TryGetComponent(out var physics))
+ {
+ return SpecificHeat * physics.Mass;
+ }
- float _secondsSinceLastDamageUpdate = 0;
+ return Atmospherics.MinimumHeatCapacity;
+ }
+ }
+
+ [ViewVariables] public float SpecificHeat => _specificHeat;
+
+ private float _heatDamageThreshold;
+ private float _coldDamageThreshold;
+ private float _tempDamageCoefficient;
+ private float _currentTemperature;
+ private float _specificHeat;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
- serializer.DataField(ref _fireDamageThreshold, "firedamagethreshold", 0);
- serializer.DataField(ref _fireDamageCoefficient, "firedamagecoefficient", 1);
+ serializer.DataField(ref _heatDamageThreshold, "heatDamageThreshold", 0);
+ serializer.DataField(ref _coldDamageThreshold, "coldDamageThreshold", 0);
+ serializer.DataField(ref _tempDamageCoefficient, "tempDamageCoefficient", 1);
+ serializer.DataField(ref _currentTemperature, "currentTemperature", Atmospherics.T20C);
+ serializer.DataField(ref _specificHeat, "specificHeat", Atmospherics.MinimumHeatCapacity);
}
- ///
- public void OnUpdate(float frameTime)
+ public void Update()
{
- var fireDamage =
- (int) Math.Floor(Math.Max(0, CurrentTemperature - _fireDamageThreshold) / _fireDamageCoefficient);
-
- _secondsSinceLastDamageUpdate += frameTime;
-
- Owner.TryGetComponent(out IDamageableComponent component);
-
- while (_secondsSinceLastDamageUpdate >= 1)
+ var tempDamage = 0;
+ DamageType? damageType = null;
+ if (CurrentTemperature >= _heatDamageThreshold)
{
- component?.ChangeDamage(DamageType.Heat, fireDamage, false, null);
- _secondsSinceLastDamageUpdate -= 1;
+ tempDamage = (int) Math.Floor((CurrentTemperature - _heatDamageThreshold) * _tempDamageCoefficient);
+ damageType = DamageType.Heat;
}
+ else if (CurrentTemperature <= _coldDamageThreshold)
+ {
+ tempDamage = (int) Math.Floor((_coldDamageThreshold - CurrentTemperature) * _tempDamageCoefficient);
+ damageType = DamageType.Cold;
+ }
+
+ if (!damageType.HasValue) return;
+
+ if (!Owner.TryGetComponent(out IDamageableComponent component)) return;
+ component.ChangeDamage(damageType.Value, tempDamage, false);
+ Debug.Write($"Temp is: {CurrentTemperature}");
}
+
+ ///
+ /// 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;
+ }
+
}
}
diff --git a/Content.Server/GameObjects/EntitySystems/AtmosExposedSystem.cs b/Content.Server/GameObjects/EntitySystems/AtmosExposedSystem.cs
new file mode 100644
index 0000000000..7f620ad222
--- /dev/null
+++ b/Content.Server/GameObjects/EntitySystems/AtmosExposedSystem.cs
@@ -0,0 +1,34 @@
+using Content.Server.Atmos;
+using Content.Server.GameObjects.Components.Atmos;
+using JetBrains.Annotations;
+using Robust.Shared.GameObjects.Systems;
+using Robust.Shared.Interfaces.GameObjects;
+using Robust.Shared.IoC;
+
+namespace Content.Server.GameObjects.EntitySystems
+{
+ [UsedImplicitly]
+ public class AtmosExposedSystem
+ : EntitySystem
+ {
+ [Dependency] private readonly IEntityManager _entityManager = default!;
+
+ private const float UpdateDelay = 3f;
+ private float _lastUpdate;
+ public override void Update(float frameTime)
+ {
+ _lastUpdate += frameTime;
+ if (_lastUpdate < UpdateDelay) return;
+ var atmoSystem = EntitySystemManager.GetEntitySystem();
+ // creadth: everything exposable by atmo should be updated as well
+ foreach (var atmosExposedComponent in EntityManager.ComponentManager.EntityQuery())
+ {
+ var tile = atmosExposedComponent.Owner.Transform.Coordinates.GetTileAtmosphere(_entityManager);
+ if (tile == null) continue;
+ atmosExposedComponent.Update(tile, _lastUpdate);
+ }
+
+ _lastUpdate = 0;
+ }
+ }
+}
diff --git a/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs b/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs
index 84bce7a646..309d8e02ca 100644
--- a/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs
+++ b/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using Content.Server.Atmos;
using Content.Server.Atmos.Reactions;
+using Content.Server.GameObjects.Components.Atmos;
using Content.Server.Interfaces;
using Content.Shared.GameObjects.EntitySystems.Atmos;
using JetBrains.Annotations;
@@ -64,8 +65,7 @@ namespace Content.Server.GameObjects.EntitySystems
foreach (var (mapGridComponent, gridAtmosphereComponent) in EntityManager.ComponentManager.EntityQuery())
{
- if (_pauseManager.IsGridPaused(mapGridComponent.GridIndex))
- continue;
+ if (_pauseManager.IsGridPaused(mapGridComponent.GridIndex)) continue;
gridAtmosphereComponent.Update(frameTime);
}
diff --git a/Content.Server/GameObjects/EntitySystems/BarotraumaSystem.cs b/Content.Server/GameObjects/EntitySystems/BarotraumaSystem.cs
deleted file mode 100644
index d607c3d984..0000000000
--- a/Content.Server/GameObjects/EntitySystems/BarotraumaSystem.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using Content.Server.GameObjects.Components.Atmos;
-using JetBrains.Annotations;
-using Robust.Shared.GameObjects.Systems;
-
-namespace Content.Server.GameObjects.EntitySystems
-{
- [UsedImplicitly]
- public class BarotraumaSystem : EntitySystem
- {
- private const float TimePerUpdate = 3f;
-
- private float _timer = 0f;
-
- ///
- public override void Update(float frameTime)
- {
- _timer += frameTime;
-
- if (_timer < TimePerUpdate) return;
-
- _timer = 0f;
-
- foreach (var barotraumaComp in ComponentManager.EntityQuery())
- {
- barotraumaComp.Update(frameTime);
- }
- }
- }
-}
diff --git a/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs b/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs
deleted file mode 100644
index f03b240a0b..0000000000
--- a/Content.Server/GameObjects/EntitySystems/TemperatureSystem.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Content.Server.GameObjects.Components.Temperature;
-using JetBrains.Annotations;
-using Robust.Shared.GameObjects.Systems;
-
-namespace Content.Server.GameObjects.EntitySystems
-{
- [UsedImplicitly]
- internal sealed class TemperatureSystem : EntitySystem
- {
- public override void Update(float frameTime)
- {
- foreach (var comp in ComponentManager.EntityQuery())
- {
- comp.OnUpdate(frameTime);
- }
- }
- }
-}
diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedStunnableComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedStunnableComponent.cs
index 1d324ba7d4..cfa2268d2b 100644
--- a/Content.Shared/GameObjects/Components/Mobs/SharedStunnableComponent.cs
+++ b/Content.Shared/GameObjects/Components/Mobs/SharedStunnableComponent.cs
@@ -260,6 +260,10 @@ namespace Content.Shared.GameObjects.Components.Mobs
public bool CanUnequip() => (!Stunned);
public bool CanChangeDirection() => true;
+
+ public bool CanShiver() => !Stunned;
+ public bool CanSweat() => true;
+
#endregion
[ViewVariables]
diff --git a/Content.Shared/GameObjects/Components/Mobs/State/SharedDeadState.cs b/Content.Shared/GameObjects/Components/Mobs/State/SharedDeadState.cs
index 6dc85a07cf..43887b878b 100644
--- a/Content.Shared/GameObjects/Components/Mobs/State/SharedDeadState.cs
+++ b/Content.Shared/GameObjects/Components/Mobs/State/SharedDeadState.cs
@@ -69,5 +69,8 @@ namespace Content.Shared.GameObjects.Components.Mobs.State
{
return false;
}
+
+ public bool CanShiver() => false;
+ public bool CanSweat() => false;
}
}
diff --git a/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs b/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs
index e9a029271c..797a1ac08d 100644
--- a/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs
+++ b/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs
@@ -17,6 +17,8 @@ namespace Content.Shared.GameObjects.Components.Observer
public bool CanPickup() => false;
public bool CanEmote() => false;
public bool CanAttack() => false;
+ public bool CanShiver() => false;
+ public bool CanSweat() => false;
}
[Serializable, NetSerializable]
diff --git a/Content.Shared/GameObjects/EntitySystems/ActionBlockerSystem.cs b/Content.Shared/GameObjects/EntitySystems/ActionBlockerSystem.cs
index e7a32bf4fe..f3db58a623 100644
--- a/Content.Shared/GameObjects/EntitySystems/ActionBlockerSystem.cs
+++ b/Content.Shared/GameObjects/EntitySystems/ActionBlockerSystem.cs
@@ -1,4 +1,5 @@
-using Robust.Shared.GameObjects.Systems;
+using System.Linq;
+using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
namespace Content.Shared.GameObjects.EntitySystems
@@ -24,6 +25,9 @@ namespace Content.Shared.GameObjects.EntitySystems
bool CanUnequip() => true;
bool CanChangeDirection() => true;
+
+ bool CanShiver() => true;
+ bool CanSweat() => true;
}
///
@@ -35,10 +39,11 @@ namespace Content.Shared.GameObjects.EntitySystems
public static bool CanMove(IEntity entity)
{
bool canmove = true;
- foreach(var actionblockercomponents in entity.GetAllComponents())
+ foreach (var actionblockercomponents in entity.GetAllComponents())
{
canmove &= actionblockercomponents.CanMove(); // Sets var to false if false
}
+
return canmove;
}
@@ -49,6 +54,7 @@ namespace Content.Shared.GameObjects.EntitySystems
{
caninteract &= actionblockercomponents.CanInteract();
}
+
return caninteract;
}
@@ -59,6 +65,7 @@ namespace Content.Shared.GameObjects.EntitySystems
{
canuse &= actionblockercomponents.CanUse();
}
+
return canuse;
}
@@ -69,6 +76,7 @@ namespace Content.Shared.GameObjects.EntitySystems
{
canthrow &= actionblockercomponents.CanThrow();
}
+
return canthrow;
}
@@ -79,6 +87,7 @@ namespace Content.Shared.GameObjects.EntitySystems
{
canspeak &= actionblockercomponents.CanSpeak();
}
+
return canspeak;
}
@@ -89,8 +98,9 @@ namespace Content.Shared.GameObjects.EntitySystems
{
candrop &= actionblockercomponents.CanDrop();
}
+
return candrop;
- }
+ }
public static bool CanPickup(IEntity entity)
{
@@ -99,6 +109,7 @@ namespace Content.Shared.GameObjects.EntitySystems
{
canpickup &= actionblockercomponents.CanPickup();
}
+
return canpickup;
}
@@ -161,5 +172,25 @@ namespace Content.Shared.GameObjects.EntitySystems
return canchangedirection;
}
+
+ public static bool CanShiver(IEntity entity)
+ {
+ var canShiver = true;
+ foreach (var component in entity.GetAllComponents())
+ {
+ canShiver &= component.CanShiver();
+ }
+ return canShiver;
+ }
+
+ public static bool CanSweat(IEntity entity)
+ {
+ var canSweat = true;
+ foreach (var component in entity.GetAllComponents())
+ {
+ canSweat &= component.CanSweat();
+ }
+ return canSweat;
+ }
}
}
diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml
index e672beebd5..24a01b43c6 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/human.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml
@@ -128,12 +128,26 @@
layer:
- Opaque
- MobImpassable
+ - type: AtmosExposed
+ - type: Temperature
+ heatDamageThreshold: 360
+ coldDamageThreshold: 260
+ currentTemperature: 310.15
+ specificHeat: 42
+ tempDamageCoefficient: 0.1
- type: BodyManager
criticalThreshold: 100
deadThreshold: 200
baseTemplate: bodyTemplate.Humanoid
basePreset: bodyPreset.BasicHuman
- type: Metabolism
+ metabolismHeat: 5000
+ radiatedHeat: 400
+ implicitHeatRegulation: 5000
+ sweatHeatRegulation: 5000
+ shiveringHeatRegulation: 5000
+ normalBodyTemperature: 310.15
+ thermalRegulationTemperatureThreshold: 25
needsGases:
Oxygen: 0.006365740
producesGases: