diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs index 3ff68a1361..eb8cc0d241 100644 --- a/Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs @@ -2,6 +2,8 @@ using System.Linq; using System.Threading.Tasks; using Content.Server.GameObjects.Components.Destructible; +using Content.Server.GameObjects.Components.Destructible.Thresholds; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior; using Content.Shared.Damage; using Content.Shared.GameObjects.Components.Damage; using NUnit.Framework; @@ -31,13 +33,17 @@ namespace Content.IntegrationTests.Tests.Destructible 20: triggersOnce: false 50: - sound: /Audio/Effects/woodhit.ogg - spawn: - WoodPlank: - min: 1 - max: 1 - acts: [""Breakage""] triggersOnce: false + behaviors: + - !type:DoActsBehavior + acts: [""Breakage""] + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 - type: TestThresholdListener "; @@ -77,7 +83,7 @@ namespace Content.IntegrationTests.Tests.Destructible var sEntityManager = server.ResolveDependency(); var sMapManager = server.ResolveDependency(); - IEntity sDestructibleEntity = null; + IEntity sDestructibleEntity; IDamageableComponent sDamageableComponent = null; DestructibleComponent sDestructibleComponent = null; TestThresholdListenerComponent sThresholdListenerComponent = null; @@ -121,10 +127,7 @@ namespace Content.IntegrationTests.Tests.Destructible var threshold = msg.Threshold; // Check that it matches the YAML prototype - Assert.That(threshold.Acts, Is.EqualTo(0)); - Assert.That(threshold.Sound, Is.Null.Or.Empty); - Assert.That(threshold.Spawn, Is.Null); - Assert.That(threshold.SoundCollection, Is.Null.Or.Empty); + Assert.That(threshold.Behaviors, Is.Empty); Assert.That(threshold.Triggered, Is.True); sThresholdListenerComponent.ThresholdsReached.Clear(); @@ -142,14 +145,19 @@ namespace Content.IntegrationTests.Tests.Destructible threshold = msg.Threshold; // Check that it matches the YAML prototype - Assert.That(threshold.Acts, Is.EqualTo((int) ThresholdActs.Breakage)); - Assert.That(threshold.Sound, Is.EqualTo("/Audio/Effects/woodhit.ogg")); - Assert.That(threshold.Spawn, Is.Not.Null); - Assert.That(threshold.Spawn.Count, Is.EqualTo(1)); - Assert.That(threshold.Spawn.Single().Key, Is.EqualTo("WoodPlank")); - Assert.That(threshold.Spawn.Single().Value.Min, Is.EqualTo(1)); - Assert.That(threshold.Spawn.Single().Value.Max, Is.EqualTo(1)); - Assert.That(threshold.SoundCollection, Is.Null.Or.Empty); + Assert.That(threshold.Behaviors, Has.Count.EqualTo(3)); + + var actsThreshold = (DoActsBehavior) threshold.Behaviors[0]; + var soundThreshold = (PlaySoundBehavior) threshold.Behaviors[1]; + var spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[2]; + + Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage)); + Assert.That(soundThreshold.Sound, Is.EqualTo("/Audio/Effects/woodhit.ogg")); + Assert.That(spawnThreshold.Spawn, Is.Not.Null); + Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1)); + Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo("WoodPlank")); + Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1)); + Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1)); Assert.That(threshold.Triggered, Is.True); sThresholdListenerComponent.ThresholdsReached.Clear(); @@ -192,14 +200,20 @@ namespace Content.IntegrationTests.Tests.Destructible threshold = msg.Threshold; // Check that it matches the YAML prototype - Assert.That(threshold.Acts, Is.EqualTo((int) ThresholdActs.Breakage)); - Assert.That(threshold.Sound, Is.EqualTo("/Audio/Effects/woodhit.ogg")); - Assert.That(threshold.Spawn, Is.Not.Null); - Assert.That(threshold.Spawn.Count, Is.EqualTo(1)); - Assert.That(threshold.Spawn.Single().Key, Is.EqualTo("WoodPlank")); - Assert.That(threshold.Spawn.Single().Value.Min, Is.EqualTo(1)); - Assert.That(threshold.Spawn.Single().Value.Max, Is.EqualTo(1)); - Assert.That(threshold.SoundCollection, Is.Null.Or.Empty); + Assert.That(threshold.Behaviors, Has.Count.EqualTo(3)); + + actsThreshold = (DoActsBehavior) threshold.Behaviors[0]; + soundThreshold = (PlaySoundBehavior) threshold.Behaviors[1]; + spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[2]; + + // Check that it matches the YAML prototype + Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage)); + Assert.That(soundThreshold.Sound, Is.EqualTo("/Audio/Effects/woodhit.ogg")); + Assert.That(spawnThreshold.Spawn, Is.Not.Null); + Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1)); + Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo("WoodPlank")); + Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1)); + Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1)); Assert.That(threshold.Triggered, Is.True); // Reset thresholds reached @@ -227,11 +241,7 @@ namespace Content.IntegrationTests.Tests.Destructible threshold = msg.Threshold; // Check that it matches the YAML prototype - Assert.That(threshold.Acts, Is.EqualTo(0)); - Assert.That(threshold.Sound, Is.Null.Or.Empty); - Assert.That(threshold.Spawn, Is.Null); - Assert.That(threshold.SoundCollection, Is.Null.Or.Empty); - Assert.That(threshold.Triggered, Is.True); + Assert.That(threshold.Behaviors, Is.Empty); // Verify the second one, should be the highest one (50) msg = sThresholdListenerComponent.ThresholdsReached[1]; @@ -242,15 +252,20 @@ namespace Content.IntegrationTests.Tests.Destructible threshold = msg.Threshold; + Assert.That(threshold.Behaviors, Has.Count.EqualTo(3)); + + actsThreshold = (DoActsBehavior) threshold.Behaviors[0]; + soundThreshold = (PlaySoundBehavior) threshold.Behaviors[1]; + spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[2]; + // Check that it matches the YAML prototype - Assert.That(threshold.Acts, Is.EqualTo((int) ThresholdActs.Breakage)); - Assert.That(threshold.Sound, Is.EqualTo("/Audio/Effects/woodhit.ogg")); - Assert.That(threshold.Spawn, Is.Not.Null); - Assert.That(threshold.Spawn.Count, Is.EqualTo(1)); - Assert.That(threshold.Spawn.Single().Key, Is.EqualTo("WoodPlank")); - Assert.That(threshold.Spawn.Single().Value.Min, Is.EqualTo(1)); - Assert.That(threshold.Spawn.Single().Value.Max, Is.EqualTo(1)); - Assert.That(threshold.SoundCollection, Is.Null.Or.Empty); + Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage)); + Assert.That(soundThreshold.Sound, Is.EqualTo("/Audio/Effects/woodhit.ogg")); + Assert.That(spawnThreshold.Spawn, Is.Not.Null); + Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1)); + Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo("WoodPlank")); + Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1)); + Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1)); Assert.That(threshold.Triggered, Is.True); // Reset thresholds reached diff --git a/Content.Server/GameObjects/Components/Destructible/ActsFlags.cs b/Content.Server/GameObjects/Components/Destructible/ActsFlags.cs deleted file mode 100644 index 6dd944c358..0000000000 --- a/Content.Server/GameObjects/Components/Destructible/ActsFlags.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Content.Server.GameObjects.Components.Destructible -{ - public sealed class ActsFlags { } -} diff --git a/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs b/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs index 05060b4880..bde01c3bbe 100644 --- a/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs +++ b/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs @@ -1,12 +1,11 @@ #nullable enable using System.Collections.Generic; +using Content.Server.GameObjects.Components.Destructible.Thresholds; +using Content.Server.GameObjects.EntitySystems; using Content.Shared.GameObjects.Components.Damage; -using Content.Shared.GameObjects.EntitySystems; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Random; -using Robust.Shared.IoC; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -19,9 +18,7 @@ namespace Content.Server.GameObjects.Components.Destructible [RegisterComponent] public class DestructibleComponent : Component { - [Dependency] private readonly IRobustRandom _random = default!; - - private ActSystem _actSystem = default!; + private DestructibleSystem _destructibleSystem = default!; public override string Name => "Destructible"; @@ -47,7 +44,7 @@ namespace Content.Server.GameObjects.Components.Destructible { base.Initialize(); - _actSystem = EntitySystem.Get(); + _destructibleSystem = EntitySystem.Get(); } public override void HandleMessage(ComponentMessage message, IComponent? component) @@ -83,7 +80,7 @@ namespace Content.Server.GameObjects.Components.Destructible var thresholdMessage = new DestructibleThresholdReachedMessage(this, threshold, msg.Damageable.TotalDamage, damage); SendMessage(thresholdMessage); - threshold.Trigger(Owner, _random, _actSystem); + threshold.Trigger(Owner, _destructibleSystem); } } diff --git a/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs b/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs index dd58f49974..9321e95a00 100644 --- a/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs +++ b/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs @@ -1,4 +1,5 @@ -using Robust.Shared.GameObjects; +using Content.Server.GameObjects.Components.Destructible.Thresholds; +using Robust.Shared.GameObjects; namespace Content.Server.GameObjects.Components.Destructible { diff --git a/Content.Server/GameObjects/Components/Destructible/Threshold.cs b/Content.Server/GameObjects/Components/Destructible/Threshold.cs deleted file mode 100644 index b03c6cd2c2..0000000000 --- a/Content.Server/GameObjects/Components/Destructible/Threshold.cs +++ /dev/null @@ -1,148 +0,0 @@ -#nullable enable -using System.Collections.Generic; -using Content.Server.GameObjects.Components.Stack; -using Content.Shared.Audio; -using Content.Shared.GameObjects.EntitySystems; -using Content.Shared.Utility; -using Robust.Server.GameObjects.EntitySystems; -using Robust.Shared.GameObjects.Systems; -using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Random; -using Robust.Shared.Interfaces.Serialization; -using Robust.Shared.Serialization; -using Robust.Shared.ViewVariables; - -namespace Content.Server.GameObjects.Components.Destructible -{ - public class Threshold : IExposeData - { - /// - /// Entities spawned on reaching this threshold, from a min to a max. - /// - [ViewVariables] public Dictionary? Spawn; - - /// - /// Sound played upon destruction. - /// - [ViewVariables] public string Sound = string.Empty; - - /// - /// Used instead of if specified. - /// - [ViewVariables] public string SoundCollection = string.Empty; - - /// - /// What acts this threshold should trigger upon activation. - /// See . - /// - [ViewVariables] public int Acts; - - /// - /// Whether or not this threshold has already been triggered. - /// - [ViewVariables] public bool Triggered; - - /// - /// Whether or not this threshold only triggers once. - /// If false, it will trigger again once the entity is healed - /// and then damaged to reach this threshold once again. - /// It will not repeatedly trigger as damage rises beyond that. - /// - [ViewVariables] public bool TriggersOnce; - - public void ExposeData(ObjectSerializer serializer) - { - serializer.DataField(ref Spawn, "spawn", null); - serializer.DataField(ref Sound, "sound", string.Empty); - serializer.DataField(ref SoundCollection, "soundCollection", string.Empty); - serializer.DataField(ref Acts, "acts", 0, WithFormat.Flags()); - serializer.DataField(ref Triggered, "triggered", false); - serializer.DataField(ref TriggersOnce, "triggersOnce", false); - } - - /// - /// Triggers this threshold. - /// - /// The entity that owns this threshold. - /// - /// An instance of to get randomness from, if relevant. - /// - /// - /// An instance of to call acts on, if relevant. - /// - public void Trigger(IEntity owner, IRobustRandom random, ActSystem actSystem) - { - Triggered = true; - - PlaySound(owner); - DoSpawn(owner, random); - DoActs(owner, actSystem); - } - - private void PlaySound(IEntity owner) - { - var pos = owner.Transform.Coordinates; - var actualSound = string.Empty; - - if (SoundCollection != string.Empty) - { - actualSound = AudioHelpers.GetRandomFileFromSoundCollection(SoundCollection); - } - else if (Sound != string.Empty) - { - actualSound = Sound; - } - - if (actualSound != string.Empty) - { - EntitySystem.Get().PlayAtCoords(actualSound, pos, AudioHelpers.WithVariation(0.125f)); - } - } - - private void DoSpawn(IEntity owner, IRobustRandom random) - { - if (Spawn == null) - { - return; - } - - foreach (var (key, value) in Spawn) - { - var count = value.Min >= value.Max - ? value.Min - : random.Next(value.Min, value.Max + 1); - - if (count == 0) continue; - - if (EntityPrototypeHelpers.HasComponent(key)) - { - var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates); - var stack = spawned.GetComponent(); - stack.Count = count; - spawned.RandomOffset(0.5f); - } - else - { - for (var i = 0; i < count; i++) - { - var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates); - spawned.RandomOffset(0.5f); - } - } - } - } - - private void DoActs(IEntity owner, ActSystem acts) - { - if ((Acts & (int) ThresholdActs.Breakage) != 0) - { - acts.HandleBreakage(owner); - } - - if ((Acts & (int) ThresholdActs.Destruction) != 0) - { - acts.HandleDestruction(owner); - } - } - } -} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/ActsFlags.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/ActsFlags.cs new file mode 100644 index 0000000000..37ebda2e56 --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/ActsFlags.cs @@ -0,0 +1,4 @@ +namespace Content.Server.GameObjects.Components.Destructible.Thresholds +{ + public sealed class ActsFlags { } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/DoActsBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/DoActsBehavior.cs new file mode 100644 index 0000000000..e4dd894598 --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/DoActsBehavior.cs @@ -0,0 +1,45 @@ +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.EntitySystems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +{ + public class DoActsBehavior : IThresholdBehavior + { + private int _acts; + + /// + /// What acts should be triggered upon activation. + /// See . + /// + public ThresholdActs Acts + { + get => (ThresholdActs) _acts; + set => _acts = (int) value; + } + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(ref _acts, "acts", 0, WithFormat.Flags()); + } + + public bool HasAct(ThresholdActs act) + { + return (_acts & (int) act) != 0; + } + + public void Trigger(IEntity owner, DestructibleSystem system) + { + if (HasAct(ThresholdActs.Breakage)) + { + system.ActSystem.HandleBreakage(owner); + } + + if (HasAct(ThresholdActs.Destruction)) + { + system.ActSystem.HandleDestruction(owner); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/IThresholdBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/IThresholdBehavior.cs new file mode 100644 index 0000000000..d857d45bbd --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/IThresholdBehavior.cs @@ -0,0 +1,11 @@ +using Content.Server.GameObjects.EntitySystems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +{ + public interface IThresholdBehavior : IExposeData + { + void Trigger(IEntity owner, DestructibleSystem system); + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundBehavior.cs new file mode 100644 index 0000000000..0ea803f937 --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundBehavior.cs @@ -0,0 +1,32 @@ +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Audio; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +{ + public class PlaySoundBehavior : IThresholdBehavior + { + /// + /// Sound played upon destruction. + /// + public string Sound { get; set; } + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(this, x => x.Sound, "sound", string.Empty); + } + + public void Trigger(IEntity owner, DestructibleSystem system) + { + if (string.IsNullOrEmpty(Sound)) + { + return; + } + + var pos = owner.Transform.Coordinates; + + system.AudioSystem.PlayAtCoords(Sound, pos, AudioHelpers.WithVariation(0.125f)); + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundCollectionBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundCollectionBehavior.cs new file mode 100644 index 0000000000..5a02635b4d --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundCollectionBehavior.cs @@ -0,0 +1,33 @@ +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Audio; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +{ + public class PlaySoundCollectionBehavior : IThresholdBehavior + { + /// + /// Sound collection from which to pick a random sound to play. + /// + private string SoundCollection { get; set; } + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(this, x => x.SoundCollection, "soundCollection", string.Empty); + } + + public void Trigger(IEntity owner, DestructibleSystem system) + { + if (string.IsNullOrEmpty(SoundCollection)) + { + return; + } + + var sound = AudioHelpers.GetRandomFileFromSoundCollection(SoundCollection); + var pos = owner.Transform.Coordinates; + + system.AudioSystem.PlayAtCoords(sound, pos, AudioHelpers.WithVariation(0.125f)); + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpawnEntitiesBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpawnEntitiesBehavior.cs new file mode 100644 index 0000000000..9864db5175 --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpawnEntitiesBehavior.cs @@ -0,0 +1,51 @@ +#nullable enable +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Stack; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Utility; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +{ + public class SpawnEntitiesBehavior : IThresholdBehavior + { + /// + /// Entities spawned on reaching this threshold, from a min to a max. + /// + public Dictionary Spawn { get; set; } = new(); + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(this, x => x.Spawn, "spawn", new Dictionary()); + } + + public void Trigger(IEntity owner, DestructibleSystem system) + { + foreach (var (entityId, minMax) in Spawn) + { + var count = minMax.Min >= minMax.Max + ? minMax.Min + : system.Random.Next(minMax.Min, minMax.Max + 1); + + if (count == 0) continue; + + if (EntityPrototypeHelpers.HasComponent(entityId)) + { + var spawned = owner.EntityManager.SpawnEntity(entityId, owner.Transform.Coordinates); + var stack = spawned.GetComponent(); + stack.Count = count; + spawned.RandomOffset(0.5f); + } + else + { + for (var i = 0; i < count; i++) + { + var spawned = owner.EntityManager.SpawnEntity(entityId, owner.Transform.Coordinates); + spawned.RandomOffset(0.5f); + } + } + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/MinMax.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs similarity index 86% rename from Content.Server/GameObjects/Components/Destructible/MinMax.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs index 0a7fa87b4d..c7ef3c7fd0 100644 --- a/Content.Server/GameObjects/Components/Destructible/MinMax.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs @@ -2,7 +2,7 @@ using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; -namespace Content.Server.GameObjects.Components.Destructible +namespace Content.Server.GameObjects.Components.Destructible.Thresholds { public struct MinMax : IExposeData { diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs new file mode 100644 index 0000000000..72bce9159e --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs @@ -0,0 +1,57 @@ +#nullable enable +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior; +using Content.Server.GameObjects.EntitySystems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Serialization; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds +{ + public class Threshold : IExposeData + { + /// + /// Whether or not this threshold has already been triggered. + /// + [ViewVariables] public bool Triggered; + + /// + /// Whether or not this threshold only triggers once. + /// If false, it will trigger again once the entity is healed + /// and then damaged to reach this threshold once again. + /// It will not repeatedly trigger as damage rises beyond that. + /// + [ViewVariables] public bool TriggersOnce; + + /// + /// Behaviors to activate once this threshold is triggered. + /// + [ViewVariables] public List Behaviors = new(); + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(ref Triggered, "triggered", false); + serializer.DataField(ref TriggersOnce, "triggersOnce", false); + serializer.DataField(ref Behaviors, "behaviors", new List()); + } + + /// + /// Triggers this threshold. + /// + /// The entity that owns this threshold. + /// + /// An instance of to get dependency and + /// system references from, if relevant. + /// + public void Trigger(IEntity owner, DestructibleSystem system) + { + Triggered = true; + + foreach (var behavior in Behaviors) + { + behavior.Trigger(owner, system); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/ThresholdActs.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/ThresholdActs.cs similarity index 68% rename from Content.Server/GameObjects/Components/Destructible/ThresholdActs.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/ThresholdActs.cs index 67aa5e5a4e..02a89fc803 100644 --- a/Content.Server/GameObjects/Components/Destructible/ThresholdActs.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/ThresholdActs.cs @@ -1,13 +1,13 @@ using System; using Robust.Shared.Serialization; -namespace Content.Server.GameObjects.Components.Destructible +namespace Content.Server.GameObjects.Components.Destructible.Thresholds { [Flags, FlagsFor(typeof(ActsFlags))] [Serializable] public enum ThresholdActs { - Invalid = 0, + None = 0, Breakage, Destruction } diff --git a/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs b/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs new file mode 100644 index 0000000000..412beefddf --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs @@ -0,0 +1,26 @@ +using Content.Shared.GameObjects.EntitySystems; +using JetBrains.Annotations; +using Robust.Server.GameObjects.EntitySystems; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.Random; +using Robust.Shared.IoC; + +namespace Content.Server.GameObjects.EntitySystems +{ + [UsedImplicitly] + public class DestructibleSystem : EntitySystem + { + [Dependency] public readonly IRobustRandom Random = default!; + + public AudioSystem AudioSystem { get; private set; } + public ActSystem ActSystem { get; private set; } + + public override void Initialize() + { + base.Initialize(); + + AudioSystem = Get(); + ActSystem = Get(); + } + } +} \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml index ebbb78ee25..0d60674560 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml @@ -61,7 +61,9 @@ - type: Destructible thresholds: 500: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] placement: mode: SnapgridCenter diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml b/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml index f69842afd4..173ef58fd1 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml @@ -32,6 +32,8 @@ - type: Destructible thresholds: 75: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] placement: mode: SnapgridCenter diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml b/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml index 9994ca8fbd..713433842b 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml @@ -24,12 +24,16 @@ - type: Destructible thresholds: 30: - sound: /Audio/Effects/woodhit.ogg - spawn: - WoodPlank: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 - type: Occluder sizeX: 32 sizeY: 32 diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml b/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml index f6a1d06dea..aa61941654 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml @@ -25,7 +25,9 @@ - type: Destructible thresholds: 50: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: UserInterface interfaces: - key: enum.InstrumentUiKey.Key diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/pilot_chair.yml b/Resources/Prototypes/Entities/Constructible/Furniture/pilot_chair.yml index 0ee346bd74..d275ab8f66 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/pilot_chair.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/pilot_chair.yml @@ -16,7 +16,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: ShuttleController - type: Strap position: Stand diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml index 86a9e86708..858df8f07e 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml @@ -35,7 +35,9 @@ - type: Destructible thresholds: 50: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: chair diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml b/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml index 42ea7246b6..2a25501675 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml @@ -32,12 +32,16 @@ - type: Destructible thresholds: 30: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: entity id: Shelf @@ -73,9 +77,13 @@ - type: Destructible thresholds: 30: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml b/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml index 365320906c..e003cd0813 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml @@ -40,12 +40,16 @@ - type: Destructible thresholds: 15: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: entity id: TableFrame @@ -62,12 +66,16 @@ - type: Destructible thresholds: 1: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: Construction graph: Tables node: TableFrame @@ -87,12 +95,16 @@ - type: Destructible thresholds: 1: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: entity id: TableMetal @@ -109,12 +121,16 @@ - type: Destructible thresholds: 15: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: Construction graph: Tables node: MetalTable @@ -134,12 +150,16 @@ - type: Destructible thresholds: 75: - sound: /Audio/Effects/metalbreak.ogg - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: Construction graph: Tables node: ReinforcedTable @@ -159,12 +179,16 @@ - type: Destructible thresholds: 5: - sound: /Audio/Effects/glass_break2.ogg - spawn: - ShardGlass: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/glass_break2.ogg + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 - type: Construction graph: Tables node: GlassTable @@ -184,12 +208,16 @@ - type: Destructible thresholds: 20: - sound: /Audio/Effects/glass_break2.ogg - spawn: - ShardGlass: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/glass_break2.ogg + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 - type: Construction graph: Tables node: RGlassTable @@ -209,12 +237,16 @@ - type: Destructible thresholds: 15: - sound: /Audio/Effects/woodhit.ogg - spawn: - WoodPlank: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 - type: Construction graph: Tables node: WoodTable @@ -234,12 +266,16 @@ - type: Destructible thresholds: 15: - sound: /Audio/Effects/woodhit.ogg - spawn: - WoodPlank: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 - type: Construction graph: Tables node: PokerTable @@ -259,8 +295,11 @@ - type: Destructible thresholds: 50: - sound: /Audio/Effects/picaxe2.ogg - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/picaxe2.ogg - type: entity id: TableDebug @@ -277,4 +316,6 @@ - type: Destructible thresholds: 1: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml b/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml index 9009cdcbda..a38ca76f30 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml @@ -14,7 +14,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: GasCanisterPort - type: entity diff --git a/Resources/Prototypes/Entities/Constructible/Ground/gascanisters.yml b/Resources/Prototypes/Entities/Constructible/Ground/gascanisters.yml index 90b2e9631c..4c8e4247a7 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/gascanisters.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/gascanisters.yml @@ -14,7 +14,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: GasCanister - type: Anchorable - type: Pullable diff --git a/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml b/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml index af0700707e..099a3fbfc7 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml @@ -24,5 +24,7 @@ - type: Destructible thresholds: 50: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: KitchenSpike diff --git a/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml b/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml index b9afde3f46..70c92e76a5 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml @@ -15,7 +15,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite - type: Appearance visuals: diff --git a/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml b/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml index d40aab4b39..31c2f366af 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml @@ -14,7 +14,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite sprite: Constructible/Atmos/pump.rsi - type: Icon diff --git a/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml b/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml index b9eddc780d..9a6858382f 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml @@ -24,7 +24,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity parent: ScrubberBase diff --git a/Resources/Prototypes/Entities/Constructible/Ground/vents.yml b/Resources/Prototypes/Entities/Constructible/Ground/vents.yml index 3a2797a12c..030275ec7c 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/vents.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/vents.yml @@ -24,7 +24,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity parent: VentBase diff --git a/Resources/Prototypes/Entities/Constructible/Power/cloning_machine.yml b/Resources/Prototypes/Entities/Constructible/Power/cloning_machine.yml index 19cf39ba88..c340c99681 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/cloning_machine.yml @@ -35,7 +35,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: CloningPodVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Power/computers.yml b/Resources/Prototypes/Entities/Constructible/Power/computers.yml index d6ef207860..7a18538c45 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/computers.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/computers.yml @@ -99,7 +99,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: BreakableConstruction node: monitorBroken - type: Sprite diff --git a/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml b/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml index 22f67230c8..04e78bfc1d 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml @@ -32,7 +32,9 @@ - type: Destructible thresholds: 100: - acts: ["Breakage"] + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: Anchorable - type: entity diff --git a/Resources/Prototypes/Entities/Constructible/Power/medical_scanner.yml b/Resources/Prototypes/Entities/Constructible/Power/medical_scanner.yml index 79558407d9..fce14c14e7 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/medical_scanner.yml @@ -36,7 +36,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: MedicalScannerVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Power/power_base.yml b/Resources/Prototypes/Entities/Constructible/Power/power_base.yml index 01e5d25777..cb671c9513 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/power_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/power_base.yml @@ -239,6 +239,8 @@ - type: Destructible thresholds: 100: - acts: ["Breakage"] + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: Anchorable - type: Pullable diff --git a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml index 5cefa79338..863a33a527 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml @@ -33,7 +33,9 @@ - type: Destructible thresholds: 50: - acts: ["Breakage"] + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: UserInterface interfaces: - key: enum.VendingMachineUiKey.Key diff --git a/Resources/Prototypes/Entities/Constructible/Power/wires.yml b/Resources/Prototypes/Entities/Constructible/Power/wires.yml index fc4e98d519..398712c0e1 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/wires.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/wires.yml @@ -23,7 +23,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: SubFloorHide - type: entity @@ -52,11 +54,14 @@ - type: Destructible thresholds: 100: - spawn: - HVWireStack1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + HVWireStack1: + min: 1 + max: 1 - type: entity parent: WireBase @@ -86,11 +91,14 @@ - type: Destructible thresholds: 100: - spawn: - MVWireStack1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + MVWireStack1: + min: 1 + max: 1 - type: entity parent: WireBase @@ -122,8 +130,11 @@ - type: Destructible thresholds: 100: - spawn: - ApcExtensionCableStack1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + ApcExtensionCableStack1: + min: 1 + max: 1 diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_controller.yml b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_controller.yml index 12c047157e..bcfbc3d1f9 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_controller.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_controller.yml @@ -26,7 +26,9 @@ - type: Destructible thresholds: 500: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: SnapGrid offset: Center - type: Anchorable diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_structure.yml b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_structure.yml index f7ef435d94..762aa88d8a 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_structure.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_structure.yml @@ -26,11 +26,14 @@ - type: Destructible thresholds: 500: - spawn: - AMEPart: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + AMEPart: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: ["Destruction"] - type: SnapGrid offset: Center - type: Airtight diff --git a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml index 16365995f2..81a14bcffb 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml @@ -22,7 +22,9 @@ - type: Destructible thresholds: 75: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Anchorable - type: Pullable - type: PowerReceiver diff --git a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml index fc376d5ff1..056608284e 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml @@ -36,11 +36,14 @@ - type: Destructible thresholds: 50: - spawn: - chem_master_broken: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + chem_master_broken: + min: 1 + max: 1 - type: UserInterface interfaces: - key: enum.ChemMasterUiKey.Key @@ -82,11 +85,14 @@ - type: Destructible thresholds: 25: - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: UserInterface interfaces: - key: enum.ChemMasterUiKey.Key diff --git a/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml b/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml index d3a603a3ce..42260b9e78 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml @@ -18,7 +18,9 @@ - type: Destructible thresholds: 100: - acts: ["Breakage"] + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: Rotatable - type: Pullable @@ -150,7 +152,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: DisposalUnitVisualizer @@ -389,7 +393,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: DisposalUnitVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml index 8517c6da06..cfc150fb63 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml @@ -34,7 +34,9 @@ - type: Destructible thresholds: 150: - acts: ["Breakage"] + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: GravityGenerator - type: UserInterface interfaces: diff --git a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml index d25bee0833..db7e51649b 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml @@ -28,7 +28,9 @@ - type: Destructible thresholds: 50: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite sprite: Constructible/Hydroponics/hydro_tools.rsi state: soil diff --git a/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml b/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml index bebbb88213..6798e6fd6a 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml @@ -43,7 +43,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: StorageVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml b/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml index d897b4e9cb..f0b3cd8b06 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml @@ -40,7 +40,9 @@ - type: Destructible thresholds: 100: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: StorageVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml b/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml index 42ce928c1d..98d0b7efda 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml @@ -28,7 +28,9 @@ - type: Destructible thresholds: 10: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: SolutionContainer maxVol: 1500 caps: RemoveFrom diff --git a/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml b/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml index d818ed65a1..a4f7617608 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml @@ -19,7 +19,9 @@ - type: Destructible thresholds: 100: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Occluder sizeX: 32 sizeY: 32 diff --git a/Resources/Prototypes/Entities/Constructible/Walls/girder.yml b/Resources/Prototypes/Entities/Constructible/Walls/girder.yml index ed944c8b94..2bdd1fbaee 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/girder.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/girder.yml @@ -30,11 +30,14 @@ - type: Destructible thresholds: 50: - spawn: - SteelSheet1: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: SnapGrid offset: Edge placement: diff --git a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml index 52daca2104..9617beec97 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml @@ -41,7 +41,9 @@ - type: Destructible thresholds: 50: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: small light @@ -68,7 +70,9 @@ - type: Destructible thresholds: 25: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: unpowered small light @@ -87,4 +91,6 @@ - type: Destructible thresholds: 25: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml b/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml index 29a0fbbf45..0feb5c8737 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml @@ -30,7 +30,9 @@ - type: Destructible thresholds: 100: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: BreakableConstruction node: start - type: SnapGrid diff --git a/Resources/Prototypes/Entities/Constructible/Walls/signs.yml b/Resources/Prototypes/Entities/Constructible/Walls/signs.yml index 88fbe58407..ce9012762a 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/signs.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/signs.yml @@ -13,7 +13,9 @@ - type: Destructible thresholds: 5: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite drawdepth: WallTops sprite: Constructible/Misc/decals.rsi diff --git a/Resources/Prototypes/Entities/Constructible/Walls/walls.yml b/Resources/Prototypes/Entities/Constructible/Walls/walls.yml index e6dbaeaf0a..de9b9a5114 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/walls.yml @@ -49,11 +49,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: brick @@ -72,11 +75,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: clock @@ -95,11 +101,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: clown @@ -119,11 +128,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: cult @@ -142,11 +154,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: debug @@ -165,11 +180,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: diamond @@ -189,11 +207,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: gold @@ -212,11 +233,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: ice @@ -235,11 +259,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: metal @@ -258,11 +285,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: plasma @@ -281,11 +311,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: plastic @@ -309,7 +342,9 @@ - type: Destructible thresholds: 600: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: BreakableConstruction node: girder - type: ReinforcedWall @@ -335,11 +370,14 @@ - type: Destructible thresholds: 1000: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: riveted @@ -358,11 +396,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: sandstone @@ -381,11 +422,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: silver @@ -408,7 +452,9 @@ - type: Destructible thresholds: 300: - acts: [ "Destruction" ] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: BreakableConstruction node: girder destroySound: /Audio/Effects/metalbreak.ogg @@ -430,11 +476,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: uranium @@ -453,11 +502,14 @@ - type: Destructible thresholds: 300: - spawn: - Girder: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 - type: IconSmooth key: walls base: wood diff --git a/Resources/Prototypes/Entities/Constructible/Walls/windows.yml b/Resources/Prototypes/Entities/Constructible/Walls/windows.yml index f34d535d3a..865aff6339 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/windows.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/windows.yml @@ -31,12 +31,16 @@ - type: Destructible thresholds: 15: - soundCollection: WindowBreak - spawn: - ShardGlass: - min: 1 - max: 2 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundCollectionBehavior + soundCollection: WindowBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 - type: SnapGrid offset: Center - type: Airtight @@ -65,12 +69,16 @@ - type: Destructible thresholds: 75: - soundCollection: WindowBreak - spawn: - ShardGlassReinforced: - min: 1 - max: 2 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundCollectionBehavior + soundCollection: WindowBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlassReinforced: + min: 1 + max: 2 - type: Window base: rwindow maxDamage: 75 @@ -93,12 +101,16 @@ - type: Destructible thresholds: 100: - soundCollection: WindowBreak - spawn: - ShardGlassPhoron: - min: 1 - max: 2 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundCollectionBehavior + soundCollection: WindowBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlassPhoron: + min: 1 + max: 2 resistances: metallicResistances - type: Window base: pwindow diff --git a/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml index 1130d17db7..5b9eaa4c92 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml @@ -28,12 +28,16 @@ - type: Destructible thresholds: 5: - acts: [ "Destruction" ] - soundCollection: WindowBreak - spawn: - ShardGlass: - min: 1 - max: 1 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundCollectionBehavior + soundCollection: WindowBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 - type: DamageOnLand amount: 5 - type: DamageOtherOnHit diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index 64c5af5ec3..54b10a78c9 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -132,12 +132,16 @@ - type: Destructible thresholds: 10: - sound: /Audio/Effects/glass_break1.ogg - spawn: - FloodlightBroken: - min: 1 - max: 1 - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/glass_break1.ogg + - !type:SpawnEntitiesBehavior + spawn: + FloodlightBroken: + min: 1 + max: 1 - type: Appearance visuals: - type: FlashLightVisualizer @@ -157,12 +161,16 @@ - type: Destructible thresholds: 20: - spawn: - SteelSheet1: - min: 1 - max: 1 - sound: /Audio/Effects/metalbreak.ogg - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 - type: Physics shapes: - !type:PhysShapeAabb diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml index acc315f254..75426cdadc 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml @@ -26,7 +26,9 @@ - type: Destructible thresholds: 10: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer @@ -56,7 +58,9 @@ - type: Destructible thresholds: 10: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer @@ -86,7 +90,9 @@ - type: Destructible thresholds: 10: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer @@ -115,7 +121,9 @@ - type: Destructible thresholds: 50: - acts: ["Destruction"] + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer