]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Predict virtual hands and co (#36617)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Sat, 19 Apr 2025 06:51:12 +0000 (16:51 +1000)
committerGitHub <noreply@github.com>
Sat, 19 Apr 2025 06:51:12 +0000 (16:51 +1000)
These are the easy ones anything else gets slightly spicier.

Content.Shared/Interaction/SharedInteractionSystem.cs
Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs
Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs
Content.Shared/Research/TechnologyDisk/Systems/TechnologyDiskSystem.cs
Content.Shared/Wieldable/SharedWieldableSystem.cs

index eeb961537b7137cb822701fb40a92578c4321314..494fbdf032945512d5141cb6baad615988f75aac 100644 (file)
@@ -51,7 +51,6 @@ namespace Content.Shared.Interaction
     public abstract partial class SharedInteractionSystem : EntitySystem
     {
         [Dependency] private readonly IGameTiming _gameTiming = default!;
-        [Dependency] private readonly INetManager _net = default!;
         [Dependency] private readonly IMapManager _mapManager = default!;
         [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
         [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
@@ -223,24 +222,24 @@ namespace Content.Shared.Interaction
         {
             if (!item.DeleteOnDrop)
                 RemCompDeferred<UnremoveableComponent>(uid);
-            else if (_net.IsServer)
-                QueueDel(uid);
+            else
+                PredictedQueueDel(uid);
         }
 
         private void OnUnequipHand(EntityUid uid, UnremoveableComponent item, GotUnequippedHandEvent args)
         {
             if (!item.DeleteOnDrop)
                 RemCompDeferred<UnremoveableComponent>(uid);
-            else if (_net.IsServer)
-                QueueDel(uid);
+            else
+                PredictedQueueDel(uid);
         }
 
         private void OnDropped(EntityUid uid, UnremoveableComponent item, DroppedEvent args)
         {
             if (!item.DeleteOnDrop)
                 RemCompDeferred<UnremoveableComponent>(uid);
-            else if (_net.IsServer)
-                QueueDel(uid);
+            else
+                PredictedQueueDel(uid);
         }
 
         private bool HandleTryPullObject(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
index 9eac60adc4028cc66b0172f1bea5a3676f32b637..393a4c09eb479309821b87e541da034b6ecdf039 100644 (file)
@@ -157,11 +157,6 @@ public abstract class SharedVirtualItemSystem : EntitySystem
     /// </summary>
     public void DeleteInHandsMatching(EntityUid user, EntityUid matching)
     {
-        // Client can't currently predict deleting networked entities so we use this workaround, another
-        // problem can popup when the hands leave PVS for example and this avoids that too
-        if (_netManager.IsClient)
-            return;
-
         foreach (var hand in _handsSystem.EnumerateHands(user))
         {
             if (TryComp(hand.HeldEntity, out VirtualItemComponent? virt) && virt.BlockingEntity == matching)
@@ -206,11 +201,6 @@ public abstract class SharedVirtualItemSystem : EntitySystem
     /// <param name="slotName">Set this param if you have the name of the slot, it avoids unnecessary queries</param>
     public void DeleteInSlotMatching(EntityUid user, EntityUid matching, string? slotName = null)
     {
-        // Client can't currently predict deleting networked entities so we use this workaround, another
-        // problem can popup when the hands leave PVS for example and this avoids that too
-        if (_netManager.IsClient)
-            return;
-
         if (slotName != null)
         {
             if (!_inventorySystem.TryGetSlotEntity(user, slotName, out var slotEnt))
@@ -244,14 +234,8 @@ public abstract class SharedVirtualItemSystem : EntitySystem
     /// <param name="virtualItem">The virtual item, if spawned</param>
     public bool TrySpawnVirtualItem(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem)
     {
-        if (_netManager.IsClient)
-        {
-            virtualItem = null;
-            return false;
-        }
-
         var pos = Transform(user).Coordinates;
-        virtualItem = Spawn(VirtualItem, pos);
+        virtualItem = PredictedSpawnAttachedTo(VirtualItem, pos);
         var virtualItemComp = Comp<VirtualItemComponent>(virtualItem.Value);
         virtualItemComp.BlockingEntity = blockingEnt;
         Dirty(virtualItem.Value, virtualItemComp);
@@ -273,7 +257,6 @@ public abstract class SharedVirtualItemSystem : EntitySystem
             return;
 
         _transformSystem.DetachEntity(item, Transform(item));
-        if (_netManager.IsServer)
-            QueueDel(item);
+        PredictedQueueDel(item);
     }
 }
index 9ddcb423b421e0e14967c0c150b2d50a16f93a16..e63c6ac7b7b276333864966501ed90850a06f09c 100644 (file)
@@ -58,13 +58,7 @@ public sealed partial class EncryptionKeySystem : EntitySystem
             _hands.PickupOrDrop(args.User, ent, dropNear: true);
         }
 
-        if (!_timing.IsFirstTimePredicted)
-            return;
-
-        // TODO add predicted pop-up overrides.
-        if (_net.IsServer)
-            _popup.PopupEntity(Loc.GetString("encryption-keys-all-extracted"), uid, args.User);
-
+        _popup.PopupPredicted(Loc.GetString("encryption-keys-all-extracted"), uid, args.User);
         _audio.PlayPredicted(component.KeyExtractionSound, uid, args.User);
     }
 
index 93c7c22471c6f5d99b25517b4ec0eb5c63ba2efb..4ca47286815de8a544d0273d674479643813a036 100644 (file)
@@ -74,8 +74,7 @@ public sealed class TechnologyDiskSystem : EntitySystem
             }
         }
         _popup.PopupClient(Loc.GetString("tech-disk-inserted"), target, args.User);
-        if (_net.IsServer)
-            QueueDel(ent);
+        PredictedQueueDel(ent);
         args.Handled = true;
     }
 
index b4a61444050fe484b9ffae664946fa5c430a934d..d3b8c4e4c67f4e2531a0bef6e2195ecc0dfaaaee 100644 (file)
@@ -21,6 +21,7 @@ using Content.Shared.Weapons.Ranged.Events;
 using Content.Shared.Weapons.Ranged.Systems;
 using Content.Shared.Wieldable.Components;
 using Robust.Shared.Audio.Systems;
+using Robust.Shared.Collections;
 using Robust.Shared.Network;
 using Robust.Shared.Timing;
 
@@ -260,26 +261,21 @@ public abstract class SharedWieldableSystem : EntitySystem
             _audio.PlayPredicted(component.WieldSound, used, user);
 
         //This section handles spawning the virtual item(s) to occupy the required additional hand(s).
-        //Since the client can't currently predict entity spawning, only do this if this is running serverside.
-        //Remove this check if TrySpawnVirtualItem in SharedVirtualItemSystem is allowed to complete clientside.
-        if (_netManager.IsServer)
+        var virtuals = new ValueList<EntityUid>();
+        for (var i = 0; i < component.FreeHandsRequired; i++)
         {
-            var virtuals = new List<EntityUid>();
-            for (var i = 0; i < component.FreeHandsRequired; i++)
+            if (_virtualItem.TrySpawnVirtualItemInHand(used, user, out var virtualItem, true))
             {
-                if (_virtualItem.TrySpawnVirtualItemInHand(used, user, out var virtualItem, true))
-                {
-                    virtuals.Add(virtualItem.Value);
-                    continue;
-                }
-
-                foreach (var existingVirtual in virtuals)
-                {
-                    QueueDel(existingVirtual);
-                }
+                virtuals.Add(virtualItem.Value);
+                continue;
+            }
 
-                return false;
+            foreach (var existingVirtual in virtuals)
+            {
+                QueueDel(existingVirtual);
             }
+
+            return false;
         }
 
         var selfMessage = Loc.GetString("wieldable-component-successful-wield", ("item", used));