| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- using Content.Server.Body.Components;
- using Content.Server.Temperature.Components;
- using Content.Server.Temperature.Systems;
- using Content.Shared.ActionBlocker;
- using Robust.Shared.Timing;
- namespace Content.Server.Body.Systems;
- public sealed class ThermalRegulatorSystem : EntitySystem
- {
- [Dependency] private readonly IGameTiming _gameTiming = default!;
- [Dependency] private readonly TemperatureSystem _tempSys = default!;
- [Dependency] private readonly ActionBlockerSystem _actionBlockerSys = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<ThermalRegulatorComponent, MapInitEvent>(OnMapInit);
- SubscribeLocalEvent<ThermalRegulatorComponent, EntityUnpausedEvent>(OnUnpaused);
- }
- private void OnMapInit(Entity<ThermalRegulatorComponent> ent, ref MapInitEvent args)
- {
- ent.Comp.NextUpdate = _gameTiming.CurTime + ent.Comp.UpdateInterval;
- }
- private void OnUnpaused(Entity<ThermalRegulatorComponent> ent, ref EntityUnpausedEvent args)
- {
- ent.Comp.NextUpdate += args.PausedTime;
- }
- public override void Update(float frameTime)
- {
- var query = EntityQueryEnumerator<ThermalRegulatorComponent>();
- while (query.MoveNext(out var uid, out var regulator))
- {
- if (_gameTiming.CurTime < regulator.NextUpdate)
- continue;
- regulator.NextUpdate += regulator.UpdateInterval;
- ProcessThermalRegulation((uid, regulator));
- }
- }
- /// <summary>
- /// Processes thermal regulation for a mob
- /// </summary>
- private void ProcessThermalRegulation(Entity<ThermalRegulatorComponent, TemperatureComponent?> ent)
- {
- if (!Resolve(ent, ref ent.Comp2, logMissing: false))
- return;
- var totalMetabolismTempChange = ent.Comp1.MetabolismHeat - ent.Comp1.RadiatedHeat;
- // implicit heat regulation
- var tempDiff = Math.Abs(ent.Comp2.CurrentTemperature - ent.Comp1.NormalBodyTemperature);
- var heatCapacity = _tempSys.GetHeatCapacity(ent, ent);
- var targetHeat = tempDiff * heatCapacity;
- if (ent.Comp2.CurrentTemperature > ent.Comp1.NormalBodyTemperature)
- {
- totalMetabolismTempChange -= Math.Min(targetHeat, ent.Comp1.ImplicitHeatRegulation);
- }
- else
- {
- totalMetabolismTempChange += Math.Min(targetHeat, ent.Comp1.ImplicitHeatRegulation);
- }
- _tempSys.ChangeHeat(ent, totalMetabolismTempChange, ignoreHeatResistance: true, ent);
- // recalc difference and target heat
- tempDiff = Math.Abs(ent.Comp2.CurrentTemperature - ent.Comp1.NormalBodyTemperature);
- targetHeat = tempDiff * heatCapacity;
- // if body temperature is not within comfortable, thermal regulation
- // processes starts
- if (tempDiff > ent.Comp1.ThermalRegulationTemperatureThreshold)
- return;
- if (ent.Comp2.CurrentTemperature > ent.Comp1.NormalBodyTemperature)
- {
- if (!_actionBlockerSys.CanSweat(ent))
- return;
- _tempSys.ChangeHeat(ent, -Math.Min(targetHeat, ent.Comp1.SweatHeatRegulation), ignoreHeatResistance: true, ent);
- }
- else
- {
- if (!_actionBlockerSys.CanShiver(ent))
- return;
- _tempSys.ChangeHeat(ent, Math.Min(targetHeat, ent.Comp1.ShiveringHeatRegulation), ignoreHeatResistance: true, ent);
- }
- }
- }
|