@@ -1,10 +1,8 @@
|
|||||||
using Content.Server.Destructible.Thresholds.Triggers;
|
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Prototypes;
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
|
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
|
||||||
|
|
||||||
@@ -91,7 +89,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
||||||
});
|
});
|
||||||
|
|
||||||
var trigger = (AndTrigger) threshold.Trigger;
|
var trigger = (AndTrigger)threshold.Trigger;
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
@@ -162,7 +160,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
||||||
});
|
});
|
||||||
|
|
||||||
trigger = (AndTrigger) threshold.Trigger;
|
trigger = (AndTrigger)threshold.Trigger;
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Content.Server.Destructible.Thresholds.Triggers;
|
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Prototypes;
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
|
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
|
||||||
@@ -86,7 +86,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
||||||
});
|
});
|
||||||
|
|
||||||
var trigger = (AndTrigger) threshold.Trigger;
|
var trigger = (AndTrigger)threshold.Trigger;
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
@@ -154,7 +154,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
Assert.That(threshold.Trigger, Is.InstanceOf<AndTrigger>());
|
||||||
});
|
});
|
||||||
|
|
||||||
trigger = (AndTrigger) threshold.Trigger;
|
trigger = (AndTrigger)threshold.Trigger;
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Destructible.Thresholds;
|
|
||||||
using Content.Server.Destructible.Thresholds.Behaviors;
|
using Content.Server.Destructible.Thresholds.Behaviors;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Prototypes;
|
using Content.Shared.Damage.Prototypes;
|
||||||
@@ -59,7 +58,7 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
||||||
});
|
});
|
||||||
|
|
||||||
var spawnEntitiesBehavior = (SpawnEntitiesBehavior) threshold.Behaviors.Single(b => b is SpawnEntitiesBehavior);
|
var spawnEntitiesBehavior = (SpawnEntitiesBehavior)threshold.Behaviors.Single(b => b is SpawnEntitiesBehavior);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ using System.Linq;
|
|||||||
using Content.Server.Destructible;
|
using Content.Server.Destructible;
|
||||||
using Content.Server.Destructible.Thresholds;
|
using Content.Server.Destructible.Thresholds;
|
||||||
using Content.Server.Destructible.Thresholds.Behaviors;
|
using Content.Server.Destructible.Thresholds.Behaviors;
|
||||||
using Content.Server.Destructible.Thresholds.Triggers;
|
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Damage.Prototypes;
|
using Content.Shared.Damage.Prototypes;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Content.Shared.Destructible;
|
||||||
|
using Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
|
using static Content.IntegrationTests.Tests.Destructible.DestructibleTestPrototypes;
|
||||||
@@ -99,9 +99,9 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
// Check that it matches the YAML prototype
|
// Check that it matches the YAML prototype
|
||||||
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
||||||
|
|
||||||
var soundThreshold = (PlaySoundBehavior) threshold.Behaviors[0];
|
var soundThreshold = (PlaySoundBehavior)threshold.Behaviors[0];
|
||||||
var spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[1];
|
var spawnThreshold = (SpawnEntitiesBehavior)threshold.Behaviors[1];
|
||||||
var actsThreshold = (DoActsBehavior) threshold.Behaviors[2];
|
var actsThreshold = (DoActsBehavior)threshold.Behaviors[2];
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
@@ -164,9 +164,9 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
// Check that it matches the YAML prototype
|
// Check that it matches the YAML prototype
|
||||||
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
||||||
|
|
||||||
soundThreshold = (PlaySoundBehavior) threshold.Behaviors[0];
|
soundThreshold = (PlaySoundBehavior)threshold.Behaviors[0];
|
||||||
spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[1];
|
spawnThreshold = (SpawnEntitiesBehavior)threshold.Behaviors[1];
|
||||||
actsThreshold = (DoActsBehavior) threshold.Behaviors[2];
|
actsThreshold = (DoActsBehavior)threshold.Behaviors[2];
|
||||||
|
|
||||||
// Check that it matches the YAML prototype
|
// Check that it matches the YAML prototype
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
@@ -201,11 +201,11 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
|
|
||||||
// Verify the first one, should be the lowest one (20)
|
// Verify the first one, should be the lowest one (20)
|
||||||
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
|
msg = sTestThresholdListenerSystem.ThresholdsReached[0];
|
||||||
var trigger = (DamageTrigger) msg.Threshold.Trigger;
|
var trigger = (DamageTrigger)msg.Threshold.Trigger;
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(trigger, Is.Not.Null);
|
Assert.That(trigger, Is.Not.Null);
|
||||||
Assert.That(trigger.Damage, Is.EqualTo(20));
|
Assert.That(trigger.Damage, Is.EqualTo(FixedPoint2.New(20)));
|
||||||
});
|
});
|
||||||
|
|
||||||
threshold = msg.Threshold;
|
threshold = msg.Threshold;
|
||||||
@@ -215,20 +215,20 @@ namespace Content.IntegrationTests.Tests.Destructible
|
|||||||
|
|
||||||
// Verify the second one, should be the highest one (50)
|
// Verify the second one, should be the highest one (50)
|
||||||
msg = sTestThresholdListenerSystem.ThresholdsReached[1];
|
msg = sTestThresholdListenerSystem.ThresholdsReached[1];
|
||||||
trigger = (DamageTrigger) msg.Threshold.Trigger;
|
trigger = (DamageTrigger)msg.Threshold.Trigger;
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(trigger, Is.Not.Null);
|
Assert.That(trigger, Is.Not.Null);
|
||||||
Assert.That(trigger.Damage, Is.EqualTo(50));
|
Assert.That(trigger.Damage, Is.EqualTo(FixedPoint2.New(50)));
|
||||||
});
|
});
|
||||||
|
|
||||||
threshold = msg.Threshold;
|
threshold = msg.Threshold;
|
||||||
|
|
||||||
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
Assert.That(threshold.Behaviors, Has.Count.EqualTo(3));
|
||||||
|
|
||||||
soundThreshold = (PlaySoundBehavior) threshold.Behaviors[0];
|
soundThreshold = (PlaySoundBehavior)threshold.Behaviors[0];
|
||||||
spawnThreshold = (SpawnEntitiesBehavior) threshold.Behaviors[1];
|
spawnThreshold = (SpawnEntitiesBehavior)threshold.Behaviors[1];
|
||||||
actsThreshold = (DoActsBehavior) threshold.Behaviors[2];
|
actsThreshold = (DoActsBehavior)threshold.Behaviors[2];
|
||||||
|
|
||||||
// Check that it matches the YAML prototype
|
// Check that it matches the YAML prototype
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Content.Server.Body.Systems;
|
|||||||
using Content.Server.Construction;
|
using Content.Server.Construction;
|
||||||
using Content.Server.Destructible.Thresholds;
|
using Content.Server.Destructible.Thresholds;
|
||||||
using Content.Server.Destructible.Thresholds.Behaviors;
|
using Content.Server.Destructible.Thresholds.Behaviors;
|
||||||
using Content.Server.Destructible.Thresholds.Triggers;
|
|
||||||
using Content.Server.Explosion.EntitySystems;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Content.Server.Fluids.EntitySystems;
|
using Content.Server.Fluids.EntitySystems;
|
||||||
using Content.Server.Stack;
|
using Content.Server.Stack;
|
||||||
@@ -14,6 +13,7 @@ using Content.Shared.Chemistry.EntitySystems;
|
|||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Destructible;
|
using Content.Shared.Destructible;
|
||||||
|
using Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
using Content.Shared.Trigger.Systems;
|
using Content.Shared.Trigger.Systems;
|
||||||
@@ -42,24 +42,24 @@ namespace Content.Server.Destructible
|
|||||||
[Dependency] public readonly PuddleSystem PuddleSystem = default!;
|
[Dependency] public readonly PuddleSystem PuddleSystem = default!;
|
||||||
[Dependency] public readonly SharedContainerSystem ContainerSystem = default!;
|
[Dependency] public readonly SharedContainerSystem ContainerSystem = default!;
|
||||||
[Dependency] public readonly IPrototypeManager PrototypeManager = default!;
|
[Dependency] public readonly IPrototypeManager PrototypeManager = default!;
|
||||||
[Dependency] public readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] public readonly IAdminLogManager AdminLogger = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<DestructibleComponent, DamageChangedEvent>(Execute);
|
SubscribeLocalEvent<DestructibleComponent, DamageChangedEvent>(OnDamageChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if any thresholds were reached. if they were, execute them.
|
/// Check if any thresholds were reached. if they were, execute them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Execute(EntityUid uid, DestructibleComponent component, DamageChangedEvent args)
|
private void OnDamageChanged(EntityUid uid, DestructibleComponent component, DamageChangedEvent args)
|
||||||
{
|
{
|
||||||
component.IsBroken = false;
|
component.IsBroken = false;
|
||||||
|
|
||||||
foreach (var threshold in component.Thresholds)
|
foreach (var threshold in component.Thresholds)
|
||||||
{
|
{
|
||||||
if (threshold.Reached(args.Damageable, this))
|
if (Triggered(threshold, (uid, args.Damageable)))
|
||||||
{
|
{
|
||||||
RaiseLocalEvent(uid, new DamageThresholdReached(component, threshold), true);
|
RaiseLocalEvent(uid, new DamageThresholdReached(component, threshold), true);
|
||||||
|
|
||||||
@@ -82,18 +82,18 @@ namespace Content.Server.Destructible
|
|||||||
|
|
||||||
if (args.Origin != null)
|
if (args.Origin != null)
|
||||||
{
|
{
|
||||||
_adminLogger.Add(LogType.Damaged,
|
AdminLogger.Add(LogType.Damaged,
|
||||||
logImpact,
|
logImpact,
|
||||||
$"{ToPrettyString(args.Origin.Value):actor} caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]");
|
$"{ToPrettyString(args.Origin.Value):actor} caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_adminLogger.Add(LogType.Damaged,
|
AdminLogger.Add(LogType.Damaged,
|
||||||
logImpact,
|
logImpact,
|
||||||
$"Unknown damage source caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]");
|
$"Unknown damage source caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
threshold.Execute(uid, this, EntityManager, args.Origin);
|
Execute(threshold, uid, args.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threshold.OldTriggered)
|
if (threshold.OldTriggered)
|
||||||
@@ -108,6 +108,61 @@ namespace Content.Server.Destructible
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the given threshold should trigger.
|
||||||
|
/// </summary>
|
||||||
|
public bool Triggered(DamageThreshold threshold, Entity<DamageableComponent> owner)
|
||||||
|
{
|
||||||
|
if (threshold.Trigger == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (threshold.Triggered && threshold.TriggersOnce)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (threshold.OldTriggered)
|
||||||
|
{
|
||||||
|
threshold.OldTriggered = threshold.Trigger.Reached(owner, this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!threshold.Trigger.Reached(owner, this))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
threshold.OldTriggered = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the conditions for the given threshold are currently true.
|
||||||
|
/// </summary>
|
||||||
|
public bool Reached(DamageThreshold threshold, Entity<DamageableComponent> owner)
|
||||||
|
{
|
||||||
|
if (threshold.Trigger == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return threshold.Trigger.Reached(owner, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers this threshold.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="owner">The entity that owns this threshold.</param>
|
||||||
|
/// <param name="cause">The entity that caused this threshold to trigger.</param>
|
||||||
|
public void Execute(DamageThreshold threshold, EntityUid owner, EntityUid? cause = null)
|
||||||
|
{
|
||||||
|
threshold.Triggered = true;
|
||||||
|
|
||||||
|
foreach (var behavior in threshold.Behaviors)
|
||||||
|
{
|
||||||
|
// The owner has been deleted. We stop execution of behaviors here.
|
||||||
|
if (!Exists(owner))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: Replace with EntityEffects.
|
||||||
|
behavior.Execute(owner, this, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryGetDestroyedAt(Entity<DestructibleComponent?> ent, [NotNullWhen(true)] out FixedPoint2? destroyedAt)
|
public bool TryGetDestroyedAt(Entity<DestructibleComponent?> ent, [NotNullWhen(true)] out FixedPoint2? destroyedAt)
|
||||||
{
|
{
|
||||||
destroyedAt = null;
|
destroyedAt = null;
|
||||||
@@ -145,7 +200,7 @@ namespace Content.Server.Destructible
|
|||||||
if (behavior is DoActsBehavior actBehavior &&
|
if (behavior is DoActsBehavior actBehavior &&
|
||||||
actBehavior.HasAct(ThresholdActs.Destruction | ThresholdActs.Breakage))
|
actBehavior.HasAct(ThresholdActs.Destruction | ThresholdActs.Breakage))
|
||||||
{
|
{
|
||||||
damageNeeded = Math.Min(damageNeeded.Float(), trigger.Damage);
|
damageNeeded = FixedPoint2.Min(damageNeeded, trigger.Damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
namespace Content.Server.Destructible.Thresholds
|
|
||||||
{
|
|
||||||
public sealed class ActsFlags { }
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace Content.Server.Destructible.Thresholds.Behaviors
|
using Content.Shared.Destructible;
|
||||||
|
|
||||||
|
namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
|
|||||||
@@ -1,26 +1,22 @@
|
|||||||
using Content.Server.Destructible.Thresholds.Behaviors;
|
using Content.Server.Destructible.Thresholds.Behaviors;
|
||||||
using Content.Server.Destructible.Thresholds.Triggers;
|
using Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
using Content.Shared.Damage;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds
|
namespace Content.Server.Destructible.Thresholds;
|
||||||
|
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed partial class DamageThreshold
|
||||||
{
|
{
|
||||||
[DataDefinition]
|
|
||||||
public sealed partial class DamageThreshold
|
|
||||||
{
|
|
||||||
[DataField("behaviors")]
|
|
||||||
private List<IThresholdBehavior> _behaviors = new();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not this threshold was triggered in the previous call to
|
/// Whether or not this threshold was triggered in the previous call to
|
||||||
/// <see cref="Reached"/>.
|
/// <see cref="Reached"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables] public bool OldTriggered { get; private set; }
|
[ViewVariables] public bool OldTriggered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not this threshold has already been triggered.
|
/// Whether or not this threshold has already been triggered.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("triggered")]
|
[DataField]
|
||||||
public bool Triggered { get; private set; }
|
public bool Triggered;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not this threshold only triggers once.
|
/// Whether or not this threshold only triggers once.
|
||||||
@@ -28,69 +24,20 @@ namespace Content.Server.Destructible.Thresholds
|
|||||||
/// and then damaged to reach this threshold once again.
|
/// and then damaged to reach this threshold once again.
|
||||||
/// It will not repeatedly trigger as damage rises beyond that.
|
/// It will not repeatedly trigger as damage rises beyond that.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("triggersOnce")]
|
[DataField]
|
||||||
public bool TriggersOnce { get; set; }
|
public bool TriggersOnce;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The trigger that decides if this threshold has been reached.
|
/// The condition that decides if this threshold has been reached.
|
||||||
|
/// Gets evaluated each time the entity's damage changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("trigger")]
|
[DataField]
|
||||||
public IThresholdTrigger? Trigger { get; set; }
|
public IThresholdTrigger? Trigger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Behaviors to activate once this threshold is triggered.
|
/// Behaviors to activate once this threshold is triggered.
|
||||||
|
/// TODO: Replace with EntityEffects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables] public IReadOnlyList<IThresholdBehavior> Behaviors => _behaviors;
|
[DataField]
|
||||||
|
public List<IThresholdBehavior> Behaviors = new();
|
||||||
public bool Reached(DamageableComponent 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Triggers this threshold.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="owner">The entity that owns this threshold.</param>
|
|
||||||
/// <param name="system">
|
|
||||||
/// An instance of <see cref="DestructibleSystem"/> to get dependency and
|
|
||||||
/// system references from, if relevant.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="entityManager"></param>
|
|
||||||
/// <param name="cause"></param>
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, IEntityManager entityManager, EntityUid? cause)
|
|
||||||
{
|
|
||||||
Triggered = true;
|
|
||||||
|
|
||||||
foreach (var behavior in Behaviors)
|
|
||||||
{
|
|
||||||
// The owner has been deleted. We stop execution of behaviors here.
|
|
||||||
if (!entityManager.EntityExists(owner))
|
|
||||||
return;
|
|
||||||
|
|
||||||
behavior.Execute(owner, system, cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
using Robust.Shared.Serialization;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds
|
|
||||||
{
|
|
||||||
[Flags, FlagsFor(typeof(ActsFlags))]
|
|
||||||
[Serializable]
|
|
||||||
public enum ThresholdActs
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Breakage,
|
|
||||||
Destruction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Content.Shared.Damage;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds.Triggers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A trigger that will activate when all of its triggers have activated.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
[DataDefinition]
|
|
||||||
public sealed partial class AndTrigger : IThresholdTrigger
|
|
||||||
{
|
|
||||||
[DataField("triggers")]
|
|
||||||
public List<IThresholdTrigger> Triggers { get; set; } = new();
|
|
||||||
|
|
||||||
public bool Reached(DamageableComponent damageable, DestructibleSystem system)
|
|
||||||
{
|
|
||||||
foreach (var trigger in Triggers)
|
|
||||||
{
|
|
||||||
if (!trigger.Reached(damageable, system))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using Content.Shared.Damage;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
using Content.Shared.Damage.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds.Triggers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A trigger that will activate when the amount of damage received
|
|
||||||
/// of the specified class is above the specified threshold.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
[DataDefinition]
|
|
||||||
public sealed partial class DamageGroupTrigger : IThresholdTrigger
|
|
||||||
{
|
|
||||||
[DataField("damageGroup", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<DamageGroupPrototype>))]
|
|
||||||
public string DamageGroup { get; set; } = default!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of damage at which this threshold will trigger.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("damage", required: true)]
|
|
||||||
public int Damage { get; set; } = default!;
|
|
||||||
|
|
||||||
public bool Reached(DamageableComponent damageable, DestructibleSystem system)
|
|
||||||
{
|
|
||||||
return damageable.DamagePerGroup[DamageGroup] >= Damage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using Content.Shared.Damage;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds.Triggers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A trigger that will activate when the amount of damage received
|
|
||||||
/// is above the specified threshold.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
[DataDefinition]
|
|
||||||
public sealed partial class DamageTrigger : IThresholdTrigger
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The amount of damage at which this threshold will trigger.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("damage", required: true)]
|
|
||||||
public int Damage { get; set; } = default!;
|
|
||||||
|
|
||||||
public bool Reached(DamageableComponent damageable, DestructibleSystem system)
|
|
||||||
{
|
|
||||||
return damageable.TotalDamage >= Damage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using Content.Shared.Damage;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
using Content.Shared.Damage.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds.Triggers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A trigger that will activate when the amount of damage received
|
|
||||||
/// of the specified type is above the specified threshold.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
[DataDefinition]
|
|
||||||
public sealed partial class DamageTypeTrigger : IThresholdTrigger
|
|
||||||
{
|
|
||||||
[DataField("damageType", required:true, customTypeSerializer: typeof(PrototypeIdSerializer<DamageTypePrototype>))]
|
|
||||||
public string DamageType { get; set; } = default!;
|
|
||||||
|
|
||||||
[DataField("damage", required: true)]
|
|
||||||
public int Damage { get; set; } = default!;
|
|
||||||
|
|
||||||
public bool Reached(DamageableComponent damageable, DestructibleSystem system)
|
|
||||||
{
|
|
||||||
return damageable.Damage.DamageDict.TryGetValue(DamageType, out var damageReceived) &&
|
|
||||||
damageReceived >= Damage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using Content.Shared.Damage;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds.Triggers
|
|
||||||
{
|
|
||||||
public interface IThresholdTrigger
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if this trigger has been reached.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="damageable">The damageable component to check with.</param>
|
|
||||||
/// <param name="system">
|
|
||||||
/// An instance of <see cref="DestructibleSystem"/> to pull
|
|
||||||
/// dependencies from, if any.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>true if this trigger has been reached, false otherwise.</returns>
|
|
||||||
bool Reached(DamageableComponent damageable, DestructibleSystem system);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Content.Shared.Damage;
|
|
||||||
|
|
||||||
namespace Content.Server.Destructible.Thresholds.Triggers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A trigger that will activate when any of its triggers have activated.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
[DataDefinition]
|
|
||||||
public sealed partial class OrTrigger : IThresholdTrigger
|
|
||||||
{
|
|
||||||
[DataField("triggers")]
|
|
||||||
public List<IThresholdTrigger> Triggers { get; private set; } = new();
|
|
||||||
|
|
||||||
public bool Reached(DamageableComponent damageable, DestructibleSystem system)
|
|
||||||
{
|
|
||||||
foreach (var trigger in Triggers)
|
|
||||||
{
|
|
||||||
if (trigger.Reached(damageable, system))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12
Content.Shared/Destructible/ThresholdActs.cs
Normal file
12
Content.Shared/Destructible/ThresholdActs.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible;
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum ThresholdActs : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Breakage = 1 << 0,
|
||||||
|
Destruction = 1 << 1,
|
||||||
|
}
|
||||||
28
Content.Shared/Destructible/Triggers/AndTrigger.cs
Normal file
28
Content.Shared/Destructible/Triggers/AndTrigger.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A trigger that will activate when all of its triggers have activated.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed partial class AndTrigger : IThresholdTrigger
|
||||||
|
{
|
||||||
|
[DataField]
|
||||||
|
public List<IThresholdTrigger> Triggers = new();
|
||||||
|
|
||||||
|
public bool Reached(Entity<DamageableComponent> damageable, SharedDestructibleSystem system)
|
||||||
|
{
|
||||||
|
foreach (var trigger in Triggers)
|
||||||
|
{
|
||||||
|
if (!trigger.Reached(damageable, system))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Content.Shared/Destructible/Triggers/DamageGroupTrigger.cs
Normal file
33
Content.Shared/Destructible/Triggers/DamageGroupTrigger.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.FixedPoint;
|
||||||
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A trigger that will activate when the amount of damage received
|
||||||
|
/// of the specified class is above the specified threshold.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed partial class DamageGroupTrigger : IThresholdTrigger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The damage group to check for.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public ProtoId<DamageGroupPrototype> DamageGroup = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of damage at which this threshold will trigger.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public FixedPoint2 Damage = default!;
|
||||||
|
|
||||||
|
public bool Reached(Entity<DamageableComponent> damageable, SharedDestructibleSystem system)
|
||||||
|
{
|
||||||
|
return damageable.Comp.DamagePerGroup[DamageGroup] >= Damage;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Content.Shared/Destructible/Triggers/DamageTrigger.cs
Normal file
25
Content.Shared/Destructible/Triggers/DamageTrigger.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.FixedPoint;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A trigger that will activate when the total amount of damage received
|
||||||
|
/// is above the specified threshold.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed partial class DamageTrigger : IThresholdTrigger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of damage at which this threshold will trigger.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public FixedPoint2 Damage = default!;
|
||||||
|
|
||||||
|
public bool Reached(Entity<DamageableComponent> damageable, SharedDestructibleSystem system)
|
||||||
|
{
|
||||||
|
return damageable.Comp.TotalDamage >= Damage;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
Content.Shared/Destructible/Triggers/DamageTypeTrigger.cs
Normal file
34
Content.Shared/Destructible/Triggers/DamageTypeTrigger.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Content.Shared.FixedPoint;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A trigger that will activate when the amount of damage received
|
||||||
|
/// of the specified type is above the specified threshold.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed partial class DamageTypeTrigger : IThresholdTrigger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The damage type to check for.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public ProtoId<DamageTypePrototype> DamageType = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of damage at which this threshold will trigger.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(required: true)]
|
||||||
|
public FixedPoint2 Damage = default!;
|
||||||
|
|
||||||
|
public bool Reached(Entity<DamageableComponent> damageable, SharedDestructibleSystem system)
|
||||||
|
{
|
||||||
|
return damageable.Comp.Damage.DamageDict.TryGetValue(DamageType, out var damageReceived) &&
|
||||||
|
damageReceived >= Damage;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
Content.Shared/Destructible/Triggers/IThresholdTrigger.cs
Normal file
27
Content.Shared/Destructible/Triggers/IThresholdTrigger.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A condition for triggering a <see cref="DamageThreshold">.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// I decided against converting these into EntityEffectConditions for performance reasons
|
||||||
|
/// (although I did not do any benchmarks, so it might be fine).
|
||||||
|
/// Entity effects will raise a separate event for each entity and each condition, which can become a huge number
|
||||||
|
/// for cases like nuke explosions or shuttle collisions where there are lots of DamageChangedEvents at once.
|
||||||
|
/// IThresholdTriggers on the other hand are directly checked in a foreach loop without raising events.
|
||||||
|
/// And there are only few of these conditions, so there is only a minor amount of code duplication.
|
||||||
|
/// </remarks>
|
||||||
|
public interface IThresholdTrigger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if this trigger has been reached.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="damageable">The damageable component to check with.</param>
|
||||||
|
/// <param name="system">
|
||||||
|
/// An instance of <see cref="SharedDestructibleSystem"/> to pull dependencies from, if any.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>true if this trigger has been reached, false otherwise.</returns>
|
||||||
|
bool Reached(Entity<DamageableComponent> damageable, SharedDestructibleSystem system);
|
||||||
|
}
|
||||||
28
Content.Shared/Destructible/Triggers/OrTrigger.cs
Normal file
28
Content.Shared/Destructible/Triggers/OrTrigger.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Destructible.Thresholds.Triggers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A trigger that will activate when any of its triggers have activated.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed partial class OrTrigger : IThresholdTrigger
|
||||||
|
{
|
||||||
|
[DataField]
|
||||||
|
public List<IThresholdTrigger> Triggers = new();
|
||||||
|
|
||||||
|
public bool Reached(Entity<DamageableComponent> damageable, SharedDestructibleSystem system)
|
||||||
|
{
|
||||||
|
foreach (var trigger in Triggers)
|
||||||
|
{
|
||||||
|
if (trigger.Reached(damageable, system))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Content.Shared.FixedPoint;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.EntityConditions.Conditions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this entity can take damage and if its damage of a given damage group is within a specified minimum and maximum.
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="EntityConditionSystem{T, TCondition}"/>
|
||||||
|
public sealed partial class DamageGroupEntityConditionSystem : EntityConditionSystem<DamageableComponent, DamageGroupCondition>
|
||||||
|
{
|
||||||
|
protected override void Condition(Entity<DamageableComponent> entity, ref EntityConditionEvent<DamageGroupCondition> args)
|
||||||
|
{
|
||||||
|
var value = entity.Comp.DamagePerGroup[args.Condition.DamageGroup];
|
||||||
|
args.Result = value >= args.Condition.Min && value <= args.Condition.Max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="EntityCondition"/>
|
||||||
|
public sealed partial class DamageGroupCondition : EntityConditionBase<DamageGroupCondition>
|
||||||
|
{
|
||||||
|
[DataField]
|
||||||
|
public FixedPoint2 Max = FixedPoint2.MaxValue;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public FixedPoint2 Min = FixedPoint2.Zero;
|
||||||
|
|
||||||
|
[DataField(required: true)]
|
||||||
|
public ProtoId<DamageGroupPrototype> DamageGroup;
|
||||||
|
|
||||||
|
public override string EntityConditionGuidebookText(IPrototypeManager prototype) =>
|
||||||
|
Loc.GetString("reagent-effect-condition-guidebook-group-damage",
|
||||||
|
("max", Max == FixedPoint2.MaxValue ? int.MaxValue : Max.Float()),
|
||||||
|
("min", Min.Float()),
|
||||||
|
("type", prototype.Index(DamageGroup).LocalizedName));
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using Content.Shared.Damage;
|
||||||
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Content.Shared.FixedPoint;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.EntityConditions.Conditions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this entity can take damage and if its damage of a given damage type is within a specified minimum and maximum.
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="EntityConditionSystem{T, TCondition}"/>
|
||||||
|
public sealed partial class DamageTypeEntityConditionSystem : EntityConditionSystem<DamageableComponent, DamageTypeCondition>
|
||||||
|
{
|
||||||
|
protected override void Condition(Entity<DamageableComponent> entity, ref EntityConditionEvent<DamageTypeCondition> args)
|
||||||
|
{
|
||||||
|
var value = entity.Comp.Damage.DamageDict.GetValueOrDefault(args.Condition.DamageType);
|
||||||
|
args.Result = value >= args.Condition.Min && value <= args.Condition.Max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="EntityCondition"/>
|
||||||
|
public sealed partial class DamageTypeCondition : EntityConditionBase<DamageTypeCondition>
|
||||||
|
{
|
||||||
|
[DataField]
|
||||||
|
public FixedPoint2 Max = FixedPoint2.MaxValue;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public FixedPoint2 Min = FixedPoint2.Zero;
|
||||||
|
|
||||||
|
[DataField(required: true)]
|
||||||
|
public ProtoId<DamageTypePrototype> DamageType;
|
||||||
|
|
||||||
|
public override string EntityConditionGuidebookText(IPrototypeManager prototype) =>
|
||||||
|
Loc.GetString("reagent-effect-condition-guidebook-type-damage",
|
||||||
|
("max", Max == FixedPoint2.MaxValue ? int.MaxValue : Max.Float()),
|
||||||
|
("min", Min.Float()),
|
||||||
|
("type", prototype.Index(DamageType).LocalizedName));
|
||||||
|
}
|
||||||
@@ -7,6 +7,24 @@ reagent-effect-condition-guidebook-total-damage =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reagent-effect-condition-guidebook-type-damage =
|
||||||
|
{ $max ->
|
||||||
|
[2147483648] it has at least {NATURALFIXED($min, 2)} of {$type} damage
|
||||||
|
*[other] { $min ->
|
||||||
|
[0] it has at most {NATURALFIXED($max, 2)} of {$type} damage
|
||||||
|
*[other] it has between {NATURALFIXED($min, 2)} and {NATURALFIXED($max, 2)} of {$type} damage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reagent-effect-condition-guidebook-group-damage =
|
||||||
|
{ $max ->
|
||||||
|
[2147483648] it has at least {NATURALFIXED($min, 2)} of {$type} damage.
|
||||||
|
*[other] { $min ->
|
||||||
|
[0] it has at most {NATURALFIXED($max, 2)} of {$type} damage.
|
||||||
|
*[other] it has between {NATURALFIXED($min, 2)} and {NATURALFIXED($max, 2)} of {$type} damage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reagent-effect-condition-guidebook-total-hunger =
|
reagent-effect-condition-guidebook-total-hunger =
|
||||||
{ $max ->
|
{ $max ->
|
||||||
[2147483648] the target has at least {NATURALFIXED($min, 2)} total hunger
|
[2147483648] the target has at least {NATURALFIXED($min, 2)} total hunger
|
||||||
|
|||||||
Reference in New Issue
Block a user