]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Change ThrownItemComponent to be removed after flytime (#20700)
authorDrSmugleaf <DrSmugleaf@users.noreply.github.com>
Sat, 7 Oct 2023 00:43:54 +0000 (17:43 -0700)
committerGitHub <noreply@github.com>
Sat, 7 Oct 2023 00:43:54 +0000 (17:43 -0700)
Content.Shared/Throwing/ThrowingSystem.cs
Content.Shared/Throwing/ThrownItemComponent.cs
Content.Shared/Throwing/ThrownItemSystem.cs
Content.Shared/Weapons/Misc/SharedTetherGunSystem.cs

index 35bfc069eb0f82a0e8aaa11111bf777084e8c715..e47cdd5acc2c228881163c56b43ca6ecc987f66c 100644 (file)
@@ -1,7 +1,6 @@
 using System.Numerics;
 using Content.Shared.Gravity;
 using Content.Shared.Interaction;
-using Content.Shared.Movement.Components;
 using Content.Shared.Projectiles;
 using Content.Shared.Tag;
 using Robust.Shared.Map;
@@ -24,6 +23,7 @@ public sealed class ThrowingSystem : EntitySystem
     /// </summary>
     public const float FlyTime = 0.15f;
 
+    [Dependency] private readonly IGameTiming _gameTiming = default!;
     [Dependency] private readonly SharedGravitySystem _gravity = default!;
     [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
@@ -112,6 +112,13 @@ public sealed class ThrowingSystem : EntitySystem
 
         var comp = EnsureComp<ThrownItemComponent>(uid);
         comp.Thrower = user;
+
+        // Estimate time to arrival so we can apply OnGround status and slow it much faster.
+        var time = direction.Length() / strength;
+        comp.ThrownTime = _gameTiming.CurTime;
+        comp.LandTime = time < FlyTime ? default : comp.ThrownTime + TimeSpan.FromSeconds(time - FlyTime);
+        comp.PlayLandSound = playSound;
+
         ThrowingAngleComponent? throwingAngle = null;
 
         // Give it a l'il spin.
@@ -134,24 +141,13 @@ public sealed class ThrowingSystem : EntitySystem
         var impulseVector = direction.Normalized() * strength * physics.Mass;
         _physics.ApplyLinearImpulse(uid, impulseVector, body: physics);
 
-        // Estimate time to arrival so we can apply OnGround status and slow it much faster.
-        var time = direction.Length() / strength;
-
-        if (time < FlyTime)
+        if (comp.LandTime <= TimeSpan.Zero)
         {
             _thrownSystem.LandComponent(uid, comp, physics, playSound);
         }
         else
         {
             _physics.SetBodyStatus(physics, BodyStatus.InAir);
-
-            Timer.Spawn(TimeSpan.FromSeconds(time - FlyTime), () =>
-            {
-                if (physics.Deleted)
-                    return;
-
-                _thrownSystem.LandComponent(uid, comp, physics, playSound);
-            });
         }
 
         // Give thrower an impulse in the other direction
index eb09127dea88f3c249c4b429fbf8f9788b7220b7..eb23ba0994d65674acb38b2ef090c9c812921130 100644 (file)
@@ -1,13 +1,41 @@
 using Robust.Shared.GameStates;
 using Robust.Shared.Serialization;
+using Robust.Shared.Timing;
 
 namespace Content.Shared.Throwing
 {
-    [RegisterComponent, NetworkedComponent]
+    [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
     public sealed partial class ThrownItemComponent : Component
     {
-        [ViewVariables(VVAccess.ReadWrite), DataField("thrower")]
+        /// <summary>
+        ///     The entity that threw this entity.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
         public EntityUid? Thrower { get; set; }
+
+        /// <summary>
+        ///     The <see cref="IGameTiming.CurTime"/> timestamp at which this entity was thrown.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+        public TimeSpan? ThrownTime { get; set; }
+
+        /// <summary>
+        ///     Compared to <see cref="IGameTiming.CurTime"/> to land this entity, if any.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+        public TimeSpan? LandTime { get; set; }
+
+        /// <summary>
+        ///     Whether or not this entity was already landed.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+        public bool Landed { get; set; }
+
+        /// <summary>
+        ///     Whether or not to play a sound when the entity lands.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+        public bool PlayLandSound { get; set; }
     }
 
     [Serializable, NetSerializable]
index 7fb1cc6b8a586051237239ab64ce5cebbd166b69..d7856543e4ac3d0cb3025449f70bc83a4d857ffd 100644 (file)
@@ -3,12 +3,11 @@ using Content.Shared.Administration.Logs;
 using Content.Shared.Database;
 using Content.Shared.Physics;
 using Content.Shared.Physics.Pull;
-using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
 using Robust.Shared.Physics;
 using Robust.Shared.Physics.Components;
 using Robust.Shared.Physics.Events;
 using Robust.Shared.Physics.Systems;
+using Robust.Shared.Timing;
 
 namespace Content.Shared.Throwing
 {
@@ -18,6 +17,7 @@ namespace Content.Shared.Throwing
     public sealed class ThrownItemSystem : EntitySystem
     {
         [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
+        [Dependency] private readonly IGameTiming _gameTiming = default!;
         [Dependency] private readonly SharedBroadphaseSystem _broadphase = default!;
         [Dependency] private readonly FixtureSystem _fixtures = default!;
         [Dependency] private readonly SharedPhysicsSystem _physics = default!;
@@ -27,29 +27,18 @@ namespace Content.Shared.Throwing
         public override void Initialize()
         {
             base.Initialize();
+            SubscribeLocalEvent<ThrownItemComponent, MapInitEvent>(OnMapInit);
             SubscribeLocalEvent<ThrownItemComponent, PhysicsSleepEvent>(OnSleep);
             SubscribeLocalEvent<ThrownItemComponent, StartCollideEvent>(HandleCollision);
             SubscribeLocalEvent<ThrownItemComponent, PreventCollideEvent>(PreventCollision);
             SubscribeLocalEvent<ThrownItemComponent, ThrownEvent>(ThrowItem);
-            SubscribeLocalEvent<ThrownItemComponent, ComponentGetState>(OnGetState);
-            SubscribeLocalEvent<ThrownItemComponent, ComponentHandleState>(OnHandleState);
+            SubscribeLocalEvent<ThrownItemComponent, EntityUnpausedEvent>(OnThrownUnpaused);
             SubscribeLocalEvent<PullStartedMessage>(HandlePullStarted);
         }
 
-        private void OnGetState(EntityUid uid, ThrownItemComponent component, ref ComponentGetState args)
+        private void OnMapInit(EntityUid uid, ThrownItemComponent component, MapInitEvent args)
         {
-            args.State = new ThrownItemComponentState(GetNetEntity(component.Thrower));
-        }
-
-        private void OnHandleState(EntityUid uid, ThrownItemComponent component, ref ComponentHandleState args)
-        {
-            if (args.Current is not ThrownItemComponentState { Thrower: not null } state ||
-                !state.Thrower.Value.IsValid())
-            {
-                return;
-            }
-
-            component.Thrower = EnsureEntity<ThrownItemComponent>(state.Thrower.Value, uid);
+            component.ThrownTime ??= _gameTiming.CurTime;
         }
 
         private void ThrowItem(EntityUid uid, ThrownItemComponent component, ThrownEvent args)
@@ -66,6 +55,14 @@ namespace Content.Shared.Throwing
             _fixtures.TryCreateFixture(uid, shape, ThrowingFixture, hard: false, collisionMask: (int) CollisionGroup.ThrownItem, manager: fixturesComponent, body: body);
         }
 
+        private void OnThrownUnpaused(EntityUid uid, ThrownItemComponent component, ref EntityUnpausedEvent args)
+        {
+            if (component.LandTime != null)
+            {
+                component.LandTime = component.LandTime.Value + args.PausedTime;
+            }
+        }
+
         private void HandleCollision(EntityUid uid, ThrownItemComponent component, ref StartCollideEvent args)
         {
             if (!args.OtherFixture.Hard)
@@ -120,9 +117,11 @@ namespace Content.Shared.Throwing
 
         public void LandComponent(EntityUid uid, ThrownItemComponent thrownItem, PhysicsComponent physics, bool playSound)
         {
-            if (thrownItem.Deleted || Deleted(uid))
+            if (thrownItem.Landed || thrownItem.Deleted || Deleted(uid))
                 return;
 
+            thrownItem.Landed = true;
+
             // Assume it's uninteresting if it has no thrower. For now anyway.
             if (thrownItem.Thrower is not null)
                 _adminLogger.Add(LogType.Landed, LogImpact.Low, $"{ToPrettyString(uid):entity} thrown by {ToPrettyString(thrownItem.Thrower.Value):thrower} landed.");
@@ -130,8 +129,6 @@ namespace Content.Shared.Throwing
             _broadphase.RegenerateContacts(uid, physics);
             var landEvent = new LandEvent(thrownItem.Thrower, playSound);
             RaiseLocalEvent(uid, ref landEvent);
-
-            StopThrow(uid, thrownItem);
         }
 
         /// <summary>
@@ -146,5 +143,25 @@ namespace Content.Shared.Throwing
             RaiseLocalEvent(target, new ThrowHitByEvent(thrown, target, component), true);
             RaiseLocalEvent(thrown, new ThrowDoHitEvent(thrown, target, component), true);
         }
+
+        public override void Update(float frameTime)
+        {
+            base.Update(frameTime);
+
+            var query = EntityQueryEnumerator<ThrownItemComponent, PhysicsComponent>();
+            while (query.MoveNext(out var uid, out var thrown, out var physics))
+            {
+                if (thrown.LandTime <= _gameTiming.CurTime)
+                {
+                    LandComponent(uid, thrown, physics, thrown.PlayLandSound);
+                }
+
+                var stopThrowTime = (thrown.LandTime ?? thrown.ThrownTime) + TimeSpan.FromSeconds(ThrowingSystem.FlyTime);
+                if (stopThrowTime <= _gameTiming.CurTime)
+                {
+                    StopThrow(uid, thrown);
+                }
+            }
+        }
     }
 }
index 807395c46551d3425600d76013cd59e089f2be2c..984ae832fb8029e4a239582422ed46287ce386f2 100644 (file)
@@ -259,6 +259,7 @@ public abstract partial class SharedTetherGunSystem : EntitySystem
             {
                 var thrown = EnsureComp<ThrownItemComponent>(component.Tethered.Value);
                 _thrown.LandComponent(component.Tethered.Value, thrown, targetPhysics, true);
+                _thrown.StopThrow(component.Tethered.Value, thrown);
             }
 
             _physics.SetBodyStatus(targetPhysics, BodyStatus.OnGround);