diff --git a/Content.Server/GameObjects/Components/Markers/ConditionalSpawnerComponent.cs b/Content.Server/GameObjects/Components/Markers/ConditionalSpawnerComponent.cs index a41c72b31d..53dfca85c1 100644 --- a/Content.Server/GameObjects/Components/Markers/ConditionalSpawnerComponent.cs +++ b/Content.Server/GameObjects/Components/Markers/ConditionalSpawnerComponent.cs @@ -2,18 +2,15 @@ using System; using System.Collections.Generic; using Content.Server.GameTicking; using Content.Server.Interfaces.GameTicking; -using NFluidsynth; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Random; using Robust.Shared.Interfaces.Reflection; using Robust.Shared.IoC; -using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; -using SQLitePCL; using Logger = Robust.Shared.Log.Logger; namespace Content.Server.GameObjects.Components.Markers diff --git a/Content.Server/GameObjects/Components/Markers/TimedSpawnerComponent.cs b/Content.Server/GameObjects/Components/Markers/TimedSpawnerComponent.cs new file mode 100644 index 0000000000..96aa996204 --- /dev/null +++ b/Content.Server/GameObjects/Components/Markers/TimedSpawnerComponent.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Random; +using Robust.Shared.IoC; +using Robust.Shared.Random; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; +using Timer = Robust.Shared.Timers.Timer; + +namespace Content.Server.GameObjects.Components.Markers +{ + [RegisterComponent] + public class TimedSpawnerComponent : Component + { +#pragma warning disable 649 + [Dependency] private IEntityManager _entityManager; + [Dependency] private IRobustRandom _robustRandom; +#pragma warning restore 649 + + public override string Name => "TimedSpawner"; + + [ViewVariables(VVAccess.ReadWrite)] + public List Prototypes { get; set; } = new List(); + + [ViewVariables(VVAccess.ReadWrite)] + public float Chance { get; set; } = 1.0f; + + [ViewVariables(VVAccess.ReadWrite)] + public int IntervalSeconds { get; set; } = 60; + + [ViewVariables(VVAccess.ReadWrite)] + public int MinimumEntitiesSpawned { get; set; } = 1; + + [ViewVariables(VVAccess.ReadWrite)] + public int MaximumEntitiesSpawned { get; set; } = 1; + + private CancellationTokenSource TokenSource; + + public override void Initialize() + { + base.Initialize(); + SetupTimer(); + } + + protected override void Shutdown() + { + base.Shutdown(); + TokenSource.Cancel(); + } + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(this, x => Prototypes, "prototypes", new List()); + serializer.DataField(this, x => Chance, "chance", 1.0f); + serializer.DataField(this, x => IntervalSeconds, "intervalSeconds", 60); + serializer.DataField(this, x => MinimumEntitiesSpawned, "minimumEntitiesSpawned", 1); + serializer.DataField(this, x => MaximumEntitiesSpawned, "maximumEntitiesSpawned", 1); + + if(MinimumEntitiesSpawned > MaximumEntitiesSpawned) + throw new ArgumentException("MaximumEntitiesSpawned can't be lower than MinimumEntitiesSpawned!"); + } + + private void SetupTimer() + { + TokenSource?.Cancel(); + TokenSource = new CancellationTokenSource(); + Timer.SpawnRepeating(TimeSpan.FromSeconds(IntervalSeconds), OnTimerFired, TokenSource.Token); + } + + private void OnTimerFired() + { + if (!_robustRandom.Prob(Chance)) + return; + + var number = _robustRandom.Next(MinimumEntitiesSpawned, MaximumEntitiesSpawned); + + for (int i = 0; i < number; i++) + { + var entity = _robustRandom.Pick(Prototypes); + _entityManager.SpawnEntity(entity, Owner.Transform.GridPosition); + } + } + } +} diff --git a/Resources/Prototypes/Entities/Markers/timed_spawners.yml b/Resources/Prototypes/Entities/Markers/timed_spawners.yml new file mode 100644 index 0000000000..4bc96baeed --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/timed_spawners.yml @@ -0,0 +1,42 @@ +- type: entity + name: base timed spawner + id: BaseTimedSpawner + abstract: true + components: + - type: Sprite + netsync: false + visible: false + sprite: Objects/markers.rsi + state: cross_blue + - type: Icon + sprite: Objects/markers.rsi + state: cross_blue + - type: Marker + - type: Clickable + - type: InteractionOutline + - type: Collidable + - type: TimedSpawner + placement: + mode: AlignTileAny + +- type: entity + name: AI Timed Spawner + id: AITimedSpawner + parent: BaseTimedSpawner + components: + - type: Sprite + netsync: false + visible: false + sprite: Objects/markers.rsi + state: spawner_rifle + - type: Icon + sprite: Objects/markers.rsi + state: spawner_rifle + - type: TimedSpawner + prototypes: + - HumanMob_Spirate + - HumanMob_Civilian + chance: 0.75 + intervalSeconds: 60 + minimumEntitiesSpawned: 1 + maximumEntitiesSpawned: 5 diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index 5e9ee1ab64..39b7cb2137 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -57,9 +57,9 @@ True True True + True True True True True - True - True + \ No newline at end of file