From 9dd569dfd5fe3c9fafcd7000d019358a63fe73ae Mon Sep 17 00:00:00 2001 From: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:39:19 +0300 Subject: [PATCH] Make Height Sliders Affect Your Bloodstream Volume (#858) # Description Something that just makes sense, this makes your effect character weight affect your bloodstream volume. As a minimum size felinid you will get 33% of normal blood volume, whereas as something as huge as a lamia you may get up to 3 times the normal blood volume. The resulting volume of your bloodstream can be calculated as `V = clamp(normal_volume * mass_contest ^ 0.6)` (assuming default parameters), where mass_contest is the result of a mass contest between your entity and the average humanoid. For average species like vulps, this means that their bloodstream can become up to ~40% smaller than normal (at minimum size), or up to 50% larger than normal (at maximum size). For onis the range is shifted towards higher values, a maximum size oni will have twice as much blood as an average human. This has both drawbacks and advantages. For instance, having little blood means you can bleed out easily, but at the same time it means it will take way less blood packs/saline/iron/proteins to restore your blood to the normal level. Opposite is also true, having more blood means you will be harder to heal. Also, this PR slightly refactors the HeightAdjustSystem to be more flexible.

Media

https://github.com/user-attachments/assets/951c2391-09d8-4a4a-812b-a2394862fadd

# Changelog :cl: - add: Your character size now affects your blood level. Smaller characters will have less blood, and larger characters will have more. --------- Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Co-authored-by: VMSolidus Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- .../HeightAdjust/BloodstreamAdjustSystem.cs | 45 +++++++++++++++++++ .../BloodstreamAffectedByMassComponent.cs | 26 +++++++++++ Content.Shared/CCVar/CCVars.cs | 9 ++++ .../HeightAdjust/HeightAdjustSystem.cs | 24 ++-------- .../HeightAdjust/HeightAdjustedEvent.cs | 11 +++++ .../Prototypes/Entities/Mobs/Species/base.yml | 2 + 6 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 Content.Server/HeightAdjust/BloodstreamAdjustSystem.cs create mode 100644 Content.Server/HeightAdjust/BloodstreamAffectedByMassComponent.cs create mode 100644 Content.Shared/HeightAdjust/HeightAdjustedEvent.cs diff --git a/Content.Server/HeightAdjust/BloodstreamAdjustSystem.cs b/Content.Server/HeightAdjust/BloodstreamAdjustSystem.cs new file mode 100644 index 00000000000..92e03e0c111 --- /dev/null +++ b/Content.Server/HeightAdjust/BloodstreamAdjustSystem.cs @@ -0,0 +1,45 @@ +using Content.Server.Body.Components; +using Content.Server.Chemistry.Containers.EntitySystems; +using Content.Shared.CCVar; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Contests; +using Content.Shared.HeightAdjust; +using Robust.Shared.Configuration; + +namespace Content.Server.HeightAdjust; + +public sealed class BloodstreamAdjustSystem : EntitySystem +{ + [Dependency] private readonly IConfigurationManager _config = default!; + [Dependency] private readonly ContestsSystem _contests = default!; + [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; + + public override void Initialize() + { + SubscribeLocalEvent((uid, comp, _) => TryAdjustBloodstream((uid, comp))); + SubscribeLocalEvent((uid, comp, _) => TryAdjustBloodstream((uid, comp))); + } + + /// + /// Adjusts the bloodstream of the specified entity based on the settings provided by the component. + /// + public bool TryAdjustBloodstream(Entity ent) + { + if (!TryComp(ent, out var bloodstream) + || !_solutionContainer.TryGetSolution(ent.Owner, bloodstream.BloodSolutionName, out var bloodSolutionEnt) + || !_config.GetCVar(CCVars.HeightAdjustModifiesBloodstream)) + return false; + + var bloodSolution = bloodSolutionEnt.Value.Comp.Solution; + + var factor = Math.Pow(_contests.MassContest(ent, bypassClamp: true, rangeFactor: 4f), ent.Comp.Power); + factor = Math.Clamp(factor, ent.Comp.Min, ent.Comp.Max); + + var newVolume = bloodstream.BloodMaxVolume * factor; + var newBloodLevel = bloodSolution.FillFraction * newVolume; + bloodSolution.MaxVolume = newVolume; + bloodSolution.SetContents([new ReagentQuantity(bloodstream.BloodReagent, newBloodLevel, null)], false); + + return true; + } +} diff --git a/Content.Server/HeightAdjust/BloodstreamAffectedByMassComponent.cs b/Content.Server/HeightAdjust/BloodstreamAffectedByMassComponent.cs new file mode 100644 index 00000000000..f6c3a0e250c --- /dev/null +++ b/Content.Server/HeightAdjust/BloodstreamAffectedByMassComponent.cs @@ -0,0 +1,26 @@ +using Content.Server.Body.Components; + +namespace Content.Server.HeightAdjust; + +/// +/// When applied to a humanoid or any mob, adjusts their blood level based on the mass contest between them +/// and an average humanoid. +///
+/// The formula for the resulting bloodstream volume is V = BloodMaxVolume * MassContest^Power +/// clamped between the specified Min and Max values. +///
+[RegisterComponent] +public sealed partial class BloodstreamAffectedByMassComponent : Component +{ + /// + /// Minimum and maximum resulting volume factors. A minimum value of 0.5 means that the resulting volume will be at least 50% of the original. + /// + [DataField] + public float Min = 1 / 3f, Max = 3f; + + /// + /// The power to which the outcome of the mass contest will be risen. + /// + [DataField] + public float Power = 1f; +} diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 84a8e460c59..1501c92f88e 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -2341,6 +2341,15 @@ public static readonly CVarDef public static readonly CVarDef HeightAdjustModifiesZoom = CVarDef.Create("heightadjust.modifies_zoom", false, CVar.SERVERONLY); + /// + /// Whether height & width sliders adjust a player's bloodstream volume. + /// + /// + /// This can be configured more precisely by modifying BloodstreamAffectedByMassComponent. + /// + public static readonly CVarDef HeightAdjustModifiesBloodstream = + CVarDef.Create("heightadjust.modifies_bloodstream", true, CVar.SERVERONLY); + /// /// Enables station goals /// diff --git a/Content.Shared/HeightAdjust/HeightAdjustSystem.cs b/Content.Shared/HeightAdjust/HeightAdjustSystem.cs index 46b2d9b656f..8bfdaccfd13 100644 --- a/Content.Shared/HeightAdjust/HeightAdjustSystem.cs +++ b/Content.Shared/HeightAdjust/HeightAdjustSystem.cs @@ -25,27 +25,7 @@ public sealed class HeightAdjustSystem : EntitySystem /// True if all operations succeeded public bool SetScale(EntityUid uid, float scale) { - var succeeded = true; - if (_config.GetCVar(CCVars.HeightAdjustModifiesZoom) && EntityManager.TryGetComponent(uid, out var eye)) - _eye.SetMaxZoom(uid, eye.MaxZoom * scale); - else - succeeded = false; - - if (_config.GetCVar(CCVars.HeightAdjustModifiesHitbox) && EntityManager.TryGetComponent(uid, out var fixtures)) - foreach (var fixture in fixtures.Fixtures) - _physics.SetRadius(uid, fixture.Key, fixture.Value, fixture.Value.Shape, MathF.MinMagnitude(fixture.Value.Shape.Radius * scale, 0.49f)); - else - succeeded = false; - - if (EntityManager.HasComponent(uid)) - { - _appearance.SetHeight(uid, scale); - _appearance.SetWidth(uid, scale); - } - else - succeeded = false; - - return succeeded; + return SetScale(uid, new Vector2(scale, scale)); } /// @@ -75,6 +55,8 @@ public bool SetScale(EntityUid uid, Vector2 scale) else succeeded = false; + RaiseLocalEvent(uid, new HeightAdjustedEvent { NewScale = scale }); + return succeeded; } } diff --git a/Content.Shared/HeightAdjust/HeightAdjustedEvent.cs b/Content.Shared/HeightAdjust/HeightAdjustedEvent.cs new file mode 100644 index 00000000000..3db856e0d83 --- /dev/null +++ b/Content.Shared/HeightAdjust/HeightAdjustedEvent.cs @@ -0,0 +1,11 @@ +using System.Numerics; + +namespace Content.Shared.HeightAdjust; + +/// +/// Raised on a humanoid after their scale has been adjusted in accordance with their profile and their physics have been updated. +/// +public sealed class HeightAdjustedEvent : EntityEventArgs +{ + public Vector2 NewScale; +} diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index 8200f0cdbff..33635eeec20 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -309,6 +309,8 @@ - type: OfferItem - type: LayingDown - type: Shoving + - type: BloodstreamAffectedByMass + power: 0.6 # A minimum size felinid will have 30% blood, a minimum size vulp will have 60%, a maximum size oni will have ~200% - type: entity save: false