]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Predict PickRandom verb (#39326)
authorslarticodefast <161409025+slarticodefast@users.noreply.github.com>
Wed, 6 Aug 2025 02:29:13 +0000 (04:29 +0200)
committerGitHub <noreply@github.com>
Wed, 6 Aug 2025 02:29:13 +0000 (19:29 -0700)
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Content.Shared/Storage/Components/PickRandomComponent.cs [moved from Content.Server/Storage/Components/PickRandomComponent.cs with 69% similarity]
Content.Shared/Storage/EntitySystems/PickRandomSystem.cs [moved from Content.Server/Storage/EntitySystems/PickRandomSystem.cs with 78% similarity]

similarity index 69%
rename from Content.Server/Storage/Components/PickRandomComponent.cs
rename to Content.Shared/Storage/Components/PickRandomComponent.cs
index 00c79b9ea4fb91250aa3b463608107af6ce49889..e243d25ddea8e0d2ed91fdf7167bf9c4c5418f96 100644 (file)
@@ -1,31 +1,32 @@
-using Content.Server.Storage.EntitySystems;
+using Content.Shared.Storage.EntitySystems;
 using Content.Shared.Whitelist;
+using Robust.Shared.GameStates;
 
-namespace Content.Server.Storage.Components;
+namespace Content.Shared.Storage.Components;
 
 /// <summary>
 /// Adds a verb to pick a random item from a container.
 /// Only picks items that match the whitelist.
 /// </summary>
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
 [Access(typeof(PickRandomSystem))]
 public sealed partial class PickRandomComponent : Component
 {
     /// <summary>
     /// Whitelist for potential picked items.
     /// </summary>
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField, AutoNetworkedField]
     public EntityWhitelist? Whitelist;
 
     /// <summary>
     /// Locale id for the pick verb text.
     /// </summary>
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField, AutoNetworkedField]
     public LocId VerbText = "comp-pick-random-verb-text";
 
     /// <summary>
     /// Locale id for the empty storage message.
     /// </summary>
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField, AutoNetworkedField]
     public LocId EmptyText = "comp-pick-random-empty";
 }
similarity index 78%
rename from Content.Server/Storage/EntitySystems/PickRandomSystem.cs
rename to Content.Shared/Storage/EntitySystems/PickRandomSystem.cs
index f0e986e199bf1cd5764a31695d80e6ab00b28937..87fb4219ade04362885f4eee5aff2a6eea3b31a9 100644 (file)
@@ -1,22 +1,22 @@
 using System.Linq;
-using Content.Server.Storage.Components;
 using Content.Shared.Database;
 using Content.Shared.Hands.EntitySystems;
-using Content.Shared.Storage;
+using Content.Shared.Storage.Components;
 using Content.Shared.Verbs;
 using Content.Shared.Whitelist;
 using Robust.Shared.Containers;
+using Robust.Shared.Network;
 using Robust.Shared.Random;
 
-namespace Content.Server.Storage.EntitySystems;
+namespace Content.Shared.Storage.EntitySystems;
 
-// TODO: move this to shared for verb prediction if/when storage is in shared
 public sealed class PickRandomSystem : EntitySystem
 {
+    [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
+    [Dependency] private readonly INetManager _net = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly SharedContainerSystem _container = default!;
     [Dependency] private readonly SharedHandsSystem _hands = default!;
-    [Dependency] private readonly IRobustRandom _random = default!;
-    [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
 
     public override void Initialize()
     {
@@ -50,12 +50,19 @@ public sealed class PickRandomSystem : EntitySystem
 
     private void TryPick(EntityUid uid, PickRandomComponent comp, StorageComponent storage, EntityUid user)
     {
+        // It's hard to predict picking a random entity from a container since the contained entity list will have a different order on the server and client.
+        // One idea might be to sort them by NetEntity ID, but that is expensive if there are a lot of entities.
+        // Another option would be to make this client authorative.
+        if (_net.IsClient)
+            return;
+
         var entities = storage.Container.ContainedEntities.Where(item => _whitelistSystem.IsWhitelistPassOrNull(comp.Whitelist, item)).ToArray();
 
-        if (!entities.Any())
+        if (entities.Length == 0)
             return;
 
         var picked = _random.Pick(entities);
+
         // if it fails to go into a hand of the user, will be on the storage
         _container.AttachParentToContainerOrGrid((picked, Transform(picked)));