diff --git a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs index 413991515b947..99646cc74f16c 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs @@ -1,5 +1,7 @@ using System.Numerics; using Content.Server.Forensics; +using Content.Server.Spawners.Components; +using Content.Server.Spawners.EntitySystems; using Content.Server.Stack; using Content.Shared.Destructible.Thresholds; using Content.Shared.Prototypes; @@ -7,6 +9,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Spawners; namespace Content.Server.Destructible.Thresholds.Behaviors { @@ -14,6 +17,8 @@ namespace Content.Server.Destructible.Thresholds.Behaviors [DataDefinition] public sealed partial class SpawnEntitiesBehavior : IThresholdBehavior { + private static readonly EntProtoId TempEntityProtoId = "TemporaryEntityForTimedDespawnSpawners"; + /// /// Entities spawned on reaching this threshold, from a min to a max. /// @@ -29,6 +34,12 @@ public sealed partial class SpawnEntitiesBehavior : IThresholdBehavior [DataField] public bool SpawnInContainer; + /// + /// Time in seconds to wait before spawning entities + /// + [DataField] + public float SpawnAfter; + public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null) { var tSys = system.EntityManager.System(); @@ -42,36 +53,69 @@ public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause executions = stack.Count; } - foreach (var (entityId, minMax) in Spawn) + // Different behaviors for delayed spawning and immediate spawning + if (SpawnAfter != 0) { - for (var execution = 0; execution < executions; execution++) - { - var count = minMax.Min >= minMax.Max - ? minMax.Min - : system.Random.Next(minMax.Min, minMax.Max + 1); + // if it fails to get the spawner, this won't ever work so just return + if (!system.PrototypeManager.Resolve(TempEntityProtoId, out var tempSpawnerProto)) + return; - if (count == 0) - continue; - - if (EntityPrototypeHelpers.HasComponent(entityId, system.PrototypeManager, system.EntityManager.ComponentFactory)) + foreach (var (entityId, minMax) in Spawn) + { + for (var execution = 0; execution < executions; execution++) { - var spawned = SpawnInContainer - ? system.EntityManager.SpawnNextToOrDrop(entityId, owner) - : system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); - system.StackSystem.SetCount(spawned, count); + var count = minMax.Min >= minMax.Max + ? minMax.Min + : system.Random.Next(minMax.Min, minMax.Max + 1); + + if (count == 0) + continue; - TransferForensics(spawned, system, owner); + for (var i = 0; i < count; i++) + { + var spawner = system.EntityManager.SpawnEntity(tempSpawnerProto.ID, position.Offset(getRandomVector())); + system.EntityManager.EnsureComponent(spawner, out var timedDespawnComponent); + timedDespawnComponent.Lifetime = SpawnAfter; + system.EntityManager.EnsureComponent(spawner, out var spawnOnDespawnComponent); + system.EntityManager.System().SetPrototype((spawner, spawnOnDespawnComponent), entityId); + } } - else + } + } + else + { + // Immediate spawning + foreach (var (entityId, minMax) in Spawn) + { + for (var execution = 0; execution < executions; execution++) { - for (var i = 0; i < count; i++) + var count = minMax.Min >= minMax.Max + ? minMax.Min + : system.Random.Next(minMax.Min, minMax.Max + 1); + + if (count == 0) + continue; + + if (EntityPrototypeHelpers.HasComponent(entityId, system.PrototypeManager, system.EntityManager.ComponentFactory)) { var spawned = SpawnInContainer ? system.EntityManager.SpawnNextToOrDrop(entityId, owner) : system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); + system.StackSystem.SetCount(spawned, count); TransferForensics(spawned, system, owner); } + else + { + for (var i = 0; i < count; i++) + { + var spawned = SpawnInContainer + ? system.EntityManager.SpawnNextToOrDrop(entityId, owner) + : system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); + + TransferForensics(spawned, system, owner); + } + } } } }