diff --git a/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs b/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs index c8bdbd38bb..d74e832f1e 100644 --- a/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs +++ b/Content.Server/Spawners/Components/ConditionalSpawnerComponent.cs @@ -1,78 +1,26 @@ using System.Collections.Generic; -using Content.Server.GameTicking; using Content.Server.GameTicking.Rules; -using Content.Server.Holiday.Greet; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Log; using Robust.Shared.Prototypes; -using Robust.Shared.Random; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; using Robust.Shared.ViewVariables; namespace Content.Server.Spawners.Components { - [RegisterComponent] - public class ConditionalSpawnerComponent : Component, IMapInit + [RegisterComponent, ComponentProtoName("ConditionalSpawner")] + public class ConditionalSpawnerComponent : Component { - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IRobustRandom _robustRandom = default!; - - public override string Name => "ConditionalSpawner"; - [ViewVariables(VVAccess.ReadWrite)] [DataField("prototypes", customTypeSerializer:typeof(PrototypeIdListSerializer))] public List Prototypes { get; set; } = new(); [ViewVariables(VVAccess.ReadWrite)] [DataField("gameRules", customTypeSerializer:typeof(PrototypeIdListSerializer))] - private readonly List _gameRules = new(); + public readonly List GameRules = new(); [ViewVariables(VVAccess.ReadWrite)] [DataField("chance")] public float Chance { get; set; } = 1.0f; - - public void RuleAdded(GameRuleAddedEvent obj) - { - if(_gameRules.Contains(obj.Rule.ID)) - Spawn(); - } - - private void TrySpawn() - { - if (_gameRules.Count == 0) - { - Spawn(); - return; - } - - foreach (var rule in _gameRules) - { - if (!EntitySystem.Get().HasGameRule(rule)) continue; - Spawn(); - return; - } - } - - public virtual void Spawn() - { - if (Chance != 1.0f && !_robustRandom.Prob(Chance)) - return; - - if (Prototypes.Count == 0) - { - Logger.Warning($"Prototype list in ConditionalSpawnComponent is empty! Entity: {Owner}"); - return; - } - - if(!_entMan.Deleted(Owner)) - _entMan.SpawnEntity(_robustRandom.Pick(Prototypes), _entMan.GetComponent(Owner).Coordinates); - } - - public virtual void MapInit() - { - TrySpawn(); - } } } diff --git a/Content.Server/Spawners/Components/RandomSpawnerComponent.cs b/Content.Server/Spawners/Components/RandomSpawnerComponent.cs index 46c7a775e3..7c99a1e1ac 100644 --- a/Content.Server/Spawners/Components/RandomSpawnerComponent.cs +++ b/Content.Server/Spawners/Components/RandomSpawnerComponent.cs @@ -1,24 +1,18 @@ using System.Collections.Generic; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Log; -using Robust.Shared.Maths; -using Robust.Shared.Random; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; using Robust.Shared.ViewVariables; namespace Content.Server.Spawners.Components { - [RegisterComponent] + [RegisterComponent, ComponentProtoName("RandomSpawner")] public class RandomSpawnerComponent : ConditionalSpawnerComponent { - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IRobustRandom _robustRandom = default!; - - public override string Name => "RandomSpawner"; - [ViewVariables(VVAccess.ReadWrite)] - [DataField("rarePrototypes")] + [DataField("rarePrototypes", customTypeSerializer:typeof(PrototypeIdListSerializer))] public List RarePrototypes { get; set; } = new(); [ViewVariables(VVAccess.ReadWrite)] @@ -28,43 +22,5 @@ namespace Content.Server.Spawners.Components [ViewVariables(VVAccess.ReadWrite)] [DataField("offset")] public float Offset { get; set; } = 0.2f; - - public override void Spawn() - { - if (RarePrototypes.Count > 0 && (RareChance == 1.0f || _robustRandom.Prob(RareChance))) - { - _entMan.SpawnEntity(_robustRandom.Pick(RarePrototypes), _entMan.GetComponent(Owner).Coordinates); - return; - } - - if (Chance != 1.0f && !_robustRandom.Prob(Chance)) - { - return; - } - - if (Prototypes.Count == 0) - { - Logger.Warning($"Prototype list in RandomSpawnerComponent is empty! Entity: {Owner}"); - return; - } - - if(!_entMan.Deleted(Owner)) - { - var random = IoCManager.Resolve(); - - var x_negative = random.Prob(0.5f) ? -1 : 1; - var y_negative = random.Prob(0.5f) ? -1 : 1; - - var entity = _entMan.SpawnEntity(_robustRandom.Pick(Prototypes), _entMan.GetComponent(Owner).Coordinates); - _entMan.GetComponent(entity).LocalPosition += new Vector2(random.NextFloat() * Offset * x_negative, random.NextFloat() * Offset * y_negative); - } - - } - - public override void MapInit() - { - Spawn(); - _entMan.QueueDeleteEntity(Owner); - } } } diff --git a/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs b/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs index 467061965c..ec36442feb 100644 --- a/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs +++ b/Content.Server/Spawners/EntitySystems/ConditionalSpawnerSystem.cs @@ -2,25 +2,110 @@ using Content.Server.GameTicking; using Content.Server.Spawners.Components; using JetBrains.Annotations; using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; +using Robust.Shared.Maths; +using Robust.Shared.Random; namespace Content.Server.Spawners.EntitySystems { [UsedImplicitly] - public class ConditionalSpawnerSystem : EntitySystem + public sealed class ConditionalSpawnerSystem : EntitySystem { + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly GameTicker _ticker = default!; + public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnRuleAdded); + SubscribeLocalEvent(OnCondSpawnMapInit); + SubscribeLocalEvent(OnRandSpawnMapInit); + } + + private void OnCondSpawnMapInit(EntityUid uid, ConditionalSpawnerComponent component, MapInitEvent args) + { + TrySpawn(component); + } + + private void OnRandSpawnMapInit(EntityUid uid, RandomSpawnerComponent component, MapInitEvent args) + { + Spawn(component); + EntityManager.QueueDeleteEntity(uid); } private void OnRuleAdded(GameRuleAddedEvent args) { foreach (var spawner in EntityManager.EntityQuery()) { - spawner.RuleAdded(args); + RuleAdded(spawner, args); } } + + public void RuleAdded(ConditionalSpawnerComponent component, GameRuleAddedEvent obj) + { + if(component.GameRules.Contains(obj.Rule.ID)) + Spawn(component); + } + + private void TrySpawn(ConditionalSpawnerComponent component) + { + if (component.GameRules.Count == 0) + { + Spawn(component); + return; + } + + foreach (var rule in component.GameRules) + { + if (!_ticker.HasGameRule(rule)) continue; + Spawn(component); + return; + } + } + + private void Spawn(ConditionalSpawnerComponent component) + { + if (component.Chance != 1.0f && !_robustRandom.Prob(component.Chance)) + return; + + if (component.Prototypes.Count == 0) + { + Logger.Warning($"Prototype list in ConditionalSpawnComponent is empty! Entity: {component.Owner}"); + return; + } + + if (!Deleted(component.Owner)) + EntityManager.SpawnEntity(_robustRandom.Pick(component.Prototypes), Transform(component.Owner).Coordinates); + } + + private void Spawn(RandomSpawnerComponent component) + { + if (component.RarePrototypes.Count > 0 && (component.RareChance == 1.0f || _robustRandom.Prob(component.RareChance))) + { + EntityManager.SpawnEntity(_robustRandom.Pick(component.RarePrototypes), Transform(component.Owner).Coordinates); + return; + } + + if (component.Chance != 1.0f && !_robustRandom.Prob(component.Chance)) + return; + + if (component.Prototypes.Count == 0) + { + Logger.Warning($"Prototype list in RandomSpawnerComponent is empty! Entity: {component.Owner}"); + return; + } + + if (Deleted(component.Owner)) return; + + var offset = component.Offset; + var xOffset = _robustRandom.NextFloat(-offset, offset); + var yOffset = _robustRandom.NextFloat(-offset, offset); + + var coordinates = Transform(component.Owner).Coordinates.Offset(new Vector2(xOffset, yOffset)); + + EntityManager.SpawnEntity(_robustRandom.Pick(component.Prototypes), coordinates); + } } }