diff --git a/Content.Server/Damage/Commands/AddDamageFlagCommand.cs b/Content.Server/Damage/Commands/AddDamageFlagCommand.cs deleted file mode 100644 index 9931608497..0000000000 --- a/Content.Server/Damage/Commands/AddDamageFlagCommand.cs +++ /dev/null @@ -1,28 +0,0 @@ -#nullable enable -using Content.Server.Administration; -using Content.Shared.Administration; -using Robust.Server.Player; -using Robust.Shared.Console; - -namespace Content.Server.Damage.Commands -{ - [AdminCommand(AdminFlags.Fun)] - public class AddDamageFlagCommand : DamageFlagCommand - { - public override string Command => "adddamageflag"; - public override string Description => "Adds a damage flag to your entity or another."; - public override string Help => $"Usage: {Command} / {Command} "; - - public override void Execute(IConsoleShell shell, string argStr, string[] args) - { - var player = shell.Player as IPlayerSession; - if (!TryGetEntity(shell, player, args, true, out var entity, out var flag, out var damageable)) - { - return; - } - - damageable.AddFlag(flag); - shell.WriteLine($"Added damage flag {flag} to entity {entity.Name}"); - } - } -} diff --git a/Content.Server/Damage/Commands/DamageFlagCommand.cs b/Content.Server/Damage/Commands/DamageFlagCommand.cs deleted file mode 100644 index be897d39cc..0000000000 --- a/Content.Server/Damage/Commands/DamageFlagCommand.cs +++ /dev/null @@ -1,116 +0,0 @@ -#nullable enable -using System; -using System.Diagnostics.CodeAnalysis; -using Content.Shared.Damage; -using Content.Shared.Damage.Components; -using Robust.Server.Player; -using Robust.Shared.Console; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; - -namespace Content.Server.Damage.Commands -{ - public abstract class DamageFlagCommand : IConsoleCommand - { - public abstract string Command { get; } - public abstract string Description { get; } - public abstract string Help { get; } - - public abstract void Execute(IConsoleShell shell, string argStr, string[] args); - - public bool TryGetEntity( - IConsoleShell shell, - IPlayerSession? player, - string[] args, - bool adding, - [NotNullWhen(true)] out IEntity? entity, - out DamageFlag flag, - [NotNullWhen(true)] out IDamageableComponent? damageable) - { - entity = null; - flag = DamageFlag.None; - damageable = null; - - IEntity? parsedEntity; - DamageFlag parsedFlag; - IDamageableComponent? parsedDamageable; - - switch (args.Length) - { - case 1: - { - if (player == null) - { - shell.WriteLine("An entity needs to be specified when the command isn't used by a player."); - return false; - } - - if (player.AttachedEntity == null) - { - shell.WriteLine("An entity needs to be specified when you aren't attached to an entity."); - return false; - } - - if (!Enum.TryParse(args[0], true, out parsedFlag)) - { - shell.WriteLine($"{args[0]} is not a valid damage flag."); - return false; - } - - parsedEntity = player.AttachedEntity; - flag = parsedFlag; - break; - } - case 2: - { - if (!EntityUid.TryParse(args[0], out var id)) - { - shell.WriteLine($"{args[0]} isn't a valid entity id."); - return false; - } - - var entityManager = IoCManager.Resolve(); - if (!entityManager.TryGetEntity(id, out parsedEntity)) - { - shell.WriteLine($"No entity found with id {id}."); - return false; - } - - if (!Enum.TryParse(args[1], true, out parsedFlag)) - { - shell.WriteLine($"{args[1]} is not a valid damage flag."); - return false; - } - - break; - } - default: - shell.WriteLine(Help); - return false; - } - - if (!parsedEntity.TryGetComponent(out parsedDamageable)) - { - shell.WriteLine($"Entity {parsedEntity.Name} doesn't have a {nameof(IDamageableComponent)}"); - return false; - } - - if (parsedDamageable.HasFlag(parsedFlag) && adding) - { - shell.WriteLine($"Entity {parsedEntity.Name} already has damage flag {parsedFlag}."); - return false; - } - else if (!parsedDamageable.HasFlag(parsedFlag) && !adding) - { - shell.WriteLine($"Entity {parsedEntity.Name} doesn't have damage flag {parsedFlag}."); - return false; - } - - entity = parsedEntity; - flag = parsedFlag; - damageable = parsedDamageable; - - return true; - } - } -} diff --git a/Content.Server/Damage/Commands/RemoveDamageFlagCommand.cs b/Content.Server/Damage/Commands/RemoveDamageFlagCommand.cs deleted file mode 100644 index 39322ab316..0000000000 --- a/Content.Server/Damage/Commands/RemoveDamageFlagCommand.cs +++ /dev/null @@ -1,28 +0,0 @@ -#nullable enable -using Content.Server.Administration; -using Content.Shared.Administration; -using Robust.Server.Player; -using Robust.Shared.Console; - -namespace Content.Server.Damage.Commands -{ - [AdminCommand(AdminFlags.Fun)] - public class RemoveDamageFlagCommand : DamageFlagCommand - { - public override string Command => "removedamageflag"; - public override string Description => "Removes a damage flag from your entity or another."; - public override string Help => $"Usage: {Command} / {Command} "; - - public override void Execute(IConsoleShell shell, string argStr, string[] args) - { - var player = shell.Player as IPlayerSession; - if (!TryGetEntity(shell, player, args, false, out var entity, out var flag, out var damageable)) - { - return; - } - - damageable.RemoveFlag(flag); - shell.WriteLine($"Removed damage flag {flag} from entity {entity.Name}"); - } - } -} diff --git a/Content.Server/Damage/GodmodeSystem.cs b/Content.Server/Damage/GodmodeSystem.cs index c768fcb1fa..08f9fc0fc4 100644 --- a/Content.Server/Damage/GodmodeSystem.cs +++ b/Content.Server/Damage/GodmodeSystem.cs @@ -1,8 +1,10 @@ #nullable enable using System.Collections.Generic; +using System.Linq; using Content.Server.GameObjects.Components.Atmos; using Content.Shared.Damage; using Content.Shared.Damage.Components; +using Content.Shared.Damage.Resistances; using Content.Shared.GameTicking; using JetBrains.Annotations; using Robust.Shared.GameObjects; @@ -35,7 +37,8 @@ namespace Content.Server.Damage if (entity.TryGetComponent(out IDamageableComponent? damageable)) { - damageable.AddFlag(DamageFlag.Invulnerable); + damageable.SupportedTypes.Clear(); + damageable.SupportedClasses.Clear(); } return true; @@ -60,7 +63,15 @@ namespace Content.Server.Damage if (entity.TryGetComponent(out IDamageableComponent? damageable)) { - damageable.RemoveFlag(DamageFlag.Invulnerable); + if (old.SupportedTypes != null) + { + damageable.SupportedTypes.UnionWith(old.SupportedTypes); + } + + if (old.SupportedClasses != null) + { + damageable.SupportedClasses.UnionWith(old.SupportedClasses); + } } return true; @@ -91,10 +102,21 @@ namespace Content.Server.Damage { Entity = entity; MovedByPressure = entity.IsMovedByPressure(); + + if (entity.TryGetComponent(out IDamageableComponent? damageable)) + { + SupportedTypes = damageable.SupportedTypes.ToHashSet(); + SupportedClasses = damageable.SupportedClasses.ToHashSet(); + } } public IEntity Entity { get; } + public bool MovedByPressure { get; } + + public HashSet? SupportedTypes { get; } + + public HashSet? SupportedClasses { get; } } } } diff --git a/Content.Shared/Damage/Components/DamageableComponent.cs b/Content.Shared/Damage/Components/DamageableComponent.cs index ec3d50c731..8c76135f24 100644 --- a/Content.Shared/Damage/Components/DamageableComponent.cs +++ b/Content.Shared/Damage/Components/DamageableComponent.cs @@ -35,67 +35,32 @@ namespace Content.Shared.Damage.Components private readonly Dictionary _damageList = DamageTypeExtensions.ToNewDictionary(); - private readonly HashSet _supportedTypes = new(); - - private readonly HashSet _supportedClasses = new(); - - [DataField("flags")] - private DamageFlag _flags; - [DataField("resistances")] public string ResistanceSetId = DefaultResistanceSet; // TODO DAMAGE Use as default values, specify overrides in a separate property through yaml for better (de)serialization [ViewVariables] [DataField("damageContainer")] public string DamageContainerId { get; set; } = DefaultDamageContainer; - [ViewVariables] private ResistanceSet Resistances { get; set; } = new(); + [ViewVariables] public ResistanceSet Resistances { get; set; } = new(); // TODO DAMAGE Cache this [ViewVariables] public int TotalDamage => _damageList.Values.Sum(); - [ViewVariables] - public IReadOnlyDictionary DamageClasses => - DamageTypeExtensions.ToClassDictionary(_damageList); + [ViewVariables] public IReadOnlyDictionary DamageClasses => _damageList.ToClassDictionary(); [ViewVariables] public IReadOnlyDictionary DamageTypes => _damageList; - public DamageFlag Flags - { - get => _flags; - private set - { - if (_flags == value) - { - return; - } + [ViewVariables] public HashSet SupportedTypes { get; } = new(); - _flags = value; - Dirty(); - } - } - - public void AddFlag(DamageFlag flag) - { - Flags |= flag; - } - - public bool HasFlag(DamageFlag flag) - { - return Flags.HasFlag(flag); - } - - public void RemoveFlag(DamageFlag flag) - { - Flags &= ~flag; - } + [ViewVariables] public HashSet SupportedClasses { get; } = new(); public bool SupportsDamageClass(DamageClass @class) { - return _supportedClasses.Contains(@class); + return SupportedClasses.Contains(@class); } public bool SupportsDamageType(DamageType type) { - return _supportedTypes.Contains(type); + return SupportedTypes.Contains(type); } public override void Initialize() @@ -107,12 +72,12 @@ namespace Content.Shared.Damage.Components // TODO DAMAGE Serialize damage done and resistance changes var damagePrototype = prototypeManager.Index(DamageContainerId); - _supportedClasses.Clear(); - _supportedTypes.Clear(); + SupportedClasses.Clear(); + SupportedTypes.Clear(); DamageContainerId = damagePrototype.ID; - _supportedClasses.UnionWith(damagePrototype.SupportedClasses); - _supportedTypes.UnionWith(damagePrototype.SupportedTypes); + SupportedClasses.UnionWith(damagePrototype.SupportedClasses); + SupportedTypes.UnionWith(damagePrototype.SupportedTypes); var resistancePrototype = prototypeManager.Index(ResistanceSetId); Resistances = new ResistanceSet(resistancePrototype); @@ -127,7 +92,7 @@ namespace Content.Shared.Damage.Components public override ComponentState GetComponentState(ICommonSession player) { - return new DamageableComponentState(_damageList, _flags); + return new DamageableComponentState(_damageList); } public override void HandleComponentState(ComponentState? curState, ComponentState? nextState) @@ -145,8 +110,6 @@ namespace Content.Shared.Damage.Components { _damageList[type] = damage; } - - _flags = state.Flags; } public int GetDamage(DamageType type) @@ -203,7 +166,7 @@ namespace Content.Shared.Damage.Components var damageClass = type.ToClass(); - if (_supportedClasses.Contains(damageClass)) + if (SupportedClasses.Contains(damageClass)) { var old = _damageList[type] = newValue; _damageList[type] = newValue; @@ -227,7 +190,7 @@ namespace Content.Shared.Damage.Components public void Heal() { - foreach (var type in _supportedTypes) + foreach (var type in SupportedTypes) { Heal(type); } @@ -240,11 +203,6 @@ namespace Content.Shared.Damage.Components IEntity? source = null, DamageChangeParams? extraParams = null) { - if (amount > 0 && HasFlag(DamageFlag.Invulnerable)) - { - return false; - } - if (!SupportsDamageType(type)) { return false; @@ -291,11 +249,6 @@ namespace Content.Shared.Damage.Components IEntity? source = null, DamageChangeParams? extraParams = null) { - if (amount > 0 && HasFlag(DamageFlag.Invulnerable)) - { - return false; - } - if (!SupportsDamageClass(@class)) { return false; @@ -374,7 +327,7 @@ namespace Content.Shared.Damage.Components public bool SetDamage(DamageType type, int newValue, IEntity? source = null, DamageChangeParams? extraParams = null) { - if (newValue >= TotalDamage && HasFlag(DamageFlag.Invulnerable)) + if (newValue >= TotalDamage) { return false; } @@ -405,7 +358,7 @@ namespace Content.Shared.Damage.Components { var data = new List(); - foreach (var type in _supportedTypes) + foreach (var type in SupportedTypes) { var damage = GetDamage(type); var datum = new DamageChangeData(type, damage, 0); @@ -457,12 +410,10 @@ namespace Content.Shared.Damage.Components public class DamageableComponentState : ComponentState { public readonly Dictionary DamageList; - public readonly DamageFlag Flags; - public DamageableComponentState(Dictionary damageList, DamageFlag flags) : base(ContentNetIDs.DAMAGEABLE) + public DamageableComponentState(Dictionary damageList) : base(ContentNetIDs.DAMAGEABLE) { DamageList = damageList; - Flags = flags; } } } diff --git a/Content.Shared/Damage/Components/IDamageableComponent.cs b/Content.Shared/Damage/Components/IDamageableComponent.cs index 54ed2cad35..6f51161d8d 100644 --- a/Content.Shared/Damage/Components/IDamageableComponent.cs +++ b/Content.Shared/Damage/Components/IDamageableComponent.cs @@ -1,6 +1,7 @@ #nullable enable using System.Collections.Generic; using Content.Shared.Acts; +using Content.Shared.Damage.Resistances; using Robust.Shared.GameObjects; namespace Content.Shared.Damage.Components @@ -22,29 +23,14 @@ namespace Content.Shared.Damage.Components /// IReadOnlyDictionary DamageTypes { get; } - /// - /// The damage flags on this component. - /// - DamageFlag Flags { get; } + HashSet SupportedTypes { get; } + + HashSet SupportedClasses { get; } /// - /// Adds a flag to this component. + /// The resistances of this component. /// - /// The flag to add. - void AddFlag(DamageFlag flag); - - /// - /// Checks whether or not this component has a specific flag. - /// - /// The flag to check for. - /// True if it has the flag, false otherwise. - bool HasFlag(DamageFlag flag); - - /// - /// Removes a flag from this component. - /// - /// The flag to remove. - void RemoveFlag(DamageFlag flag); + ResistanceSet Resistances { get; } bool SupportsDamageClass(DamageClass @class); diff --git a/Content.Shared/Damage/DamageFlag.cs b/Content.Shared/Damage/DamageFlag.cs deleted file mode 100644 index c0d04ac348..0000000000 --- a/Content.Shared/Damage/DamageFlag.cs +++ /dev/null @@ -1,14 +0,0 @@ -#nullable enable -using System; -using Robust.Shared.Serialization; - -namespace Content.Shared.Damage -{ - [Flags] - [Serializable, NetSerializable] - public enum DamageFlag - { - None = 0, - Invulnerable = 1 << 0 - } -} diff --git a/Content.Shared/Damage/DamageType.cs b/Content.Shared/Damage/DamageType.cs index c0ebb1b252..c639c86ac1 100644 --- a/Content.Shared/Damage/DamageType.cs +++ b/Content.Shared/Damage/DamageType.cs @@ -42,7 +42,7 @@ namespace Content.Shared.Damage return ToNewDictionary(); } - public static Dictionary ToClassDictionary(IReadOnlyDictionary types) + public static Dictionary ToClassDictionary(this IReadOnlyDictionary types) { var classes = DamageClassExtensions.ToNewDictionary(); diff --git a/Content.Shared/Damage/Resistances/ResistanceSet.cs b/Content.Shared/Damage/Resistances/ResistanceSet.cs index 1c3300a78c..81a9fb6973 100644 --- a/Content.Shared/Damage/Resistances/ResistanceSet.cs +++ b/Content.Shared/Damage/Resistances/ResistanceSet.cs @@ -11,30 +11,29 @@ namespace Content.Shared.Damage.Resistances /// Each has a multiplier and flat damage /// reduction value. /// - [NetSerializable] - [Serializable] + [Serializable, NetSerializable] public class ResistanceSet { - [ViewVariables] - private Dictionary _resistances = - new(); - public ResistanceSet() { foreach (var damageType in (DamageType[]) Enum.GetValues(typeof(DamageType))) { - _resistances.Add(damageType, new ResistanceSetSettings(1f, 0)); + Resistances.Add(damageType, new ResistanceSetSettings(1f, 0)); } } public ResistanceSet(ResistanceSetPrototype data) { ID = data.ID; - _resistances = data.Resistances; + Resistances = data.Resistances; } + [ViewVariables] public string ID { get; } = string.Empty; + [ViewVariables] + public Dictionary Resistances { get; } = new(); + /// /// Adjusts input damage with the resistance set values. /// Only applies reduction if the amount is damage (positive), not @@ -46,7 +45,7 @@ namespace Content.Shared.Damage.Resistances { if (amount > 0) // Only apply reduction if it's healing, not damage. { - amount -= _resistances[damageType].FlatReduction; + amount -= Resistances[damageType].FlatReduction; if (amount <= 0) { @@ -54,7 +53,7 @@ namespace Content.Shared.Damage.Resistances } } - amount = (int) Math.Ceiling(amount * _resistances[damageType].Coefficient); + amount = (int) Math.Ceiling(amount * Resistances[damageType].Coefficient); return amount; } @@ -64,11 +63,10 @@ namespace Content.Shared.Damage.Resistances /// Settings for a specific damage type in a resistance set. Flat reduction is applied before the coefficient. /// [Serializable, NetSerializable] - public struct ResistanceSetSettings + public readonly struct ResistanceSetSettings { - [ViewVariables] public float Coefficient { get; private set; } - - [ViewVariables] public int FlatReduction { get; private set; } + [ViewVariables] public readonly float Coefficient; + [ViewVariables] public readonly int FlatReduction; public ResistanceSetSettings(float coefficient, int flatReduction) {