]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Animals obey conservation of matter unless they are undead (#21922)
authorSirionaut <148076704+Sirionaut@users.noreply.github.com>
Mon, 11 Dec 2023 03:20:41 +0000 (04:20 +0100)
committerGitHub <noreply@github.com>
Mon, 11 Dec 2023 03:20:41 +0000 (19:20 -0800)
Content.Server/Animals/Components/EggLayerComponent.cs
Content.Server/Animals/Components/UdderComponent.cs
Content.Server/Animals/Components/WoolyComponent.cs
Content.Server/Animals/Systems/EggLayerSystem.cs
Content.Server/Animals/Systems/UdderSystem.cs
Content.Server/Animals/Systems/WoolySystem.cs
Content.Server/Zombies/ZombieSystem.Transform.cs

index 33d14c8e360f2e0986ba3e6cf22a97286122ca1c..a0f7de676e5fc0b93e48f6f83caa24c391006110 100644 (file)
@@ -1,7 +1,6 @@
 using Content.Shared.Storage;
 using Robust.Shared.Audio;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
 
 namespace Content.Server.Animals.Components;
 
@@ -9,28 +8,29 @@ namespace Content.Server.Animals.Components;
 ///     This component handles animals which lay eggs (or some other item) on a timer, using up hunger to do so.
 ///     It also grants an action to players who are controlling these entities, allowing them to do it manually.
 /// </summary>
+
 [RegisterComponent]
 public sealed partial class EggLayerComponent : Component
 {
-    [DataField("eggLayAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-    public string EggLayAction = "ActionAnimalLayEgg";
+    [DataField]
+    public EntProtoId EggLayAction = "ActionAnimalLayEgg";
 
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("hungerUsage")]
+    /// <summary>
+    ///     The amount of nutrient consumed on update.
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite)]
     public float HungerUsage = 60f;
 
     /// <summary>
     ///     Minimum cooldown used for the automatic egg laying.
     /// </summary>
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("eggLayCooldownMin")]
+    [DataField, ViewVariables(VVAccess.ReadWrite)]
     public float EggLayCooldownMin = 60f;
 
     /// <summary>
     ///     Maximum cooldown used for the automatic egg laying.
     /// </summary>
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("eggLayCooldownMax")]
+    [DataField, ViewVariables(VVAccess.ReadWrite)]
     public float EggLayCooldownMax = 120f;
 
     /// <summary>
@@ -39,14 +39,13 @@ public sealed partial class EggLayerComponent : Component
     [ViewVariables(VVAccess.ReadWrite)]
     public float CurrentEggLayCooldown;
 
-    [ViewVariables(VVAccess.ReadWrite)]
-    [DataField("eggSpawn", required: true)]
+    [DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
     public List<EntitySpawnEntry> EggSpawn = default!;
 
-    [DataField("eggLaySound")]
+    [DataField]
     public SoundSpecifier EggLaySound = new SoundPathSpecifier("/Audio/Effects/pop.ogg");
 
-    [DataField("accumulatedFrametime")]
+    [DataField]
     public float AccumulatedFrametime;
 
     [DataField] public EntityUid? Action;
index 1c71fcb7c5e87c78c77f492cbbae613eeee44886..3895a8ba24f10ccc959906d0b8b3efee013526b7 100644 (file)
@@ -1,9 +1,15 @@
 using Content.Server.Animals.Systems;
 using Content.Shared.Chemistry.Reagent;
 using Content.Shared.FixedPoint;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
 
 namespace Content.Server.Animals.Components
+
+/// <summary>
+///     Lets an entity produce milk. Uses hunger if present.
+/// </summary>
 {
     [RegisterComponent, Access(typeof(UdderSystem))]
     internal sealed partial class UdderComponent : Component
@@ -11,31 +17,37 @@ namespace Content.Server.Animals.Components
         /// <summary>
         ///     The reagent to produce.
         /// </summary>
-        [ViewVariables(VVAccess.ReadOnly)]
-        [DataField("reagentId", customTypeSerializer:typeof(PrototypeIdSerializer<ReagentPrototype>))]
-        public string ReagentId = "Milk";
+        [DataField, ViewVariables(VVAccess.ReadOnly)]
+        public ProtoId<ReagentPrototype> ReagentId = "Milk";
 
         /// <summary>
         ///     The solution to add reagent to.
         /// </summary>
-        [ViewVariables(VVAccess.ReadOnly)]
-        [DataField("targetSolution")]
-        public string TargetSolutionName = "udder";
+        [DataField, ViewVariables(VVAccess.ReadOnly)]
+        public string Solution = "udder";
 
         /// <summary>
         ///     The amount of reagent to be generated on update.
         /// </summary>
-        [ViewVariables(VVAccess.ReadOnly)]
-        [DataField("quantity")]
-        public FixedPoint2 QuantityPerUpdate = 1;
+        [DataField, ViewVariables(VVAccess.ReadOnly)]
+        public FixedPoint2 QuantityPerUpdate = 25;
 
         /// <summary>
-        ///     The time between updates (in seconds).
+        ///     The amount of nutrient consumed on update.
         /// </summary>
-        [ViewVariables(VVAccess.ReadOnly)]
-        [DataField("updateRate")]
-        public float UpdateRate = 5;
+        [DataField, ViewVariables(VVAccess.ReadWrite)]
+        public float HungerUsage = 10f;
 
-        public float AccumulatedFrameTime;
+        /// <summary>
+        ///     How long to wait before producing.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite)]
+        public TimeSpan GrowthDelay = TimeSpan.FromMinutes(1);
+
+        /// <summary>
+        ///     When to next try to produce.
+        /// </summary>
+        [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
+        public TimeSpan NextGrowth = TimeSpan.FromSeconds(0);
     }
 }
index 8db44973e5f83657ba4f3ba2b04338427223560e..e700fd76f66a9c26861a17ee87e3803d94e53e76 100644 (file)
@@ -4,38 +4,47 @@ using Content.Shared.FixedPoint;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
 
+namespace Content.Server.Animals.Components;
+
 /// <summary>
-/// Lets an animal grow a wool solution when not hungry.
+///     Lets an entity produce wool fibers. Uses hunger if present.
 /// </summary>
+
 [RegisterComponent, Access(typeof(WoolySystem))]
 public sealed partial class WoolyComponent : Component
 {
     /// <summary>
-    /// What reagent to grow.
+    ///     The reagent to grow.
     /// </summary>
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField, ViewVariables(VVAccess.ReadOnly)]
     public ProtoId<ReagentPrototype> ReagentId = "Fiber";
 
     /// <summary>
-    /// How much wool to grow at every growth cycle.
+    ///     The solution to add reagent to.
     /// </summary>
-    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    [DataField, ViewVariables(VVAccess.ReadOnly)]
+    public string Solution = "wool";
+
+    /// <summary>
+    ///     The amount of reagent to be generated on update.
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadOnly)]
     public FixedPoint2 Quantity = 25;
 
     /// <summary>
-    /// What solution to add the wool reagent to.
+    ///     The amount of nutrient consumed on update.
     /// </summary>
     [DataField, ViewVariables(VVAccess.ReadWrite)]
-    public string Solution = "wool";
+    public float HungerUsage = 10f;
 
     /// <summary>
-    /// How long to wait before growing wool.
+    ///     How long to wait before growing wool.
     /// </summary>
     [DataField, ViewVariables(VVAccess.ReadWrite)]
     public TimeSpan GrowthDelay = TimeSpan.FromMinutes(1);
 
     /// <summary>
-    /// When to next try growing wool.
+    ///     When to next try growing wool.
     /// </summary>
     [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
     public TimeSpan NextGrowth = TimeSpan.FromSeconds(0);
index 35c3bab01dd8ab3aadcb866fbdd97121e2ccfb94..55d63808a4b9e16fc20bf6834d1820c200f363fa 100644 (file)
@@ -2,6 +2,7 @@ using Content.Server.Actions;
 using Content.Server.Animals.Components;
 using Content.Server.Popups;
 using Content.Shared.Actions.Events;
+using Content.Shared.Mobs.Systems;
 using Content.Shared.Nutrition.Components;
 using Content.Shared.Nutrition.EntitySystems;
 using Content.Shared.Storage;
@@ -12,6 +13,10 @@ using Robust.Shared.Random;
 
 namespace Content.Server.Animals.Systems;
 
+/// <summary>
+///     Gives ability to produce eggs, produces endless if the 
+///     owner has no HungerComponent
+/// </summary>
 public sealed class EggLayerSystem : EntitySystem
 {
     [Dependency] private readonly IRobustRandom _random = default!;
@@ -19,6 +24,7 @@ public sealed class EggLayerSystem : EntitySystem
     [Dependency] private readonly AudioSystem _audio = default!;
     [Dependency] private readonly HungerSystem _hunger = default!;
     [Dependency] private readonly PopupSystem _popup = default!;
+    [Dependency] private readonly MobStateSystem _mobState = default!;
 
     public override void Initialize()
     {
@@ -57,35 +63,38 @@ public sealed class EggLayerSystem : EntitySystem
         component.CurrentEggLayCooldown = _random.NextFloat(component.EggLayCooldownMin, component.EggLayCooldownMax);
     }
 
-    private void OnEggLayAction(EntityUid uid, EggLayerComponent component, EggLayInstantActionEvent args)
+    private void OnEggLayAction(EntityUid uid, EggLayerComponent egglayer, EggLayInstantActionEvent args)
     {
-        args.Handled = TryLayEgg(uid, component);
+        args.Handled = TryLayEgg(uid, egglayer);
     }
 
-    public bool TryLayEgg(EntityUid uid, EggLayerComponent? component)
+    public bool TryLayEgg(EntityUid uid, EggLayerComponent? egglayer)
     {
-        if (!Resolve(uid, ref component))
+        if (!Resolve(uid, ref egglayer))
+            return false;
+
+        if (_mobState.IsDead(uid))
             return false;
 
         // Allow infinitely laying eggs if they can't get hungry
         if (TryComp<HungerComponent>(uid, out var hunger))
         {
-            if (hunger.CurrentHunger < component.HungerUsage)
+            if (hunger.CurrentHunger < egglayer.HungerUsage)
             {
                 _popup.PopupEntity(Loc.GetString("action-popup-lay-egg-too-hungry"), uid, uid);
                 return false;
             }
 
-            _hunger.ModifyHunger(uid, -component.HungerUsage, hunger);
+            _hunger.ModifyHunger(uid, -egglayer.HungerUsage, hunger);
         }
 
-        foreach (var ent in EntitySpawnCollection.GetSpawns(component.EggSpawn, _random))
+        foreach (var ent in EntitySpawnCollection.GetSpawns(egglayer.EggSpawn, _random))
         {
             Spawn(ent, Transform(uid).Coordinates);
         }
 
         // Sound + popups
-        _audio.PlayPvs(component.EggLaySound, uid);
+        _audio.PlayPvs(egglayer.EggLaySound, uid);
         _popup.PopupEntity(Loc.GetString("action-popup-lay-egg-user"), uid, uid);
         _popup.PopupEntity(Loc.GetString("action-popup-lay-egg-others", ("entity", uid)), uid, Filter.PvsExcept(uid), true);
 
index 4164aedfd18476e2e3126903fe2dc9e08615b366..c07ba12dd5b195ad7c251511939fe99b9fbf5d3e 100644 (file)
@@ -4,124 +4,132 @@ using Content.Shared.Chemistry.Components;
 using Content.Shared.Chemistry.EntitySystems;
 using Content.Shared.DoAfter;
 using Content.Shared.IdentityManagement;
+using Content.Shared.Mobs.Systems;
 using Content.Shared.Nutrition.Components;
 using Content.Shared.Nutrition.EntitySystems;
 using Content.Shared.Popups;
 using Content.Shared.Udder;
 using Content.Shared.Verbs;
+using Robust.Shared.Timing;
 
-namespace Content.Server.Animals.Systems
+namespace Content.Server.Animals.Systems;
+
+/// <summary>
+///     Gives ability to produce milkable reagents, produces endless if the 
+///     owner has no HungerComponent
+/// </summary>
+internal sealed class UdderSystem : EntitySystem
 {
-    /// <summary>
-    ///     Gives ability to living beings with acceptable hunger level to produce milkable reagents.
-    /// </summary>
-    internal sealed class UdderSystem : EntitySystem
+    [Dependency] private readonly HungerSystem _hunger = default!;
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly MobStateSystem _mobState = default!;
+    [Dependency] private readonly PopupSystem _popupSystem = default!;
+    [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
+    [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
+
+    public override void Initialize()
     {
-        [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
-        [Dependency] private readonly HungerSystem _hunger = default!;
-        [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
-        [Dependency] private readonly PopupSystem _popupSystem = default!;
+        base.Initialize();
 
-        public override void Initialize()
-        {
-            base.Initialize();
+        SubscribeLocalEvent<UdderComponent, GetVerbsEvent<AlternativeVerb>>(AddMilkVerb);
+        SubscribeLocalEvent<UdderComponent, MilkingDoAfterEvent>(OnDoAfter);
+    }
 
-            SubscribeLocalEvent<UdderComponent, GetVerbsEvent<AlternativeVerb>>(AddMilkVerb);
-            SubscribeLocalEvent<UdderComponent, MilkingDoAfterEvent>(OnDoAfter);
-        }
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
 
-        public override void Update(float frameTime)
+        var query = EntityQueryEnumerator<UdderComponent>();
+        var now = _timing.CurTime;
+        while (query.MoveNext(out var uid, out var udder))
         {
-            var query = EntityQueryEnumerator<UdderComponent>();
-            while (query.MoveNext(out var uid, out var udder))
+            if (now < udder.NextGrowth)
+                continue;
+
+            udder.NextGrowth = now + udder.GrowthDelay;
+
+            if (_mobState.IsDead(uid))
+                continue;
+
+            // Actually there is food digestion so no problem with instant reagent generation "OnFeed"
+            if (EntityManager.TryGetComponent(uid, out HungerComponent? hunger))
             {
-                udder.AccumulatedFrameTime += frameTime;
-
-                while (udder.AccumulatedFrameTime > udder.UpdateRate)
-                {
-                    udder.AccumulatedFrameTime -= udder.UpdateRate;
-
-                    // Actually there is food digestion so no problem with instant reagent generation "OnFeed"
-                    if (EntityManager.TryGetComponent(uid, out HungerComponent? hunger))
-                    {
-                        // Is there enough nutrition to produce reagent?
-                        if (_hunger.GetHungerThreshold(hunger) < HungerThreshold.Peckish)
-                            continue;
-                    }
-
-                    if (!_solutionContainerSystem.TryGetSolution(uid, udder.TargetSolutionName,
-                            out var solution))
-                        continue;
-
-                    //TODO: toxins from bloodstream !?
-                    _solutionContainerSystem.TryAddReagent(uid, solution, udder.ReagentId,
-                        udder.QuantityPerUpdate, out var accepted);
-                }
+                // Is there enough nutrition to produce reagent?
+                if (_hunger.GetHungerThreshold(hunger) < HungerThreshold.Okay)
+                    continue;
+
+                _hunger.ModifyHunger(uid, -udder.HungerUsage, hunger);
             }
+
+            if (!_solutionContainerSystem.TryGetSolution(uid, udder.Solution, out var solution))
+                continue;
+
+            //TODO: toxins from bloodstream !?
+            _solutionContainerSystem.TryAddReagent(uid, solution, udder.ReagentId, udder.QuantityPerUpdate, out _);
         }
+    }
+
+    private void AttemptMilk(Entity<UdderComponent?> udder, EntityUid userUid, EntityUid containerUid)
+    {
+        if (!Resolve(udder, ref udder.Comp))
+            return;
 
-        private void AttemptMilk(EntityUid uid, EntityUid userUid, EntityUid containerUid, UdderComponent? udder = null)
+        var doargs = new DoAfterArgs(EntityManager, userUid, 5, new MilkingDoAfterEvent(), udder, udder, used: containerUid)
         {
-            if (!Resolve(uid, ref udder))
-                return;
+            BreakOnUserMove = true,
+            BreakOnDamage = true,
+            BreakOnTargetMove = true,
+            MovementThreshold = 1.0f,
+        };
 
-            var doargs = new DoAfterArgs(EntityManager, userUid, 5, new MilkingDoAfterEvent(), uid, uid, used: containerUid)
-            {
-                BreakOnUserMove = true,
-                BreakOnDamage = true,
-                BreakOnTargetMove = true,
-                MovementThreshold = 1.0f,
-            };
+        _doAfterSystem.TryStartDoAfter(doargs);
+    }
 
-            _doAfterSystem.TryStartDoAfter(doargs);
-        }
+    private void OnDoAfter(EntityUid uid, UdderComponent component, MilkingDoAfterEvent args)
+    {
+        if (args.Cancelled || args.Handled || args.Args.Used == null)
+            return;
 
-        private void OnDoAfter(EntityUid uid, UdderComponent component, MilkingDoAfterEvent args)
-        {
-            if (args.Cancelled || args.Handled || args.Args.Used == null)
-                return;
+        if (!_solutionContainerSystem.TryGetSolution(uid, component.Solution, out var solution))
+            return;
 
-            if (!_solutionContainerSystem.TryGetSolution(uid, component.TargetSolutionName, out var solution))
-                return;
+        if (!_solutionContainerSystem.TryGetRefillableSolution(args.Args.Used.Value, out var targetSolution))
+            return;
 
-            if (!_solutionContainerSystem.TryGetRefillableSolution(args.Args.Used.Value, out var targetSolution))
-                return;
+        args.Handled = true;
+        var quantity = solution.Volume;
+        if (quantity == 0)
+        {
+            _popupSystem.PopupEntity(Loc.GetString("udder-system-dry"), uid, args.Args.User);
+            return;
+        }
 
-            args.Handled = true;
-            var quantity = solution.Volume;
-            if(quantity == 0)
-            {
-                _popupSystem.PopupEntity(Loc.GetString("udder-system-dry"), uid, args.Args.User);
-                return;
-            }
+        if (quantity > targetSolution.AvailableVolume)
+            quantity = targetSolution.AvailableVolume;
 
-            if (quantity > targetSolution.AvailableVolume)
-                quantity = targetSolution.AvailableVolume;
+        var split = _solutionContainerSystem.SplitSolution(uid, solution, quantity);
+        _solutionContainerSystem.TryAddSolution(args.Args.Used.Value, targetSolution, split);
 
-            var split = _solutionContainerSystem.SplitSolution(uid, solution, quantity);
-            _solutionContainerSystem.TryAddSolution(args.Args.Used.Value, targetSolution, split);
+        _popupSystem.PopupEntity(Loc.GetString("udder-system-success", ("amount", quantity), ("target", Identity.Entity(args.Args.Used.Value, EntityManager))), uid,
+            args.Args.User, PopupType.Medium);
+    }
 
-            _popupSystem.PopupEntity(Loc.GetString("udder-system-success", ("amount", quantity), ("target", Identity.Entity(args.Args.Used.Value, EntityManager))), uid,
-                args.Args.User, PopupType.Medium);
-        }
+    private void AddMilkVerb(EntityUid uid, UdderComponent component, GetVerbsEvent<AlternativeVerb> args)
+    {
+        if (args.Using == null ||
+             !args.CanInteract ||
+             !EntityManager.HasComponent<RefillableSolutionComponent>(args.Using.Value))
+            return;
 
-        private void AddMilkVerb(EntityUid uid, UdderComponent component, GetVerbsEvent<AlternativeVerb> args)
+        AlternativeVerb verb = new()
         {
-            if (args.Using == null ||
-                 !args.CanInteract ||
-                 !EntityManager.HasComponent<RefillableSolutionComponent>(args.Using.Value))
-                return;
-
-            AlternativeVerb verb = new()
+            Act = () =>
             {
-                Act = () =>
-                {
-                    AttemptMilk(uid, args.User, args.Using.Value, component);
-                },
-                Text = Loc.GetString("udder-system-verb-milk"),
-                Priority = 2
-            };
-            args.Verbs.Add(verb);
-        }
+                AttemptMilk(uid, args.User, args.Using.Value);
+            },
+            Text = Loc.GetString("udder-system-verb-milk"),
+            Priority = 2
+        };
+        args.Verbs.Add(verb);
     }
 }
index e63718c39576d3965df8ded633ea0e98a2e75674..6cf8d8c88f303ee18b8cb186ff315e7a73cda8d6 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.Animals.Components;
 using Content.Server.Nutrition;
 using Content.Shared.Chemistry.EntitySystems;
+using Content.Shared.Mobs.Systems;
 using Content.Shared.Nutrition.Components;
 using Content.Shared.Nutrition.EntitySystems;
 using Robust.Shared.Timing;
@@ -8,13 +9,14 @@ using Robust.Shared.Timing;
 namespace Content.Server.Animals.Systems;
 
 /// <summary>
-/// Handles regeneration of an animal's wool solution when not hungry.
-/// Shearing is not currently possible so the only use is for moths to eat.
+///     Gives ability to produce fiber reagents, produces endless if the 
+///     owner has no HungerComponent
 /// </summary>
 public sealed class WoolySystem : EntitySystem
 {
     [Dependency] private readonly HungerSystem _hunger = default!;
     [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly MobStateSystem _mobState = default!;
     [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
 
     public override void Initialize()
@@ -28,23 +30,32 @@ public sealed class WoolySystem : EntitySystem
     {
         base.Update(frameTime);
 
-        var query = EntityQueryEnumerator<WoolyComponent, HungerComponent>();
+        var query = EntityQueryEnumerator<WoolyComponent>();
         var now = _timing.CurTime;
-        while (query.MoveNext(out var uid, out var comp, out var hunger))
+        while (query.MoveNext(out var uid, out var wooly))
         {
-            if (now < comp.NextGrowth)
+            if (now < wooly.NextGrowth)
                 continue;
 
-            comp.NextGrowth = now + comp.GrowthDelay;
+            wooly.NextGrowth = now + wooly.GrowthDelay;
 
-            // Is there enough nutrition to produce reagent?
-            if (_hunger.GetHungerThreshold(hunger) < HungerThreshold.Peckish)
+            if (_mobState.IsDead(uid))
                 continue;
 
-            if (!_solutionContainer.TryGetSolution(uid, comp.Solution, out var solution))
+            // Actually there is food digestion so no problem with instant reagent generation "OnFeed"
+            if (EntityManager.TryGetComponent(uid, out HungerComponent? hunger))
+            {
+                // Is there enough nutrition to produce reagent?
+                if (_hunger.GetHungerThreshold(hunger) < HungerThreshold.Okay)
+                    continue;
+
+                _hunger.ModifyHunger(uid, -wooly.HungerUsage, hunger);
+            }
+
+            if (!_solutionContainer.TryGetSolution(uid, wooly.Solution, out var solution))
                 continue;
 
-            _solutionContainer.TryAddReagent(uid, solution, comp.ReagentId, comp.Quantity, out _);
+            _solutionContainer.TryAddReagent(uid, solution, wooly.ReagentId, wooly.Quantity, out _);
         }
     }
 
index 77cf121102bc7d0a0499549b0faa68419772f123..cac516407ba1f6765628862112b8440c247fae9b 100644 (file)
@@ -25,6 +25,7 @@ using Content.Shared.Mobs;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Mobs.Systems;
 using Content.Shared.Movement.Systems;
+using Content.Shared.Nutrition.AnimalHusbandry;
 using Content.Shared.Nutrition.Components;
 using Content.Shared.Popups;
 using Content.Shared.Roles;
@@ -96,11 +97,13 @@ namespace Content.Server.Zombies
             var zombiecomp = AddComp<ZombieComponent>(target);
 
             //we need to basically remove all of these because zombies shouldn't
-            //get diseases, breath, be thirst, be hungry, or die in space
+            //get diseases, breath, be thirst, be hungry, die in space or have offspring
             RemComp<RespiratorComponent>(target);
             RemComp<BarotraumaComponent>(target);
             RemComp<HungerComponent>(target);
             RemComp<ThirstComponent>(target);
+            RemComp<ReproductiveComponent>(target); 
+            RemComp<ReproductivePartnerComponent>(target);
 
             //funny voice
             var accentType = "zombie";