]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
allow biomass reclaimer to reclaim plants (#23731)
authorIlya246 <57039557+Ilya246@users.noreply.github.com>
Mon, 11 Mar 2024 21:59:21 +0000 (01:59 +0400)
committerGitHub <noreply@github.com>
Mon, 11 Mar 2024 21:59:21 +0000 (17:59 -0400)
Content.Server/Medical/BiomassReclaimer/BiomassReclaimerComponent.cs
Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs

index 25378bb3ede272e39098757175784ab0a9e3607e..61d36f98b960604ee6b34f87f27ca5f220ac3f0d 100644 (file)
@@ -15,7 +15,7 @@ namespace Content.Server.Medical.BiomassReclaimer
         /// <summary>
         /// The interval for <see cref="RandomMessTimer"/>.
         /// </summary>
-        [ViewVariables(VVAccess.ReadWrite), DataField("randomMessInterval")]
+        [ViewVariables(VVAccess.ReadWrite), DataField]
         public TimeSpan RandomMessInterval = TimeSpan.FromSeconds(5);
 
         /// <summary>
@@ -28,9 +28,10 @@ namespace Content.Server.Medical.BiomassReclaimer
         /// <summary>
         /// Amount of biomass that the mob being processed will yield.
         /// This is calculated from the YieldPerUnitMass.
+        /// Also stores non-integer leftovers.
         /// </summary>
         [ViewVariables]
-        public int CurrentExpectedYield = default;
+        public float CurrentExpectedYield = 0f;
 
         /// <summary>
         /// The reagent that will be spilled while processing a mob.
@@ -49,6 +50,18 @@ namespace Content.Server.Medical.BiomassReclaimer
         [DataField, ViewVariables(VVAccess.ReadWrite)]
         public float YieldPerUnitMass = 0.4f;
 
+        /// <summary>
+        /// How many seconds to take to insert an entity per unit of its mass.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite)]
+        public float BaseInsertionDelay = 0.1f;
+
+        /// <summary>
+        /// How much to multiply biomass yield from botany produce.
+        /// </summary>
+        [DataField, ViewVariables(VVAccess.ReadWrite)]
+        public float ProduceYieldMultiplier = 0.25f;
+
         /// <summary>
         /// The time it takes to process a mob, per mass.
         /// </summary>
@@ -58,7 +71,7 @@ namespace Content.Server.Medical.BiomassReclaimer
         /// <summary>
         /// Will this refuse to gib a living mob?
         /// </summary>
-        [ViewVariables(VVAccess.ReadWrite), DataField("safetyEnabled")]
+        [ViewVariables(VVAccess.ReadWrite), DataField]
         public bool SafetyEnabled = true;
     }
 }
index b126c74a10aa1bfbda1bb44aa8a218ad8e01c9e8..d07858aec5c749860c3b424a66b7c60205d9c96a 100644 (file)
@@ -1,5 +1,6 @@
 using System.Numerics;
 using Content.Server.Body.Components;
+using Content.Server.Botany.Components;
 using Content.Server.Fluids.EntitySystems;
 using Content.Server.Materials;
 using Content.Server.Power.Components;
@@ -17,6 +18,7 @@ using Content.Shared.Interaction.Events;
 using Content.Shared.Jittering;
 using Content.Shared.Medical;
 using Content.Shared.Mind;
+using Content.Shared.Materials;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Mobs.Systems;
 using Content.Shared.Nutrition.Components;
@@ -26,6 +28,7 @@ using Robust.Server.Player;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Configuration;
 using Robust.Shared.Physics.Components;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 
 namespace Content.Server.Medical.BiomassReclaimer
@@ -47,6 +50,9 @@ namespace Content.Server.Medical.BiomassReclaimer
         [Dependency] private readonly MaterialStorageSystem _material = default!;
         [Dependency] private readonly SharedMindSystem _minds = default!;
 
+        [ValidatePrototypeId<MaterialPrototype>]
+        public const string BiomassPrototype = "Biomass";
+
         public override void Update(float frameTime)
         {
             base.Update(frameTime);
@@ -79,7 +85,9 @@ namespace Content.Server.Medical.BiomassReclaimer
                     continue;
                 }
 
-                _material.SpawnMultipleFromMaterial(reclaimer.CurrentExpectedYield, "Biomass", Transform(uid).Coordinates);
+                var actualYield = (int) (reclaimer.CurrentExpectedYield); // can only have integer biomass
+                reclaimer.CurrentExpectedYield = reclaimer.CurrentExpectedYield - actualYield; // store non-integer leftovers
+                _material.SpawnMultipleFromMaterial(actualYield, BiomassPrototype, Transform(uid).Coordinates);
 
                 reclaimer.BloodReagent = null;
                 reclaimer.SpawnedEntities.Clear();
@@ -148,10 +156,14 @@ namespace Content.Server.Medical.BiomassReclaimer
             if (!args.CanReach || args.Target == null)
                 return;
 
-            if (!HasComp<MobStateComponent>(args.Used) || !CanGib(reclaimer, args.Used))
+            if (!CanGib(reclaimer, args.Used))
+                return;
+
+            if (!TryComp<PhysicsComponent>(args.Used, out var physics))
                 return;
 
-            _doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, 7f, new ReclaimerDoAfterEvent(), reclaimer, target: args.Target, used: args.Used)
+            var delay = reclaimer.Comp.BaseInsertionDelay * physics.FixturesMass;
+            _doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, delay, new ReclaimerDoAfterEvent(), reclaimer, target: args.Target, used: args.Used)
             {
                 BreakOnTargetMove = true,
                 BreakOnUserMove = true,
@@ -174,11 +186,14 @@ namespace Content.Server.Medical.BiomassReclaimer
 
         private void OnDoAfter(Entity<BiomassReclaimerComponent> reclaimer, ref ReclaimerDoAfterEvent args)
         {
-            if (args.Handled || args.Cancelled || args.Args.Target == null || HasComp<BiomassReclaimerComponent>(args.Args.Target.Value))
+            if (args.Handled || args.Cancelled)
+                return;
+
+            if (args.Args.Used == null || args.Args.Target == null || !HasComp<BiomassReclaimerComponent>(args.Args.Target.Value))
                 return;
 
             _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(args.Args.User):player} used a biomass reclaimer to gib {ToPrettyString(args.Args.Target.Value):target} in {ToPrettyString(reclaimer):reclaimer}");
-            StartProcessing(args.Args.Target.Value, reclaimer);
+            StartProcessing(args.Args.Used.Value, reclaimer);
 
             args.Handled = true;
         }
@@ -200,8 +215,13 @@ namespace Content.Server.Medical.BiomassReclaimer
                 component.SpawnedEntities = butcherableComponent.SpawnedEntities;
             }
 
-            component.CurrentExpectedYield = (int) Math.Max(0, physics.FixturesMass * component.YieldPerUnitMass);
+            var expectedYield = physics.FixturesMass * component.YieldPerUnitMass;
+            if (HasComp<ProduceComponent>(toProcess))
+                expectedYield *= component.ProduceYieldMultiplier;
+            component.CurrentExpectedYield += expectedYield;
+
             component.ProcessingTimer = physics.FixturesMass * component.ProcessingTimePerUnitMass;
+
             QueueDel(toProcess);
         }
 
@@ -210,7 +230,8 @@ namespace Content.Server.Medical.BiomassReclaimer
             if (HasComp<ActiveBiomassReclaimerComponent>(reclaimer))
                 return false;
 
-            if (!HasComp<MobStateComponent>(dragged))
+            bool isPlant = HasComp<ProduceComponent>(dragged);
+            if (!isPlant && !HasComp<MobStateComponent>(dragged))
                 return false;
 
             if (!Transform(reclaimer).Anchored)
@@ -219,7 +240,7 @@ namespace Content.Server.Medical.BiomassReclaimer
             if (TryComp<ApcPowerReceiverComponent>(reclaimer, out var power) && !power.Powered)
                 return false;
 
-            if (reclaimer.Comp.SafetyEnabled && !_mobState.IsDead(dragged))
+            if (!isPlant && reclaimer.Comp.SafetyEnabled && !_mobState.IsDead(dragged))
                 return false;
 
             // Reject souled bodies in easy mode.