diff --git a/Content.Client/Armor/ArmorSystem.cs b/Content.Client/Armor/ArmorSystem.cs new file mode 100644 index 0000000000..a4116d2f7a --- /dev/null +++ b/Content.Client/Armor/ArmorSystem.cs @@ -0,0 +1,9 @@ +using Content.Shared.Armor; + +namespace Content.Client.Armor; + +/// +public sealed class ArmorSystem : SharedArmorSystem +{ + +} diff --git a/Content.Server/Armor/ArmorComponent.cs b/Content.Server/Armor/ArmorComponent.cs deleted file mode 100644 index 09be3bf240..0000000000 --- a/Content.Server/Armor/ArmorComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Content.Shared.Damage; - -namespace Content.Server.Armor -{ - [RegisterComponent] - public sealed partial class ArmorComponent : Component - { - [DataField("modifiers", required: true)] - public DamageModifierSet Modifiers = default!; - } -} diff --git a/Content.Server/Armor/ArmorSystem.cs b/Content.Server/Armor/ArmorSystem.cs index dc02b06667..dc4b3c7935 100644 --- a/Content.Server/Armor/ArmorSystem.cs +++ b/Content.Server/Armor/ArmorSystem.cs @@ -1,125 +1,34 @@ -using Content.Shared.Damage; -using Content.Server.Examine; -using Content.Shared.Verbs; -using Robust.Shared.Utility; using Content.Server.Cargo.Systems; +using Content.Shared.Armor; using Robust.Shared.Prototypes; using Content.Shared.Damage.Prototypes; -using Content.Shared.Inventory; -using Content.Shared.Silicons.Borgs; -namespace Content.Server.Armor +namespace Content.Server.Armor; + +/// +public sealed class ArmorSystem : SharedArmorSystem { - public sealed class ArmorSystem : EntitySystem + [Dependency] private readonly IPrototypeManager _protoManager = default!; + + public override void Initialize() { - const double CoefDefaultPrice = 2; // default price of 1% protection against any type of damage - const double FlatDefaultPrice = 10; //default price of 1 damage protection against a certain type of damage + base.Initialize(); - [Dependency] private readonly ExamineSystem _examine = default!; - [Dependency] private readonly IPrototypeManager _protoManager = default!; + SubscribeLocalEvent(GetArmorPrice); + } - public override void Initialize() + private void GetArmorPrice(EntityUid uid, ArmorComponent component, ref PriceCalculationEvent args) + { + foreach (var modifier in component.Modifiers.Coefficients) { - base.Initialize(); - - SubscribeLocalEvent>(OnDamageModify); - SubscribeLocalEvent>(OnBorgDamageModify); - SubscribeLocalEvent>(OnArmorVerbExamine); - SubscribeLocalEvent(GetArmorPrice); + var damageType = _protoManager.Index(modifier.Key); + args.Price += damageType.ArmorPriceCoefficient * 100 * (1 - modifier.Value); } - private void GetArmorPrice(EntityUid uid, ArmorComponent component, ref PriceCalculationEvent args) + foreach (var modifier in component.Modifiers.FlatReduction) { - if (component.Modifiers == null) - return; - - double price = 0; - - foreach (var modifier in component.Modifiers.Coefficients) - { - _protoManager.TryIndex(modifier.Key, out DamageTypePrototype? damageType); - - if (damageType != null) - { - price += damageType.ArmorPriceCoefficient * 100 * (1 - modifier.Value); - } - else - { - price += CoefDefaultPrice * 100 * (1 - modifier.Value); - } - } - foreach (var modifier in component.Modifiers.FlatReduction) - { - _protoManager.TryIndex(modifier.Key, out DamageTypePrototype? damageType); - - if (damageType != null) - { - price += damageType.ArmorPriceFlat * modifier.Value; - } - else - { - price += FlatDefaultPrice * modifier.Value; - } - } - args.Price += price; - } - - private void OnDamageModify(EntityUid uid, ArmorComponent component, InventoryRelayedEvent args) - { - args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); - } - - private void OnBorgDamageModify(EntityUid uid, ArmorComponent component, ref BorgModuleRelayedEvent args) - { - args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); - } - - private void OnArmorVerbExamine(EntityUid uid, ArmorComponent component, GetVerbsEvent args) - { - if (!args.CanInteract || !args.CanAccess) - return; - - var armorModifiers = component.Modifiers; - - if (armorModifiers == null) - return; - - var examineMarkup = GetArmorExamine(armorModifiers); - - var ev = new ArmorExamineEvent(examineMarkup); - RaiseLocalEvent(uid, ref ev); - - _examine.AddDetailedExamineVerb(args, component, examineMarkup, Loc.GetString("armor-examinable-verb-text"), "/Textures/Interface/VerbIcons/dot.svg.192dpi.png", Loc.GetString("armor-examinable-verb-message")); - } - - private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers) - { - var msg = new FormattedMessage(); - - msg.AddMarkup(Loc.GetString("armor-examine")); - - foreach (var coefficientArmor in armorModifiers.Coefficients) - { - msg.PushNewline(); - msg.AddMarkup(Loc.GetString("armor-coefficient-value", - ("type", coefficientArmor.Key), - ("value", MathF.Round((1f - coefficientArmor.Value) * 100,1)) - )); - } - - foreach (var flatArmor in armorModifiers.FlatReduction) - { - msg.PushNewline(); - msg.AddMarkup(Loc.GetString("armor-reduction-value", - ("type", flatArmor.Key), - ("value", flatArmor.Value) - )); - } - - return msg; + var damageType = _protoManager.Index(modifier.Key); + args.Price += damageType.ArmorPriceFlat * modifier.Value; } } } - -[ByRefEvent] -public record struct ArmorExamineEvent(FormattedMessage Msg); diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 06c95383fc..aa007c61c0 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Chat.Managers; using Content.Server.Explosion.Components; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NPC.Pathfinding; +using Content.Shared.Armor; using Content.Shared.Camera; using Content.Shared.CCVar; using Content.Shared.Damage; diff --git a/Content.Shared/Armor/ArmorComponent.cs b/Content.Shared/Armor/ArmorComponent.cs new file mode 100644 index 0000000000..a1bb75923f --- /dev/null +++ b/Content.Shared/Armor/ArmorComponent.cs @@ -0,0 +1,25 @@ +using Content.Shared.Damage; +using Robust.Shared.GameStates; +using Robust.Shared.Utility; + +namespace Content.Shared.Armor; + +/// +/// Used for clothing that reduces damage when worn. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(SharedArmorSystem))] +public sealed partial class ArmorComponent : Component +{ + /// + /// The damage reduction + /// + [DataField(required: true)] + public DamageModifierSet Modifiers = default!; +} + +/// +/// Event raised on an armor entity to get additional examine text relating to its armor. +/// +/// +[ByRefEvent] +public record struct ArmorExamineEvent(FormattedMessage Msg); diff --git a/Content.Shared/Armor/SharedArmorSystem.cs b/Content.Shared/Armor/SharedArmorSystem.cs new file mode 100644 index 0000000000..89141fcbd3 --- /dev/null +++ b/Content.Shared/Armor/SharedArmorSystem.cs @@ -0,0 +1,78 @@ +using Content.Shared.Damage; +using Content.Shared.Examine; +using Content.Shared.Inventory; +using Content.Shared.Silicons.Borgs; +using Content.Shared.Verbs; +using Robust.Shared.Utility; + +namespace Content.Shared.Armor; + +/// +/// This handles logic relating to +/// +public abstract class SharedArmorSystem : EntitySystem +{ + [Dependency] private readonly ExamineSystemShared _examine = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnDamageModify); + SubscribeLocalEvent>(OnBorgDamageModify); + SubscribeLocalEvent>(OnArmorVerbExamine); + } + + private void OnDamageModify(EntityUid uid, ArmorComponent component, InventoryRelayedEvent args) + { + args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); + } + + private void OnBorgDamageModify(EntityUid uid, ArmorComponent component, ref BorgModuleRelayedEvent args) + { + args.Args.Damage = DamageSpecifier.ApplyModifierSet(args.Args.Damage, component.Modifiers); + } + + private void OnArmorVerbExamine(EntityUid uid, ArmorComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + var examineMarkup = GetArmorExamine(component.Modifiers); + + var ev = new ArmorExamineEvent(examineMarkup); + RaiseLocalEvent(uid, ref ev); + + _examine.AddDetailedExamineVerb(args, component, examineMarkup, + Loc.GetString("armor-examinable-verb-text"), "/Textures/Interface/VerbIcons/dot.svg.192dpi.png", + Loc.GetString("armor-examinable-verb-message")); + } + + private FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers) + { + var msg = new FormattedMessage(); + + msg.AddMarkup(Loc.GetString("armor-examine")); + + foreach (var coefficientArmor in armorModifiers.Coefficients) + { + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("armor-coefficient-value", + ("type", coefficientArmor.Key), + ("value", MathF.Round((1f - coefficientArmor.Value) * 100,1)) + )); + } + + foreach (var flatArmor in armorModifiers.FlatReduction) + { + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("armor-reduction-value", + ("type", flatArmor.Key), + ("value", flatArmor.Value) + )); + } + + return msg; + } +} diff --git a/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml b/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml index d807bcc5a9..4a8fa0da5c 100644 --- a/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml +++ b/Resources/Prototypes/Entities/Objects/Vehicles/buckleable.yml @@ -39,7 +39,7 @@ sound: path: /Audio/Effects/metalbreak.ogg - !type:ExplodeBehavior - + - type: entity parent: BaseVehicle id: BaseVehicleRideable @@ -198,7 +198,7 @@ baseSprintSpeed: 6 - type: Armor modifiers: - coeffecients: + coefficients: Blunt: 0.8 Slash: 0.6 Piercing: 0.85 @@ -289,7 +289,7 @@ maxBuckleDistance: 1 - type: Armor modifiers: - coeffecients: + coefficients: Blunt: 0.8 Slash: 0.6 Piercing: 0.85