public async Task TestAllSupportDamageableComponent() { var server = StartServerDummyTicker(); await server.WaitIdleAsync(); var sEntityManager = server.ResolveDependency <IEntityManager>(); var sMapManager = server.ResolveDependency <IMapManager>(); var sPrototypeManager = server.ResolveDependency <IPrototypeManager>(); IEntity sFullyDamageableEntity; IDamageableComponent sFullyDamageableComponent = null; await server.WaitPost(() => { var mapId = sMapManager.NextMapId(); var coordinates = new MapCoordinates(0, 0, mapId); sMapManager.CreateMap(mapId); // When prototypes are loaded using the ExtraPrototypes option, they seem to be loaded first? // Or at least, no damage prototypes were loaded in by the time that the damageContainer here is loaded. // So for now doing explicit loading of prototypes. // I have no idea what I am doing, but it works. sPrototypeManager.LoadString($@" # we want to test the all damage container - type: damageContainer id: testAllDamageContainer supportAll: true # create entities - type: entity id: {AllDamageDamageableEntityId} name: {AllDamageDamageableEntityId} components: - type: Damageable damageContainer: testAllDamageContainer "); sFullyDamageableEntity = sEntityManager.SpawnEntity(AllDamageDamageableEntityId, coordinates); sFullyDamageableComponent = sFullyDamageableEntity.GetComponent <IDamageableComponent>(); }); await server.WaitRunTicks(5); await server.WaitAssertion(() => { // First check that there actually are any damage types/groups // This test depends on a non-empty damage.yml Assert.That(sPrototypeManager.EnumeratePrototypes <DamageTypePrototype>().ToList().Count, Is.GreaterThan(0)); Assert.That(sPrototypeManager.EnumeratePrototypes <DamageGroupPrototype>().ToList().Count, Is.GreaterThan(0)); // Can we set and get all damage. Assert.That(sFullyDamageableComponent.TrySetAllDamage(-10), Is.False); Assert.That(sFullyDamageableComponent.TrySetAllDamage(0), Is.True); // Test that the all damage container supports every damage type, and that we can get, set, and change // every type with the expected results. Notable: if the damage does not change, they all return false var initialDamage = 10; foreach (var damageType in sPrototypeManager.EnumeratePrototypes <DamageTypePrototype>()) { var damage = initialDamage; Assert.That(sFullyDamageableComponent.IsSupportedDamageType(damageType)); Assert.That(sFullyDamageableComponent.TrySetDamage(damageType, -damage), Is.False); Assert.That(sFullyDamageableComponent.TrySetDamage(damageType, damage), Is.True); Assert.That(sFullyDamageableComponent.TrySetDamage(damageType, damage), Is.True); // intentional duplicate Assert.That(sFullyDamageableComponent.GetDamage(damageType), Is.EqualTo(damage)); Assert.That(sFullyDamageableComponent.TryChangeDamage(damageType, -damage / 2, true), Is.True); Assert.That(sFullyDamageableComponent.TryGetDamage(damageType, out damage), Is.True); Assert.That(damage, Is.EqualTo(initialDamage / 2)); Assert.That(sFullyDamageableComponent.TryChangeDamage(damageType, damage, true), Is.True); Assert.That(sFullyDamageableComponent.GetDamage(damageType), Is.EqualTo(2 * damage)); Assert.That(sFullyDamageableComponent.TryChangeDamage(damageType, 0, true), Is.False); } // And again, for every group foreach (var damageGroup in sPrototypeManager.EnumeratePrototypes <DamageGroupPrototype>()) { var damage = initialDamage; var groupSize = damageGroup.DamageTypes.Count(); Assert.That(sFullyDamageableComponent.IsFullySupportedDamageGroup(damageGroup)); Assert.That(sFullyDamageableComponent.IsApplicableDamageGroup(damageGroup)); Assert.That(sFullyDamageableComponent.TrySetDamage(damageGroup, -damage), Is.False); Assert.That(sFullyDamageableComponent.TrySetDamage(damageGroup, damage), Is.True); Assert.That(sFullyDamageableComponent.TrySetDamage(damageGroup, damage), Is.True); // intentional duplicate Assert.That(sFullyDamageableComponent.GetDamage(damageGroup), Is.EqualTo(damage *groupSize)); Assert.That(sFullyDamageableComponent.TryChangeDamage(damageGroup, -groupSize *damage / 2, true), Is.True); Assert.That(sFullyDamageableComponent.TryGetDamage(damageGroup, out damage), Is.True); Assert.That(damage, Is.EqualTo(groupSize *initialDamage / 2)); Assert.That(sFullyDamageableComponent.TryChangeDamage(damageGroup, damage, true), Is.True); Assert.That(sFullyDamageableComponent.GetDamage(damageGroup), Is.EqualTo(2 * damage)); Assert.That(sFullyDamageableComponent.TryChangeDamage(damageGroup, 0, true), Is.False); } }); }
public async Task Test() { var server = StartServerDummyTicker(new ServerContentIntegrationOption { ExtraPrototypes = Prototypes, ContentBeforeIoC = () => { IoCManager.Resolve <IComponentFactory>().RegisterClass <TestThresholdListenerComponent>(); } }); await server.WaitIdleAsync(); var sEntityManager = server.ResolveDependency <IEntityManager>(); var sMapManager = server.ResolveDependency <IMapManager>(); var sPrototypeManager = server.ResolveDependency <IPrototypeManager>(); IEntity sDestructibleEntity; 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(DestructibleEntityId, coordinates); sDamageableComponent = sDestructibleEntity.GetComponent <IDamageableComponent>(); sDestructibleComponent = sDestructibleEntity.GetComponent <DestructibleComponent>(); sThresholdListenerComponent = sDestructibleEntity.GetComponent <TestThresholdListenerComponent>(); }); await server.WaitRunTicks(5); await server.WaitAssertion(() => { Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); }); await server.WaitAssertion(() => { var bluntDamageType = sPrototypeManager.Index <DamageTypePrototype>("TestBlunt"); Assert.True(sDamageableComponent.TryChangeDamage(bluntDamageType, 10, true)); // No thresholds reached yet, the earliest one is at 20 damage Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); Assert.True(sDamageableComponent.TryChangeDamage(bluntDamageType, 10, true)); // Only one threshold reached, 20 Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); // Threshold 20 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); sThresholdListenerComponent.ThresholdsReached.Clear(); Assert.True(sDamageableComponent.TryChangeDamage(bluntDamageType, 30, true)); // 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]; threshold = msg.Threshold; // Check that it matches the YAML prototype Assert.That(threshold.Behaviors, Has.Count.EqualTo(3)); var soundThreshold = (PlaySoundBehavior)threshold.Behaviors[0]; var spawnThreshold = (SpawnEntitiesBehavior)threshold.Behaviors[1]; var actsThreshold = (DoActsBehavior)threshold.Behaviors[2]; Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage)); Assert.That(soundThreshold.Sound.GetSound(), Is.EqualTo("/Audio/Effects/woodhit.ogg")); Assert.That(spawnThreshold.Spawn, Is.Not.Null); Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1)); Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(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(); // Damage for 50 again, up to 100 now Assert.True(sDamageableComponent.TryChangeDamage(bluntDamageType, 50, true)); // No thresholds reached as they weren't healed below the trigger amount Assert.IsEmpty(sThresholdListenerComponent.ThresholdsReached); // Set damage to 0 sDamageableComponent.TrySetAllDamage(0); // Damage for 100, up to 100 Assert.True(sDamageableComponent.TryChangeDamage(bluntDamageType, 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.TryChangeDamage(bluntDamageType, -40, true); // Thresholds don't work backwards Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); // Damage for 10, up to 70 sDamageableComponent.TryChangeDamage(bluntDamageType, 10, true); // Not enough healing to de-trigger a threshold Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); // Heal by 30, down to 40 sDamageableComponent.TryChangeDamage(bluntDamageType, -30, true); // Thresholds don't work backwards Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); // Damage up to 50 again sDamageableComponent.TryChangeDamage(bluntDamageType, 10, true); // The 50 threshold should have triggered again, after being healed Assert.That(sThresholdListenerComponent.ThresholdsReached.Count, Is.EqualTo(1)); msg = sThresholdListenerComponent.ThresholdsReached[0]; threshold = msg.Threshold; // Check that it matches the YAML prototype Assert.That(threshold.Behaviors, Has.Count.EqualTo(3)); soundThreshold = (PlaySoundBehavior)threshold.Behaviors[0]; spawnThreshold = (SpawnEntitiesBehavior)threshold.Behaviors[1]; actsThreshold = (DoActsBehavior)threshold.Behaviors[2]; // Check that it matches the YAML prototype Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage)); Assert.That(soundThreshold.Sound.GetSound(), Is.EqualTo("/Audio/Effects/woodhit.ogg")); Assert.That(spawnThreshold.Spawn, Is.Not.Null); Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1)); Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(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 sThresholdListenerComponent.ThresholdsReached.Clear(); // Heal all damage sDamageableComponent.TrySetAllDamage(0); // Damage up to 50 sDamageableComponent.TryChangeDamage(bluntDamageType, 50, true); // Check that the total damage matches Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(50)); // Both thresholds should have triggered Assert.That(sThresholdListenerComponent.ThresholdsReached, Has.Exactly(2).Items); // Verify the first one, should be the lowest one (20) msg = sThresholdListenerComponent.ThresholdsReached[0]; var trigger = (DamageTrigger)msg.Threshold.Trigger; Assert.NotNull(trigger); Assert.That(trigger.Damage, Is.EqualTo(20)); threshold = msg.Threshold; // Check that it matches the YAML prototype Assert.That(threshold.Behaviors, Is.Empty); // Verify the second one, should be the highest one (50) msg = sThresholdListenerComponent.ThresholdsReached[1]; trigger = (DamageTrigger)msg.Threshold.Trigger; Assert.NotNull(trigger); Assert.That(trigger.Damage, Is.EqualTo(50)); threshold = msg.Threshold; Assert.That(threshold.Behaviors, Has.Count.EqualTo(3)); soundThreshold = (PlaySoundBehavior)threshold.Behaviors[0]; spawnThreshold = (SpawnEntitiesBehavior)threshold.Behaviors[1]; actsThreshold = (DoActsBehavior)threshold.Behaviors[2]; // Check that it matches the YAML prototype Assert.That(actsThreshold.Acts, Is.EqualTo(ThresholdActs.Breakage)); Assert.That(soundThreshold.Sound.GetSound(), Is.EqualTo("/Audio/Effects/woodhit.ogg")); Assert.That(spawnThreshold.Spawn, Is.Not.Null); Assert.That(spawnThreshold.Spawn.Count, Is.EqualTo(1)); Assert.That(spawnThreshold.Spawn.Single().Key, Is.EqualTo(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 sThresholdListenerComponent.ThresholdsReached.Clear(); // Heal the entity completely sDamageableComponent.TrySetAllDamage(0); // Check that the entity has 0 damage Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(0)); // Set both thresholds to only trigger once foreach (var destructibleThreshold in sDestructibleComponent.Thresholds) { Assert.NotNull(destructibleThreshold.Trigger); destructibleThreshold.TriggersOnce = true; } // Damage the entity up to 50 damage again sDamageableComponent.TryChangeDamage(bluntDamageType, 50, true); // Check that the total damage matches Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(50)); // No thresholds should have triggered as they were already triggered before, and they are set to only trigger once Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); // Set both thresholds to trigger multiple times foreach (var destructibleThreshold in sDestructibleComponent.Thresholds) { Assert.NotNull(destructibleThreshold.Trigger); destructibleThreshold.TriggersOnce = false; } // Check that the total damage matches Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(50)); // They shouldn't have been triggered by changing TriggersOnce Assert.That(sThresholdListenerComponent.ThresholdsReached, Is.Empty); }); }