Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
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;
using Content.Shared.Stacks;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Spawners;

namespace Content.Server.Destructible.Thresholds.Behaviors
{
[Serializable]
[DataDefinition]
public sealed partial class SpawnEntitiesBehavior : IThresholdBehavior
{
private static readonly EntProtoId TempEntityProtoId = "TemporaryEntityForTimedDespawnSpawners";

/// <summary>
/// Entities spawned on reaching this threshold, from a min to a max.
/// </summary>
Expand All @@ -29,6 +34,12 @@ public sealed partial class SpawnEntitiesBehavior : IThresholdBehavior
[DataField]
public bool SpawnInContainer;

/// <summary>
/// Time in seconds to wait before spawning entities
/// </summary>
[DataField]
public float SpawnAfter;

public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
{
var tSys = system.EntityManager.System<TransformSystem>();
Expand All @@ -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<StackComponent>(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<TimedDespawnComponent>(spawner, out var timedDespawnComponent);
timedDespawnComponent.Lifetime = SpawnAfter;
system.EntityManager.EnsureComponent<SpawnOnDespawnComponent>(spawner, out var spawnOnDespawnComponent);
system.EntityManager.System<SpawnOnDespawnSystem>().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<StackComponent>(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);
}
}
}
}
}
Expand Down
Loading