From 498d070a73227dedb9e08636a6f574682b86f0d3 Mon Sep 17 00:00:00 2001 From: "Tad \"Taddy\" Johnson" <120885811+TadJohnson00@users.noreply.github.com> Date: Wed, 7 Aug 2024 05:05:46 +1000 Subject: [PATCH 1/6] Remove Overlay Restrict From Vulps (#683) # Description As title, will allow players to put as many overlay markings as required for their vulps. --- # Changelog :cl: TJohnson - tweak: Removed overlay restriction for vulps, you can now have as many overlay markings as you want! Signed-off-by: Tad "Taddy" Johnson <120885811+TadJohnson00@users.noreply.github.com> --- Resources/Prototypes/DeltaV/Species/vulpkanin.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Resources/Prototypes/DeltaV/Species/vulpkanin.yml b/Resources/Prototypes/DeltaV/Species/vulpkanin.yml index 8a3cd4c47ce..e139279dd5c 100644 --- a/Resources/Prototypes/DeltaV/Species/vulpkanin.yml +++ b/Resources/Prototypes/DeltaV/Species/vulpkanin.yml @@ -62,9 +62,6 @@ points: 1 required: true defaultMarkings: [ VulpEar ] - Overlay: - points: 2 - required: false - type: humanoidBaseSprite id: MobVulpkaninHead From cb3ddd458132809a21f0bfc38028f0ed79795b83 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:06:41 +0000 Subject: [PATCH 2/6] Automatic Changelog Update (#683) --- Resources/Changelog/Changelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 01f1a833faf..39fcb78cfa7 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4969,3 +4969,11 @@ Entries: toxin/airloss damage. id: 6221 time: '2024-08-06T08:05:59.0000000+00:00' +- author: TJohnson + changes: + - type: Tweak + message: >- + Removed overlay restriction for vulps, you can now have as many overlay + markings as you want! + id: 6222 + time: '2024-08-06T19:05:46.0000000+00:00' From 55aa822a96f2ef8777e3b17efff0d4b4860b7010 Mon Sep 17 00:00:00 2001 From: username <113782077+whateverusername0@users.noreply.github.com> Date: Wed, 7 Aug 2024 05:08:47 +1000 Subject: [PATCH 3/6] Stamina Damage Resistance Real (#679) # Description Added stamina damage resistance, acts the same way as armor does. Call this shock resistance if you wish :trollface: Just attach StaminaDamageResistance component to an entity with a set multiplier and have fun. Made all hardsuits 25% stun resistant by default. With some variety, e.g. nukie, ERT, captain, HoS suits are 50%, DS are 90%, etc. etc. This will not remove stuneta but it will make it more difficult to stamcrit a traitor or such. Some armor/batong ratios that you need to hit before the target is stamcritted: 0% - 3 batong hits 25% - 4 batong hits 50% - 6 batong hits 75% - 12 batong hits 90% - 28 batong hits :trollface: 100% - ![image](https://github.com/user-attachments/assets/da147676-520b-4e3c-b027-ef9dc6a7394b) # Changelog :cl: - add: Added different stamina damage resistance to hardsuits. --------- Co-authored-by: whateverusername0 --- .../Abilities/Boxer/BoxingSystem.cs | 4 +- .../Nyanotrasen/Abilities/Oni/OniSystem.cs | 4 +- .../Nyanotrasen/Psionics/PsionicsSystem.cs | 12 +++-- ...eHitEvent.cs => TakeStaminaDamageEvent.cs} | 12 ++--- .../Damage/Systems/StaminaSystem.cs | 35 ++++++++++----- .../Inventory/InventorySystem.Relay.cs | 2 + .../StaminaDamageResistanceComponent.cs | 12 +++++ .../StaminaDamageResistanceSystem.cs | 26 +++++++++++ .../Locale/en-US/armor/armor-examine.ftl | 1 + .../OuterClothing/base_clothingouter.yml | 2 + .../Clothing/OuterClothing/hardsuits.yml | 44 +++++++++++++++++++ 11 files changed, 128 insertions(+), 26 deletions(-) rename Content.Shared/Damage/Events/{StaminaMeleeHitEvent.cs => TakeStaminaDamageEvent.cs} (67%) create mode 100644 Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs create mode 100644 Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs diff --git a/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs b/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs index 8bb68cb6f55..6f533c34199 100644 --- a/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs +++ b/Content.Server/Nyanotrasen/Abilities/Boxer/BoxingSystem.cs @@ -14,7 +14,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnMeleeHit); - SubscribeLocalEvent(OnStamHit); + SubscribeLocalEvent(OnStamHit); } private void OnInit(EntityUid uid, BoxerComponent component, ComponentInit args) @@ -27,7 +27,7 @@ private void OnMeleeHit(EntityUid uid, BoxerComponent component, MeleeHitEvent a args.ModifiersList.Add(component.UnarmedModifiers); } - private void OnStamHit(EntityUid uid, BoxingGlovesComponent component, StaminaMeleeHitEvent args) + private void OnStamHit(EntityUid uid, BoxingGlovesComponent component, TakeStaminaDamageEvent args) { if (!_containerSystem.TryGetContainingContainer(uid, out var equipee)) return; diff --git a/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs b/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs index 6fdb27097e9..4fc078e85bc 100644 --- a/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs +++ b/Content.Server/Nyanotrasen/Abilities/Oni/OniSystem.cs @@ -21,7 +21,7 @@ public override void Initialize() SubscribeLocalEvent(OnEntRemoved); SubscribeLocalEvent(OnOniMeleeHit); SubscribeLocalEvent(OnHeldMeleeHit); - SubscribeLocalEvent(OnStamHit); + SubscribeLocalEvent(OnStamHit); } private void OnEntInserted(EntityUid uid, OniComponent component, EntInsertedIntoContainerMessage args) @@ -68,7 +68,7 @@ private void OnHeldMeleeHit(EntityUid uid, HeldByOniComponent component, MeleeHi args.ModifiersList.Add(oni.MeleeModifiers); } - private void OnStamHit(EntityUid uid, HeldByOniComponent component, StaminaMeleeHitEvent args) + private void OnStamHit(EntityUid uid, HeldByOniComponent component, TakeStaminaDamageEvent args) { if (!TryComp(component.Holder, out var oni)) return; diff --git a/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs b/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs index 5a96af2e96b..33505e3f6fc 100644 --- a/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs +++ b/Content.Server/Nyanotrasen/Psionics/PsionicsSystem.cs @@ -51,7 +51,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnMeleeHit); - SubscribeLocalEvent(OnStamHit); + SubscribeLocalEvent(OnStamHit); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnRemove); @@ -110,14 +110,12 @@ private void OnRemove(EntityUid uid, PsionicComponent component, ComponentRemove _npcFactonSystem.RemoveFaction(uid, "PsionicInterloper"); } - private void OnStamHit(EntityUid uid, AntiPsionicWeaponComponent component, StaminaMeleeHitEvent args) + private void OnStamHit(EntityUid uid, AntiPsionicWeaponComponent component, TakeStaminaDamageEvent args) { var bonus = false; - foreach (var stam in args.HitList) - { - if (HasComp(stam.Entity)) - bonus = true; - } + + if (HasComp(args.Target)) + bonus = true; if (!bonus) return; diff --git a/Content.Shared/Damage/Events/StaminaMeleeHitEvent.cs b/Content.Shared/Damage/Events/TakeStaminaDamageEvent.cs similarity index 67% rename from Content.Shared/Damage/Events/StaminaMeleeHitEvent.cs rename to Content.Shared/Damage/Events/TakeStaminaDamageEvent.cs index c5ed0ddb602..6fca9dc2ef3 100644 --- a/Content.Shared/Damage/Events/StaminaMeleeHitEvent.cs +++ b/Content.Shared/Damage/Events/TakeStaminaDamageEvent.cs @@ -1,5 +1,5 @@ using Content.Shared.Damage.Components; -using Robust.Shared.Collections; +using Content.Shared.Inventory; namespace Content.Shared.Damage.Events; @@ -7,12 +7,14 @@ namespace Content.Shared.Damage.Events; /// The components in the list are going to be hit, /// give opportunities to change the damage or other stuff. /// -public sealed class StaminaMeleeHitEvent : HandledEntityEventArgs +public sealed class TakeStaminaDamageEvent : HandledEntityEventArgs, IInventoryRelayEvent { + public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; + /// /// List of hit stamina components. /// - public List<(EntityUid Entity, StaminaComponent Component)> HitList; + public EntityUid Target; /// /// The multiplier. Generally, try to use *= or /= instead of overwriting. @@ -24,8 +26,8 @@ public sealed class StaminaMeleeHitEvent : HandledEntityEventArgs /// public float FlatModifier = 0; - public StaminaMeleeHitEvent(List<(EntityUid Entity, StaminaComponent Component)> hitList) + public TakeStaminaDamageEvent(EntityUid target) { - HitList = hitList; + Target = target; } } diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index de5338615ee..5c46e6055d1 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -166,20 +166,20 @@ private void OnMeleeHit(EntityUid uid, StaminaDamageOnHitComponent component, Me toHit.Add((ent, stam)); } - var hitEvent = new StaminaMeleeHitEvent(toHit); - RaiseLocalEvent(uid, hitEvent); + foreach (var (ent, comp) in toHit) + { + var hitEvent = new TakeStaminaDamageEvent(ent); + RaiseLocalEvent(uid, hitEvent); - if (hitEvent.Handled) - return; + if (hitEvent.Handled) + return; - var damage = component.Damage; + var damage = component.Damage; - damage *= hitEvent.Multiplier; + damage *= hitEvent.Multiplier; - damage += hitEvent.FlatModifier; + damage += hitEvent.FlatModifier; - foreach (var (ent, comp) in toHit) - { TakeStaminaDamage(ent, damage / toHit.Count, comp, source: args.User, with: args.Weapon, sound: component.Sound); } } @@ -204,12 +204,27 @@ private void OnThrowHit(EntityUid uid, StaminaDamageOnCollideComponent component private void OnCollide(EntityUid uid, StaminaDamageOnCollideComponent component, EntityUid target) { + if (!TryComp(target, out var stamComp)) + return; + var ev = new StaminaDamageOnHitAttemptEvent(); RaiseLocalEvent(uid, ref ev); if (ev.Cancelled) return; - TakeStaminaDamage(target, component.Damage, source: uid, sound: component.Sound); + var hitEvent = new TakeStaminaDamageEvent(target); + RaiseLocalEvent(target, hitEvent); + + if (hitEvent.Handled) + return; + + var damage = component.Damage; + + damage *= hitEvent.Multiplier; + + damage += hitEvent.FlatModifier; + + TakeStaminaDamage(target, damage, source: uid, sound: component.Sound); } private void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null) diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index c43a5885077..3308e881c52 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -1,5 +1,6 @@ using Content.Shared.Chemistry; using Content.Shared.Damage; +using Content.Shared.Damage.Events; using Content.Shared.Electrocution; using Content.Shared.Explosion; using Content.Shared.Eye.Blinding.Systems; @@ -20,6 +21,7 @@ public partial class InventorySystem public void InitializeRelay() { SubscribeLocalEvent(RelayInventoryEvent); + SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); diff --git a/Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs b/Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs new file mode 100644 index 00000000000..dc291bbe8ba --- /dev/null +++ b/Content.Shared/Stunnable/StaminaDamageResistanceComponent.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Stunnable; + +[RegisterComponent, NetworkedComponent] +public sealed partial class StaminaDamageResistanceComponent : Component +{ + /// + /// 1 - no reduction, 0 - full reduction + /// + [DataField] public float Coefficient = 1; +} diff --git a/Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs b/Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs new file mode 100644 index 00000000000..7632eed504d --- /dev/null +++ b/Content.Shared/Stunnable/StaminaDamageResistanceSystem.cs @@ -0,0 +1,26 @@ +using Content.Shared.Damage.Events; +using Content.Shared.Examine; +using Content.Shared.Inventory; + +namespace Content.Shared.Stunnable; + +public sealed partial class StaminaDamageResistanceSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnStaminaMeleeHit); + SubscribeLocalEvent(OnExamine); + } + + private void OnStaminaMeleeHit(Entity ent, ref InventoryRelayedEvent args) + { + args.Args.Multiplier *= ent.Comp.Coefficient; + } + private void OnExamine(Entity ent, ref ExaminedEvent args) + { + var percentage = (1 - ent.Comp.Coefficient) * 100; + args.PushMarkup(Loc.GetString("armor-examine-stamina", ("num", percentage))); + } +} diff --git a/Resources/Locale/en-US/armor/armor-examine.ftl b/Resources/Locale/en-US/armor/armor-examine.ftl index d49a1373f28..6dc511e66e5 100644 --- a/Resources/Locale/en-US/armor/armor-examine.ftl +++ b/Resources/Locale/en-US/armor/armor-examine.ftl @@ -17,3 +17,4 @@ armor-damage-type-cold = Cold armor-damage-type-poison = Poison armor-damage-type-shock = Shock armor-damage-type-structural = Structural +armor-examine-stamina = Reduces your stamina damage by [color=cyan]{$num}%[/color]. \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index 36327fe1f78..d6a2cd446be 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -142,6 +142,8 @@ - type: Clothing equipDelay: 2.5 # Hardsuits are heavy and take a while to put on/off. unequipDelay: 2.5 + - type: StaminaDamageResistance + coefficient: 0.75 # 25% - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index e0d8e7290da..70ab3016469 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -100,6 +100,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitEngineering + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #Spationaut Hardsuit - type: entity @@ -221,6 +223,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSecurity + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #Brigmedic Hardsuit - type: entity @@ -248,6 +252,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitBrigmedic + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #Warden's Hardsuit - type: entity @@ -278,6 +284,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitWarden + - type: StaminaDamageResistance + coefficient: 0.65 # 35% #Captain's Hardsuit - type: entity @@ -310,6 +318,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitCap + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Chief Engineer's Hardsuit - type: entity @@ -345,6 +355,8 @@ - type: ClothingGrantComponent component: - type: SupermatterImmune + - type: StaminaDamageResistance + coefficient: 0.65 # 35% #Chief Medical Officer's Hardsuit - type: entity @@ -412,6 +424,8 @@ price: 750 - type: StealTarget stealGroup: ClothingOuterHardsuitRd + - type: StaminaDamageResistance + coefficient: 0.75 # 25% as in "shock resistance" :trollface: #Head of Security's Hardsuit - type: entity @@ -443,6 +457,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSecurityRed + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Luxury Mining Hardsuit - type: entity @@ -520,6 +536,8 @@ - Hardsuit - WhitelistChameleon - HidesHarpyWings + - type: StaminaDamageResistance + coefficient: 0.5 # 50% # Syndicate Medic Hardsuit - type: entity @@ -539,6 +557,8 @@ - Hardsuit - WhitelistChameleon - HidesHarpyWings + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Syndicate Elite Hardsuit - type: entity @@ -575,6 +595,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndieElite + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Syndicate Commander Hardsuit - type: entity @@ -607,6 +629,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitSyndieCommander + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Cybersun Juggernaut Hardsuit - type: entity @@ -639,6 +663,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitCybersun + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Wizard Hardsuit - type: entity @@ -671,6 +697,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitWizard + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Ling Space Suit - type: entity @@ -766,6 +794,8 @@ clothingPrototype: ClothingHeadHelmetHardsuitPirateCap - type: StaticPrice price: 0 + - type: StaminaDamageResistance + coefficient: 0.75 # 25% #CENTCOMM / ERT HARDSUITS #ERT Leader Hardsuit @@ -781,6 +811,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertleader.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTLeader + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Chaplain Hardsuit - type: entity @@ -795,6 +827,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTChaplain + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Engineer Hardsuit - type: entity @@ -809,6 +843,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertengineer.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTEngineer + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Medic Hardsuit - type: entity @@ -823,6 +859,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertmedical.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTMedical + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Security Hardsuit - type: entity @@ -841,6 +879,8 @@ tags: - Hardsuit - WhitelistChameleon + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #ERT Janitor Hardsuit - type: entity @@ -855,6 +895,8 @@ sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertjanitor.rsi - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTJanitor + - type: StaminaDamageResistance + coefficient: 0.5 # 50% #Deathsquad - type: entity @@ -889,6 +931,8 @@ - type: HeldSpeedModifier - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitDeathsquad + - type: StaminaDamageResistance + coefficient: 0.1 # 90% #CBURN Hardsuit - type: entity From b7d30808f78456443343312d16b64ae01ea54d10 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:09:14 +0000 Subject: [PATCH 4/6] Automatic Changelog Update (#679) --- Resources/Changelog/Changelog.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 39fcb78cfa7..018c5adbd0d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4977,3 +4977,9 @@ Entries: markings as you want! id: 6222 time: '2024-08-06T19:05:46.0000000+00:00' +- author: whateverusername0 + changes: + - type: Add + message: Added different stamina damage resistance to hardsuits. + id: 6223 + time: '2024-08-06T19:08:48.0000000+00:00' From 6ab179737b5f42b800ab7436791509e9cc917254 Mon Sep 17 00:00:00 2001 From: Angelo Fallaria Date: Wed, 7 Aug 2024 03:12:33 +0800 Subject: [PATCH 5/6] New Trait: Blood Deficiency (#686) # Description **Blood Deficiency** is a +2 points negative Physical trait that makes you slowly lose blood over time. When left untreated you will die from blood loss. Inspired by the SS13 trait of the same name. Slash/Piercing weapons and bleeding are much more lethal against you. The moment you start taking **any** blood loss damage, you start dying because you can't regenerate blood. Even just two consecutive kitchen knife stabs will make you bleed enough to die slowly unless you immediately apply gauze. Blood packs, iron pills (or copper for Arachnids), and gauze to stop bleeding will help you survive with this trait. Here's how the timeline looks for untreated blood deficiency: - ~0-21 minutes: losing blood slowly - ~21-31 minutes: blood level below 90%, start taking bloodloss damage - ~31-33 minutes: critical - ~34 minutes: death ## Media
Expand **Trait entry** ![image](https://github.com/user-attachments/assets/ea4a0c3c-7c05-45fc-8a32-48957701a246) ![image](https://github.com/user-attachments/assets/37398779-90a4-4f4f-a183-38d806184394) As shown above, even just reducing the blood volume to less than 90% means you will die a slow and painful death.

# Changelog :cl: Skubman - add: Add the Blood Deficiency trait, a new negative trait that makes you slowly lose blood over time. You must routinely receive blood loss treatment to live, and even normally non-lethal bleeding can make you start dying slowly. --- .../Body/Components/BloodstreamComponent.cs | 15 ++++++++++- .../Body/Systems/BloodstreamSystem.cs | 25 +++++++++++++++---- .../Traits/BloodDeficiencyComponent.cs | 14 +++++++++++ .../Traits/BloodDeficiencySystem.cs | 23 +++++++++++++++++ Resources/Locale/en-US/traits/traits.ftl | 5 ++++ Resources/Prototypes/Traits/disabilities.yml | 14 +++++++++++ 6 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 Content.Server/Traits/BloodDeficiencyComponent.cs create mode 100644 Content.Server/Traits/BloodDeficiencySystem.cs diff --git a/Content.Server/Body/Components/BloodstreamComponent.cs b/Content.Server/Body/Components/BloodstreamComponent.cs index 1d8aa9ffd3d..7a4af3e4cc1 100644 --- a/Content.Server/Body/Components/BloodstreamComponent.cs +++ b/Content.Server/Body/Components/BloodstreamComponent.cs @@ -1,5 +1,6 @@ using Content.Server.Body.Systems; using Content.Server.Chemistry.EntitySystems; +using Content.Server.Traits.Assorted; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; using Content.Shared.Damage; @@ -11,7 +12,7 @@ namespace Content.Server.Body.Components { - [RegisterComponent, Access(typeof(BloodstreamSystem), typeof(ReactionMixerSystem))] + [RegisterComponent, Access(typeof(BloodstreamSystem), typeof(ReactionMixerSystem), typeof(BloodDeficiencySystem))] public sealed partial class BloodstreamComponent : Component { public static string DefaultChemicalsSolutionName = "chemicals"; @@ -171,5 +172,17 @@ public sealed partial class BloodstreamComponent : Component /// [ViewVariables(VVAccess.ReadWrite)] public TimeSpan StatusTime; + + /// + /// If this is true, the entity will not passively regenerate blood, + /// and instead will slowly lose blood. + /// + public bool HasBloodDeficiency = false; + + /// + /// How much reagent of blood should be removed with blood deficiency in each update interval? + /// + [DataField] + public FixedPoint2 BloodDeficiencyLossAmount; } } diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs index 0edb190c16e..fafc649eb29 100644 --- a/Content.Server/Body/Systems/BloodstreamSystem.cs +++ b/Content.Server/Body/Systems/BloodstreamSystem.cs @@ -118,11 +118,14 @@ public override void Update(float frameTime) if (!_solutionContainerSystem.ResolveSolution(uid, bloodstream.BloodSolutionName, ref bloodstream.BloodSolution, out var bloodSolution)) continue; - // Adds blood to their blood level if it is below the maximum; Blood regeneration. Must be alive. - if (bloodSolution.Volume < bloodSolution.MaxVolume && !_mobStateSystem.IsDead(uid)) - { - TryModifyBloodLevel(uid, bloodstream.BloodRefreshAmount, bloodstream); - } + // Removes blood for Blood Deficiency constantly. + if (bloodstream.HasBloodDeficiency) + if (!_mobStateSystem.IsDead(uid)) + RemoveBlood(uid, bloodstream.BloodDeficiencyLossAmount, bloodstream); + // Adds blood to their blood level if it is below the maximum. + else if (bloodSolution.Volume < bloodSolution.MaxVolume) + if (!_mobStateSystem.IsDead(uid)) + TryModifyBloodLevel(uid, bloodstream.BloodRefreshAmount, bloodstream); // Removes blood from the bloodstream based on bleed amount (bleed rate) // as well as stop their bleeding to a certain extent. @@ -472,4 +475,16 @@ public void ChangeBloodReagent(EntityUid uid, string reagent, BloodstreamCompone if (currentVolume > 0) _solutionContainerSystem.TryAddReagent(component.BloodSolution.Value, component.BloodReagent, currentVolume, out _); } + + /// + /// Remove blood from an entity, without spilling it. + /// + private void RemoveBlood(EntityUid uid, FixedPoint2 amount, BloodstreamComponent? component = null) + { + if (!Resolve(uid, ref component, logMissing: false) + || !_solutionContainerSystem.ResolveSolution(uid, component.BloodSolutionName, ref component.BloodSolution, out var bloodSolution)) + return; + + bloodSolution.RemoveReagent(component.BloodReagent, amount); + } } diff --git a/Content.Server/Traits/BloodDeficiencyComponent.cs b/Content.Server/Traits/BloodDeficiencyComponent.cs new file mode 100644 index 00000000000..616f60cd834 --- /dev/null +++ b/Content.Server/Traits/BloodDeficiencyComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Server.Traits.Assorted; + +/// +/// This is used for the Blood Deficiency trait. +/// +[RegisterComponent] +public sealed partial class BloodDeficiencyComponent : Component +{ + // + // How much reagent of blood should be removed in each update interval? + // + [DataField(required: true)] + public float BloodLossAmount; +} diff --git a/Content.Server/Traits/BloodDeficiencySystem.cs b/Content.Server/Traits/BloodDeficiencySystem.cs new file mode 100644 index 00000000000..f1ae4909956 --- /dev/null +++ b/Content.Server/Traits/BloodDeficiencySystem.cs @@ -0,0 +1,23 @@ +using Content.Server.Body.Systems; +using Content.Server.Body.Components; +using Content.Shared.Damage; + +namespace Content.Server.Traits.Assorted; + +public sealed class BloodDeficiencySystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, BloodDeficiencyComponent component, ComponentStartup args) + { + if (!TryComp(uid, out var bloodstream)) + return; + + bloodstream.HasBloodDeficiency = true; + bloodstream.BloodDeficiencyLossAmount = component.BloodLossAmount; + } +} diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index 07ef099f832..bf0a44e767e 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -23,6 +23,11 @@ trait-description-HeavyweightDrunk = Alcohol is afraid of you. trait-name-Muted = Muted trait-description-Muted = You can't speak +trait-name-BloodDeficiency = Blood Deficiency +trait-description-BloodDeficiency = + Your body loses more blood than it can replenish. + You lose blood over time, and when left untreated you will eventually die from blood loss. + trait-name-Paracusia = Paracusia trait-description-Paracusia = You hear sounds that aren't really there diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index eb96d37e01a..afdd27f339d 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -94,3 +94,17 @@ - MedicalBorg components: - type: Snoring + +- type: trait + id: BloodDeficiency + category: Physical + points: 2 + requirements: + - !type:CharacterJobRequirement + inverted: true + jobs: + - Borg + - MedicalBorg + components: + - type: BloodDeficiency # 0.07 = start taking bloodloss damage at around ~21.4 minutes, + bloodLossAmount: 0.07 # then become crit ~10 minutes later From bc3ffaf0cb61ba7febfad2c94c90e3d371510fc6 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Tue, 6 Aug 2024 19:13:16 +0000 Subject: [PATCH 6/6] Automatic Changelog Update (#686) --- Resources/Changelog/Changelog.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 018c5adbd0d..7b3e9c5f2cc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4983,3 +4983,13 @@ Entries: message: Added different stamina damage resistance to hardsuits. id: 6223 time: '2024-08-06T19:08:48.0000000+00:00' +- author: Skubman + changes: + - type: Add + message: >- + Add the Blood Deficiency trait, a new negative trait that makes you + slowly lose blood over time. You must routinely receive blood loss + treatment to live, and even normally non-lethal bleeding can make you + start dying slowly. + id: 6224 + time: '2024-08-06T19:12:34.0000000+00:00'