1
0

ThermalRegulatorSystem.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using Content.Server.Body.Components;
  2. using Content.Server.Temperature.Components;
  3. using Content.Server.Temperature.Systems;
  4. using Content.Shared.ActionBlocker;
  5. using Robust.Shared.Timing;
  6. namespace Content.Server.Body.Systems;
  7. public sealed class ThermalRegulatorSystem : EntitySystem
  8. {
  9. [Dependency] private readonly IGameTiming _gameTiming = default!;
  10. [Dependency] private readonly TemperatureSystem _tempSys = default!;
  11. [Dependency] private readonly ActionBlockerSystem _actionBlockerSys = default!;
  12. public override void Initialize()
  13. {
  14. base.Initialize();
  15. SubscribeLocalEvent<ThermalRegulatorComponent, MapInitEvent>(OnMapInit);
  16. SubscribeLocalEvent<ThermalRegulatorComponent, EntityUnpausedEvent>(OnUnpaused);
  17. }
  18. private void OnMapInit(Entity<ThermalRegulatorComponent> ent, ref MapInitEvent args)
  19. {
  20. ent.Comp.NextUpdate = _gameTiming.CurTime + ent.Comp.UpdateInterval;
  21. }
  22. private void OnUnpaused(Entity<ThermalRegulatorComponent> ent, ref EntityUnpausedEvent args)
  23. {
  24. ent.Comp.NextUpdate += args.PausedTime;
  25. }
  26. public override void Update(float frameTime)
  27. {
  28. var query = EntityQueryEnumerator<ThermalRegulatorComponent>();
  29. while (query.MoveNext(out var uid, out var regulator))
  30. {
  31. if (_gameTiming.CurTime < regulator.NextUpdate)
  32. continue;
  33. regulator.NextUpdate += regulator.UpdateInterval;
  34. ProcessThermalRegulation((uid, regulator));
  35. }
  36. }
  37. /// <summary>
  38. /// Processes thermal regulation for a mob
  39. /// </summary>
  40. private void ProcessThermalRegulation(Entity<ThermalRegulatorComponent, TemperatureComponent?> ent)
  41. {
  42. if (!Resolve(ent, ref ent.Comp2, logMissing: false))
  43. return;
  44. var totalMetabolismTempChange = ent.Comp1.MetabolismHeat - ent.Comp1.RadiatedHeat;
  45. // implicit heat regulation
  46. var tempDiff = Math.Abs(ent.Comp2.CurrentTemperature - ent.Comp1.NormalBodyTemperature);
  47. var heatCapacity = _tempSys.GetHeatCapacity(ent, ent);
  48. var targetHeat = tempDiff * heatCapacity;
  49. if (ent.Comp2.CurrentTemperature > ent.Comp1.NormalBodyTemperature)
  50. {
  51. totalMetabolismTempChange -= Math.Min(targetHeat, ent.Comp1.ImplicitHeatRegulation);
  52. }
  53. else
  54. {
  55. totalMetabolismTempChange += Math.Min(targetHeat, ent.Comp1.ImplicitHeatRegulation);
  56. }
  57. _tempSys.ChangeHeat(ent, totalMetabolismTempChange, ignoreHeatResistance: true, ent);
  58. // recalc difference and target heat
  59. tempDiff = Math.Abs(ent.Comp2.CurrentTemperature - ent.Comp1.NormalBodyTemperature);
  60. targetHeat = tempDiff * heatCapacity;
  61. // if body temperature is not within comfortable, thermal regulation
  62. // processes starts
  63. if (tempDiff > ent.Comp1.ThermalRegulationTemperatureThreshold)
  64. return;
  65. if (ent.Comp2.CurrentTemperature > ent.Comp1.NormalBodyTemperature)
  66. {
  67. if (!_actionBlockerSys.CanSweat(ent))
  68. return;
  69. _tempSys.ChangeHeat(ent, -Math.Min(targetHeat, ent.Comp1.SweatHeatRegulation), ignoreHeatResistance: true, ent);
  70. }
  71. else
  72. {
  73. if (!_actionBlockerSys.CanShiver(ent))
  74. return;
  75. _tempSys.ChangeHeat(ent, Math.Min(targetHeat, ent.Comp1.ShiveringHeatRegulation), ignoreHeatResistance: true, ent);
  76. }
  77. }
  78. }