diff --git a/Content.Server/Body/Systems/BloodstreamSystem.cs b/Content.Server/Body/Systems/BloodstreamSystem.cs
index c2185750af..a58deec494 100644
--- a/Content.Server/Body/Systems/BloodstreamSystem.cs
+++ b/Content.Server/Body/Systems/BloodstreamSystem.cs
@@ -37,7 +37,10 @@ public sealed class BloodstreamSystem : SharedBloodstreamSystem
// Fill blood solution with BLOOD
// The DNA string might not be initialized yet, but the reagent data gets updated in the GenerateDnaEvent subscription
- bloodSolution.AddReagent(new ReagentId(entity.Comp.BloodReagent, GetEntityBloodData(entity.Owner)), entity.Comp.BloodMaxVolume - bloodSolution.Volume);
+ var solution = entity.Comp.BloodReagents.Clone();
+ solution.ScaleTo(entity.Comp.BloodMaxVolume - bloodSolution.Volume);
+ solution.SetReagentData(GetEntityBloodData(entity.Owner));
+ bloodSolution.AddSolution(solution, PrototypeManager);
}
// forensics is not predicted yet
diff --git a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerComponent.cs b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerComponent.cs
index 61d36f98b9..bc295545b0 100644
--- a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerComponent.cs
+++ b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerComponent.cs
@@ -1,3 +1,4 @@
+using Content.Shared.Chemistry.Components;
using Content.Shared.Storage;
namespace Content.Server.Medical.BiomassReclaimer
@@ -34,10 +35,10 @@ namespace Content.Server.Medical.BiomassReclaimer
public float CurrentExpectedYield = 0f;
///
- /// The reagent that will be spilled while processing a mob.
+ /// The reagents that will be spilled while processing a mob.
///
[ViewVariables]
- public string? BloodReagent;
+ public Solution? BloodReagents = null;
///
/// Entities that can be randomly spawned while processing a mob.
diff --git a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs
index e029071574..83dcd9cf7c 100644
--- a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs
+++ b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs
@@ -7,7 +7,7 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Audio;
using Content.Shared.Body.Components;
using Content.Shared.CCVar;
-using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Climbing.Events;
using Content.Shared.Construction.Components;
using Content.Shared.Database;
@@ -45,6 +45,7 @@ namespace Content.Server.Medical.BiomassReclaimer
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly PuddleSystem _puddleSystem = default!;
+ [Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
[Dependency] private readonly ThrowingSystem _throwing = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
@@ -68,10 +69,8 @@ namespace Content.Server.Medical.BiomassReclaimer
if (reclaimer.RandomMessTimer <= 0)
{
- if (_robustRandom.Prob(0.2f) && reclaimer.BloodReagent is not null)
+ if (_robustRandom.Prob(0.2f) && reclaimer.BloodReagents is { } blood)
{
- Solution blood = new();
- blood.AddReagent(reclaimer.BloodReagent, 50);
_puddleSystem.TrySpillAt(uid, blood, out _);
}
if (_robustRandom.Prob(0.03f) && reclaimer.SpawnedEntities.Count > 0)
@@ -92,7 +91,7 @@ namespace Content.Server.Medical.BiomassReclaimer
reclaimer.CurrentExpectedYield = reclaimer.CurrentExpectedYield - actualYield; // store non-integer leftovers
_material.SpawnMultipleFromMaterial(actualYield, BiomassPrototype, Transform(uid).Coordinates);
- reclaimer.BloodReagent = null;
+ reclaimer.BloodReagents = null;
reclaimer.SpawnedEntities.Clear();
RemCompDeferred(uid);
}
@@ -208,9 +207,11 @@ namespace Content.Server.Medical.BiomassReclaimer
var component = ent.Comp;
AddComp(ent);
- if (TryComp(toProcess, out var stream))
+ if (TryComp(toProcess, out var stream) &&
+ _solution.ResolveSolution(toProcess, stream.BloodSolutionName, ref stream.BloodSolution, out var solution))
{
- component.BloodReagent = stream.BloodReagent;
+ component.BloodReagents = solution.Clone();
+ component.BloodReagents.ScaleSolution(50 / component.BloodReagents.Volume);
}
if (TryComp(toProcess, out var butcherableComponent))
{
diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs
index 5a03fb6ce3..c47549b8ba 100644
--- a/Content.Server/Zombies/ZombieSystem.Transform.cs
+++ b/Content.Server/Zombies/ZombieSystem.Transform.cs
@@ -17,7 +17,6 @@ using Content.Shared.Abilities.Psionics; // DeltaV
using Content.Shared.Body.Components;
using Content.Shared.CombatMode;
using Content.Shared.CombatMode.Pacification;
-using Content.Shared.Damage.Components;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid;
@@ -209,8 +208,8 @@ public sealed partial class ZombieSystem
zombiecomp.BeforeZombifiedSkinColor = huApComp.SkinColor;
zombiecomp.BeforeZombifiedEyeColor = huApComp.EyeColor;
zombiecomp.BeforeZombifiedCustomBaseLayers = new(huApComp.CustomBaseLayers);
- if (TryComp(target, out var stream))
- zombiecomp.BeforeZombifiedBloodReagent = stream.BloodReagent;
+ if (TryComp(target, out var stream) && stream.BloodReagents is { } reagents)
+ zombiecomp.BeforeZombifiedBloodReagents = reagents.Clone();
_humanoidAppearance.SetSkinColor(target, zombiecomp.SkinColor, verify: false, humanoid: huApComp);
@@ -244,7 +243,7 @@ public sealed partial class ZombieSystem
//NOTE: they are supposed to bleed, just not take damage
_bloodstream.SetBloodLossThreshold(target, 0f);
//Give them zombie blood
- _bloodstream.ChangeBloodReagent(target, zombiecomp.NewBloodReagent);
+ _bloodstream.ChangeBloodReagents(target, zombiecomp.NewBloodReagents);
//This is specifically here to combat insuls, because frying zombies on grilles is funny as shit.
//_inventory.TryUnequip(target, "gloves", true, true); // DeltaV - Buff Zombies
diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs
index 72c5236930..b840e7203e 100644
--- a/Content.Server/Zombies/ZombieSystem.cs
+++ b/Content.Server/Zombies/ZombieSystem.cs
@@ -305,7 +305,7 @@ namespace Content.Server.Zombies
appcomp.EyeColor = zombiecomp.BeforeZombifiedEyeColor;
}
_humanoidAppearance.SetSkinColor(target, zombiecomp.BeforeZombifiedSkinColor, false);
- _bloodstream.ChangeBloodReagent(target, zombiecomp.BeforeZombifiedBloodReagent);
+ _bloodstream.ChangeBloodReagents(target, zombiecomp.BeforeZombifiedBloodReagents);
return true;
}
diff --git a/Content.Shared/Body/Components/BloodstreamComponent.cs b/Content.Shared/Body/Components/BloodstreamComponent.cs
index 51814eaba9..2ebfae6f33 100644
--- a/Content.Shared/Body/Components/BloodstreamComponent.cs
+++ b/Content.Shared/Body/Components/BloodstreamComponent.cs
@@ -1,7 +1,6 @@
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;
@@ -152,13 +151,13 @@ public sealed partial class BloodstreamComponent : Component
public FixedPoint2 BloodMaxVolume = FixedPoint2.New(300);
///
- /// Which reagent is considered this entities 'blood'?
+ /// Which reagents are considered this entities 'blood'?
///
///
/// Slime-people might use slime as their blood or something like that.
///
[DataField, AutoNetworkedField]
- public ProtoId BloodReagent = "Blood";
+ public Solution BloodReagents = new([new("Blood", 1)]);
///
/// Name/Key that is indexed by.
diff --git a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs
index 688e3ccb92..e108cbfb27 100644
--- a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs
+++ b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs
@@ -29,9 +29,9 @@ public abstract class SharedBloodstreamSystem : EntitySystem
{
public static readonly EntProtoId Bloodloss = "StatusEffectBloodloss";
+ [Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
[Dependency] protected readonly SharedSolutionContainerSystem SolutionContainer = default!;
[Dependency] private readonly IGameTiming _timing = default!;
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedPuddleSystem _puddle = default!;
@@ -193,7 +193,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem
}
// TODO probably cache this or something. humans get hurt a lot
- if (!_prototypeManager.Resolve(ent.Comp.DamageBleedModifiers, out var modifiers))
+ if (!PrototypeManager.Resolve(ent.Comp.DamageBleedModifiers, out var modifiers))
return;
// some reagents may deal and heal different damage types in the same tick, which means DamageIncreased will be true
@@ -366,11 +366,18 @@ public abstract class SharedBloodstreamSystem : EntitySystem
public bool TryModifyBloodLevel(Entity ent, FixedPoint2 amount)
{
if (!Resolve(ent, ref ent.Comp, logMissing: false)
- || !SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.BloodSolutionName, ref ent.Comp.BloodSolution))
+ || !SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.BloodSolutionName, ref ent.Comp.BloodSolution, out var bloodSolution))
return false;
if (amount >= 0)
- return SolutionContainer.TryAddReagent(ent.Comp.BloodSolution.Value, ent.Comp.BloodReagent, amount, null, GetEntityBloodData(ent));
+ {
+ var min = FixedPoint2.Min(bloodSolution.AvailableVolume, amount);
+ var solution = ent.Comp.BloodReagents.Clone();
+ solution.ScaleTo(min);
+ solution.SetReagentData(GetEntityBloodData(ent));
+ SolutionContainer.AddSolution(ent.Comp.BloodSolution.Value, solution);
+ return min == amount;
+ }
// Removal is more involved,
// since we also wanna handle moving it to the temporary solution
@@ -380,7 +387,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem
if (!SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.BloodTemporarySolutionName, ref ent.Comp.TemporarySolution, out var tempSolution))
return true;
- tempSolution.AddSolution(newSol, _prototypeManager);
+ tempSolution.AddSolution(newSol, PrototypeManager);
if (tempSolution.Volume > ent.Comp.BleedPuddleThreshold)
{
@@ -388,7 +395,7 @@ public abstract class SharedBloodstreamSystem : EntitySystem
if (SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.ChemicalSolutionName, ref ent.Comp.ChemicalSolution))
{
var temp = SolutionContainer.SplitSolution(ent.Comp.ChemicalSolution.Value, tempSolution.Volume / 10);
- tempSolution.AddSolution(temp, _prototypeManager);
+ tempSolution.AddSolution(temp, PrototypeManager);
}
_puddle.TrySpillAt(ent.Owner, tempSolution, out _, sound: false);
@@ -439,21 +446,21 @@ public abstract class SharedBloodstreamSystem : EntitySystem
if (SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.BloodSolutionName, ref ent.Comp.BloodSolution, out var bloodSolution))
{
tempSol.MaxVolume += bloodSolution.MaxVolume;
- tempSol.AddSolution(bloodSolution, _prototypeManager);
+ tempSol.AddSolution(bloodSolution, PrototypeManager);
SolutionContainer.RemoveAllSolution(ent.Comp.BloodSolution.Value);
}
if (SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.ChemicalSolutionName, ref ent.Comp.ChemicalSolution, out var chemSolution))
{
tempSol.MaxVolume += chemSolution.MaxVolume;
- tempSol.AddSolution(chemSolution, _prototypeManager);
+ tempSol.AddSolution(chemSolution, PrototypeManager);
SolutionContainer.RemoveAllSolution(ent.Comp.ChemicalSolution.Value);
}
if (SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.BloodTemporarySolutionName, ref ent.Comp.TemporarySolution, out var tempSolution))
{
tempSol.MaxVolume += tempSolution.MaxVolume;
- tempSol.AddSolution(tempSolution, _prototypeManager);
+ tempSol.AddSolution(tempSolution, PrototypeManager);
SolutionContainer.RemoveAllSolution(ent.Comp.TemporarySolution.Value);
}
@@ -463,27 +470,45 @@ public abstract class SharedBloodstreamSystem : EntitySystem
///
/// Change what someone's blood is made of, on the fly.
///
+ [Obsolete("ChangeBloodReagent is obsolete, please use ChangeBloodReagents.")]
public void ChangeBloodReagent(Entity ent, ProtoId reagent)
{
- if (!Resolve(ent, ref ent.Comp, logMissing: false)
- || reagent == ent.Comp.BloodReagent)
+ ChangeBloodReagents(ent, new([new(reagent, 1)]));
+ }
+
+ ///
+ /// Change what someone's blood is made of, on the fly.
+ ///
+ public void ChangeBloodReagents(Entity ent, Solution reagents)
+ {
+ if (!Resolve(ent, ref ent.Comp, logMissing: false))
{
return;
}
if (!SolutionContainer.ResolveSolution(ent.Owner, ent.Comp.BloodSolutionName, ref ent.Comp.BloodSolution, out var bloodSolution))
{
- ent.Comp.BloodReagent = reagent;
+ ent.Comp.BloodReagents = reagents.Clone();
+ DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.BloodReagents));
return;
}
- var currentVolume = bloodSolution.RemoveReagent(ent.Comp.BloodReagent, bloodSolution.Volume, ignoreReagentData: true);
+ var currentVolume = FixedPoint2.Zero;
+ foreach (var reagent in ent.Comp.BloodReagents)
+ {
+ currentVolume += bloodSolution.RemoveReagent(reagent.Reagent, quantity: bloodSolution.Volume, ignoreReagentData: true);
+ }
- ent.Comp.BloodReagent = reagent;
- DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.BloodReagent));
+ ent.Comp.BloodReagents = reagents.Clone();
+ DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.BloodReagents));
- if (currentVolume > 0)
- SolutionContainer.TryAddReagent(ent.Comp.BloodSolution.Value, ent.Comp.BloodReagent, currentVolume, null, GetEntityBloodData(ent));
+ if (currentVolume == FixedPoint2.Zero)
+ return;
+
+ var solution = ent.Comp.BloodReagents.Clone();
+ solution.ScaleSolution(currentVolume / solution.Volume);
+ solution.SetReagentData(GetEntityBloodData(ent));
+ SolutionContainer.AddSolution(ent.Comp.BloodSolution.Value, solution);
}
///
diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs
index df09f7f3f6..cd0314419a 100644
--- a/Content.Shared/Chemistry/Components/Solution.cs
+++ b/Content.Shared/Chemistry/Components/Solution.cs
@@ -167,7 +167,12 @@ namespace Content.Shared.Chemistry.Components
public Solution(Solution solution)
{
- Contents = solution.Contents.ShallowClone();
+ Contents = new(solution.Contents.Count);
+ foreach (var item in solution.Contents)
+ {
+ Contents.Add(item.Clone());
+ }
+
Volume = solution.Volume;
MaxVolume = solution.MaxVolume;
Temperature = solution.Temperature;
@@ -474,6 +479,37 @@ namespace Content.Shared.Chemistry.Components
ValidateSolution();
}
+ ///
+ /// Scales the amount of solution.
+ ///
+ /// The scalar to modify the solution by.
+ public void ScaleSolution(FixedPoint2 scale)
+ {
+ ScaleSolution(scale.Float());
+ }
+
+ ///
+ /// Scales the amount of solution to a given target.
+ ///
+ /// The volume the solutions should have after scaling.
+ public void ScaleTo(FixedPoint2 target)
+ {
+ if (Volume == FixedPoint2.Zero || Volume == target)
+ return;
+
+ if (target == FixedPoint2.Zero)
+ {
+ RemoveAllSolution();
+ return;
+ }
+
+ var nearestIntScale = (int)Math.Ceiling(target.Float() / Volume.Float());
+ ScaleSolution(nearestIntScale);
+
+ var overflow = Volume - target;
+ RemoveSolution(overflow);
+ }
+
///
/// Attempts to remove an amount of reagent from the solution.
///
@@ -965,5 +1001,15 @@ namespace Content.Shared.Chemistry.Components
}
return dict;
}
+
+ public void SetReagentData(List? data)
+ {
+ for (var i = 0; i < Contents.Count; i++)
+ {
+ var old = Contents[i];
+ Contents[i] = new ReagentQuantity(new ReagentId(old.Reagent.Prototype, data), old.Quantity);
+ }
+ ValidateSolution();
+ }
}
}
diff --git a/Content.Shared/Chemistry/Reagent/DNAData.cs b/Content.Shared/Chemistry/Reagent/DNAData.cs
index e75e994ece..5a88c0b41c 100644
--- a/Content.Shared/Chemistry/Reagent/DNAData.cs
+++ b/Content.Shared/Chemistry/Reagent/DNAData.cs
@@ -1,4 +1,3 @@
-using Content.Shared.FixedPoint;
using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry.Reagent;
@@ -7,9 +6,15 @@ namespace Content.Shared.Chemistry.Reagent;
public sealed partial class DnaData : ReagentData
{
[DataField]
- public string DNA = String.Empty;
+ public string DNA = string.Empty;
- public override ReagentData Clone() => this;
+ public override ReagentData Clone()
+ {
+ return new DnaData
+ {
+ DNA = DNA,
+ };
+ }
public override bool Equals(ReagentData? other)
{
diff --git a/Content.Shared/Chemistry/Reagent/ReagentQuantity.cs b/Content.Shared/Chemistry/Reagent/ReagentQuantity.cs
index cc5b52fbe2..22c1a3e0e5 100644
--- a/Content.Shared/Chemistry/Reagent/ReagentQuantity.cs
+++ b/Content.Shared/Chemistry/Reagent/ReagentQuantity.cs
@@ -8,9 +8,9 @@ namespace Content.Shared.Chemistry.Reagent;
///
[Serializable, NetSerializable]
[DataDefinition]
-public partial struct ReagentQuantity : IEquatable
+public partial struct ReagentQuantity : IEquatable, IRobustCloneable
{
- [DataField("Quantity", required:true)]
+ [DataField("Quantity", required: true)]
public FixedPoint2 Quantity { get; private set; }
[IncludeDataField]
@@ -28,6 +28,28 @@ public partial struct ReagentQuantity : IEquatable
Quantity = quantity;
}
+ public ReagentQuantity(ReagentQuantity reagentQuantity)
+ {
+ Quantity = reagentQuantity.Quantity;
+ if (reagentQuantity.Reagent.Data is not { } data)
+ {
+ Reagent = new ReagentId(reagentQuantity.Reagent.Prototype, null);
+ return;
+ }
+
+ List copy = new(data.Count);
+ foreach (var item in data)
+ {
+ copy.Add(item.Clone());
+ }
+ Reagent = new ReagentId(reagentQuantity.Reagent.Prototype, copy);
+ }
+
+ public readonly ReagentQuantity Clone()
+ {
+ return new ReagentQuantity(this);
+ }
+
public ReagentQuantity() : this(default, default)
{
}
diff --git a/Content.Shared/Zombies/ZombieComponent.cs b/Content.Shared/Zombies/ZombieComponent.cs
index 9627ee2f94..4435ffa631 100644
--- a/Content.Shared/Zombies/ZombieComponent.cs
+++ b/Content.Shared/Zombies/ZombieComponent.cs
@@ -1,7 +1,7 @@
using Content.Shared.Chat.Prototypes;
+using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
-using Content.Shared.FixedPoint;
using Content.Shared.Humanoid;
using Content.Shared.Roles;
using Content.Shared.StatusIcon;
@@ -167,14 +167,14 @@ public sealed partial class ZombieComponent : Component
public SoundSpecifier BiteSound = new SoundPathSpecifier("/Audio/Effects/bite.ogg");
///
- /// The blood reagent of the humanoid to restore in case of cloning
+ /// The blood reagents of the humanoid to restore in case of cloning
///
- [DataField("beforeZombifiedBloodReagent")]
- public string BeforeZombifiedBloodReagent = string.Empty;
+ [DataField("beforeZombifiedBloodReagents")]
+ public Solution BeforeZombifiedBloodReagents = new();
///
- /// The blood reagent to give the zombie. In case you want zombies that bleed milk, or something.
+ /// The blood reagents to give the zombie. In case you want zombies that bleed milk, or something.
///
- [DataField("newBloodReagent", customTypeSerializer: typeof(PrototypeIdSerializer))]
- public string NewBloodReagent = "ZombieBlood";
+ [DataField("newBloodReagents")]
+ public Solution NewBloodReagents = new([new("ZombieBlood", 1)]);
}
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
index f9e172142a..c54ca66221 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
@@ -141,7 +141,10 @@
- Bee
- Trash
- type: Bloodstream
- bloodReagent: InsectBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: InsectBlood
+ Quantity: 1
bloodMaxVolume: 0.1
- type: MobPrice
price: 50
@@ -391,7 +394,10 @@
Dead:
Base: cockroach_dead
- type: Bloodstream
- bloodReagent: InsectBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: InsectBlood
+ Quantity: 1
bloodMaxVolume: 20
- type: Edible
- type: FlavorProfile
@@ -556,7 +562,10 @@
damageContainer: Biological
damageModifierSet: Moth
- type: Bloodstream
- bloodReagent: InsectBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: InsectBlood
+ Quantity: 1
- type: Respirator
damage:
types:
@@ -844,7 +853,10 @@
tags:
- Trash
- type: Bloodstream
- bloodReagent: InsectBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: InsectBlood
+ Quantity: 1
bloodMaxVolume: 0.1
- type: MobPrice
price: 50
@@ -1009,7 +1021,10 @@
accent: crab
- type: Bloodstream
bloodMaxVolume: 50
- bloodReagent: CopperBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: CopperBlood
+ Quantity: 1
- type: Tag
tags:
- VimPilot
@@ -2155,7 +2170,10 @@
- type: RadiationSource
intensity: 0.3
- type: Bloodstream
- bloodReagent: UnstableMutagen
+ bloodReagents:
+ reagents:
+ - ReagentId: UnstableMutagen
+ Quantity: 1
- type: SolutionContainerManager
solutions:
food:
@@ -2699,7 +2717,10 @@
- type: IgnoreSpiderWeb
- type: Bloodstream
bloodMaxVolume: 150
- bloodReagent: CopperBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: CopperBlood
+ Quantity: 1
- type: Speech
speechVerb: Arachnid
speechSounds: Arachnid
@@ -2845,8 +2866,10 @@
speechVerb: Cluwne
- type: Bloodstream
bloodMaxVolume: 150
- bloodReagent: Laughter
-
+ bloodReagents:
+ reagents:
+ - ReagentId: Laughter
+ Quantity: 1
- type: entity
name: wizard spider
parent: MobGiantSpider
@@ -3180,7 +3203,10 @@
attributes:
gender: epicene
- type: Bloodstream
- bloodReagent: DemonsBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: DemonsBlood
+ Quantity: 1
- type: Damageable
damageContainer: BiologicalMetaphysical
damageModifierSet: Infernal
@@ -3841,7 +3867,10 @@
speciesId: cat
templateId: pet
- type: Bloodstream
- bloodReagent: Sap
+ bloodReagents:
+ reagents:
+ - ReagentId: Sap
+ Quantity: 1
bloodMaxVolume: 60
- type: DamageStateVisuals
states:
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml
index 36ddf71d4b..4c9f851ba0 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml
@@ -18,7 +18,10 @@
- type: ReplacementAccent
accent: xeno
- type: Bloodstream
- bloodReagent: FerrochromicAcid
+ bloodReagents:
+ reagents:
+ - ReagentId: FerrochromicAcid
+ Quantity: 1
bloodMaxVolume: 75 #we don't want the map to become pools of blood
bloodlossDamage:
types:
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml
index 1cb00ef760..23e3230937 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml
@@ -115,8 +115,10 @@
context: "human"
- type: Bloodstream
bloodMaxVolume: 300
- bloodReagent: Laughter
-
+ bloodReagents:
+ reagents:
+ - ReagentId: Laughter
+ Quantity: 1
- type: entity
name: behonker
parent: BaseMobBehonker
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml
index d30114104b..a434f1e4fe 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml
@@ -349,7 +349,10 @@
speedModifierThresholds:
50: 0.4
- type: Bloodstream
- bloodReagent: Water
+ bloodReagents:
+ reagents:
+ - ReagentId: Water
+ Quantity: 1
chemicalMaxVolume: 100
- type: StatusEffects
allowed:
@@ -418,7 +421,10 @@
suffix: Beer
components:
- type: Bloodstream
- bloodReagent: Beer
+ bloodReagents:
+ reagents:
+ - ReagentId: Beer
+ Quantity: 1
- type: PointLight
color: "#cfa85f"
- type: Sprite
@@ -435,7 +441,10 @@
suffix: Pax
components:
- type: Bloodstream
- bloodReagent: Pax
+ bloodReagents:
+ reagents:
+ - ReagentId: Pax
+ Quantity: 1
- type: PointLight
color: "#AAAAAA"
- type: Sprite
@@ -455,7 +464,10 @@
suffix: Nocturine
components:
- type: Bloodstream
- bloodReagent: Nocturine
+ bloodReagents:
+ reagents:
+ - ReagentId: Nocturine
+ Quantity: 1
- type: PointLight
color: "#128e80"
- type: Sprite
@@ -475,7 +487,10 @@
suffix: THC
components:
- type: Bloodstream
- bloodReagent: THC
+ bloodReagents:
+ reagents:
+ - ReagentId: THC
+ Quantity: 1
- type: PointLight
color: "#808080"
- type: Sprite
@@ -492,7 +507,10 @@
suffix: Bicaridine
components:
- type: Bloodstream
- bloodReagent: Bicaridine
+ bloodReagents:
+ reagents:
+ - ReagentId: Bicaridine
+ Quantity: 1
- type: PointLight
color: "#ffaa00"
- type: Sprite
@@ -509,7 +527,10 @@
suffix: Toxin
components:
- type: Bloodstream
- bloodReagent: Toxin
+ bloodReagents:
+ reagents:
+ - ReagentId: Toxin
+ Quantity: 1
- type: PointLight
color: "#cf3600"
- type: Sprite
@@ -526,7 +547,10 @@
suffix: Napalm
components:
- type: Bloodstream
- bloodReagent: Napalm
+ bloodReagents:
+ reagents:
+ - ReagentId: Napalm
+ Quantity: 1
- type: PointLight
color: "#FA00AF"
- type: Sprite
@@ -543,7 +567,10 @@
suffix: Omnizine
components:
- type: Bloodstream
- bloodReagent: Omnizine
+ bloodReagents:
+ reagents:
+ - ReagentId: Omnizine
+ Quantity: 1
- type: PointLight
color: "#fcf7f9"
- type: Sprite
@@ -560,7 +587,10 @@
suffix: Mute Toxin
components:
- type: Bloodstream
- bloodReagent: MuteToxin
+ bloodReagents:
+ reagents:
+ - ReagentId: MuteToxin
+ Quantity: 1
- type: PointLight
color: "#0f0f0f"
- type: Sprite
@@ -577,7 +607,10 @@
suffix: Norepinephric Acid
components:
- type: Bloodstream
- bloodReagent: NorepinephricAcid
+ bloodReagents:
+ reagents:
+ - ReagentId: NorepinephricAcid
+ Quantity: 1
- type: PointLight
color: "#96a8b5"
- type: Sprite
@@ -594,7 +627,10 @@
suffix: Ephedrine
components:
- type: Bloodstream
- bloodReagent: Ephedrine
+ bloodReagents:
+ reagents:
+ - ReagentId: Ephedrine
+ Quantity: 1
- type: PointLight
color: "#D2FFFA"
- type: Sprite
@@ -611,7 +647,10 @@
suffix: Robust Harvest
components:
- type: Bloodstream
- bloodReagent: RobustHarvest
+ bloodReagents:
+ reagents:
+ - ReagentId: RobustHarvest
+ Quantity: 1
- type: PointLight
color: "#3e901c"
- type: Sprite
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml
index 3b89ba17d5..fcac87f1c0 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml
@@ -152,7 +152,10 @@
- map: [ "enum.DamageStateVisualLayers.Base" ]
state: alive
- type: Bloodstream
- bloodReagent: JuiceTomato
+ bloodReagents:
+ reagents:
+ - ReagentId: JuiceTomato
+ Quantity: 1
bloodMaxVolume: 50
chemicalMaxVolume: 30
- type: DamageStateVisuals
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml
index 5a96810d94..86e0450b96 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml
@@ -54,7 +54,10 @@
damageContainer: Biological
damageModifierSet: Slime
- type: Bloodstream
- bloodReagent: Slime
+ bloodReagents:
+ reagents:
+ - ReagentId: Slime
+ Quantity: 1
bloodlossDamage:
types:
Bloodloss:
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
index b7ed511761..5aa4be9b47 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
@@ -40,7 +40,10 @@
- type: MovementAlwaysTouching
- type: Bloodstream
bloodMaxVolume: 300
- bloodReagent: Cryoxadone
+ bloodReagents:
+ reagents:
+ - ReagentId: Cryoxadone
+ Quantity: 1
- type: CombatMode
- type: Temperature
heatDamageThreshold: 500
@@ -213,7 +216,10 @@
prob: 0.5
- type: Bloodstream
bloodMaxVolume: 250
- bloodReagent: Cryoxadone
+ bloodReagents:
+ reagents:
+ - ReagentId: Cryoxadone
+ Quantity: 1
- type: Fixtures
fixtures:
fix1:
@@ -318,7 +324,10 @@
prob: 0.3
- type: Bloodstream
bloodMaxVolume: 200
- bloodReagent: Cryoxadone
+ bloodReagents:
+ reagents:
+ - ReagentId: Cryoxadone
+ Quantity: 1
- type: Fixtures
fixtures:
fix1:
@@ -486,7 +495,10 @@
combatToggleAction: ActionCombatModeToggleOff
- type: Bloodstream
bloodMaxVolume: 30
- bloodReagent: Cryoxadone
+ bloodReagents:
+ reagents:
+ - ReagentId: Cryoxadone
+ Quantity: 1
- type: CanEscapeInventory
- type: MobPrice
price: 50
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
index eebef82d46..a9a46cf387 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
@@ -67,7 +67,10 @@
- type: Stamina
critThreshold: 200
- type: Bloodstream
- bloodReagent: FluorosulfuricAcid
+ bloodReagents:
+ reagents:
+ - ReagentId: FluorosulfuricAcid
+ Quantity: 1
bloodMaxVolume: 650
- type: MeleeWeapon
altDisarm: false
@@ -522,7 +525,10 @@
- type: Stamina
critThreshold: 200
- type: Bloodstream
- bloodReagent: FluorosulfuricAcid
+ bloodReagents:
+ reagents:
+ - ReagentId: FluorosulfuricAcid
+ Quantity: 1
bloodMaxVolume: 300
- type: MeleeWeapon
altDisarm: false
diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml
index dc89b4c8f4..ba07d16c5e 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml
@@ -43,7 +43,10 @@
- !type:WashCreamPie
# Damage (Self)
- type: Bloodstream
- bloodReagent: CopperBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: CopperBlood
+ Quantity: 1
# Damage (Others)
- type: MeleeWeapon
animation: WeaponArcBite
diff --git a/Resources/Prototypes/Entities/Mobs/Species/diona.yml b/Resources/Prototypes/Entities/Mobs/Species/diona.yml
index 8b0246778d..9c4790f2e5 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/diona.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/diona.yml
@@ -33,7 +33,10 @@
- id: FoodMeatPlant
amount: 5
- type: Bloodstream
- bloodReagent: Sap
+ bloodReagents:
+ reagents:
+ - ReagentId: Sap
+ Quantity: 1
- type: Reactive
groups:
Flammable: [ Touch ]
diff --git a/Resources/Prototypes/Entities/Mobs/Species/gingerbread.yml b/Resources/Prototypes/Entities/Mobs/Species/gingerbread.yml
index cc4b506dc8..7844c80082 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/gingerbread.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/gingerbread.yml
@@ -29,7 +29,12 @@
- id: FoodBakedCookie #should be replaced with gingerbread sheets or something... provided you're willing to make a full spriteset of those.
amount: 5
- type: Bloodstream
- bloodReagent: Sugar
+ bloodReagents:
+ reagents:
+ - ReagentId: Sugar
+ Quantity: 1
+ - ReagentId: Butter
+ Quantity: 2
- type: Fixtures
fixtures:
fix1:
diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml
index c841ebc79f..d5ff093b09 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml
@@ -33,7 +33,10 @@
- id: FoodMeat
amount: 5
- type: Bloodstream
- bloodReagent: InsectBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: InsectBlood
+ Quantity: 1
- type: DamageVisuals
damageOverlayGroups:
Brute:
diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml
index f8c7d64a9c..5ea8291ff1 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml
@@ -74,7 +74,10 @@
Burn:
sprite: Mobs/Effects/burn_damage.rsi
- type: Bloodstream
- bloodReagent: Slime # TODO Color slime blood based on their slime color or smth
+ bloodReagents: # TODO Color slime blood based on their slime color or smth
+ reagents:
+ - ReagentId: Slime
+ Quantity: 1
- type: Barotrauma
damage:
types:
diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml
index 841f95b667..611681c6d1 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml
@@ -89,7 +89,10 @@
Burn:
sprite: Mobs/Effects/burn_damage.rsi
- type: Bloodstream
- bloodReagent: AmmoniaBlood
+ bloodReagents:
+ reagents:
+ - ReagentId: AmmoniaBlood
+ Quantity: 1
- type: MeleeWeapon
soundHit:
collection: AlienClaw