]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
SpawnEntityTableOnTrigger (#39909)
authorāda <ss.adasts@gmail.com>
Wed, 10 Sep 2025 16:59:42 +0000 (11:59 -0500)
committerGitHub <noreply@github.com>
Wed, 10 Sep 2025 16:59:42 +0000 (19:59 +0300)
* commit

* comment

* empty

* better xform

---------

Co-authored-by: iaada <iaada@users.noreply.github.com>
Content.Shared/Trigger/Components/Effects/SpawnEntityTableOnTriggerComponent.cs [new file with mode: 0644]
Content.Shared/Trigger/Components/Effects/SpawnOnTriggerComponent.cs
Content.Shared/Trigger/Systems/TriggerSystem.Spawn.cs
Content.Shared/Trigger/Systems/TriggerSystem.cs

diff --git a/Content.Shared/Trigger/Components/Effects/SpawnEntityTableOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/SpawnEntityTableOnTriggerComponent.cs
new file mode 100644 (file)
index 0000000..41cb785
--- /dev/null
@@ -0,0 +1,33 @@
+using Content.Shared.EntityTable.EntitySelectors;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Effects;
+
+/// <summary>
+/// Spawns an entity table at this entity when triggered.
+/// If TargetUser is true it will be spawned at their location.
+/// </summary>
+/// <seealso cref="SpawnOnTriggerComponent"/>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class SpawnEntityTableOnTriggerComponent : BaseXOnTriggerComponent
+{
+    /// <summary>
+    /// The table to spawn.
+    /// </summary>
+    [DataField(required: true), AutoNetworkedField]
+    public EntityTableSelector Table;
+
+    /// <summary>
+    /// Use MapCoordinates for spawning?
+    /// Set to true if you don't want the new entity parented to the spawner.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool UseMapCoords;
+
+    /// <summary>
+    /// Whether to use predicted spawning.
+    /// </summary>
+    /// <remarks>Randomization in EntityTables is not currently predicted! Use with caution.</remarks>
+    [DataField, AutoNetworkedField]
+    public bool Predicted;
+}
index 782626f479be67e24d66cd95ffc44b3bf9474618..e1c7dad0b80149238fdfca5815cd5930159d1844 100644 (file)
@@ -7,6 +7,7 @@ namespace Content.Shared.Trigger.Components.Effects;
 /// Spawns a protoype when triggered.
 /// If TargetUser is true it will be spawned at their location.
 /// </summary>
+/// <seealso cref="SpawnEntityTableOnTriggerComponent"/>
 [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
 public sealed partial class SpawnOnTriggerComponent : BaseXOnTriggerComponent
 {
index edcdd038941053adf6197fb91f090ad7716bd3a3..83457361fd5469e655cce0ce5aab81f3b92f02b2 100644 (file)
@@ -1,16 +1,17 @@
 using Content.Shared.Trigger.Components.Effects;
 using Content.Shared.Trigger.Components.Triggers;
+using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Trigger.Systems;
 
 public sealed partial class TriggerSystem
 {
-
     private void InitializeSpawn()
     {
         SubscribeLocalEvent<TriggerOnSpawnComponent, MapInitEvent>(OnSpawnInit);
 
         SubscribeLocalEvent<SpawnOnTriggerComponent, TriggerEvent>(HandleSpawnOnTrigger);
+        SubscribeLocalEvent<SpawnEntityTableOnTriggerComponent, TriggerEvent>(HandleSpawnTableOnTrigger);
         SubscribeLocalEvent<DeleteOnTriggerComponent, TriggerEvent>(HandleDeleteOnTrigger);
     }
 
@@ -30,27 +31,55 @@ public sealed partial class TriggerSystem
             return;
 
         var xform = Transform(target.Value);
+        SpawnTriggerHelper((target.Value, xform), ent.Comp.Proto, ent.Comp.UseMapCoords, ent.Comp.Predicted);
+    }
+
+    private void HandleSpawnTableOnTrigger(Entity<SpawnEntityTableOnTriggerComponent> ent, ref TriggerEvent args)
+    {
+        if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
+            return;
+
+        var target = ent.Comp.TargetUser ? args.User : ent.Owner;
+
+        if (target == null)
+            return;
+
+        var xform = Transform(target.Value);
+        var spawns = _entityTable.GetSpawns(ent.Comp.Table);
+        foreach (var proto in spawns)
+        {
+            SpawnTriggerHelper((target.Value, xform), proto, ent.Comp.UseMapCoords, ent.Comp.Predicted);
+        }
+    }
 
-        if (ent.Comp.UseMapCoords)
+    /// <summary>
+    /// Helper function to combine HandleSpawnOnTrigger and HandleSpawnTableOnTrigger.
+    /// </summary>
+    /// <param name="target">The entity to spawn attached to or at the feet of.</param>
+    /// <param name="proto">The entity to spawn.</param>
+    /// <param name="useMapCoords">If true, spawn at target's MapCoordinates. If false, spawn attached to target.</param>
+    /// <param name="predicted">Whether to use predicted spawning.</param>
+    private void SpawnTriggerHelper(Entity<TransformComponent> target, EntProtoId proto, bool useMapCoords, bool predicted)
+    {
+        if (useMapCoords)
         {
-            var mapCoords = _transform.GetMapCoordinates(target.Value, xform);
-            if (ent.Comp.Predicted)
-                EntityManager.PredictedSpawn(ent.Comp.Proto, mapCoords);
+            var mapCoords = _transform.GetMapCoordinates(target);
+            if (predicted)
+                EntityManager.PredictedSpawn(proto, mapCoords);
             else if (_net.IsServer)
-                Spawn(ent.Comp.Proto, mapCoords);
-
+                Spawn(proto, mapCoords);
         }
+
         else
         {
-            var coords = xform.Coordinates;
+            var coords = target.Comp.Coordinates;
             if (!coords.IsValid(EntityManager))
                 return;
 
-            if (ent.Comp.Predicted)
-                PredictedSpawnAttachedTo(ent.Comp.Proto, coords);
+            if (predicted)
+                PredictedSpawnAttachedTo(proto, coords);
             else if (_net.IsServer)
-                SpawnAttachedTo(ent.Comp.Proto, coords);
-
+                SpawnAttachedTo(proto, coords);
         }
     }
 
index 6a749b87abd8d5f6593a1530dbb45ed78e629502..ca60901a79d9862cb80ebc83228249149fcfd5b6 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.Administration.Logs;
 using Content.Shared.Database;
 using Content.Shared.DeviceLinking;
+using Content.Shared.EntityTable;
 using Content.Shared.Item.ItemToggle;
 using Content.Shared.Popups;
 using Content.Shared.Timing;
@@ -38,6 +39,7 @@ public sealed partial class TriggerSystem : EntitySystem
     [Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
     [Dependency] private readonly ItemToggleSystem _itemToggle = default!;
     [Dependency] private readonly SharedDeviceLinkSystem _deviceLink = default!;
+    [Dependency] private readonly EntityTableSystem _entityTable = default!;
 
     public const string DefaultTriggerKey = "trigger";