Merge branch 'master' into expl_int_analyzer

This commit is contained in:
Pieter-Jan Briers
2021-02-08 22:46:28 +01:00
140 changed files with 3622 additions and 1208 deletions

View File

@@ -22,22 +22,15 @@ namespace Content.Server.GameObjects.Components.Destructible
public override string Name => "Destructible";
[ViewVariables]
private SortedDictionary<int, Threshold> _lowestToHighestThresholds = new();
[ViewVariables] private List<Threshold> _thresholds = new();
[ViewVariables] private int PreviousTotalDamage { get; set; }
public IReadOnlyDictionary<int, Threshold> LowestToHighestThresholds => _lowestToHighestThresholds;
public IReadOnlyList<Threshold> Thresholds => _thresholds;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataReadWriteFunction(
"thresholds",
new Dictionary<int, Threshold>(),
thresholds => _lowestToHighestThresholds = new SortedDictionary<int, Threshold>(thresholds),
() => new Dictionary<int, Threshold>(_lowestToHighestThresholds));
serializer.DataField(ref _thresholds, "thresholds", new List<Threshold>());
}
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;
}
}

View File

@@ -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; }
/// <summary>
/// The amount of total damage currently had that triggered this threshold.
/// </summary>
public int TotalDamage { get; }
/// <summary>
/// The amount of damage at which this threshold triggers.
/// </summary>
public int ThresholdAmount { get; }
}
}

View File

@@ -1,11 +1,13 @@
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.Interfaces.Serialization;
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;
@@ -30,7 +32,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))
{

View File

@@ -5,7 +5,7 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
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
@@ -17,7 +17,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))
{

View File

@@ -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
{
/// <summary>
/// Triggers this behavior.
/// Executes this behavior.
/// </summary>
/// <param name="owner">The entity that owns this behavior.</param>
/// <param name="system">
/// An instance of <see cref="DestructibleSystem"/> to pull dependencies
/// and other systems from.
/// </param>
void Trigger(IEntity owner, DestructibleSystem system);
void Execute(IEntity owner, DestructibleSystem system);
}
}

View File

@@ -1,11 +1,13 @@
using Content.Server.GameObjects.EntitySystems;
using System;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Audio;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
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
{
/// <summary>
@@ -18,7 +20,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))
{

View File

@@ -1,11 +1,13 @@
using Content.Server.GameObjects.EntitySystems;
using System;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Audio;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
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
{
/// <summary>
@@ -18,7 +20,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))
{

View File

@@ -1,4 +1,5 @@
#nullable enable
using System;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Stack;
using Content.Server.GameObjects.EntitySystems;
@@ -7,8 +8,9 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
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
{
/// <summary>
@@ -21,7 +23,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Behavior
serializer.DataField(this, x => x.Spawn, "spawn", new Dictionary<string, MinMax>());
}
public void Trigger(IEntity owner, DestructibleSystem system)
public void Execute(IEntity owner, DestructibleSystem system)
{
foreach (var (entityId, minMax) in Spawn)
{

View File

@@ -7,14 +7,14 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
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
{
void IExposeData.ExposeData(ObjectSerializer serializer) { }
public void Trigger(IEntity owner, DestructibleSystem system)
public void Execute(IEntity owner, DestructibleSystem system)
{
if (!owner.TryGetComponent(out SolutionContainerComponent? solutionContainer))
return;

View File

@@ -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]

View File

@@ -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<IThresholdBehavior> _behaviors = new();
/// <summary>
/// Whether or not this threshold was triggered in the previous call to
/// <see cref="Reached"/>.
/// </summary>
[ViewVariables] public bool OldTriggered { get; private set; }
/// <summary>
/// Whether or not this threshold has already been triggered.
/// </summary>
@@ -26,6 +34,11 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds
/// </summary>
[ViewVariables] public bool TriggersOnce { get; set; }
/// <summary>
/// The trigger that decides if this threshold has been reached.
/// </summary>
[ViewVariables] public IThresholdTrigger? Trigger { get; set; }
/// <summary>
/// Behaviors to activate once this threshold is triggered.
/// </summary>
@@ -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<IThresholdBehavior>());
}
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;
}
/// <summary>
/// Triggers this threshold.
/// </summary>
@@ -46,7 +87,7 @@ namespace Content.Server.GameObjects.Components.Destructible.Thresholds
/// An instance of <see cref="DestructibleSystem"/> to get dependency and
/// system references from, if relevant.
/// </param>
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);
}
}
}

View File

@@ -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
{
/// <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(IDamageableComponent damageable, DestructibleSystem system);
}
}

View File

@@ -0,0 +1,48 @@
#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.Interfaces.Serialization;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers
{
/// <summary>
/// A trigger that will activate when all of the damage classes received
/// are above the specified threshold.
/// </summary>
[Serializable]
public class TotalDamageClassesTrigger : IThresholdTrigger
{
/// <summary>
/// The amount of damage at which this threshold will trigger.
/// The damage requirements of all <see cref="DamageClass"/> must be met.
/// </summary>
private Dictionary<DamageClass, int> Damage { get; set; } = new();
void IExposeData.ExposeData(ObjectSerializer serializer)
{
serializer.DataField(this, x => x.Damage, "damage", new Dictionary<DamageClass, int>());
}
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;
}
}
}

View File

@@ -0,0 +1,32 @@
#nullable enable
using System;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Damage;
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers
{
/// <summary>
/// A trigger that will activate when the amount of total damage received
/// is above the specified threshold.
/// </summary>
[Serializable]
public class TotalDamageTrigger : IThresholdTrigger
{
/// <summary>
/// The amount of total damage at which this threshold will trigger.
/// </summary>
public int Damage { get; private set; }
void IExposeData.ExposeData(ObjectSerializer serializer)
{
serializer.DataField(this, x => x.Damage, "damage", 0);
}
public bool Reached(IDamageableComponent damageable, DestructibleSystem system)
{
return damageable.TotalDamage >= Damage;
}
}
}

View File

@@ -0,0 +1,48 @@
#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.Interfaces.Serialization;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Destructible.Thresholds.Triggers
{
/// <summary>
/// A trigger that will activate when all of the damage types received
/// are above the specified threshold.
/// </summary>
[Serializable]
public class TotalDamageTypesTrigger : IThresholdTrigger
{
/// <summary>
/// The amount of damage at which this threshold will trigger.
/// The damage requirements of all <see cref="DamageType"/> must be met.
/// </summary>
private Dictionary<DamageType, int> Damage { get; set; } = new();
void IExposeData.ExposeData(ObjectSerializer serializer)
{
serializer.DataField(this, x => x.Damage, "damage", new Dictionary<DamageType, int>());
}
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;
}
}
}