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:
Tomeno
2021-11-19 17:54:01 +01:00
committed by GitHub
parent 2397f14f34
commit 8c71099fa2
5 changed files with 50 additions and 36 deletions

View File

@@ -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!;
} }
} }

View File

@@ -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

View File

@@ -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)
{
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); 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);
} }
} }

View File

@@ -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

View File

@@ -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