]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
[Bugfix/Optimization] Metabolize Foreign Blood (#41892)
authorPrincess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com>
Thu, 18 Dec 2025 08:48:30 +0000 (00:48 -0800)
committerGitHub <noreply@github.com>
Thu, 18 Dec 2025 08:48:30 +0000 (08:48 +0000)
* Metabolize foreign blood

* fix

* misc

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Content.Server/Body/Systems/BloodstreamSystem.cs
Content.Server/Body/Systems/MetabolizerSystem.cs
Content.Shared/Body/Components/BloodstreamComponent.cs
Content.Shared/Body/Events/MetabolismExclusionEvent.cs
Content.Shared/Body/Systems/SharedBloodstreamSystem.cs
Content.Shared/Medical/VomitSystem.cs

index 08f640711ae814b8fcf4598639b6fb2b12bfc1b5..b142d86fad5410f68581ba026a780a761fb15dff 100644 (file)
@@ -30,12 +30,12 @@ public sealed class BloodstreamSystem : SharedBloodstreamSystem
 
         bloodSolution.MaxVolume = entity.Comp.BloodReferenceSolution.Volume * entity.Comp.MaxVolumeModifier;
         tempSolution.MaxVolume = entity.Comp.BleedPuddleThreshold * 4; // give some leeway, for chemstream as well
+        entity.Comp.BloodReferenceSolution.SetReagentData(GetEntityBloodData((entity, entity.Comp)));
 
         // Fill blood solution with BLOOD
         // The DNA string might not be initialized yet, but the reagent data gets updated in the GenerateDnaEvent subscription
         var solution = entity.Comp.BloodReferenceSolution.Clone();
         solution.ScaleTo(entity.Comp.BloodReferenceSolution.Volume - bloodSolution.Volume);
-        solution.SetReagentData(GetEntityBloodData(entity.Owner));
         bloodSolution.AddSolution(solution, PrototypeManager);
     }
 
@@ -44,11 +44,14 @@ public sealed class BloodstreamSystem : SharedBloodstreamSystem
     {
         if (SolutionContainer.ResolveSolution(entity.Owner, entity.Comp.BloodSolutionName, ref entity.Comp.BloodSolution, out var bloodSolution))
         {
+            var data = NewEntityBloodData(entity);
+            entity.Comp.BloodReferenceSolution.SetReagentData(data);
+
             foreach (var reagent in bloodSolution.Contents)
             {
                 List<ReagentData> reagentData = reagent.Reagent.EnsureReagentData();
                 reagentData.RemoveAll(x => x is DnaData);
-                reagentData.AddRange(GetEntityBloodData(entity.Owner));
+                reagentData.AddRange(data);
             }
         }
         else
index 35c7b0572a30be6b41c90c82fe4df27595e63bb8..8e329bc420825f7b1c24a438b8b4376af0d5b1da 100644 (file)
@@ -16,7 +16,6 @@ using Content.Shared.EntityEffects.Effects.Body;
 using Content.Shared.EntityEffects.Effects.Solution;
 using Content.Shared.FixedPoint;
 using Content.Shared.Mobs.Systems;
-using Content.Shared.Random.Helpers;
 using Robust.Shared.Collections;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
@@ -138,8 +137,7 @@ public sealed class MetabolizerSystem : SharedMetabolizerSystem
         var list = solution.Contents.ToList();
 
         // Collecting blood reagent for filtering
-        var bloodList = new List<string>();
-        var ev = new MetabolismExclusionEvent(bloodList);
+        var ev = new MetabolismExclusionEvent();
         RaiseLocalEvent(solutionEntityUid.Value, ref ev);
 
         // randomize the reagent list so we don't have any weird quirks
@@ -155,7 +153,7 @@ public sealed class MetabolizerSystem : SharedMetabolizerSystem
                 continue;
 
             // Skip blood reagents
-            if (bloodList.Contains(reagent.Prototype))
+            if (ev.Reagents.Contains(reagent))
                 continue;
 
             var mostToRemove = FixedPoint2.Zero;
index 8309397b621b64079e57ca0169bb00f6d5bbd7cc..533b486da5cd9b4cb141a6cb452d0a575929f900 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.Alert;
 using Content.Shared.Body.Systems;
 using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Reagent;
 using Content.Shared.Damage;
 using Content.Shared.Damage.Prototypes;
 using Content.Shared.FixedPoint;
@@ -137,9 +138,9 @@ public sealed partial class BloodstreamComponent : Component
     // TODO probably damage bleed thresholds.
 
     /// <summary>
-    /// Modifier applied to <see cref="BloodReferenceSolution.Volume"/> to determine maximum volume for bloodstream.
+    /// Modifier applied to <see cref="BloodstreamComponent.BloodReferenceSolution.Volume"/> to determine maximum volume for bloodstream.
     /// </summary>
-    [DataField]
+    [DataField, AutoNetworkedField]
     public float MaxVolumeModifier = 2f;
 
     /// <summary>
@@ -151,6 +152,13 @@ public sealed partial class BloodstreamComponent : Component
     [DataField, AutoNetworkedField]
     public Solution BloodReferenceSolution = new([new("Blood", 300)]);
 
+    /// <summary>
+    /// Caches the blood data of an entity.
+    /// This is modified by DNA on init so it's not savable.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadOnly)]
+    public List<ReagentData>? BloodData;
+
     /// <summary>
     /// Name/Key that <see cref="BloodSolution"/> is indexed by.
     /// </summary>
index 791b8ed959845084dce83fe4cb181363bca0a910..3626e5af777de701e75db8bc47e32fccf33e0e67 100644 (file)
@@ -1,3 +1,5 @@
+using Content.Shared.Chemistry.Reagent;
+
 namespace Content.Shared.Body.Events;
 
 /// <summary>
@@ -5,4 +7,7 @@ namespace Content.Shared.Body.Events;
 /// blood like reagents for metabolism to skip.
 /// </summary>
 [ByRefEvent]
-public readonly record struct MetabolismExclusionEvent(List<string> ReagentList);
\ No newline at end of file
+public readonly record struct MetabolismExclusionEvent()
+{
+    public readonly List<ReagentId> Reagents = [];
+}
index 7c8fca6deb5a7420a8e3288c736b99453bb6203c..5f3794acd2e2e04c3dd8490d507861d126053d46 100644 (file)
@@ -296,9 +296,9 @@ public abstract class SharedBloodstreamSystem : EntitySystem
     private void OnMetabolismExclusion(Entity<BloodstreamComponent> ent, ref MetabolismExclusionEvent args)
     {
         // Adding all blood reagents for filtering blood in metabolizer
-        foreach (var (reagentId, _) in ent.Comp.BloodReferenceSolution)
+        foreach (var (reagent, _) in ent.Comp.BloodReferenceSolution)
         {
-            args.ReagentList.Add(reagentId.Prototype);
+            args.Reagents.Add(reagent);
         }
     }
 
@@ -424,8 +424,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem
             if (error > 0)
             {
                 error = FixedPoint2.Min(error, adjustedAmount);
-                var reagentToAdd = new ReagentId(referenceReagent.Prototype, GetEntityBloodData(ent));
-                bloodSolution.AddReagent(reagentToAdd, error);
+                bloodSolution.AddReagent(referenceReagent, error);
             }
             else if (error < 0)
             {
@@ -561,14 +560,24 @@ public abstract class SharedBloodstreamSystem : EntitySystem
 
         var solution = ent.Comp.BloodReferenceSolution.Clone();
         solution.ScaleSolution(currentVolume / solution.Volume);
-        solution.SetReagentData(GetEntityBloodData(ent));
         SolutionContainer.AddSolution(ent.Comp.BloodSolution.Value, solution);
     }
 
     /// <summary>
     /// Get the reagent data for blood that a specific entity should have.
     /// </summary>
-    public List<ReagentData> GetEntityBloodData(EntityUid uid)
+    public List<ReagentData> GetEntityBloodData(Entity<BloodstreamComponent?> entity)
+    {
+        if (!Resolve(entity, ref entity.Comp))
+            return NewEntityBloodData(entity);
+
+        return entity.Comp.BloodData ?? NewEntityBloodData(entity);
+    }
+
+    /// <summary>
+    /// Gets new blood data for this entity and caches it in <see cref="BloodstreamComponent.BloodData"/>
+    /// </summary>
+    protected List<ReagentData> NewEntityBloodData(EntityUid uid)
     {
         var bloodData = new List<ReagentData>();
         var dnaData = new DnaData();
@@ -579,7 +588,6 @@ public abstract class SharedBloodstreamSystem : EntitySystem
             dnaData.DNA = Loc.GetString("forensics-dna-unknown");
 
         bloodData.Add(dnaData);
-
         return bloodData;
     }
 }
index cf927754e323bcc3e8f49e263685de2f990c707b..bdde1f0c98b694cdf95506c44f535c53b39e71fa 100644 (file)
@@ -121,7 +121,7 @@ public sealed class VomitSystem : EntitySystem
             }
 
             // Makes a vomit solution the size of 90% of the chemicals removed from the chemstream
-            solution.AddReagent(new ReagentId(VomitPrototype, _bloodstream.GetEntityBloodData(uid)), vomitAmount);
+            solution.AddReagent(new ReagentId(VomitPrototype, _bloodstream.GetEntityBloodData((uid, bloodStream))), vomitAmount);
         }
 
         if (_puddle.TrySpillAt(uid, solution, out var puddle, false))