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)]
[DataField("canResistFire")]
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.Collections.Generic;
using Content.Server.Alert;
using Content.Server.Atmos.Components;
using Content.Server.Stunnable;
@@ -25,16 +26,23 @@ namespace Content.Server.Atmos.EntitySystems
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
[Dependency] private readonly TemperatureSystem _temperatureSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
private const float MinimumFireStacks = -10f;
private const float MaximumFireStacks = 20f;
private const float UpdateTime = 1f;
private const float MinIgnitionTemperature = 373.15f;
private float _timer = 0f;
private Dictionary<FlammableComponent, float> _fireEvents = new();
// TODO: Port the rest of Flammable.
public override void Initialize()
{
UpdatesAfter.Add(typeof(AtmosphereSystem));
SubscribeLocalEvent<FlammableComponent, InteractUsingEvent>(OnInteractUsingEvent);
SubscribeLocalEvent<FlammableComponent, StartCollideEvent>(OnCollideEvent);
SubscribeLocalEvent<FlammableComponent, IsHotEvent>(OnIsHotEvent);
@@ -94,8 +102,13 @@ namespace Content.Server.Atmos.EntitySystems
private void OnTileFireEvent(EntityUid uid, FlammableComponent flammable, TileFireEvent args)
{
AdjustFireStacks(uid, 3, flammable);
Ignite(uid, flammable);
var tempDelta = args.Temperature - MinIgnitionTemperature;
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)
@@ -168,13 +181,27 @@ namespace Content.Server.Atmos.EntitySystems
flammable.Owner.SpawnTimer(2000, () =>
{
flammable.Resisting = false;
flammable.FireStacks -= 3f;
flammable.FireStacks -= 1f;
UpdateAppearance(uid, flammable);
});
}
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;
if (_timer < UpdateTime)
@@ -205,7 +232,11 @@ namespace Content.Server.Atmos.EntitySystems
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);
}
else

View File

@@ -30,9 +30,6 @@ namespace Content.Server.Body.Components
private float _accumulatedFrameTime;
private bool _isShivering;
private bool _isSweating;
[ViewVariables] [DataField("needsGases")] public Dictionary<Gas, float> NeedsGases { 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);
}
temperatureSystem.ChangeHeat(Owner.Uid, totalMetabolismTempChange, true, temperatureComponent);
// recalc difference and target heat
tempDiff = Math.Abs(temperatureComponent.CurrentTemperature - NormalBodyTemperature);
targetHeat = tempDiff * temperatureComponent.HeatCapacity;
temperatureSystem.ChangeHeat(Owner.Uid, totalMetabolismTempChange, true, temperatureComponent);
// if body temperature is not within comfortable, thermal regulation
// processes starts
if (tempDiff < ThermalRegulationTemperatureThreshold)
{
if (_isShivering || _isSweating)
{
Owner.PopupMessage(Loc.GetString("metabolism-component-is-comfortable"));
}
_isShivering = false;
_isSweating = false;
if (tempDiff > ThermalRegulationTemperatureThreshold)
return;
}
var actionBlocker = EntitySystem.Get<ActionBlockerSystem>();
if (temperatureComponent.CurrentTemperature > NormalBodyTemperature)
{
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);
}
}
else
{
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);
}
}

View File

@@ -63,6 +63,9 @@
- type: Flammable
fireSpread: true
canResistFire: true
damage:
types:
Heat: 1 #per second, scales with number of fire 'stacks'
- type: Temperature
heatDamageThreshold: 360
coldDamageThreshold: 260

View File

@@ -173,6 +173,9 @@
- type: Flammable
fireSpread: true
canResistFire: true
damage:
types:
Heat: 1 #per second, scales with number of fire 'stacks'
- type: Temperature
heatDamageThreshold: 360
coldDamageThreshold: 260