]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Flammable system bug fixes. (#21594)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Tue, 14 Nov 2023 11:55:45 +0000 (22:55 +1100)
committerGitHub <noreply@github.com>
Tue, 14 Nov 2023 11:55:45 +0000 (22:55 +1100)
Content.Server/Atmos/Components/FlammableComponent.cs
Content.Server/Atmos/EntitySystems/FlammableSystem.cs
Content.Shared/Timing/UseDelaySystem.cs

index 94bc78318c2e179b3bd418d0beed03e66d931b79..679b55105860ddc5905b96abdc769a7c47a5aec5 100644 (file)
@@ -6,16 +6,15 @@ namespace Content.Server.Atmos.Components
     [RegisterComponent]
     public sealed partial class FlammableComponent : Component
     {
-        [ViewVariables]
-        public bool Resisting = false;
-
-        [ViewVariables]
-        public readonly List<EntityUid> Collided = new();
+        [DataField]
+        public bool Resisting;
 
         [ViewVariables(VVAccess.ReadWrite)]
+        [DataField]
         public bool OnFire { get; set; }
 
         [ViewVariables(VVAccess.ReadWrite)]
+        [DataField]
         public float FireStacks { get; set; }
 
         [ViewVariables(VVAccess.ReadWrite)]
index 716c5b88e5b8f3998fcfff9615e18ffed6e5a19d..e045b552a2eff6c9eb0628e9566e1d9393771586 100644 (file)
@@ -56,6 +56,7 @@ namespace Content.Server.Atmos.EntitySystems
         private float _timer;
 
         private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new();
+        private readonly List<EntityUid> _toRemove = new();
 
         public override void Initialize()
         {
@@ -73,7 +74,6 @@ namespace Content.Server.Atmos.EntitySystems
 
             SubscribeLocalEvent<IgniteOnMeleeHitComponent, MeleeHitEvent>(OnMeleeHit);
 
-            SubscribeLocalEvent<ExtinguishOnInteractComponent, UseInHandEvent>(OnExtinguishUsingInHand);
             SubscribeLocalEvent<ExtinguishOnInteractComponent, ActivateInWorldEvent>(OnExtinguishActivateInWorld);
         }
 
@@ -142,29 +142,26 @@ namespace Content.Server.Atmos.EntitySystems
 
         private void OnExtinguishActivateInWorld(EntityUid uid, ExtinguishOnInteractComponent component, ActivateInWorldEvent args)
         {
-            TryHandExtinguish(uid, component);
-        }
-
-        private void OnExtinguishUsingInHand(EntityUid uid, ExtinguishOnInteractComponent component, UseInHandEvent args)
-        {
-            TryHandExtinguish(uid, component);
-        }
+            if (args.Handled)
+                return;
 
-        private void TryHandExtinguish(EntityUid uid, ExtinguishOnInteractComponent component)
-        {
             if (!TryComp(uid, out FlammableComponent? flammable))
                 return;
+
             if (!flammable.OnFire)
                 return;
-            if (TryComp(uid, out UseDelayComponent? useDelay) && _useDelay.ActiveDelay(uid, useDelay))
+
+            args.Handled = true;
+
+            if (!_useDelay.BeginDelay(uid))
                 return;
 
-            _useDelay.BeginDelay(uid);
             _audio.PlayPvs(component.ExtinguishAttemptSound, uid);
             if (_random.Prob(component.Probability))
             {
                 AdjustFireStacks(uid, component.StackDelta, flammable);
-            } else
+            }
+            else
             {
                 _popup.PopupEntity(Loc.GetString(component.ExtinguishFailed), uid);
             }
@@ -173,52 +170,56 @@ namespace Content.Server.Atmos.EntitySystems
         {
             var otherUid = args.OtherEntity;
 
+            // Collisions cause events to get raised directed at both entities. We only want to handle this collision
+            // once, hence the uid check.
+            if (otherUid.Id < uid.Id)
+                return;
+
             // Normal hard collisions, though this isn't generally possible since most flammable things are mobs
             // which don't collide with one another, shouldn't work here.
             if (args.OtherFixtureId != FlammableFixtureID && args.OurFixtureId != FlammableFixtureID)
                 return;
 
-            if (!EntityManager.TryGetComponent(otherUid, out FlammableComponent? otherFlammable))
+            if (!flammable.FireSpread)
+                return;
+
+            if (!TryComp(otherUid, out FlammableComponent? otherFlammable) || !otherFlammable.FireSpread)
                 return;
 
-            if (!flammable.FireSpread || !otherFlammable.FireSpread)
+            if (!flammable.OnFire && !otherFlammable.OnFire)
+                return; // Neither are on fire
+
+            if (flammable.OnFire && otherFlammable.OnFire)
+            {
+                // Both are on fire -> equalize fire stacks.
+                var avg = (flammable.FireStacks + otherFlammable.FireStacks) / 2;
+                flammable.FireStacks = flammable.CanExtinguish ? avg : Math.Max(flammable.FireStacks, avg);
+                otherFlammable.FireStacks = otherFlammable.CanExtinguish ? avg : Math.Max(otherFlammable.FireStacks, avg);
+                UpdateAppearance(uid, flammable);
+                UpdateAppearance(otherUid, otherFlammable);
                 return;
+            }
 
+            // Only one is on fire -> attempt to spread the fire.
             if (flammable.OnFire)
             {
-                if (otherFlammable.OnFire)
+                otherFlammable.FireStacks += flammable.FireStacks / 2;
+                Ignite(otherUid, uid, otherFlammable);
+                if (flammable.CanExtinguish)
                 {
-                    if (flammable.CanExtinguish)
-                    {
-                        var fireSplit = (flammable.FireStacks + otherFlammable.FireStacks) / 2;
-                        flammable.FireStacks = fireSplit;
-                        otherFlammable.FireStacks = fireSplit;
-                    }
-                    else
-                    {
-                        otherFlammable.FireStacks = flammable.FireStacks / 2;
-                    }
-                }
-                else
-                {
-                    if (!flammable.CanExtinguish)
-                    {
-                        otherFlammable.FireStacks += flammable.FireStacks / 2;
-                        Ignite(otherUid, uid, otherFlammable);
-                    }
-                    else
-                    {
-                        flammable.FireStacks /= 2;
-                        otherFlammable.FireStacks += flammable.FireStacks;
-                        Ignite(otherUid, uid, otherFlammable);
-                    }
+                    flammable.FireStacks /= 2;
+                    UpdateAppearance(uid, flammable);
                 }
             }
-            else if (otherFlammable.OnFire)
+            else
             {
-                otherFlammable.FireStacks /= 2;
-                flammable.FireStacks += otherFlammable.FireStacks;
+                flammable.FireStacks += otherFlammable.FireStacks / 2;
                 Ignite(uid, otherUid, flammable);
+                if (otherFlammable.CanExtinguish)
+                {
+                    otherFlammable.FireStacks /= 2;
+                    UpdateAppearance(otherUid, otherFlammable);
+                }
             }
         }
 
@@ -254,7 +255,7 @@ namespace Content.Server.Atmos.EntitySystems
             // This is intended so that matches & candles can re-use code for un-shaded layers on in-hand sprites.
             // However, this could cause conflicts if something is ACTUALLY both a toggleable light and flammable.
             // if that ever happens, then fire visuals will need to implement their own in-hand sprite management.
-            _appearance.SetData(uid, ToggleableLightVisuals.Enabled, true, appearance);
+            _appearance.SetData(uid, ToggleableLightVisuals.Enabled, flammable.OnFire, appearance);
         }
 
         public void AdjustFireStacks(EntityUid uid, float relativeFireStacks, FlammableComponent? flammable = null)
@@ -266,8 +267,8 @@ namespace Content.Server.Atmos.EntitySystems
 
             if (flammable.OnFire && flammable.FireStacks <= 0)
                 Extinguish(uid, flammable);
-
-            UpdateAppearance(uid, flammable);
+            else
+                UpdateAppearance(uid, flammable);
         }
 
         public void Extinguish(EntityUid uid, FlammableComponent? flammable = null)
@@ -282,8 +283,6 @@ namespace Content.Server.Atmos.EntitySystems
             flammable.OnFire = false;
             flammable.FireStacks = 0;
 
-            flammable.Collided.Clear();
-
             UpdateAppearance(uid, flammable);
         }
 
@@ -409,24 +408,6 @@ namespace Content.Server.Atmos.EntitySystems
                         700f, 50f, uid, true);
 
                 }
-
-                for (var i = flammable.Collided.Count - 1; i >= 0; i--)
-                {
-                    var otherUid = flammable.Collided[i];
-
-                    if (!otherUid.IsValid() || !EntityManager.EntityExists(otherUid))
-                    {
-                        flammable.Collided.RemoveAt(i);
-                        continue;
-                    }
-
-                    // TODO: Sloth, please save our souls!
-                    // no
-                    if (!_lookup.GetWorldAABB(uid, transform).Intersects(_lookup.GetWorldAABB(otherUid)))
-                    {
-                        flammable.Collided.RemoveAt(i);
-                    }
-                }
             }
         }
     }
index 1d1d636b89fae4c986c2b8627cef918fae1eeb1a..17a806f09429d62b805100275f847d975ae12cde 100644 (file)
@@ -77,13 +77,20 @@ public sealed class UseDelaySystem : EntitySystem
         }
     }
 
-    public void BeginDelay(EntityUid uid, UseDelayComponent? component = null)
+    /// <summary>
+    /// Attempts tp start a use-delay for some entity. Returns true unless there is already an active delay.
+    /// </summary>
+    /// <remarks>
+    /// Note that this will always return true if the entity does not have a use delay component, as in that case there
+    /// is no reason to block/prevent an interaction.
+    /// </remarks>
+    public bool BeginDelay(EntityUid uid, UseDelayComponent? component = null)
     {
         if (!Resolve(uid, ref component, false))
-            return;
+            return true;
 
         if (component.ActiveDelay)
-            return;
+            return false;
 
         DebugTools.Assert(!_activeDelays.Contains(component));
         _activeDelays.Add(component);
@@ -91,12 +98,12 @@ public sealed class UseDelaySystem : EntitySystem
         var currentTime = _gameTiming.CurTime;
         component.LastUseTime = currentTime;
         component.DelayEndTime = currentTime + component.Delay;
-        Dirty(component);
+        Dirty(uid, component);
 
-        // TODO just merge these components?
-        var cooldown = EnsureComp<ItemCooldownComponent>(component.Owner);
+        var cooldown = EnsureComp<ItemCooldownComponent>(uid);
         cooldown.CooldownStart = currentTime;
         cooldown.CooldownEnd = component.DelayEndTime;
+        return true;
     }
 
     public bool ActiveDelay(EntityUid uid, UseDelayComponent? component = null)