]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix robusted dionas not being recoverable (#21636)
authorBakke <luringens@protonmail.com>
Thu, 4 Jan 2024 13:10:04 +0000 (14:10 +0100)
committerGitHub <noreply@github.com>
Thu, 4 Jan 2024 13:10:04 +0000 (06:10 -0700)
* Fix robusted dionas not being recoverable

* Implement a polymorph cooldown field, used for TreeMorph

Allows the polymorphed Diona some time to work off robust harvest
without immediately polymorphing again.

* Minor adjustment to polymorph cooldown timing

* Apply suggestions from code review

Co-authored-by: Kara <lunarautomaton6@gmail.com>
* fix: trigger polymorph revert on destruction

As suggested by mirrorcult, DamageThresholdReached is not the ideal
candidate for reverting a polymorph on destruction, as there exists a
DestructionEventArgs to listen for instead.

---------

Co-authored-by: Kara <lunarautomaton6@gmail.com>
Content.Server/Polymorph/Components/PolymorphableComponent.cs
Content.Server/Polymorph/Systems/PolymorphSystem.cs
Content.Shared/Polymorph/PolymorphPrototype.cs
Resources/Prototypes/Polymorphs/polymorph.yml

index c05d36a8425ccfb7fa8ee9c632d1b98325f322b7..2e9c5fee0a5fb79daac206fd374c9d74db571aca 100644 (file)
@@ -12,6 +12,12 @@ namespace Content.Server.Polymorph.Components
         /// </summary>
         public Dictionary<string, EntityUid>? PolymorphActions = null;
 
+        /// <summary>
+        /// Timestamp for when the most recent polymorph ended.
+        /// </summary>
+        [ViewVariables(VVAccess.ReadOnly)]
+        public TimeSpan? LastPolymorphEnd = null;
+
         /// <summary>
         /// The polymorphs that the entity starts out being able to do.
         /// </summary>
index 5b8a7b71653e160825a6e3797ee1c03892f2abda..4d3bbcdf7805237b7102d8b65aafd8c26b404f6d 100644 (file)
@@ -7,6 +7,7 @@ using Content.Server.Polymorph.Components;
 using Content.Shared.Actions;
 using Content.Shared.Buckle;
 using Content.Shared.Damage;
+using Content.Shared.Destructible;
 using Content.Shared.Hands.EntitySystems;
 using Content.Shared.IdentityManagement;
 using Content.Shared.Mind;
@@ -20,6 +21,7 @@ using Robust.Server.Containers;
 using Robust.Server.GameObjects;
 using Robust.Shared.Map;
 using Robust.Shared.Prototypes;
+using Robust.Shared.Timing;
 using Robust.Shared.Utility;
 
 namespace Content.Server.Polymorph.Systems
@@ -44,6 +46,7 @@ namespace Content.Server.Polymorph.Systems
         [Dependency] private readonly TransformSystem _transform = default!;
         [Dependency] private readonly SharedMindSystem _mindSystem = default!;
         [Dependency] private readonly MetaDataSystem _metaData = default!;
+        [Dependency] private readonly IGameTiming _gameTiming = default!;
 
         private ISawmill _sawmill = default!;
 
@@ -59,6 +62,7 @@ namespace Content.Server.Polymorph.Systems
             SubscribeLocalEvent<PolymorphedEntityComponent, BeforeFullyEatenEvent>(OnBeforeFullyEaten);
             SubscribeLocalEvent<PolymorphedEntityComponent, BeforeFullySlicedEvent>(OnBeforeFullySliced);
             SubscribeLocalEvent<PolymorphedEntityComponent, RevertPolymorphActionEvent>(OnRevertPolymorphActionEvent);
+            SubscribeLocalEvent<PolymorphedEntityComponent, DestructionEventArgs>(OnDestruction);
 
             InitializeCollide();
             InitializeMap();
@@ -122,6 +126,24 @@ namespace Content.Server.Polymorph.Systems
             }
         }
 
+        /// <summary>
+        /// It is possible to be polymorphed into an entity that can't "die", but is instead
+        /// destroyed. This handler ensures that destruction is treated like death.
+        /// </summary>
+        private void OnDestruction(EntityUid uid, PolymorphedEntityComponent comp, DestructionEventArgs args)
+        {
+            if (!_proto.TryIndex<PolymorphPrototype>(comp.Prototype, out var proto))
+            {
+                _sawmill.Error($"Invalid polymorph prototype {comp.Prototype}");
+                return;
+            }
+
+            if (proto.RevertOnDeath)
+            {
+                Revert(uid, comp);
+            }
+        }
+
         private void OnBeforeFullySliced(EntityUid uid, PolymorphedEntityComponent comp, BeforeFullySlicedEvent args)
         {
             if (!_proto.TryIndex<PolymorphPrototype>(comp.Prototype, out var proto))
@@ -164,6 +186,13 @@ namespace Content.Server.Polymorph.Systems
             if (!proto.AllowRepeatedMorphs && HasComp<PolymorphedEntityComponent>(uid))
                 return null;
 
+            // If this polymorph has a cooldown, check if that amount of time has passed since the
+            // last polymorph ended.
+            if (TryComp<PolymorphableComponent>(uid, out var polymorphableComponent) &&
+                polymorphableComponent.LastPolymorphEnd != null &&
+                _gameTiming.CurTime < polymorphableComponent.LastPolymorphEnd + proto.Cooldown)
+                return null;
+
             // mostly just for vehicles
             _buckle.TryUnbuckle(uid, uid, true);
 
@@ -302,6 +331,9 @@ namespace Content.Server.Polymorph.Systems
             if (_mindSystem.TryGetMind(uid, out var mindId, out var mind))
                 _mindSystem.TransferTo(mindId, parent, mind: mind);
 
+            if (TryComp<PolymorphableComponent>(parent, out var polymorphableComponent))
+                polymorphableComponent.LastPolymorphEnd = _gameTiming.CurTime;
+
             // if an item polymorph was picked up, put it back down after reverting
             Transform(parent).AttachToGridOrMap();
 
index 75c6d58d24c3f39d7b626886ff7904130d413fe6..f093489b040abf7266eb5553fb24818155ff026d 100644 (file)
@@ -97,6 +97,14 @@ namespace Content.Shared.Polymorph
 
         [DataField("allowRepeatedMorphs", serverOnly: true)]
         public bool AllowRepeatedMorphs = false;
+
+        /// <summary>
+        /// The amount of time that should pass after this polymorph has ended, before a new one
+        /// can occur.
+        /// </summary>
+        [DataField("cooldown", serverOnly: true)]
+        [ViewVariables(VVAccess.ReadWrite)]
+        public TimeSpan Cooldown = TimeSpan.Zero;
     }
 
     public enum PolymorphInventoryChange : byte
index 8593c2194d1a0209f075eb03c4f133ed76bb296d..46590248aec09cffde65f6201b4578462f245a43 100644 (file)
   forced: true
   transferName: true
   revertOnDeath: true
-
+  inventory: Drop
+  cooldown: 160
 
 # this is the monkey polymorph for artifact.
 - type: polymorph