]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add slowdown to low temperatures (#29692)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Mon, 5 Aug 2024 08:07:02 +0000 (04:07 -0400)
committerGitHub <noreply@github.com>
Mon, 5 Aug 2024 08:07:02 +0000 (18:07 +1000)
* TemperatureSpeed component

* temperature slowdown prediction (done right)

* remove unnecessary changes

* that too

* get in line

* make it readonly

* auto pause

Content.Server/Construction/ConstructionSystem.Interactions.cs
Content.Server/Temperature/Components/TemperatureComponent.cs
Content.Server/Temperature/Systems/TemperatureSystem.cs
Content.Shared/Temperature/Components/TemperatureSpeedComponent.cs [new file with mode: 0644]
Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs [new file with mode: 0644]
Content.Shared/Temperature/TemperatureEvents.cs
Resources/Prototypes/Entities/Mobs/Species/base.yml
Resources/Prototypes/Entities/Mobs/Species/moth.yml
Resources/Prototypes/Entities/Mobs/Species/reptilian.yml

index ad7b2a11b0edb2c00b1401ce6ee4dd29a608b226..c844dd2c9adc720046015074e581e3848c5f2cc5 100644 (file)
@@ -2,7 +2,6 @@ using System.Linq;
 using Content.Server.Administration.Logs;
 using Content.Server.Construction.Components;
 using Content.Server.Temperature.Components;
-using Content.Server.Temperature.Systems;
 using Content.Shared.Construction;
 using Content.Shared.Construction.Components;
 using Content.Shared.Construction.EntitySystems;
@@ -11,6 +10,7 @@ using Content.Shared.DoAfter;
 using Content.Shared.Interaction;
 using Content.Shared.Prying.Systems;
 using Content.Shared.Radio.EntitySystems;
+using Content.Shared.Temperature;
 using Content.Shared.Tools.Systems;
 using Robust.Shared.Containers;
 using Robust.Shared.Utility;
index 3bfa12f26938e73251be6554cffada1fee8f46a5..ae2c373b1403c04d4c43d72e6188224a0cf0037b 100644 (file)
@@ -1,4 +1,3 @@
-using Content.Server.Temperature.Systems;
 using Content.Shared.Alert;
 using Content.Shared.Atmos;
 using Content.Shared.Damage;
@@ -51,15 +50,6 @@ public sealed partial class TemperatureComponent : Component
     [DataField, ViewVariables(VVAccess.ReadWrite)]
     public float AtmosTemperatureTransferEfficiency = 0.1f;
 
-    [Obsolete("Use system method")]
-    public float HeatCapacity
-    {
-        get
-        {
-            return IoCManager.Resolve<IEntityManager>().System<TemperatureSystem>().GetHeatCapacity(Owner, this);
-        }
-    }
-
     [DataField, ViewVariables(VVAccess.ReadWrite)]
     public DamageSpecifier ColdDamage = new();
 
@@ -71,7 +61,7 @@ public sealed partial class TemperatureComponent : Component
     /// </summary>
     /// <remarks>
     /// Okay it genuinely reaches this basically immediately for a plasma fire.
-    /// </summary>
+    /// </remarks>
     [DataField, ViewVariables(VVAccess.ReadWrite)]
     public FixedPoint2 DamageCap = FixedPoint2.New(8);
 
@@ -79,7 +69,7 @@ public sealed partial class TemperatureComponent : Component
     /// Used to keep track of when damage starts/stops. Useful for logs.
     /// </summary>
     [DataField]
-    public bool TakingDamage = false;
+    public bool TakingDamage;
 
     [DataField]
     public ProtoId<AlertPrototype> HotAlert = "Hot";
index d33bf6e0256e531e7695f2059807d70a8b1d5519..8b6fa107cc0b11fe07c06e616911a779b6f864ac 100644 (file)
@@ -412,17 +412,3 @@ public sealed class TemperatureSystem : EntitySystem
         return (newHeatThreshold, newColdThreshold);
     }
 }
-
-public sealed class OnTemperatureChangeEvent : EntityEventArgs
-{
-    public float CurrentTemperature { get; }
-    public float LastTemperature { get; }
-    public float TemperatureDelta { get; }
-
-    public OnTemperatureChangeEvent(float current, float last, float delta)
-    {
-        CurrentTemperature = current;
-        LastTemperature = last;
-        TemperatureDelta = delta;
-    }
-}
diff --git a/Content.Shared/Temperature/Components/TemperatureSpeedComponent.cs b/Content.Shared/Temperature/Components/TemperatureSpeedComponent.cs
new file mode 100644 (file)
index 0000000..74ba2a0
--- /dev/null
@@ -0,0 +1,30 @@
+using Content.Shared.Temperature.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Temperature.Components;
+
+/// <summary>
+/// This is used for an entity that varies in speed based on current temperature.
+/// </summary>
+[RegisterComponent, NetworkedComponent, Access(typeof(SharedTemperatureSystem)), AutoGenerateComponentState, AutoGenerateComponentPause]
+public sealed partial class TemperatureSpeedComponent : Component
+{
+    /// <summary>
+    /// Pairs of temperature thresholds to applied slowdown values.
+    /// </summary>
+    [DataField]
+    public Dictionary<float, float> Thresholds = new();
+
+    /// <summary>
+    /// The current speed modifier from <see cref="Thresholds"/> we reached.
+    /// Stored and networked so that the client doesn't mispredict temperature
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public float? CurrentSpeedModifier;
+
+    /// <summary>
+    /// The time at which the temperature slowdown is updated.
+    /// </summary>
+    [DataField, AutoNetworkedField, AutoPausedField]
+    public TimeSpan? NextSlowdownUpdate;
+}
diff --git a/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs b/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs
new file mode 100644 (file)
index 0000000..efea2df
--- /dev/null
@@ -0,0 +1,80 @@
+using System.Linq;
+using Content.Shared.Movement.Components;
+using Content.Shared.Movement.Systems;
+using Content.Shared.Temperature.Components;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.Temperature.Systems;
+
+/// <summary>
+/// This handles predicting temperature based speedup.
+/// </summary>
+public sealed class SharedTemperatureSystem : EntitySystem
+{
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
+
+    /// <summary>
+    /// Band-aid for unpredicted atmos. Delays the application for a short period so that laggy clients can get the replicated temperature.
+    /// </summary>
+    private static readonly TimeSpan SlowdownApplicationDelay = TimeSpan.FromSeconds(1f);
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<TemperatureSpeedComponent, OnTemperatureChangeEvent>(OnTemperatureChanged);
+        SubscribeLocalEvent<TemperatureSpeedComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
+    }
+
+    private void OnTemperatureChanged(Entity<TemperatureSpeedComponent> ent, ref OnTemperatureChangeEvent args)
+    {
+        foreach (var (threshold, modifier) in ent.Comp.Thresholds)
+        {
+            if (args.CurrentTemperature < threshold && args.LastTemperature > threshold ||
+                args.CurrentTemperature > threshold && args.LastTemperature < threshold)
+            {
+                ent.Comp.NextSlowdownUpdate = _timing.CurTime + SlowdownApplicationDelay;
+                ent.Comp.CurrentSpeedModifier = modifier;
+                Dirty(ent);
+                break;
+            }
+        }
+
+        var maxThreshold = ent.Comp.Thresholds.Max(p => p.Key);
+        if (args.CurrentTemperature > maxThreshold && args.LastTemperature < maxThreshold)
+        {
+            ent.Comp.NextSlowdownUpdate = _timing.CurTime + SlowdownApplicationDelay;
+            ent.Comp.CurrentSpeedModifier = null;
+            Dirty(ent);
+        }
+    }
+
+    private void OnRefreshMovementSpeedModifiers(Entity<TemperatureSpeedComponent> ent, ref RefreshMovementSpeedModifiersEvent args)
+    {
+        // Don't update speed and mispredict while we're compensating for lag.
+        if (ent.Comp.NextSlowdownUpdate != null || ent.Comp.CurrentSpeedModifier == null)
+            return;
+
+        args.ModifySpeed(ent.Comp.CurrentSpeedModifier.Value, ent.Comp.CurrentSpeedModifier.Value);
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        var query = EntityQueryEnumerator<TemperatureSpeedComponent, MovementSpeedModifierComponent>();
+        while (query.MoveNext(out var uid, out var temp, out var movement))
+        {
+            if (temp.NextSlowdownUpdate == null)
+                continue;
+
+            if (_timing.CurTime < temp.NextSlowdownUpdate)
+                continue;
+
+            temp.NextSlowdownUpdate = null;
+            _movementSpeedModifier.RefreshMovementSpeedModifiers(uid, movement);
+            Dirty(uid, temp);
+        }
+    }
+}
index ac12224868f4035865487e193b6afed2d8f67730..7a26d07e306d9600b385be8a9950210a02d71dd7 100644 (file)
@@ -13,3 +13,18 @@ public sealed class ModifyChangedTemperatureEvent : EntityEventArgs, IInventoryR
         TemperatureDelta = temperature;
     }
 }
+
+public sealed class OnTemperatureChangeEvent : EntityEventArgs
+{
+    public readonly float CurrentTemperature;
+    public readonly float LastTemperature;
+    public readonly float TemperatureDelta;
+
+    public OnTemperatureChangeEvent(float current, float last, float delta)
+    {
+        CurrentTemperature = current;
+        LastTemperature = last;
+        TemperatureDelta = delta;
+    }
+}
+
index 99aa2d4bc8feba2c1e914a59d71a9a9fa1f8d2d1..af309e93adda9f9589e248cda4daadac82841f31 100644 (file)
     heatDamage:
       types:
         Heat: 1.5 #per second, scales with temperature & other constants
+  - type: TemperatureSpeed
+    thresholds:
+      293: 0.8
+      280: 0.6
+      260: 0.4
   - type: ThermalRegulator
     metabolismHeat: 800
     radiatedHeat: 100
index 153d5cccd3cb9497805158aac266554ae3cfc8e9..da0dca740c4abe5611aa6a04179efec185fec9ba 100644 (file)
     heatDamage:
       types:
         Heat : 3 #per second, scales with temperature & other constants
+  - type: TemperatureSpeed
+    thresholds:
+      289: 0.8
+      275: 0.6
+      250: 0.4
   - type: Sprite # sprite again because we want different layer ordering
     noRot: true
     drawdepth: Mobs
index 1c9eaa2ec625090a4a14631d6bf316b248b46fb7..c023dc1c25243019f0b809dc59c1f58685f3dd21 100644 (file)
     heatDamage:
       types:
         Heat : 1.5 #per second, scales with temperature & other constants
+  - type: TemperatureSpeed
+    thresholds:
+      301: 0.8
+      295: 0.6
+      285: 0.4
   - type: Wagging
   - type: Inventory
     speciesId: reptilian