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 { [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; 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); } } } }