diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleDamageClassTest.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleDamageClassTest.cs new file mode 100644 index 0000000000..b7fe431931 --- /dev/null +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleDamageClassTest.cs @@ -0,0 +1,170 @@ +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers; +using Content.Shared.Damage; +using Content.Shared.GameObjects.Components.Damage; +using NUnit.Framework; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes; + +namespace Content.IntegrationTests.Tests.Destructible +{ + [TestFixture] + [TestOf(typeof(TotalDamageClassesTrigger))] + public class DestructibleDamageClassTest : ContentIntegrationTest + { + [Test] + public async Task Test() + { + var server = StartServerDummyTicker(new ServerContentIntegrationOption + { + ExtraPrototypes = Prototypes, + ContentBeforeIoC = () => + { + IoCManager.Resolve().Register(); + } + }); + + await server.WaitIdleAsync(); + + var sEntityManager = server.ResolveDependency(); + var sMapManager = server.ResolveDependency(); + + IEntity sDestructibleEntity; + IDamageableComponent sDamageableComponent = null; + TestThresholdListenerComponent sThresholdListenerComponent = null; + + await server.WaitPost(() => + { + var mapId = new MapId(1); + var coordinates = new MapCoordinates(0, 0, mapId); + sMapManager.CreateMap(mapId); + + sDestructibleEntity = sEntityManager.SpawnEntity(DestructibleDamageClassEntityId, coordinates); + sDamageableComponent = sDestructibleEntity.GetComponent(); + sThresholdListenerComponent = sDestructibleEntity.GetComponent(); + }); + + await server.WaitRunTicks(5); + + await server.WaitAssertion(() => + { + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + }); + + await server.WaitAssertion(() => + { + // Raise brute damage to 5 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 5, true)); + + // No thresholds reached yet, the earliest one is at 10 damage + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise brute damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 5, true)); + + // No threshold reached, burn needs to be 10 as well + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise burn damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Burn, 10, true)); + + // One threshold reached, brute 10 + burn 10 + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + // Threshold brute 10 + burn 10 + var msg = sThresholdListenerComponent.ThresholdsReached[0]; + var threshold = msg.Threshold; + + // Check that it matches the YAML prototype + Assert.That(threshold.Behaviors, Is.Empty); + Assert.NotNull(threshold.Trigger); + Assert.That(threshold.Triggered, Is.True); + Assert.IsInstanceOf(threshold.Trigger); + + sThresholdListenerComponent.ThresholdsReached.Clear(); + + // Raise brute damage to 20 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise burn damage to 20 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Burn, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Lower brute damage to 0 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, -20, true)); + + // No new thresholds reached, healing should not trigger it + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise brute damage back up to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 10, true)); + + // 10 brute + 10 burn threshold reached, brute was healed and brought back to its threshold amount and slash stayed the same + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + sThresholdListenerComponent.ThresholdsReached.Clear(); + + // Heal both classes of damage to 0 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, -10, true)); + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Burn, -20, true)); + + // No new thresholds reached, healing should not trigger it + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise brute damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise burn damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Burn, 10, true)); + + // Both classes of damage were healed and then raised again, the threshold should have been reached as triggers once is default false + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + // Threshold brute 10 + burn 10 + msg = sThresholdListenerComponent.ThresholdsReached[0]; + threshold = msg.Threshold; + + // Check that it matches the YAML prototype + Assert.That(threshold.Behaviors, Is.Empty); + Assert.NotNull(threshold.Trigger); + Assert.That(threshold.Triggered, Is.True); + Assert.IsInstanceOf(threshold.Trigger); + + sThresholdListenerComponent.ThresholdsReached.Clear(); + + // Change triggers once to true + threshold.TriggersOnce = true; + + // Heal brute and burn back to 0 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, -10, true)); + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Burn, -10, true)); + + // No new thresholds reached from healing + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise brute damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise burn damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Burn, 10, true)); + + // No new thresholds reached as triggers once is set to true and it already triggered before + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + }); + } + } +} diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleDamageTypeTest.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleDamageTypeTest.cs new file mode 100644 index 0000000000..3ecbacfa30 --- /dev/null +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleDamageTypeTest.cs @@ -0,0 +1,170 @@ +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers; +using Content.Shared.Damage; +using Content.Shared.GameObjects.Components.Damage; +using NUnit.Framework; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes; + +namespace Content.IntegrationTests.Tests.Destructible +{ + [TestFixture] + [TestOf(typeof(TotalDamageTypesTrigger))] + public class DestructibleDamageTypeTest : ContentIntegrationTest + { + [Test] + public async Task Test() + { + var server = StartServerDummyTicker(new ServerContentIntegrationOption + { + ExtraPrototypes = Prototypes, + ContentBeforeIoC = () => + { + IoCManager.Resolve().Register(); + } + }); + + await server.WaitIdleAsync(); + + var sEntityManager = server.ResolveDependency(); + var sMapManager = server.ResolveDependency(); + + IEntity sDestructibleEntity; + IDamageableComponent sDamageableComponent = null; + TestThresholdListenerComponent sThresholdListenerComponent = null; + + await server.WaitPost(() => + { + var mapId = new MapId(1); + var coordinates = new MapCoordinates(0, 0, mapId); + sMapManager.CreateMap(mapId); + + sDestructibleEntity = sEntityManager.SpawnEntity(DestructibleDamageTypeEntityId, coordinates); + sDamageableComponent = sDestructibleEntity.GetComponent(); + sThresholdListenerComponent = sDestructibleEntity.GetComponent(); + }); + + await server.WaitRunTicks(5); + + await server.WaitAssertion(() => + { + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + }); + + await server.WaitAssertion(() => + { + // Raise blunt damage to 5 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 5, true)); + + // No thresholds reached yet, the earliest one is at 10 damage + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise blunt damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 5, true)); + + // No threshold reached, slash needs to be 10 as well + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise slash damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Slash, 10, true)); + + // One threshold reached, blunt 10 + slash 10 + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + // Threshold blunt 10 + slash 10 + var msg = sThresholdListenerComponent.ThresholdsReached[0]; + var threshold = msg.Threshold; + + // Check that it matches the YAML prototype + Assert.That(threshold.Behaviors, Is.Empty); + Assert.NotNull(threshold.Trigger); + Assert.That(threshold.Triggered, Is.True); + Assert.IsInstanceOf(threshold.Trigger); + + sThresholdListenerComponent.ThresholdsReached.Clear(); + + // Raise blunt damage to 20 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise slash damage to 20 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Slash, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Lower blunt damage to 0 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, -20, true)); + + // No new thresholds reached, healing should not trigger it + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise blunt damage back up to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 10, true)); + + // 10 blunt + 10 slash threshold reached, blunt was healed and brought back to its threshold amount and slash stayed the same + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + sThresholdListenerComponent.ThresholdsReached.Clear(); + + // Heal both types of damage to 0 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, -10, true)); + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Slash, -20, true)); + + // No new thresholds reached, healing should not trigger it + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise blunt damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise slash damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Slash, 10, true)); + + // Both types of damage were healed and then raised again, the threshold should have been reached as triggers once is default false + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + // Threshold blunt 10 + slash 10 + msg = sThresholdListenerComponent.ThresholdsReached[0]; + threshold = msg.Threshold; + + // Check that it matches the YAML prototype + Assert.That(threshold.Behaviors, Is.Empty); + Assert.NotNull(threshold.Trigger); + Assert.That(threshold.Triggered, Is.True); + Assert.IsInstanceOf(threshold.Trigger); + + sThresholdListenerComponent.ThresholdsReached.Clear(); + + // Change triggers once to true + threshold.TriggersOnce = true; + + // Heal blunt and slash back to 0 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, -10, true)); + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Slash, -10, true)); + + // No new thresholds reached from healing + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise blunt damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 10, true)); + + // No new thresholds reached + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Raise slash damage to 10 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Slash, 10, true)); + + // No new thresholds reached as triggers once is set to true and it already triggered before + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + }); + } + } +} diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleDestructionTest.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleDestructionTest.cs new file mode 100644 index 0000000000..2890b390dc --- /dev/null +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleDestructionTest.cs @@ -0,0 +1,95 @@ +using System.Linq; +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Destructible.Thresholds; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors; +using Content.Shared.Damage; +using Content.Shared.GameObjects.Components.Damage; +using NUnit.Framework; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes; + +namespace Content.IntegrationTests.Tests.Destructible +{ + public class DestructibleDestructionTest : ContentIntegrationTest + { + [Test] + public async Task Test() + { + var server = StartServerDummyTicker(new ServerContentIntegrationOption + { + ExtraPrototypes = Prototypes, + ContentBeforeIoC = () => + { + IoCManager.Resolve().Register(); + } + }); + + await server.WaitIdleAsync(); + + var sEntityManager = server.ResolveDependency(); + var sMapManager = server.ResolveDependency(); + + IEntity sDestructibleEntity = null; + IDamageableComponent sDamageableComponent = null; + TestThresholdListenerComponent sThresholdListenerComponent = null; + + await server.WaitPost(() => + { + var mapId = new MapId(1); + var coordinates = new MapCoordinates(0, 0, mapId); + sMapManager.CreateMap(mapId); + + sDestructibleEntity = sEntityManager.SpawnEntity(DestructibleDestructionEntityId, coordinates); + sDamageableComponent = sDestructibleEntity.GetComponent(); + sThresholdListenerComponent = sDestructibleEntity.GetComponent(); + }); + + await server.WaitAssertion(() => + { + var coordinates = sDestructibleEntity.Transform.Coordinates; + + Assert.DoesNotThrow(() => + { + Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 50, true)); + }); + + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + + var threshold = sThresholdListenerComponent.ThresholdsReached[0].Threshold; + + Assert.That(threshold.Triggered, Is.True); + Assert.That(threshold.Behaviors.Count, Is.EqualTo(3)); + + var spawnEntitiesBehavior = (SpawnEntitiesBehavior) threshold.Behaviors.Single(b => b is SpawnEntitiesBehavior); + + Assert.That(spawnEntitiesBehavior.Spawn.Count, Is.EqualTo(1)); + Assert.That(spawnEntitiesBehavior.Spawn.Keys.Single(), Is.EqualTo(SpawnedEntityId)); + Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax {Min = 1, Max = 1})); + + var entitiesInRange = sEntityManager.GetEntitiesInRange(coordinates, 2); + var found = false; + + foreach (var entity in entitiesInRange) + { + if (entity.Prototype == null) + { + continue; + } + + if (entity.Prototype.Name != SpawnedEntityId) + { + continue; + } + + found = true; + break; + } + + Assert.That(found, Is.True); + }); + } + } +} diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs new file mode 100644 index 0000000000..32fb9048e8 --- /dev/null +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleTestPrototypes.cs @@ -0,0 +1,94 @@ +namespace Content.IntegrationTests.Tests.Destructible +{ + public static class DestructibleTestPrototypes + { + public const string SpawnedEntityId = "DestructibleTestsSpawnedEntity"; + public const string DestructibleEntityId = "DestructibleTestsDestructibleEntity"; + public const string DestructibleDestructionEntityId = "DestructibleTestsDestructibleDestructionEntity"; + public const string DestructibleDamageTypeEntityId = "DestructibleTestsDestructibleDamageTypeEntity"; + public const string DestructibleDamageClassEntityId = "DestructibleTestsDestructibleDamageClassEntity"; + + public static readonly string Prototypes = $@" +- type: entity + id: {SpawnedEntityId} + name: {SpawnedEntityId} + +- type: entity + id: {DestructibleEntityId} + name: {DestructibleEntityId} + components: + - type: Damageable + - type: Destructible + thresholds: + - trigger: + !type:TotalDamageTrigger + damage: 20 + triggersOnce: false + - trigger: + !type:TotalDamageTrigger + damage: 50 + triggersOnce: false + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + {SpawnedEntityId}: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [""Breakage""] + - type: TestThresholdListener + +- type: entity + id: {DestructibleDestructionEntityId} + name: {DestructibleDestructionEntityId} + components: + - type: Damageable + - type: Destructible + thresholds: + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + {SpawnedEntityId}: + min: 1 + max: 1 + - !type:DoActsBehavior # This must come last as it destroys the entity. + acts: [""Destruction""] + - type: TestThresholdListener + +- type: entity + id: {DestructibleDamageTypeEntityId} + name: {DestructibleDamageTypeEntityId} + components: + - type: Damageable + - type: Destructible + thresholds: + - trigger: + !type:TotalDamageTypesTrigger + damage: + Blunt: 10 + Slash: 10 + - type: TestThresholdListener + + +- type: entity + id: {DestructibleDamageClassEntityId} + name: {DestructibleDamageClassEntityId} + components: + - type: Damageable + - type: Destructible + thresholds: + - trigger: + !type:TotalDamageClassesTrigger + damage: + Brute: 10 + Burn: 10 + - type: TestThresholdListener"; + } +} diff --git a/Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs b/Content.IntegrationTests/Tests/Destructible/DestructibleThresholdActivationTest.cs similarity index 60% rename from Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs rename to Content.IntegrationTests/Tests/Destructible/DestructibleThresholdActivationTest.cs index 31c5e1f470..55c1aeadbb 100644 --- a/Content.IntegrationTests/Tests/Destructible/DestructibleTests.cs +++ b/Content.IntegrationTests/Tests/Destructible/DestructibleThresholdActivationTest.cs @@ -1,99 +1,27 @@ -using System.Collections.Generic; -using System.Linq; +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.Server.GameObjects.Components.Destructible.Thresholds.Behaviors; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers; using Content.Shared.Damage; using Content.Shared.GameObjects.Components.Damage; using NUnit.Framework; -using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; using Robust.Shared.Map; +using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes; namespace Content.IntegrationTests.Tests.Destructible { [TestFixture] [TestOf(typeof(DestructibleComponent))] [TestOf(typeof(Threshold))] - public class DestructibleTests : ContentIntegrationTest + public class DestructibleThresholdActivationTest : ContentIntegrationTest { - private static readonly string SpawnedEntityId = "DestructibleTestsSpawnedEntity"; - private static readonly string DestructibleEntityId = "DestructibleTestsDestructibleEntity"; - private static readonly string DestructibleDestructionEntityId = "DestructibleTestsDestructibleDestructionEntity"; - - private static readonly string Prototypes = $@" -- type: entity - id: {SpawnedEntityId} - name: {SpawnedEntityId} - -- type: entity - id: {DestructibleEntityId} - name: {DestructibleEntityId} - components: - - type: Damageable - - type: Destructible - thresholds: - 20: - triggersOnce: false - 50: - triggersOnce: false - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/woodhit.ogg - - !type:SpawnEntitiesBehavior - spawn: - {SpawnedEntityId}: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [""Breakage""] - - type: TestThresholdListener - -- type: entity - id: {DestructibleDestructionEntityId} - name: {DestructibleDestructionEntityId} - components: - - type: Damageable - - type: Destructible - thresholds: - 50: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/woodhit.ogg - - !type:SpawnEntitiesBehavior - spawn: - {SpawnedEntityId}: - min: 1 - max: 1 - - !type:DoActsBehavior # This must come last as it destroys the entity. - acts: [""Destruction""] - - type: TestThresholdListener -"; - - private class TestThresholdListenerComponent : Component - { - public override string Name => "TestThresholdListener"; - - public List ThresholdsReached { get; } = new(); - - public override void HandleMessage(ComponentMessage message, IComponent component) - { - base.HandleMessage(message, component); - - switch (message) - { - case DestructibleThresholdReachedMessage msg: - ThresholdsReached.Add(msg); - break; - } - } - } - [Test] - public async Task TestThresholdActivation() + public async Task Test() { var server = StartServerDummyTicker(new ServerContentIntegrationOption { @@ -130,7 +58,7 @@ namespace Content.IntegrationTests.Tests.Destructible await server.WaitAssertion(() => { - Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.Zero); + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); }); await server.WaitAssertion(() => @@ -138,36 +66,31 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 10, true)); // No thresholds reached yet, the earliest one is at 20 damage - Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.Zero); + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 10, true)); // Only one threshold reached, 20 Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + // Threshold 20 var msg = sThresholdListenerComponent.ThresholdsReached[0]; - - // Check that it matches the total damage dealt - Assert.That(msg.TotalDamage, Is.EqualTo(20)); - var threshold = msg.Threshold; // Check that it matches the YAML prototype Assert.That(threshold.Behaviors, Is.Empty); + Assert.NotNull(threshold.Trigger); Assert.That(threshold.Triggered, Is.True); sThresholdListenerComponent.ThresholdsReached.Clear(); Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 30, true)); - // Only one threshold reached, 50, since 20 was already reached before + // One threshold reached, 50, since 20 already triggered before and it has not been healed below that amount Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); + // Threshold 50 msg = sThresholdListenerComponent.ThresholdsReached[0]; - - // Check that it matches the total damage dealt - Assert.That(msg.TotalDamage, Is.EqualTo(50)); - threshold = msg.Threshold; // Check that it matches the YAML prototype @@ -184,6 +107,7 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(SpawnedEntityId)); Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1)); Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1)); + Assert.NotNull(threshold.Trigger); Assert.That(threshold.Triggered, Is.True); sThresholdListenerComponent.ThresholdsReached.Clear(); @@ -191,8 +115,19 @@ namespace Content.IntegrationTests.Tests.Destructible // Damage for 50 again, up to 100 now Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 50, true)); - // No new thresholds reached as even though they don't only trigger once, the entity was not healed below the threshold - Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); + // No thresholds reached as they weren't healed below the trigger amount + Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); + + // Heal down to 0 + sDamageableComponent.Heal(); + + // Damage for 100, up to 100 + Assert.True(sDamageableComponent.ChangeDamage(DamageType.Blunt, 100, true)); + + // Two thresholds reached as damage increased past the previous, 20 and 50 + Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(2)); + + sThresholdListenerComponent.ThresholdsReached.Clear(); // Heal the entity for 40 damage, down to 60 sDamageableComponent.ChangeDamage(DamageType.Blunt, -40, true); @@ -219,10 +154,6 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); msg = sThresholdListenerComponent.ThresholdsReached[0]; - - // Check that it matches the total damage dealt - Assert.That(msg.TotalDamage, Is.EqualTo(50)); - threshold = msg.Threshold; // Check that it matches the YAML prototype @@ -240,6 +171,7 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(SpawnedEntityId)); Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1)); Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1)); + Assert.NotNull(threshold.Trigger); Assert.That(threshold.Triggered, Is.True); // Reset thresholds reached @@ -259,10 +191,9 @@ namespace Content.IntegrationTests.Tests.Destructible // Verify the first one, should be the lowest one (20) msg = sThresholdListenerComponent.ThresholdsReached[0]; - Assert.That(msg.ThresholdAmount, Is.EqualTo(20)); - - // The total damage should be 50 - Assert.That(msg.TotalDamage, Is.EqualTo(50)); + var trigger = (TotalDamageTrigger) msg.Threshold.Trigger; + Assert.NotNull(trigger); + Assert.That(trigger.Damage, Is.EqualTo(20)); threshold = msg.Threshold; @@ -271,10 +202,9 @@ namespace Content.IntegrationTests.Tests.Destructible // Verify the second one, should be the highest one (50) msg = sThresholdListenerComponent.ThresholdsReached[1]; - Assert.That(msg.ThresholdAmount, Is.EqualTo(50)); - - // Check that it matches the total damage dealt - Assert.That(msg.TotalDamage, Is.EqualTo(50)); + trigger = (TotalDamageTrigger) msg.Threshold.Trigger; + Assert.NotNull(trigger); + Assert.That(trigger.Damage, Is.EqualTo(50)); threshold = msg.Threshold; @@ -292,6 +222,7 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(SpawnedEntityId)); Assert.That(spawnThreshold.Spawn.Single().Value.Min, Is.EqualTo(1)); Assert.That(spawnThreshold.Spawn.Single().Value.Max, Is.EqualTo(1)); + Assert.NotNull(threshold.Trigger); Assert.That(threshold.Triggered, Is.True); // Reset thresholds reached @@ -304,8 +235,9 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(0)); // Set both thresholds to only trigger once - foreach (var destructibleThreshold in sDestructibleComponent.LowestToHighestThresholds.Values) + foreach (var destructibleThreshold in sDestructibleComponent.Thresholds) { + Assert.NotNull(destructibleThreshold.Trigger); destructibleThreshold.TriggersOnce = true; } @@ -319,8 +251,9 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); // Set both thresholds to trigger multiple times - foreach (var destructibleThreshold in sDestructibleComponent.LowestToHighestThresholds.Values) + foreach (var destructibleThreshold in sDestructibleComponent.Thresholds) { + Assert.NotNull(destructibleThreshold.Trigger); destructibleThreshold.TriggersOnce = false; } @@ -331,84 +264,5 @@ namespace Content.IntegrationTests.Tests.Destructible Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); }); } - - [Test] - public async Task DestructibleDestructionTest() - { - var server = StartServerDummyTicker(new ServerContentIntegrationOption - { - ExtraPrototypes = Prototypes, - ContentBeforeIoC = () => - { - IoCManager.Resolve().Register(); - } - }); - - await server.WaitIdleAsync(); - - var sEntityManager = server.ResolveDependency(); - var sMapManager = server.ResolveDependency(); - - IEntity sDestructibleEntity = null; - IDamageableComponent sDamageableComponent = null; - DestructibleComponent sDestructibleComponent = null; - TestThresholdListenerComponent sThresholdListenerComponent = null; - - await server.WaitPost(() => - { - var mapId = new MapId(1); - var coordinates = new MapCoordinates(0, 0, mapId); - sMapManager.CreateMap(mapId); - - sDestructibleEntity = sEntityManager.SpawnEntity(DestructibleDestructionEntityId, coordinates); - sDamageableComponent = sDestructibleEntity.GetComponent(); - sDestructibleComponent = sDestructibleEntity.GetComponent(); - sThresholdListenerComponent = sDestructibleEntity.GetComponent(); - }); - - await server.WaitAssertion(() => - { - var coordinates = sDestructibleEntity.Transform.Coordinates; - - Assert.DoesNotThrow(() => - { - Assert.True(sDamageableComponent.ChangeDamage(DamageClass.Brute, 50, true)); - }); - - Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); - - var threshold = sThresholdListenerComponent.ThresholdsReached[0].Threshold; - - Assert.That(threshold.Triggered, Is.True); - Assert.That(threshold.Behaviors.Count, Is.EqualTo(3)); - - var spawnEntitiesBehavior = (SpawnEntitiesBehavior) threshold.Behaviors.Single(b => b is SpawnEntitiesBehavior); - - Assert.That(spawnEntitiesBehavior.Spawn.Count, Is.EqualTo(1)); - Assert.That(spawnEntitiesBehavior.Spawn.Keys.Single(), Is.EqualTo(SpawnedEntityId)); - Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax {Min = 1, Max = 1})); - - var entitiesInRange = sEntityManager.GetEntitiesInRange(coordinates, 2); - var found = false; - - foreach (var entity in entitiesInRange) - { - if (entity.Prototype == null) - { - continue; - } - - if (entity.Prototype.Name != SpawnedEntityId) - { - continue; - } - - found = true; - break; - } - - Assert.That(found, Is.True); - }); - } } } diff --git a/Content.IntegrationTests/Tests/Destructible/TestThresholdListenerComponent.cs b/Content.IntegrationTests/Tests/Destructible/TestThresholdListenerComponent.cs new file mode 100644 index 0000000000..f0d6258355 --- /dev/null +++ b/Content.IntegrationTests/Tests/Destructible/TestThresholdListenerComponent.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Destructible; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.IntegrationTests.Tests.Destructible +{ + public class TestThresholdListenerComponent : Component + { + public override string Name => "TestThresholdListener"; + + public List ThresholdsReached { get; } = new(); + + public override void HandleMessage(ComponentMessage message, IComponent component) + { + base.HandleMessage(message, component); + + switch (message) + { + case DestructibleThresholdReachedMessage msg: + ThresholdsReached.Add(msg); + break; + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs b/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs index bde01c3bbe..a63ec55721 100644 --- a/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs +++ b/Content.Server/GameObjects/Components/Destructible/DestructibleComponent.cs @@ -22,22 +22,15 @@ namespace Content.Server.GameObjects.Components.Destructible public override string Name => "Destructible"; - [ViewVariables] - private SortedDictionary _lowestToHighestThresholds = new(); + [ViewVariables] private List _thresholds = new(); - [ViewVariables] private int PreviousTotalDamage { get; set; } - - public IReadOnlyDictionary LowestToHighestThresholds => _lowestToHighestThresholds; + public IReadOnlyList Thresholds => _thresholds; public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); - serializer.DataReadWriteFunction( - "thresholds", - new Dictionary(), - thresholds => _lowestToHighestThresholds = new SortedDictionary(thresholds), - () => new Dictionary(_lowestToHighestThresholds)); + serializer.DataField(ref _thresholds, "thresholds", new List()); } public override void Initialize() @@ -60,32 +53,17 @@ namespace Content.Server.GameObjects.Components.Destructible break; } - foreach (var (damage, threshold) in _lowestToHighestThresholds) + foreach (var threshold in _thresholds) { - if (threshold.Triggered) + if (threshold.Reached(msg.Damageable, _destructibleSystem)) { - if (threshold.TriggersOnce) - { - continue; - } - - if (PreviousTotalDamage >= damage) - { - continue; - } - } - - if (msg.Damageable.TotalDamage >= damage) - { - var thresholdMessage = new DestructibleThresholdReachedMessage(this, threshold, msg.Damageable.TotalDamage, damage); + var thresholdMessage = new DestructibleThresholdReachedMessage(this, threshold); SendMessage(thresholdMessage); - threshold.Trigger(Owner, _destructibleSystem); + threshold.Execute(Owner, _destructibleSystem); } } - PreviousTotalDamage = msg.Damageable.TotalDamage; - break; } } diff --git a/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs b/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs index 9321e95a00..6bbad73fbc 100644 --- a/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs +++ b/Content.Server/GameObjects/Components/Destructible/DestructibleThresholdReachedMessage.cs @@ -5,26 +5,14 @@ namespace Content.Server.GameObjects.Components.Destructible { public class DestructibleThresholdReachedMessage : ComponentMessage { - public DestructibleThresholdReachedMessage(DestructibleComponent parent, Threshold threshold, int totalDamage, int thresholdAmount) + public DestructibleThresholdReachedMessage(DestructibleComponent parent, Threshold threshold) { Parent = parent; Threshold = threshold; - TotalDamage = totalDamage; - ThresholdAmount = thresholdAmount; } public DestructibleComponent Parent { get; } public Threshold Threshold { get; } - - /// - /// The amount of total damage currently had that triggered this threshold. - /// - public int TotalDamage { get; } - - /// - /// The amount of damage at which this threshold triggers. - /// - public int ThresholdAmount { get; } } } diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/DoActsBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/DoActsBehavior.cs similarity index 87% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/DoActsBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/DoActsBehavior.cs index e4dd894598..a62bbdfd16 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/DoActsBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/DoActsBehavior.cs @@ -1,10 +1,12 @@ -using Content.Server.GameObjects.EntitySystems; +using System; +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 +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { + [Serializable] public class DoActsBehavior : IThresholdBehavior { private int _acts; @@ -29,7 +31,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior return (_acts & (int) act) != 0; } - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { if (HasAct(ThresholdActs.Breakage)) { diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/GibBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/GibBehavior.cs similarity index 89% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/GibBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/GibBehavior.cs index c388666c24..729e421fac 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/GibBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/GibBehavior.cs @@ -4,7 +4,7 @@ using JetBrains.Annotations; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; -namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { [UsedImplicitly] public class GibBehavior : IThresholdBehavior @@ -16,7 +16,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior serializer.DataField(ref _recursive, "recursive", true); } - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { if (owner.TryGetComponent(out IBody body)) { diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/IThresholdBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs similarity index 82% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/IThresholdBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs index d4a6e86e56..20e06e3687 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/IThresholdBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs @@ -2,18 +2,18 @@ using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Serialization; -namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { public interface IThresholdBehavior : IExposeData { /// - /// Triggers this behavior. + /// Executes this behavior. /// /// The entity that owns this behavior. /// /// An instance of to pull dependencies /// and other systems from. /// - void Trigger(IEntity owner, DestructibleSystem system); + void Execute(IEntity owner, DestructibleSystem system); } } diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/PlaySoundBehavior.cs similarity index 82% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/PlaySoundBehavior.cs index 0ea803f937..38a8af6df7 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/PlaySoundBehavior.cs @@ -1,10 +1,12 @@ -using Content.Server.GameObjects.EntitySystems; +using System; +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 +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { + [Serializable] public class PlaySoundBehavior : IThresholdBehavior { /// @@ -17,7 +19,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior serializer.DataField(this, x => x.Sound, "sound", string.Empty); } - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { if (string.IsNullOrEmpty(Sound)) { diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundCollectionBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/PlaySoundCollectionBehavior.cs similarity index 85% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundCollectionBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/PlaySoundCollectionBehavior.cs index 5a02635b4d..b9caf7a3a6 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/PlaySoundCollectionBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/PlaySoundCollectionBehavior.cs @@ -1,10 +1,12 @@ -using Content.Server.GameObjects.EntitySystems; +using System; +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 +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { + [Serializable] public class PlaySoundCollectionBehavior : IThresholdBehavior { /// @@ -17,7 +19,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior serializer.DataField(this, x => x.SoundCollection, "soundCollection", string.Empty); } - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { if (string.IsNullOrEmpty(SoundCollection)) { diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpawnEntitiesBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs similarity index 93% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpawnEntitiesBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs index 9864db5175..f3f4f6c04d 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpawnEntitiesBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs @@ -1,4 +1,5 @@ #nullable enable +using System; using System.Collections.Generic; using Content.Server.GameObjects.Components.Stack; using Content.Server.GameObjects.EntitySystems; @@ -6,8 +7,9 @@ using Content.Shared.Utility; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; -namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { + [Serializable] public class SpawnEntitiesBehavior : IThresholdBehavior { /// @@ -20,7 +22,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior serializer.DataField(this, x => x.Spawn, "spawn", new Dictionary()); } - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { foreach (var (entityId, minMax) in Spawn) { diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpillBehavior.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/SpillBehavior.cs similarity index 90% rename from Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpillBehavior.cs rename to Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/SpillBehavior.cs index 53ac16d632..02a40b1af0 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Behavior/SpillBehavior.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Behaviors/SpillBehavior.cs @@ -6,14 +6,14 @@ using JetBrains.Annotations; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; -namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors { [UsedImplicitly] public class SpillBehavior : IThresholdBehavior { public void ExposeData(ObjectSerializer serializer) { } - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { if (!owner.TryGetComponent(out SolutionContainerComponent? solutionContainer)) return; diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs index c7ef3c7fd0..ab2c576508 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/MinMax.cs @@ -1,9 +1,11 @@ -using Robust.Shared.Interfaces.Serialization; +using System; +using Robust.Shared.Interfaces.Serialization; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Destructible.Thresholds { + [Serializable] public struct MinMax : IExposeData { [ViewVariables] diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs index e0e402f5df..7e2865c74b 100644 --- a/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Threshold.cs @@ -1,7 +1,9 @@ #nullable enable using System.Collections.Generic; -using Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Behaviors; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers; using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.Components.Damage; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Serialization; using Robust.Shared.Serialization; @@ -13,6 +15,12 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds { private List _behaviors = new(); + /// + /// Whether or not this threshold was triggered in the previous call to + /// . + /// + [ViewVariables] public bool OldTriggered { get; private set; } + /// /// Whether or not this threshold has already been triggered. /// @@ -26,6 +34,11 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds /// [ViewVariables] public bool TriggersOnce { get; set; } + /// + /// The trigger that decides if this threshold has been reached. + /// + [ViewVariables] public IThresholdTrigger? Trigger { get; set; } + /// /// Behaviors to activate once this threshold is triggered. /// @@ -35,9 +48,37 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds { serializer.DataField(this, x => x.Triggered, "triggered", false); serializer.DataField(this, x => x.TriggersOnce, "triggersOnce", false); + serializer.DataField(this, x => x.Trigger, "trigger", null); serializer.DataField(ref _behaviors, "behaviors", new List()); } + public bool Reached(IDamageableComponent damageable, DestructibleSystem system) + { + if (Trigger == null) + { + return false; + } + + if (Triggered && TriggersOnce) + { + return false; + } + + if (OldTriggered) + { + OldTriggered = Trigger.Reached(damageable, system); + return false; + } + + if (!Trigger.Reached(damageable, system)) + { + return false; + } + + OldTriggered = true; + return true; + } + /// /// Triggers this threshold. /// @@ -46,7 +87,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds /// An instance of to get dependency and /// system references from, if relevant. /// - public void Trigger(IEntity owner, DestructibleSystem system) + public void Execute(IEntity owner, DestructibleSystem system) { Triggered = true; @@ -56,7 +97,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds if (owner.Deleted) return; - behavior.Trigger(owner, system); + behavior.Execute(owner, system); } } } diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/IThresholdTrigger.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/IThresholdTrigger.cs new file mode 100644 index 0000000000..88742fdd4e --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/IThresholdTrigger.cs @@ -0,0 +1,21 @@ +#nullable enable +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.Components.Damage; +using Robust.Shared.Interfaces.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers +{ + public interface IThresholdTrigger : IExposeData + { + /// + /// Checks if this trigger has been reached. + /// + /// The damageable component to check with. + /// + /// An instance of to pull + /// dependencies from, if any. + /// + /// true if this trigger has been reached, false otherwise. + bool Reached(IDamageableComponent damageable, DestructibleSystem system); + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageClassesTrigger.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageClassesTrigger.cs new file mode 100644 index 0000000000..c7c469c6fb --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageClassesTrigger.cs @@ -0,0 +1,47 @@ +#nullable enable +using System; +using System.Collections.Generic; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Damage; +using Content.Shared.GameObjects.Components.Damage; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers +{ + /// + /// A trigger that will activate when all of the damage classes received + /// are above the specified threshold. + /// + [Serializable] + public class TotalDamageClassesTrigger : IThresholdTrigger + { + /// + /// The amount of damage at which this threshold will trigger. + /// The damage requirements of all must be met. + /// + private Dictionary Damage { get; set; } = new(); + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(this, x => x.Damage, "damage", new Dictionary()); + } + + public bool Reached(IDamageableComponent damageable, DestructibleSystem system) + { + foreach (var (type, damageRequired) in Damage) + { + if (!damageable.TryGetDamage(type, out var damageReceived)) + { + return false; + } + + if (damageReceived < damageRequired) + { + return false; + } + } + + return true; + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageTrigger.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageTrigger.cs new file mode 100644 index 0000000000..978b423363 --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageTrigger.cs @@ -0,0 +1,31 @@ +#nullable enable +using System; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.GameObjects.Components.Damage; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers +{ + /// + /// A trigger that will activate when the amount of total damage received + /// is above the specified threshold. + /// + [Serializable] + public class TotalDamageTrigger : IThresholdTrigger + { + /// + /// The amount of total damage at which this threshold will trigger. + /// + public int Damage { get; private set; } + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(this, x => x.Damage, "damage", 0); + } + + public bool Reached(IDamageableComponent damageable, DestructibleSystem system) + { + return damageable.TotalDamage >= Damage; + } + } +} diff --git a/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageTypesTrigger.cs b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageTypesTrigger.cs new file mode 100644 index 0000000000..fa48dfc0cc --- /dev/null +++ b/Content.Server/GameObjects/Components/Destructible/Thresholds/Triggers/TotalDamageTypesTrigger.cs @@ -0,0 +1,47 @@ +#nullable enable +using System; +using System.Collections.Generic; +using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Damage; +using Content.Shared.GameObjects.Components.Damage; +using Robust.Shared.Serialization; + +namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers +{ + /// + /// A trigger that will activate when all of the damage types received + /// are above the specified threshold. + /// + [Serializable] + public class TotalDamageTypesTrigger : IThresholdTrigger + { + /// + /// The amount of damage at which this threshold will trigger. + /// The damage requirements of all must be met. + /// + private Dictionary Damage { get; set; } = new(); + + public void ExposeData(ObjectSerializer serializer) + { + serializer.DataField(this, x => x.Damage, "damage", new Dictionary()); + } + + public bool Reached(IDamageableComponent damageable, DestructibleSystem system) + { + foreach (var (type, damageRequired) in Damage) + { + if (!damageable.TryGetDamage(type, out var damageReceived)) + { + return false; + } + + if (damageReceived < damageRequired) + { + return false; + } + } + + return true; + } + } +} diff --git a/Content.Server/GameObjects/Components/WindowComponent.cs b/Content.Server/GameObjects/Components/WindowComponent.cs index 669971fb6d..da399aae44 100644 --- a/Content.Server/GameObjects/Components/WindowComponent.cs +++ b/Content.Server/GameObjects/Components/WindowComponent.cs @@ -1,5 +1,6 @@ -#nullable enable +#nullable enable using System; +using System.Linq; using Content.Server.Utility; using Content.Shared.Audio; using Content.Shared.GameObjects.Components; @@ -7,6 +8,7 @@ using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Interfaces.GameObjects.Components; using Content.Server.GameObjects.Components.Destructible; +using Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers; using Content.Shared.Utility; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; @@ -22,7 +24,6 @@ namespace Content.Server.GameObjects.Components [ComponentReference(typeof(SharedWindowComponent))] public class WindowComponent : SharedWindowComponent, IExamine, IInteractHand { - public override void HandleMessage(ComponentMessage message, IComponent? component) { base.HandleMessage(message, component); @@ -40,26 +41,52 @@ namespace Content.Server.GameObjects.Components private void UpdateVisuals(int currentDamage) { - if (Owner.TryGetComponent(out AppearanceComponent? appearance)) + if (Owner.TryGetComponent(out AppearanceComponent? appearance) && + Owner.TryGetComponent(out DestructibleComponent? destructible)) { - if (Owner.TryGetComponent(out DestructibleComponent? destructible)) + foreach (var threshold in destructible.Thresholds) { - var damageThreshold = destructible.LowestToHighestThresholds.FirstOrNull()?.Key; - if (damageThreshold == null) return; - appearance.SetData(WindowVisuals.Damage, (float) currentDamage / damageThreshold); + if (threshold.Trigger is not TotalDamageTrigger trigger) + { + continue; + } + + appearance.SetData(WindowVisuals.Damage, (float) currentDamage / trigger.Damage); } } } void IExamine.Examine(FormattedMessage message, bool inDetailsRange) { - var damage = Owner.GetComponentOrNull()?.TotalDamage; - var damageThreshold = Owner.GetComponentOrNull()?.LowestToHighestThresholds.FirstOrNull()?.Key; - if (damage == null || damageThreshold == null) return; - var fraction = ((damage == 0 || damageThreshold == 0) + if (!Owner.TryGetComponent(out IDamageableComponent? damageable) || + !Owner.TryGetComponent(out DestructibleComponent? destructible)) + { + return; + } + + var damage = damageable.TotalDamage; + TotalDamageTrigger? trigger = null; + + // TODO: Pretend this does not exist until https://github.com/space-wizards/space-station-14/pull/2783 is merged + foreach (var threshold in destructible.Thresholds) + { + if ((trigger = threshold.Trigger as TotalDamageTrigger) != null) + { + break; + } + } + + if (trigger == null) + { + return; + } + + var damageThreshold = trigger.Damage; + var fraction = damage == 0 || damageThreshold == 0 ? 0f - : (float) damage / damageThreshold); + : (float) damage / damageThreshold; var level = Math.Min(ContentHelpers.RoundToLevels((double) fraction, 1, 7), 5); + switch (level) { case 0: diff --git a/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs b/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs index 412beefddf..e9449cde08 100644 --- a/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/DestructibleSystem.cs @@ -11,8 +11,9 @@ namespace Content.Server.GameObjects.EntitySystems 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() @@ -23,4 +24,4 @@ namespace Content.Server.GameObjects.EntitySystems ActSystem = Get(); } } -} \ No newline at end of file +} diff --git a/Content.Shared/Damage/DamageClass.cs b/Content.Shared/Damage/DamageClass.cs index 0801728f39..3463b1c430 100644 --- a/Content.Shared/Damage/DamageClass.cs +++ b/Content.Shared/Damage/DamageClass.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using Content.Shared.GameObjects.EntitySystems; -using Robust.Shared.GameObjects.Systems; using Robust.Shared.Serialization; namespace Content.Shared.Damage diff --git a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml index 4358793df8..e35a2639b5 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml @@ -60,10 +60,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 500: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 500 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: IconSmooth key: walls mode: NoSprite diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml b/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml index 33ed616d29..1c778b4ff5 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/beds.yml @@ -25,9 +25,11 @@ resistances: metallicResistances - type: Destructible thresholds: - 75: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 75 + 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 e151c5db20..670f0d1972 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/bookshelf.yml @@ -23,17 +23,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 30: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/woodhit.ogg - - !type:SpawnEntitiesBehavior - spawn: - WoodPlank: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 30 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Occluder sizeX: 32 diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml b/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml index aa61941654..0efff560fe 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/instruments.yml @@ -24,10 +24,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + 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 d275ab8f66..d952e787cf 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/pilot_chair.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/pilot_chair.yml @@ -15,10 +15,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 fae372caf0..893aa5de52 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/seats.yml @@ -34,10 +34,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + 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 6d960128fa..9ef4248c6b 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/storage.yml @@ -31,17 +31,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 30: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 30 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: Shelf @@ -76,14 +78,16 @@ resistances: metallicResistances - type: Destructible thresholds: - 30: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 30 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] diff --git a/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml b/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml index 1b279f4080..661981e61d 100644 --- a/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml +++ b/Resources/Prototypes/Entities/Constructible/Furniture/tables.yml @@ -39,17 +39,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 15: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 15 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: TableFrame @@ -65,17 +67,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 1: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 1 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: TableFrame @@ -94,17 +98,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 1: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 1 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: TableMetal @@ -120,17 +126,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 15: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 15 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: MetalTable @@ -149,17 +157,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 75: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 75 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: ReinforcedTable @@ -178,17 +188,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 5: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/glass_break2.ogg - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 5 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/glass_break2.ogg + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: GlassTable @@ -207,17 +219,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 20: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/glass_break2.ogg - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 20 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/glass_break2.ogg + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: RGlassTable @@ -236,17 +250,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 15: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/woodhit.ogg - - !type:SpawnEntitiesBehavior - spawn: - WoodPlank: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 15 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: WoodTable @@ -265,17 +281,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 15: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/woodhit.ogg - - !type:SpawnEntitiesBehavior - spawn: - WoodPlank: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 15 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/woodhit.ogg + - !type:SpawnEntitiesBehavior + spawn: + WoodPlank: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: Tables node: PokerTable @@ -294,12 +312,14 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/picaxe2.ogg - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/picaxe2.ogg + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: TableDebug @@ -315,7 +335,9 @@ resistances: metallicResistances - type: Destructible thresholds: - 1: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 1 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml b/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml index 52fbfd854c..a5f42544a1 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/gascanisterports.yml @@ -19,10 +19,12 @@ - type: Damageable - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 4c8e4247a7..c013fe4a85 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/gascanisters.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/gascanisters.yml @@ -13,10 +13,12 @@ - type: Damageable - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: GasCanister - type: Anchorable - type: Pullable diff --git a/Resources/Prototypes/Entities/Constructible/Ground/gasfilters.yml b/Resources/Prototypes/Entities/Constructible/Ground/gasfilters.yml index 19a2f0e1cb..511c366131 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/gasfilters.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/gasfilters.yml @@ -13,10 +13,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite netsync: false sprite: Constructible/Atmos/gasfilter.rsi @@ -27,7 +29,7 @@ - type: Appearance visuals: - type: GasFilterVisualizer - + - type: entity parent: GasFilterBase id: GasFilter @@ -48,4 +50,4 @@ - type: GasFilter inletDirection: South filterOutletDirection: East - outletDirection: North + outletDirection: North diff --git a/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml b/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml index 099a3fbfc7..b96351cbe8 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/kitchen.yml @@ -23,8 +23,10 @@ - type: Damageable - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + 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 1d0732e4d3..c28a4aac76 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity abstract: true id: PipeBase name: Pipe @@ -14,10 +14,12 @@ - type: Damageable - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite netsync: false - type: Appearance diff --git a/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml b/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml index fc5f3d712c..7c49244cbf 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/pumps.yml @@ -13,10 +13,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite netsync: false sprite: Constructible/Atmos/pump.rsi @@ -44,4 +46,3 @@ - type: PressurePump inletDirection: West outletDirection: East - \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml b/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml index f83102c2b7..56a588242c 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/scrubbers.yml @@ -13,10 +13,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite netsync: false sprite: Constructible/Atmos/scrubber.rsi @@ -27,7 +29,7 @@ - type: Appearance visuals: - type: SiphonVisualizer - + - type: entity parent: ScrubberBase id: Scrubber diff --git a/Resources/Prototypes/Entities/Constructible/Ground/vents.yml b/Resources/Prototypes/Entities/Constructible/Ground/vents.yml index 08c981107a..a07116725e 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/vents.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/vents.yml @@ -13,21 +13,23 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite netsync: false sprite: Constructible/Atmos/vent.rsi layers: - sprite: Constructible/Atmos/pipe.rsi state: pipeHalf - - state: ventOff + - state: ventOff - type: Appearance visuals: - type: VentVisualizer - + - type: entity parent: VentBase id: Vent diff --git a/Resources/Prototypes/Entities/Constructible/Power/computers.yml b/Resources/Prototypes/Entities/Constructible/Power/computers.yml index 7a18538c45..540b1c3fca 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/computers.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/computers.yml @@ -98,10 +98,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 04e78bfc1d..ac2097e731 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/debug_power.yml @@ -31,10 +31,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Breakage"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: Anchorable - type: entity diff --git a/Resources/Prototypes/Entities/Constructible/Power/power_base.yml b/Resources/Prototypes/Entities/Constructible/Power/power_base.yml index aa504efbe8..7dd653d735 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/power_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/power_base.yml @@ -99,7 +99,7 @@ - type: ClientEntitySpawner prototypes: - HVDummyWire - + - type: entity id: BaseSubstation description: Reduces the voltage of electricity put into it. @@ -158,7 +158,7 @@ prototypes: - HVDummyWire - MVDummyWire - + - type: entity id: BaseApc description: A control terminal for the area's electrical systems. @@ -215,7 +215,7 @@ prototypes: - MVDummyWire - LVDummyWire - + - type: entity id: SolarPanel name: solar panel @@ -257,12 +257,14 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Breakage"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: Anchorable - type: Pullable - type: ClientEntitySpawner prototypes: - - HVDummyWire \ No newline at end of file + - HVDummyWire diff --git a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml index 863a33a527..f19620729b 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml @@ -32,10 +32,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Breakage"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + 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 144c1e1550..4f64639e05 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/wires.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/wires.yml @@ -22,10 +22,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: SubFloorHide - type: entity @@ -53,15 +55,17 @@ wireType: HighVoltage - type: Destructible thresholds: - 100: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - HVWireStack1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + HVWireStack1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: WireBase @@ -90,15 +94,17 @@ wireType: MediumVoltage - type: Destructible thresholds: - 100: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - MVWireStack1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + MVWireStack1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: WireBase @@ -129,15 +135,17 @@ wireType: Apc - type: Destructible thresholds: - 100: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ApcExtensionCableStack1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ApcExtensionCableStack1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] #Dummy wires @@ -153,8 +161,8 @@ drawdepth: BelowFloor - type: IconSmooth mode: CardinalFlags - - type: SubFloorHide - + - type: SubFloorHide + - type: entity abstract: true parent: BaseDummyWire @@ -167,7 +175,7 @@ - type: IconSmooth base: hvcable_ key: hv_cables - + - type: entity abstract: true parent: BaseDummyWire @@ -181,7 +189,7 @@ - type: IconSmooth base: mvcable_ key: mv_cables - + - type: entity abstract: true parent: BaseDummyWire @@ -194,4 +202,4 @@ color: Green - type: IconSmooth base: lvcable_ - key: lv_cables \ No newline at end of file + key: lv_cables 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 c4c1442a6f..6cd9655e6f 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_controller.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_controller.yml @@ -25,10 +25,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 500: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 500 + 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 762aa88d8a..829e1c3c7e 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_structure.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Engines/AME/ame_structure.yml @@ -25,15 +25,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 500: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - AMEPart: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 500 + 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/Medical/cloning_machine.yml b/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml index f58464d996..c9c770647a 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Medical/cloning_machine.yml @@ -34,10 +34,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: CloningPodVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml b/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml index 1c0b3988c3..23048139d1 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/Medical/medical_scanner.yml @@ -34,10 +34,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: MedicalScannerVisualizer diff --git a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml index 81a14bcffb..f2553f0bd4 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/cargo_telepad.yml @@ -21,10 +21,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 75: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 75 + 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 df75f399ba..a29d04f713 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/chem_master.yml @@ -35,15 +35,17 @@ - type: Damageable - type: Destructible thresholds: - 50: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - chem_master_broken: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + chem_master_broken: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: UserInterface interfaces: - key: enum.ChemMasterUiKey.Key @@ -84,15 +86,17 @@ - type: Damageable - type: Destructible thresholds: - 25: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 25 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - 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 42260b9e78..68ddd0dcf1 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/disposal.yml @@ -17,10 +17,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Breakage"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Breakage"] - type: Rotatable - type: Pullable @@ -151,10 +153,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: DisposalUnitVisualizer @@ -392,10 +396,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 cfc150fb63..f902754032 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/gravity_generator.yml @@ -33,10 +33,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 150: - behaviors: - - !type:DoActsBehavior - acts: ["Breakage"] + - trigger: + !type:TotalDamageTrigger + damage: 150 + 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 ab9faa97dd..5afac6dd20 100644 --- a/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml +++ b/Resources/Prototypes/Entities/Constructible/Specific/hydroponics.yml @@ -27,10 +27,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + 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 bfab9479d3..5c721679e6 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/Closets/closet.yml @@ -43,10 +43,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 f0b3cd8b06..851baac2b8 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/Crates/crate_base.yml @@ -39,10 +39,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 54110ab38d..efce938513 100644 --- a/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml +++ b/Resources/Prototypes/Entities/Constructible/Storage/StorageTanks/base_tank.yml @@ -27,10 +27,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 10: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 10 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: SolutionContainer maxVol: 1500 caps: Drainable diff --git a/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml b/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml index a4f7617608..9f87b72f8a 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/asteroid.yml @@ -18,10 +18,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 8960980e53..8895c3a02d 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/girder.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/girder.yml @@ -30,15 +30,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: SnapGrid offset: Edge placement: diff --git a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml index 9617beec97..47a5cd08d5 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/lighting.yml @@ -40,10 +40,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: small light @@ -69,10 +71,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 25: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 25 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: unpowered small light @@ -90,7 +94,9 @@ resistances: metallicResistances - type: Destructible thresholds: - 25: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 25 + 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 0feb5c8737..855d13a9d0 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/low_wall.yml @@ -29,10 +29,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 100 + 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 ce9012762a..5fa72911c7 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/signs.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/signs.yml @@ -12,10 +12,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 5: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 5 + 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 8f8b9cc644..7b1f289dc2 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/walls.yml @@ -48,15 +48,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: brick @@ -74,15 +76,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: clock @@ -100,15 +104,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: clown @@ -127,15 +133,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: cult @@ -153,15 +161,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: debug @@ -179,15 +189,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: diamond @@ -206,15 +218,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: gold @@ -232,15 +246,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: ice @@ -258,15 +274,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: metal @@ -284,15 +302,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: plasma @@ -310,15 +330,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: plastic @@ -341,10 +363,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 600: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 600 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: BreakableConstruction node: girder - type: ReinforcedWall @@ -369,15 +393,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 1000: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 1000 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: riveted @@ -395,15 +421,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: sandstone @@ -421,15 +449,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: silver @@ -451,10 +481,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: BreakableConstruction node: girder destroySound: /Audio/Effects/metalbreak.ogg @@ -475,15 +507,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth key: walls base: uranium @@ -501,15 +535,17 @@ resistances: metallicResistances - type: Destructible thresholds: - 300: - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 300 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - 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 9f9778ae6e..3561517408 100644 --- a/Resources/Prototypes/Entities/Constructible/Walls/windows.yml +++ b/Resources/Prototypes/Entities/Constructible/Walls/windows.yml @@ -30,17 +30,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 15: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 15 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: SnapGrid offset: Center - type: Airtight @@ -67,17 +69,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 75: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:SpawnEntitiesBehavior - spawn: - ShardGlassReinforced: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 75 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlassReinforced: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Window base: rwindow - type: Construction @@ -98,17 +102,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 100: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:SpawnEntitiesBehavior - spawn: - ShardGlassPhoron: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlassPhoron: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] resistances: metallicResistances - type: Window base: pwindow diff --git a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml index 00e78fce7f..90d3f438df 100644 --- a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml +++ b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml @@ -125,10 +125,12 @@ resistances: metallicResistances - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: FoamedIronMetal diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 3f9254499c..4291e33116 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -164,9 +164,12 @@ 200: !type:DeadMobState {} - type: Destructible thresholds: - 400: - behaviors: - - !type:GibBehavior { } + - trigger: + !type:TotalDamageTypesTrigger + damage: + Blunt: 400 + behaviors: + - !type:GibBehavior { } - type: HeatResistance - type: Appearance visuals: diff --git a/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml index 545c343390..31c5f77a48 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/drinks.yml @@ -26,18 +26,20 @@ - type: Damageable - type: Destructible thresholds: - 5: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:SpillBehavior { } - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 5 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:SpillBehavior { } + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: DamageOnLand amount: 5 - type: DamageOtherOnHit diff --git a/Resources/Prototypes/Entities/Objects/Consumable/drinks_bottles.yml b/Resources/Prototypes/Entities/Objects/Consumable/drinks_bottles.yml index 1dce8418b5..b294dfab05 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/drinks_bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/drinks_bottles.yml @@ -19,18 +19,20 @@ - type: Damageable - type: Destructible thresholds: - 5: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:SpillBehavior { } - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 5 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:SpillBehavior { } + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: DrinkBottleBaseFull diff --git a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml index f4c5420753..5da29c32bb 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fluff_lights.yml @@ -131,17 +131,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 10: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/glass_break1.ogg - - !type:SpawnEntitiesBehavior - spawn: - FloodlightBroken: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 10 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/glass_break1.ogg + - !type:SpawnEntitiesBehavior + spawn: + FloodlightBroken: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Appearance visuals: - type: FlashLightVisualizer @@ -160,17 +162,19 @@ resistances: metallicResistances - type: Destructible thresholds: - 20: - behaviors: - - !type:PlaySoundBehavior - sound: /Audio/Effects/metalbreak.ogg - - !type:SpawnEntitiesBehavior - spawn: - SteelSheet1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 20 + behaviors: + - !type:PlaySoundBehavior + sound: /Audio/Effects/metalbreak.ogg + - !type:SpawnEntitiesBehavior + spawn: + SteelSheet1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Physics shapes: - !type:PhysShapeAabb diff --git a/Resources/Prototypes/Entities/Objects/Power/lights.yml b/Resources/Prototypes/Entities/Objects/Power/lights.yml index 0037831aa0..386970c607 100644 --- a/Resources/Prototypes/Entities/Objects/Power/lights.yml +++ b/Resources/Prototypes/Entities/Objects/Power/lights.yml @@ -11,23 +11,27 @@ amount: 5 - type: Destructible thresholds: - 5: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:DoActsBehavior - acts: [ "Breakage" ] - 10: - behaviors: - - !type:PlaySoundCollectionBehavior - soundCollection: GlassBreak - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] + - trigger: + !type:TotalDamageTrigger + damage: 5 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:DoActsBehavior + acts: [ "Breakage" ] + - trigger: + !type:TotalDamageTrigger + damage: 10 + behaviors: + - !type:PlaySoundCollectionBehavior + soundCollection: GlassBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: BaseLightbulb diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml index 75426cdadc..ac0c09d3ee 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Explosives/grenades.yml @@ -25,10 +25,12 @@ - type: Damageable - type: Destructible thresholds: - 10: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 10 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer @@ -57,10 +59,12 @@ - type: Damageable - type: Destructible thresholds: - 10: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 10 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer @@ -89,10 +93,12 @@ - type: Damageable - type: Destructible thresholds: - 10: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 10 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer @@ -120,10 +126,12 @@ - type: Damageable - type: Destructible thresholds: - 50: - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + - trigger: + !type:TotalDamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance visuals: - type: TimerTriggerVisualizer