Fix thermoregulation + rebalance/refactor FlammableComponent (#5406)
Co-authored-by: Paul Ritter <ritter.paul1@googlemail.com> Co-authored-by: Tomeno <tomeno@lulzsec.co.uk>
This commit is contained in:
@@ -31,5 +31,9 @@ namespace Content.Server.Atmos.Components
|
|||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("canResistFire")]
|
[DataField("canResistFire")]
|
||||||
public bool CanResistFire { get; private set; } = false;
|
public bool CanResistFire { get; private set; } = false;
|
||||||
|
|
||||||
|
[DataField("damage", required: true)]
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public DamageSpecifier Damage = default!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Content.Server.Alert;
|
using Content.Server.Alert;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.Stunnable;
|
using Content.Server.Stunnable;
|
||||||
@@ -25,16 +26,23 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||||
[Dependency] private readonly StunSystem _stunSystem = default!;
|
[Dependency] private readonly StunSystem _stunSystem = default!;
|
||||||
[Dependency] private readonly TemperatureSystem _temperatureSystem = default!;
|
[Dependency] private readonly TemperatureSystem _temperatureSystem = default!;
|
||||||
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
|
|
||||||
private const float MinimumFireStacks = -10f;
|
private const float MinimumFireStacks = -10f;
|
||||||
private const float MaximumFireStacks = 20f;
|
private const float MaximumFireStacks = 20f;
|
||||||
private const float UpdateTime = 1f;
|
private const float UpdateTime = 1f;
|
||||||
|
|
||||||
|
private const float MinIgnitionTemperature = 373.15f;
|
||||||
|
|
||||||
private float _timer = 0f;
|
private float _timer = 0f;
|
||||||
|
|
||||||
|
private Dictionary<FlammableComponent, float> _fireEvents = new();
|
||||||
|
|
||||||
// TODO: Port the rest of Flammable.
|
// TODO: Port the rest of Flammable.
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
UpdatesAfter.Add(typeof(AtmosphereSystem));
|
||||||
|
|
||||||
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsingEvent);
|
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsingEvent);
|
||||||
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollideEvent);
|
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollideEvent);
|
||||||
SubscribeLocalEvent<FlammableComponent, IsHotEvent>(OnIsHotEvent);
|
SubscribeLocalEvent<FlammableComponent, IsHotEvent>(OnIsHotEvent);
|
||||||
@@ -94,8 +102,13 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
private void OnTileFireEvent(EntityUid uid, FlammableComponent flammable, TileFireEvent args)
|
private void OnTileFireEvent(EntityUid uid, FlammableComponent flammable, TileFireEvent args)
|
||||||
{
|
{
|
||||||
AdjustFireStacks(uid, 3, flammable);
|
var tempDelta = args.Temperature - MinIgnitionTemperature;
|
||||||
Ignite(uid, flammable);
|
|
||||||
|
var maxTemp = 0f;
|
||||||
|
_fireEvents.TryGetValue(flammable, out maxTemp);
|
||||||
|
|
||||||
|
if (tempDelta > maxTemp)
|
||||||
|
_fireEvents[flammable] = tempDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateAppearance(EntityUid uid, FlammableComponent? flammable = null, AppearanceComponent? appearance = null)
|
public void UpdateAppearance(EntityUid uid, FlammableComponent? flammable = null, AppearanceComponent? appearance = null)
|
||||||
@@ -168,13 +181,27 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
flammable.Owner.SpawnTimer(2000, () =>
|
flammable.Owner.SpawnTimer(2000, () =>
|
||||||
{
|
{
|
||||||
flammable.Resisting = false;
|
flammable.Resisting = false;
|
||||||
flammable.FireStacks -= 3f;
|
flammable.FireStacks -= 1f;
|
||||||
UpdateAppearance(uid, flammable);
|
UpdateAppearance(uid, flammable);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
|
// process all fire events
|
||||||
|
foreach (var (flammable, deltaTemp) in _fireEvents)
|
||||||
|
{
|
||||||
|
// 100 -> 1, 200 -> 2, 400 -> 3...
|
||||||
|
var fireStackMod = Math.Max(MathF.Log2(deltaTemp / 100) + 1, 0);
|
||||||
|
var fireStackDelta = fireStackMod - flammable.FireStacks;
|
||||||
|
if (fireStackDelta > 0)
|
||||||
|
{
|
||||||
|
AdjustFireStacks(flammable.OwnerUid, fireStackDelta, flammable);
|
||||||
|
}
|
||||||
|
Ignite(flammable.OwnerUid, flammable);
|
||||||
|
}
|
||||||
|
_fireEvents.Clear();
|
||||||
|
|
||||||
_timer += frameTime;
|
_timer += frameTime;
|
||||||
|
|
||||||
if (_timer < UpdateTime)
|
if (_timer < UpdateTime)
|
||||||
@@ -205,7 +232,11 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
if (flammable.FireStacks > 0)
|
if (flammable.FireStacks > 0)
|
||||||
{
|
{
|
||||||
_temperatureSystem.ChangeHeat(uid, 80000 * flammable.FireStacks);
|
// TODO FLAMMABLE: further balancing
|
||||||
|
var damageScale = Math.Min((int)flammable.FireStacks, 5);
|
||||||
|
_temperatureSystem.ChangeHeat(uid, 12500 * damageScale);
|
||||||
|
_damageableSystem.TryChangeDamage(uid, flammable.Damage * damageScale);
|
||||||
|
|
||||||
AdjustFireStacks(uid, -0.1f * (flammable.Resisting ? 10f : 1f), flammable);
|
AdjustFireStacks(uid, -0.1f * (flammable.Resisting ? 10f : 1f), flammable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ namespace Content.Server.Body.Components
|
|||||||
|
|
||||||
private float _accumulatedFrameTime;
|
private float _accumulatedFrameTime;
|
||||||
|
|
||||||
private bool _isShivering;
|
|
||||||
private bool _isSweating;
|
|
||||||
|
|
||||||
[ViewVariables] [DataField("needsGases")] public Dictionary<Gas, float> NeedsGases { get; set; } = new();
|
[ViewVariables] [DataField("needsGases")] public Dictionary<Gas, float> NeedsGases { get; set; } = new();
|
||||||
|
|
||||||
[ViewVariables] [DataField("producesGases")] public Dictionary<Gas, float> ProducesGases { get; set; } = new();
|
[ViewVariables] [DataField("producesGases")] public Dictionary<Gas, float> ProducesGases { get; set; } = new();
|
||||||
@@ -253,52 +250,28 @@ namespace Content.Server.Body.Components
|
|||||||
{
|
{
|
||||||
totalMetabolismTempChange += Math.Min(targetHeat, ImplicitHeatRegulation);
|
totalMetabolismTempChange += Math.Min(targetHeat, ImplicitHeatRegulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
temperatureSystem.ChangeHeat(Owner.Uid, totalMetabolismTempChange, true, temperatureComponent);
|
||||||
|
|
||||||
// recalc difference and target heat
|
// recalc difference and target heat
|
||||||
tempDiff = Math.Abs(temperatureComponent.CurrentTemperature - NormalBodyTemperature);
|
tempDiff = Math.Abs(temperatureComponent.CurrentTemperature - NormalBodyTemperature);
|
||||||
targetHeat = tempDiff * temperatureComponent.HeatCapacity;
|
targetHeat = tempDiff * temperatureComponent.HeatCapacity;
|
||||||
|
|
||||||
temperatureSystem.ChangeHeat(Owner.Uid, totalMetabolismTempChange, true, temperatureComponent);
|
|
||||||
|
|
||||||
// if body temperature is not within comfortable, thermal regulation
|
// if body temperature is not within comfortable, thermal regulation
|
||||||
// processes starts
|
// processes starts
|
||||||
if (tempDiff < ThermalRegulationTemperatureThreshold)
|
if (tempDiff > ThermalRegulationTemperatureThreshold)
|
||||||
{
|
|
||||||
if (_isShivering || _isSweating)
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(Loc.GetString("metabolism-component-is-comfortable"));
|
|
||||||
}
|
|
||||||
|
|
||||||
_isShivering = false;
|
|
||||||
_isSweating = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var actionBlocker = EntitySystem.Get<ActionBlockerSystem>();
|
var actionBlocker = EntitySystem.Get<ActionBlockerSystem>();
|
||||||
|
|
||||||
if (temperatureComponent.CurrentTemperature > NormalBodyTemperature)
|
if (temperatureComponent.CurrentTemperature > NormalBodyTemperature)
|
||||||
{
|
{
|
||||||
if (!actionBlocker.CanSweat(OwnerUid)) return;
|
if (!actionBlocker.CanSweat(OwnerUid)) return;
|
||||||
if (!_isSweating)
|
temperatureSystem.ChangeHeat(OwnerUid, -Math.Min(targetHeat, SweatHeatRegulation), true, temperatureComponent);
|
||||||
{
|
|
||||||
Owner.PopupMessage(Loc.GetString("metabolism-component-is-sweating"));
|
|
||||||
_isSweating = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// creadth: sweating does not help in airless environment
|
|
||||||
if (EntitySystem.Get<AtmosphereSystem>().GetTileMixture(Owner.Transform.Coordinates) is not {})
|
|
||||||
{
|
|
||||||
temperatureSystem.ChangeHeat(OwnerUid, -Math.Min(targetHeat, SweatHeatRegulation), true, temperatureComponent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!actionBlocker.CanShiver(OwnerUid)) return;
|
if (!actionBlocker.CanShiver(OwnerUid)) return;
|
||||||
if (!_isShivering)
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(Loc.GetString("metabolism-component-is-shivering"));
|
|
||||||
_isShivering = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
temperatureSystem.ChangeHeat(OwnerUid, Math.Min(targetHeat, ShiveringHeatRegulation), true, temperatureComponent);
|
temperatureSystem.ChangeHeat(OwnerUid, Math.Min(targetHeat, ShiveringHeatRegulation), true, temperatureComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,9 @@
|
|||||||
- type: Flammable
|
- type: Flammable
|
||||||
fireSpread: true
|
fireSpread: true
|
||||||
canResistFire: true
|
canResistFire: true
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 1 #per second, scales with number of fire 'stacks'
|
||||||
- type: Temperature
|
- type: Temperature
|
||||||
heatDamageThreshold: 360
|
heatDamageThreshold: 360
|
||||||
coldDamageThreshold: 260
|
coldDamageThreshold: 260
|
||||||
|
|||||||
@@ -173,6 +173,9 @@
|
|||||||
- type: Flammable
|
- type: Flammable
|
||||||
fireSpread: true
|
fireSpread: true
|
||||||
canResistFire: true
|
canResistFire: true
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Heat: 1 #per second, scales with number of fire 'stacks'
|
||||||
- type: Temperature
|
- type: Temperature
|
||||||
heatDamageThreshold: 360
|
heatDamageThreshold: 360
|
||||||
coldDamageThreshold: 260
|
coldDamageThreshold: 260
|
||||||
|
|||||||
Reference in New Issue
Block a user