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);
}
{
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
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;
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
continue;
// Skip blood reagents
- if (bloodList.Contains(reagent.Prototype))
+ if (ev.Reagents.Contains(reagent))
continue;
var mostToRemove = FixedPoint2.Zero;
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;
// 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>
[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>
+using Content.Shared.Chemistry.Reagent;
+
namespace Content.Shared.Body.Events;
/// <summary>
/// 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 = [];
+}
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);
}
}
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)
{
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();
dnaData.DNA = Loc.GetString("forensics-dna-unknown");
bloodData.Add(dnaData);
-
return bloodData;
}
}
}
// 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))