From 6b4a39006eabd434c4cc0e602a62710e4a91f1b8 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Mon, 2 Nov 2020 11:37:37 +0100 Subject: [PATCH] Make mechanism behaviors properly update, fix eating and drinking (#2472) * Make mechanisms properly update and fix eating and drinking * Remove outdated component ignores * Fix nullable error * Fix mechanism behavior events * Remove unnecessary code --- .../Body/Mechanism/HeartBehaviorComponent.cs | 12 -- Content.Client/IgnoredComponents.cs | 3 - .../Tests/Body/LungTest.cs | 6 +- .../Tests/Body/MechanismBehaviorEventsTest.cs | 93 ++++++------- Content.Server/Commands/Hungry.cs | 39 ++++++ ...nBehaviorComponent.cs => BrainBehavior.cs} | 14 +- ...tBehaviorComponent.cs => HeartBehavior.cs} | 9 +- ...ngBehaviorComponent.cs => LungBehavior.cs} | 29 ++-- .../Body/Behavior/MechanismBehavior.cs | 28 ++-- .../Body/Behavior}/MechanismExtensions.cs | 21 ++- .../Body/Behavior/StomachBehavior.cs | 26 +++- .../Body/Behavior/StomachBehaviorComponent.cs | 24 ---- .../Components/Chemistry/PillComponent.cs | 2 +- .../Metabolism/MetabolismComponent.cs | 2 +- .../Components/Nutrition/DrinkComponent.cs | 2 +- .../Components/Nutrition/FoodComponent.cs | 3 +- .../GameObjects/EntitySystems/HeartSystem.cs | 28 ---- .../GameObjects/EntitySystems/LungSystem.cs | 28 ---- .../Body/Behavior/IMechanismBehavior.cs | 18 ++- .../Behavior/SharedHeartBehaviorComponent.cs | 8 -- .../Behavior/SharedLungBehaviorComponent.cs | 39 ------ .../Components/Body/Mechanism/IMechanism.cs | 20 +++ .../Mechanism/SharedMechanismComponent.cs | 126 ++++++++++++++---- .../Nutrition/SharedStomachComponent.cs | 12 -- .../EntitySystems/MechanismSystem.cs | 21 +++ Resources/Groups/groups.yml | 2 + .../Body/Mechanisms/basic_human_organs.yml | 14 +- .../Entities/Mobs/Species/human.yml | 3 - 28 files changed, 326 insertions(+), 306 deletions(-) delete mode 100644 Content.Client/GameObjects/Components/Body/Mechanism/HeartBehaviorComponent.cs create mode 100644 Content.Server/Commands/Hungry.cs rename Content.Server/GameObjects/Components/Body/Behavior/{BrainBehaviorComponent.cs => BrainBehavior.cs} (80%) rename Content.Server/GameObjects/Components/Body/Behavior/{HeartBehaviorComponent.cs => HeartBehavior.cs} (71%) rename Content.Server/GameObjects/Components/Body/Behavior/{LungBehaviorComponent.cs => LungBehavior.cs} (91%) rename Content.Shared/GameObjects/Components/Body/Behavior/MechanismBehaviorComponent.cs => Content.Server/GameObjects/Components/Body/Behavior/MechanismBehavior.cs (75%) rename {Content.Shared/GameObjects/Components/Body/Mechanism => Content.Server/GameObjects/Components/Body/Behavior}/MechanismExtensions.cs (79%) rename Content.Shared/GameObjects/Components/Body/Behavior/SharedStomachBehaviorComponent.cs => Content.Server/GameObjects/Components/Body/Behavior/StomachBehavior.cs (88%) delete mode 100644 Content.Server/GameObjects/Components/Body/Behavior/StomachBehaviorComponent.cs delete mode 100644 Content.Server/GameObjects/EntitySystems/HeartSystem.cs delete mode 100644 Content.Server/GameObjects/EntitySystems/LungSystem.cs delete mode 100644 Content.Shared/GameObjects/Components/Body/Behavior/SharedHeartBehaviorComponent.cs delete mode 100644 Content.Shared/GameObjects/Components/Body/Behavior/SharedLungBehaviorComponent.cs delete mode 100644 Content.Shared/GameObjects/Components/Nutrition/SharedStomachComponent.cs create mode 100644 Content.Shared/GameObjects/EntitySystems/MechanismSystem.cs diff --git a/Content.Client/GameObjects/Components/Body/Mechanism/HeartBehaviorComponent.cs b/Content.Client/GameObjects/Components/Body/Mechanism/HeartBehaviorComponent.cs deleted file mode 100644 index 0131117d81..0000000000 --- a/Content.Client/GameObjects/Components/Body/Mechanism/HeartBehaviorComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Content.Shared.GameObjects.Components.Body.Behavior; -using Robust.Shared.GameObjects; - -namespace Content.Client.GameObjects.Components.Body.Mechanism -{ - [RegisterComponent] - [ComponentReference(typeof(SharedHeartBehaviorComponent))] - public class HeartBehaviorComponent : SharedHeartBehaviorComponent - { - public override void Update(float frameTime) { } - } -} diff --git a/Content.Client/IgnoredComponents.cs b/Content.Client/IgnoredComponents.cs index b54be45138..38483522c7 100644 --- a/Content.Client/IgnoredComponents.cs +++ b/Content.Client/IgnoredComponents.cs @@ -58,7 +58,6 @@ "Drink", "Food", "FoodContainer", - "Stomach", "Rotatable", "MagicMirror", "FloorTile", @@ -180,10 +179,8 @@ "BreakableConstruction", "GasCanister", "GasCanisterPort", - "Lung", "Cleanable", "Configuration", - "Brain", "PlantHolder", "SeedExtractor", "Produce", diff --git a/Content.IntegrationTests/Tests/Body/LungTest.cs b/Content.IntegrationTests/Tests/Body/LungTest.cs index 30c181e189..6722ea41a0 100644 --- a/Content.IntegrationTests/Tests/Body/LungTest.cs +++ b/Content.IntegrationTests/Tests/Body/LungTest.cs @@ -20,7 +20,7 @@ using Robust.Shared.Maths; namespace Content.IntegrationTests.Tests.Body { [TestFixture] - [TestOf(typeof(LungBehaviorComponent))] + [TestOf(typeof(LungBehavior))] public class LungTest : ContentIntegrationTest { [Test] @@ -39,7 +39,7 @@ namespace Content.IntegrationTests.Tests.Body var human = entityManager.SpawnEntity("HumanMob_Content", MapCoordinates.Nullspace); Assert.That(human.TryGetComponent(out IBody body)); - Assert.That(body.TryGetMechanismBehaviors(out List lungs)); + Assert.That(body.TryGetMechanismBehaviors(out List lungs)); Assert.That(lungs.Count, Is.EqualTo(1)); Assert.That(human.TryGetComponent(out BloodstreamComponent bloodstream)); @@ -141,7 +141,7 @@ namespace Content.IntegrationTests.Tests.Body human = entityManager.SpawnEntity("HumanMob_Content", coordinates); Assert.True(human.TryGetComponent(out IBody body)); - Assert.True(body.HasMechanismBehavior()); + Assert.True(body.HasMechanismBehavior()); Assert.True(human.TryGetComponent(out metabolism)); Assert.False(metabolism.Suffocating); }); diff --git a/Content.IntegrationTests/Tests/Body/MechanismBehaviorEventsTest.cs b/Content.IntegrationTests/Tests/Body/MechanismBehaviorEventsTest.cs index e3c571496e..08afb1ae91 100644 --- a/Content.IntegrationTests/Tests/Body/MechanismBehaviorEventsTest.cs +++ b/Content.IntegrationTests/Tests/Body/MechanismBehaviorEventsTest.cs @@ -1,12 +1,12 @@ #nullable enable using System.Linq; using System.Threading.Tasks; +using Content.Server.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body; using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Mechanism; using Content.Shared.GameObjects.Components.Body.Part; using NUnit.Framework; -using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; @@ -18,14 +18,11 @@ namespace Content.IntegrationTests.Tests.Body [TestOf(typeof(SharedBodyComponent))] [TestOf(typeof(SharedBodyPartComponent))] [TestOf(typeof(SharedMechanismComponent))] - [TestOf(typeof(MechanismBehaviorComponent))] + [TestOf(typeof(MechanismBehavior))] public class MechanismBehaviorEventsTest : ContentIntegrationTest { - [RegisterComponent] - private class TestBehaviorComponent : MechanismBehaviorComponent + private class TestMechanismBehavior : MechanismBehavior { - public override string Name => nameof(MechanismBehaviorEventsTest) + "TestBehavior"; - public bool WasAddedToBody; public bool WasAddedToPart; public bool WasAddedToPartInBody; @@ -33,8 +30,6 @@ namespace Content.IntegrationTests.Tests.Body public bool WasRemovedFromPart; public bool WasRemovedFromPartInBody; - public override void Update(float frameTime) { } - public bool NoAdded() { return !WasAddedToBody && !WasAddedToPart && !WasAddedToPartInBody; @@ -111,13 +106,7 @@ namespace Content.IntegrationTests.Tests.Body [Test] public async Task EventsTest() { - var server = StartServerDummyTicker(new ServerContentIntegrationOption - { - ContentBeforeIoC = () => - { - IoCManager.Resolve().Register(); - } - }); + var server = StartServerDummyTicker(); await server.WaitAssertion(() => { @@ -141,68 +130,68 @@ namespace Content.IntegrationTests.Tests.Body var mechanism = centerPart!.Mechanisms.First(); Assert.NotNull(mechanism); - var component = mechanism.Owner.AddComponent(); - Assert.False(component.WasAddedToBody); - Assert.False(component.WasAddedToPart); - Assert.That(component.WasAddedToPartInBody); - Assert.That(component.NoRemoved); + mechanism.EnsureBehavior(out var behavior); + Assert.False(behavior.WasAddedToBody); + Assert.False(behavior.WasAddedToPart); + Assert.That(behavior.WasAddedToPartInBody); + Assert.That(behavior.NoRemoved); - component.ResetAll(); + behavior.ResetAll(); - Assert.That(component.NoAdded); - Assert.That(component.NoRemoved); + Assert.That(behavior.NoAdded); + Assert.That(behavior.NoRemoved); centerPart.RemoveMechanism(mechanism); - Assert.That(component.NoAdded); - Assert.False(component.WasRemovedFromBody); - Assert.False(component.WasRemovedFromPart); - Assert.That(component.WasRemovedFromPartInBody); + Assert.That(behavior.NoAdded); + Assert.False(behavior.WasRemovedFromBody); + Assert.False(behavior.WasRemovedFromPart); + Assert.That(behavior.WasRemovedFromPartInBody); - component.ResetAll(); + behavior.ResetAll(); centerPart.TryAddMechanism(mechanism, true); - Assert.False(component.WasAddedToBody); - Assert.False(component.WasAddedToPart); - Assert.That(component.WasAddedToPartInBody); - Assert.That(component.NoRemoved()); + Assert.False(behavior.WasAddedToBody); + Assert.False(behavior.WasAddedToPart); + Assert.That(behavior.WasAddedToPartInBody); + Assert.That(behavior.NoRemoved()); - component.ResetAll(); + behavior.ResetAll(); body.RemovePart(centerPart); - Assert.That(component.NoAdded); - Assert.That(component.WasRemovedFromBody); - Assert.False(component.WasRemovedFromPart); - Assert.False(component.WasRemovedFromPartInBody); + Assert.That(behavior.NoAdded); + Assert.That(behavior.WasRemovedFromBody); + Assert.False(behavior.WasRemovedFromPart); + Assert.False(behavior.WasRemovedFromPartInBody); - component.ResetAll(); + behavior.ResetAll(); centerPart.RemoveMechanism(mechanism); - Assert.That(component.NoAdded); - Assert.False(component.WasRemovedFromBody); - Assert.That(component.WasRemovedFromPart); - Assert.False(component.WasRemovedFromPartInBody); + Assert.That(behavior.NoAdded); + Assert.False(behavior.WasRemovedFromBody); + Assert.That(behavior.WasRemovedFromPart); + Assert.False(behavior.WasRemovedFromPartInBody); - component.ResetAll(); + behavior.ResetAll(); centerPart.TryAddMechanism(mechanism, true); - Assert.False(component.WasAddedToBody); - Assert.That(component.WasAddedToPart); - Assert.False(component.WasAddedToPartInBody); - Assert.That(component.NoRemoved); + Assert.False(behavior.WasAddedToBody); + Assert.That(behavior.WasAddedToPart); + Assert.False(behavior.WasAddedToPartInBody); + Assert.That(behavior.NoRemoved); - component.ResetAll(); + behavior.ResetAll(); body.TryAddPart(centerSlot!, centerPart, true); - Assert.That(component.WasAddedToBody); - Assert.False(component.WasAddedToPart); - Assert.False(component.WasAddedToPartInBody); - Assert.That(component.NoRemoved); + Assert.That(behavior.WasAddedToBody); + Assert.False(behavior.WasAddedToPart); + Assert.False(behavior.WasAddedToPartInBody); + Assert.That(behavior.NoRemoved); }); } } diff --git a/Content.Server/Commands/Hungry.cs b/Content.Server/Commands/Hungry.cs new file mode 100644 index 0000000000..b3a56c0171 --- /dev/null +++ b/Content.Server/Commands/Hungry.cs @@ -0,0 +1,39 @@ +#nullable enable +using Content.Server.GameObjects.Components.Nutrition; +using Content.Shared.GameObjects.Components.Nutrition; +using Robust.Server.Interfaces.Console; +using Robust.Server.Interfaces.Player; + +namespace Content.Server.Commands +{ + public class Hungry : IClientCommand + { + public string Command => "hungry"; + public string Description => "Makes you hungry."; + public string Help => $"{Command}"; + + public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args) + { + if (player == null) + { + shell.SendText(player, "You cannot use this command unless you are a player."); + return; + } + + if (player.AttachedEntity == null) + { + shell.SendText(player, "You cannot use this command without an entity."); + return; + } + + if (!player.AttachedEntity.TryGetComponent(out HungerComponent? hunger)) + { + shell.SendText(player, $"Your entity does not have a {nameof(HungerComponent)} component."); + return; + } + + var hungryThreshold = hunger.HungerThresholds[HungerThreshold.Starving]; + hunger.CurrentHunger = hungryThreshold; + } + } +} diff --git a/Content.Server/GameObjects/Components/Body/Behavior/BrainBehaviorComponent.cs b/Content.Server/GameObjects/Components/Body/Behavior/BrainBehavior.cs similarity index 80% rename from Content.Server/GameObjects/Components/Body/Behavior/BrainBehaviorComponent.cs rename to Content.Server/GameObjects/Components/Body/Behavior/BrainBehavior.cs index 0dff9e5a98..d5533a961d 100644 --- a/Content.Server/GameObjects/Components/Body/Behavior/BrainBehaviorComponent.cs +++ b/Content.Server/GameObjects/Components/Body/Behavior/BrainBehavior.cs @@ -1,22 +1,14 @@ #nullable enable using Content.Server.GameObjects.Components.Mobs; -using Content.Server.Mobs; using Content.Shared.GameObjects.Components.Body; -using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Part; using Robust.Shared.GameObjects; -using Robust.Shared.GameObjects.ComponentDependencies; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Log; -using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Body.Behavior { - [RegisterComponent] - public class BrainBehaviorComponent : MechanismBehaviorComponent + public class BrainBehavior : MechanismBehavior { - public override string Name => "Brain"; - protected override void OnAddedToBody(IBody body) { base.OnAddedToBody(body); @@ -66,9 +58,5 @@ namespace Content.Server.GameObjects.Components.Body.Behavior oldMind.Mind?.TransferTo(newEntity); } - - public override void Update(float frameTime) - { - } } } diff --git a/Content.Server/GameObjects/Components/Body/Behavior/HeartBehaviorComponent.cs b/Content.Server/GameObjects/Components/Body/Behavior/HeartBehavior.cs similarity index 71% rename from Content.Server/GameObjects/Components/Body/Behavior/HeartBehaviorComponent.cs rename to Content.Server/GameObjects/Components/Body/Behavior/HeartBehavior.cs index 9b0c9bc5fb..855c5831ef 100644 --- a/Content.Server/GameObjects/Components/Body/Behavior/HeartBehaviorComponent.cs +++ b/Content.Server/GameObjects/Components/Body/Behavior/HeartBehavior.cs @@ -1,20 +1,17 @@ using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Networks; -using Robust.Shared.GameObjects; namespace Content.Server.GameObjects.Components.Body.Behavior { - [RegisterComponent] - [ComponentReference(typeof(SharedHeartBehaviorComponent))] - public class HeartBehaviorComponent : SharedHeartBehaviorComponent + public class HeartBehavior : MechanismBehavior { private float _accumulatedFrameTime; public override void Update(float frameTime) { // TODO BODY do between pre and metabolism - if (Mechanism?.Body == null || - !Mechanism.Body.Owner.HasComponent()) + if (Parent.Body == null || + !Parent.Body.Owner.HasComponent()) { return; } diff --git a/Content.Server/GameObjects/Components/Body/Behavior/LungBehaviorComponent.cs b/Content.Server/GameObjects/Components/Body/Behavior/LungBehavior.cs similarity index 91% rename from Content.Server/GameObjects/Components/Body/Behavior/LungBehaviorComponent.cs rename to Content.Server/GameObjects/Components/Body/Behavior/LungBehavior.cs index 195733fe71..6755c4d6b2 100644 --- a/Content.Server/GameObjects/Components/Body/Behavior/LungBehaviorComponent.cs +++ b/Content.Server/GameObjects/Components/Body/Behavior/LungBehavior.cs @@ -8,19 +8,15 @@ using Content.Server.GameObjects.Components.Body.Respiratory; using Content.Server.Utility; using Content.Shared.Atmos; using Content.Shared.GameObjects.Components.Body.Behavior; -using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; using Robust.Shared.Localization; -using Robust.Shared.Log; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Body.Behavior { - [RegisterComponent] - [ComponentReference(typeof(SharedLungBehaviorComponent))] - public class LungBehaviorComponent : SharedLungBehaviorComponent + public class LungBehavior : MechanismBehavior { [Dependency] private readonly IGameTiming _gameTiming = default!; @@ -30,18 +26,24 @@ namespace Content.Server.GameObjects.Components.Body.Behavior [ViewVariables] public GasMixture Air { get; set; } = default!; - [ViewVariables] public override float Temperature => Air.Temperature; + [ViewVariables] public float Temperature => Air.Temperature; - [ViewVariables] public override float Volume => Air.Volume; + [ViewVariables] public float Volume => Air.Volume; [ViewVariables] public TimeSpan GaspPopupCooldown { get; private set; } + [ViewVariables] public LungStatus Status { get; set; } + + [ViewVariables] public float CycleDelay { get; set; } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); Air = new GasMixture {Temperature = Atmospherics.NormalBodyTemperature}; + serializer.DataField(this, l => l.CycleDelay, "cycleDelay", 2); + serializer.DataReadWriteFunction( "volume", 6, @@ -61,7 +63,7 @@ namespace Content.Server.GameObjects.Components.Body.Behavior () => GaspPopupCooldown.TotalSeconds); } - public override void Gasp() + public void Gasp() { if (_gameTiming.CurTime >= _lastGaspPopupTime + GaspPopupCooldown) { @@ -148,7 +150,7 @@ namespace Content.Server.GameObjects.Components.Body.Behavior _accumulatedFrameTime = absoluteTime - delay; } - public override void Inhale(float frameTime) + public void Inhale(float frameTime) { if (Body != null && Body.Owner.TryGetComponent(out InternalsComponent? internals) && internals.BreathToolEntity != null && internals.GasTankEntity != null @@ -176,7 +178,7 @@ namespace Content.Server.GameObjects.Components.Body.Behavior ToBloodstream(Air); } - public override void Exhale(float frameTime) + public void Exhale(float frameTime) { if (!Owner.Transform.Coordinates.TryGetTileAir(out var tileAir)) { @@ -218,4 +220,11 @@ namespace Content.Server.GameObjects.Components.Body.Behavior Air.Merge(lungRemoved); } } + + public enum LungStatus + { + None = 0, + Inhaling, + Exhaling + } } diff --git a/Content.Shared/GameObjects/Components/Body/Behavior/MechanismBehaviorComponent.cs b/Content.Server/GameObjects/Components/Body/Behavior/MechanismBehavior.cs similarity index 75% rename from Content.Shared/GameObjects/Components/Body/Behavior/MechanismBehaviorComponent.cs rename to Content.Server/GameObjects/Components/Body/Behavior/MechanismBehavior.cs index f4a0683eca..ca571ab0ac 100644 --- a/Content.Shared/GameObjects/Components/Body/Behavior/MechanismBehaviorComponent.cs +++ b/Content.Server/GameObjects/Components/Body/Behavior/MechanismBehavior.cs @@ -1,23 +1,33 @@ #nullable enable +using Content.Shared.GameObjects.Components.Body; +using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Mechanism; using Content.Shared.GameObjects.Components.Body.Part; -using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Serialization; using Robust.Shared.Utility; -namespace Content.Shared.GameObjects.Components.Body.Behavior +namespace Content.Server.GameObjects.Components.Body.Behavior { - public abstract class MechanismBehaviorComponent : Component, IMechanismBehavior + public abstract class MechanismBehavior : IMechanismBehavior { public IBody? Body => Part?.Body; - public IBodyPart? Part => Mechanism?.Part; + public IBodyPart? Part => Parent.Part; - public IMechanism? Mechanism => Owner.GetComponentOrNull(); + public IMechanism Parent { get; private set; } = default!; - protected override void Startup() + public IEntity Owner => Parent.Owner; + + public virtual void ExposeData(ObjectSerializer serializer) { } + + public virtual void Initialize(IMechanism parent) { - base.Startup(); + Parent = parent; + } + public virtual void Startup() + { if (Part == null) { return; @@ -33,8 +43,6 @@ namespace Content.Shared.GameObjects.Components.Body.Behavior } } - public abstract void Update(float frameTime); - public void AddedToBody(IBody body) { DebugTools.AssertNotNull(Body); @@ -98,5 +106,7 @@ namespace Content.Shared.GameObjects.Components.Body.Behavior protected virtual void OnRemovedFromPart(IBodyPart old) { } protected virtual void OnRemovedFromPartInBody(IBody oldBody, IBodyPart oldPart) { } + + public virtual void Update(float frameTime) { } } } diff --git a/Content.Shared/GameObjects/Components/Body/Mechanism/MechanismExtensions.cs b/Content.Server/GameObjects/Components/Body/Behavior/MechanismExtensions.cs similarity index 79% rename from Content.Shared/GameObjects/Components/Body/Mechanism/MechanismExtensions.cs rename to Content.Server/GameObjects/Components/Body/Behavior/MechanismExtensions.cs index 8dfb8750de..453b089c94 100644 --- a/Content.Shared/GameObjects/Components/Body/Mechanism/MechanismExtensions.cs +++ b/Content.Server/GameObjects/Components/Body/Behavior/MechanismExtensions.cs @@ -2,33 +2,29 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Content.Shared.GameObjects.Components.Body; using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Part; -namespace Content.Shared.GameObjects.Components.Body.Mechanism +namespace Content.Server.GameObjects.Components.Body.Behavior { public static class MechanismExtensions { - public static bool HasMechanismBehavior(this IBody body) + public static bool HasMechanismBehavior(this IBody body) where T : IMechanismBehavior { return body.Parts.Values.Any(p => p.HasMechanismBehavior()); } - public static bool HasMechanismBehavior(this IBodyPart part) + public static bool HasMechanismBehavior(this IBodyPart part) where T : IMechanismBehavior { - return part.Mechanisms.Any(m => m.Owner.HasComponent()); - } - - public static bool HasMechanismBehavior(this IMechanism mechanism) - { - return mechanism.Owner.HasComponent(); + return part.Mechanisms.Any(m => m.HasBehavior()); } public static IEnumerable GetMechanismBehaviors(this IBody body) { foreach (var part in body.Parts.Values) foreach (var mechanism in part.Mechanisms) - foreach (var behavior in mechanism.Owner.GetAllComponents()) + foreach (var behavior in mechanism.Behaviors.Values) { yield return behavior; } @@ -52,10 +48,11 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism { foreach (var part in body.Parts.Values) foreach (var mechanism in part.Mechanisms) + foreach (var behavior in mechanism.Behaviors.Values) { - if (mechanism.Owner.TryGetComponent(out T? behavior)) + if (behavior is T tBehavior) { - yield return behavior; + yield return tBehavior; } } } diff --git a/Content.Shared/GameObjects/Components/Body/Behavior/SharedStomachBehaviorComponent.cs b/Content.Server/GameObjects/Components/Body/Behavior/StomachBehavior.cs similarity index 88% rename from Content.Shared/GameObjects/Components/Body/Behavior/SharedStomachBehaviorComponent.cs rename to Content.Server/GameObjects/Components/Body/Behavior/StomachBehavior.cs index 2045a1f0fa..6bb18a8a89 100644 --- a/Content.Shared/GameObjects/Components/Body/Behavior/SharedStomachBehaviorComponent.cs +++ b/Content.Server/GameObjects/Components/Body/Behavior/StomachBehavior.cs @@ -1,23 +1,23 @@ -#nullable enable +#nullable enable using System.Collections.Generic; using System.Linq; +using Content.Server.GameObjects.Components.Chemistry; using Content.Shared.Chemistry; using Content.Shared.GameObjects.Components.Body.Networks; using Content.Shared.GameObjects.Components.Chemistry; using Robust.Shared.GameObjects; +using Robust.Shared.Log; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; -namespace Content.Shared.GameObjects.Components.Body.Behavior +namespace Content.Server.GameObjects.Components.Body.Behavior { /// /// Where reagents go when ingested. Tracks ingested reagents over time, and /// eventually transfers them to once digested. /// - public abstract class SharedStomachBehaviorComponent : MechanismBehaviorComponent + public class StomachBehavior : MechanismBehavior { - public override string Name => "Stomach"; - private float _accumulatedFrameTime; /// @@ -45,7 +45,7 @@ namespace Content.Shared.GameObjects.Components.Body.Behavior _accumulatedFrameTime -= 1; - if (!Body.Owner.TryGetComponent(out SharedSolutionContainerComponent? solution) || + if (!Owner.TryGetComponent(out SharedSolutionContainerComponent? solution) || !Body.Owner.TryGetComponent(out SharedBloodstreamComponent? bloodstream)) { return; @@ -58,7 +58,7 @@ namespace Content.Shared.GameObjects.Components.Body.Behavior foreach (var delta in _reagentDeltas.ToList()) { //Increment lifetime of reagents - delta.Increment(frameTime); + delta.Increment(1); if (delta.Lifetime > _digestionDelay) { solution.TryRemoveReagent(delta.ReagentId, delta.Quantity); @@ -112,6 +112,18 @@ namespace Content.Shared.GameObjects.Components.Body.Behavior serializer.DataField(ref _digestionDelay, "digestionDelay", 20); } + public override void Startup() + { + base.Startup(); + + if (!Owner.EnsureComponent(out SolutionContainerComponent solution)) + { + Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionContainerComponent)}"); + } + + solution.MaxVolume = InitialMaxVolume; + } + public bool CanTransferSolution(Solution solution) { if (!Owner.TryGetComponent(out SharedSolutionContainerComponent? solutionComponent)) diff --git a/Content.Server/GameObjects/Components/Body/Behavior/StomachBehaviorComponent.cs b/Content.Server/GameObjects/Components/Body/Behavior/StomachBehaviorComponent.cs deleted file mode 100644 index 10476d09c6..0000000000 --- a/Content.Server/GameObjects/Components/Body/Behavior/StomachBehaviorComponent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Content.Server.GameObjects.Components.Chemistry; -using Content.Shared.GameObjects.Components.Body.Behavior; -using Robust.Shared.GameObjects; -using Robust.Shared.Log; - -namespace Content.Server.GameObjects.Components.Body.Behavior -{ - [RegisterComponent] - [ComponentReference(typeof(SharedStomachBehaviorComponent))] - public class StomachBehaviorComponent : SharedStomachBehaviorComponent - { - protected override void Startup() - { - base.Startup(); - - if (!Owner.EnsureComponent(out SolutionContainerComponent solution)) - { - Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition} didn't have a {nameof(SolutionContainerComponent)}"); - } - - solution.MaxVolume = InitialMaxVolume; - } - } -} diff --git a/Content.Server/GameObjects/Components/Chemistry/PillComponent.cs b/Content.Server/GameObjects/Components/Chemistry/PillComponent.cs index a507974bea..b6b7f1ea26 100644 --- a/Content.Server/GameObjects/Components/Chemistry/PillComponent.cs +++ b/Content.Server/GameObjects/Components/Chemistry/PillComponent.cs @@ -84,7 +84,7 @@ namespace Content.Server.GameObjects.Components.Chemistry var trueTarget = target ?? user; if (!trueTarget.TryGetComponent(out IBody body) || - !body.TryGetMechanismBehaviors(out var stomachs)) + !body.TryGetMechanismBehaviors(out var stomachs)) { return false; } diff --git a/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs b/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs index a93e3dec88..05ed21f0e2 100644 --- a/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs +++ b/Content.Server/GameObjects/Components/Metabolism/MetabolismComponent.cs @@ -192,7 +192,7 @@ namespace Content.Server.GameObjects.Components.Metabolism return; } - var lungs = _body.GetMechanismBehaviors().ToArray(); + var lungs = _body.GetMechanismBehaviors().ToArray(); var needs = NeedsAndDeficit(frameTime); var used = 0f; diff --git a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs index 29625d59cb..709bc3bf32 100644 --- a/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/DrinkComponent.cs @@ -153,7 +153,7 @@ namespace Content.Server.GameObjects.Components.Nutrition } if (!target.TryGetComponent(out IBody body) || - !body.TryGetMechanismBehaviors(out var stomachs)) + !body.TryGetMechanismBehaviors(out var stomachs)) { return false; } diff --git a/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs b/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs index 0dbfc3f292..a71ff53d02 100644 --- a/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs +++ b/Content.Server/GameObjects/Components/Nutrition/FoodComponent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Content.Server.GameObjects.Components.Body.Behavior; using Content.Server.GameObjects.Components.Chemistry; using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.Items.Storage; @@ -133,7 +134,7 @@ namespace Content.Server.GameObjects.Components.Nutrition var trueTarget = target ?? user; if (!trueTarget.TryGetComponent(out IBody? body) || - !body.TryGetMechanismBehaviors(out var stomachs)) + !body.TryGetMechanismBehaviors(out var stomachs)) { return false; } diff --git a/Content.Server/GameObjects/EntitySystems/HeartSystem.cs b/Content.Server/GameObjects/EntitySystems/HeartSystem.cs deleted file mode 100644 index e1da130db4..0000000000 --- a/Content.Server/GameObjects/EntitySystems/HeartSystem.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Content.Shared.GameObjects.Components.Body.Behavior; -using Content.Shared.GameObjects.EntitySystems; -using JetBrains.Annotations; -using Robust.Shared.GameObjects.Systems; - -namespace Content.Server.GameObjects.EntitySystems -{ - [UsedImplicitly] - public class HeartSystem : EntitySystem - { - public override void Initialize() - { - base.Initialize(); - - UpdatesBefore.Add(typeof(MetabolismSystem)); - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - foreach (var heart in ComponentManager.EntityQuery()) - { - heart.Update(frameTime); - } - } - } -} diff --git a/Content.Server/GameObjects/EntitySystems/LungSystem.cs b/Content.Server/GameObjects/EntitySystems/LungSystem.cs deleted file mode 100644 index 6b04f5f0d1..0000000000 --- a/Content.Server/GameObjects/EntitySystems/LungSystem.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Content.Shared.GameObjects.Components.Body.Behavior; -using Content.Shared.GameObjects.EntitySystems; -using JetBrains.Annotations; -using Robust.Shared.GameObjects.Systems; - -namespace Content.Server.GameObjects.EntitySystems -{ - [UsedImplicitly] - public class LungSystem : EntitySystem - { - public override void Initialize() - { - base.Initialize(); - - UpdatesBefore.Add(typeof(MetabolismSystem)); - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - foreach (var lung in ComponentManager.EntityQuery()) - { - lung.Update(frameTime); - } - } - } -} diff --git a/Content.Shared/GameObjects/Components/Body/Behavior/IMechanismBehavior.cs b/Content.Shared/GameObjects/Components/Body/Behavior/IMechanismBehavior.cs index 2e38200f58..e1ddcb17b8 100644 --- a/Content.Shared/GameObjects/Components/Body/Behavior/IMechanismBehavior.cs +++ b/Content.Shared/GameObjects/Components/Body/Behavior/IMechanismBehavior.cs @@ -2,10 +2,11 @@ using Content.Shared.GameObjects.Components.Body.Mechanism; using Content.Shared.GameObjects.Components.Body.Part; using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Serialization; namespace Content.Shared.GameObjects.Components.Body.Behavior { - public interface IMechanismBehavior : IComponent + public interface IMechanismBehavior : IExposeData { IBody? Body { get; } @@ -15,7 +16,20 @@ namespace Content.Shared.GameObjects.Components.Body.Behavior /// Upward reference to the parent that this /// behavior is attached to. /// - IMechanism? Mechanism { get; } + IMechanism Parent { get; } + + /// + /// The entity that owns . + /// For the entity owning the body that this mechanism may be in, + /// see + /// + IEntity Owner { get; } + + void Initialize(IMechanism parent); + + void Startup(); + + void Update(float frameTime); /// /// Called when the containing is attached to a diff --git a/Content.Shared/GameObjects/Components/Body/Behavior/SharedHeartBehaviorComponent.cs b/Content.Shared/GameObjects/Components/Body/Behavior/SharedHeartBehaviorComponent.cs deleted file mode 100644 index 6d4f6c0f3d..0000000000 --- a/Content.Shared/GameObjects/Components/Body/Behavior/SharedHeartBehaviorComponent.cs +++ /dev/null @@ -1,8 +0,0 @@ -#nullable enable -namespace Content.Shared.GameObjects.Components.Body.Behavior -{ - public abstract class SharedHeartBehaviorComponent : MechanismBehaviorComponent - { - public override string Name => "Heart"; - } -} diff --git a/Content.Shared/GameObjects/Components/Body/Behavior/SharedLungBehaviorComponent.cs b/Content.Shared/GameObjects/Components/Body/Behavior/SharedLungBehaviorComponent.cs deleted file mode 100644 index dbbff4e9d9..0000000000 --- a/Content.Shared/GameObjects/Components/Body/Behavior/SharedLungBehaviorComponent.cs +++ /dev/null @@ -1,39 +0,0 @@ -#nullable enable -using Robust.Shared.Serialization; -using Robust.Shared.ViewVariables; - -namespace Content.Shared.GameObjects.Components.Body.Behavior -{ - public abstract class SharedLungBehaviorComponent : MechanismBehaviorComponent - { - public override string Name => "Lung"; - - [ViewVariables] public abstract float Temperature { get; } - - [ViewVariables] public abstract float Volume { get; } - - [ViewVariables] public LungStatus Status { get; set; } - - [ViewVariables] public float CycleDelay { get; set; } - - public override void ExposeData(ObjectSerializer serializer) - { - base.ExposeData(serializer); - - serializer.DataField(this, l => l.CycleDelay, "cycleDelay", 2); - } - - public abstract void Inhale(float frameTime); - - public abstract void Exhale(float frameTime); - - public abstract void Gasp(); - } - - public enum LungStatus - { - None = 0, - Inhaling, - Exhaling - } -} diff --git a/Content.Shared/GameObjects/Components/Body/Mechanism/IMechanism.cs b/Content.Shared/GameObjects/Components/Body/Mechanism/IMechanism.cs index 092b838819..f6f82627cb 100644 --- a/Content.Shared/GameObjects/Components/Body/Mechanism/IMechanism.cs +++ b/Content.Shared/GameObjects/Components/Body/Mechanism/IMechanism.cs @@ -1,4 +1,7 @@ #nullable enable +using System; +using System.Collections.Generic; +using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Part; using Robust.Shared.Interfaces.GameObjects; @@ -10,6 +13,8 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism IBodyPart? Part { get; set; } + IReadOnlyDictionary Behaviors { get; } + /// /// Professional description of the . /// @@ -55,6 +60,21 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism /// BodyPartCompatibility Compatibility { get; set; } + /// + /// Adds a behavior if it does not exist already. + /// + /// The behavior type to add. + /// + /// True if the behavior already existed, false if it had to be created. + /// + bool EnsureBehavior(out T behavior) where T : IMechanismBehavior, new(); + + bool HasBehavior() where T : IMechanismBehavior; + + bool TryRemoveBehavior() where T : IMechanismBehavior; + + void Update(float frameTime); + // TODO BODY Turn these into event listeners so they dont need to be exposed /// /// Called when the containing is attached to a diff --git a/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs b/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs index cfd6d8e2f9..7ac3c76ce2 100644 --- a/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs +++ b/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs @@ -1,10 +1,14 @@ #nullable enable +using System; using System.Collections.Generic; using System.Linq; using Content.Shared.GameObjects.Components.Body.Behavior; using Content.Shared.GameObjects.Components.Body.Part; +using Content.Shared.Interfaces; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -14,11 +18,12 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism { public override string Name => "Mechanism"; - private IBodyPart? _part; protected readonly Dictionary OptionsCache = new Dictionary(); protected IBody? BodyCache; protected int IdHash; protected IEntity? PerformerCache; + private IBodyPart? _part; + private readonly Dictionary _behaviors = new Dictionary(); public IBody? Body => Part?.Body; @@ -61,6 +66,8 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism } } + public IReadOnlyDictionary Behaviors => _behaviors; + public string Description { get; set; } = string.Empty; public string ExamineMessage { get; set; } = string.Empty; @@ -98,6 +105,91 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism serializer.DataField(this, m => m.Size, "size", 1); serializer.DataField(this, m => m.Compatibility, "compatibility", BodyPartCompatibility.Universal); + + var moduleManager = IoCManager.Resolve(); + + if (moduleManager.IsServerModule) + { + serializer.DataReadWriteFunction( + "behaviors", + null!, + behaviors => + { + if (behaviors == null) + { + return; + } + + foreach (var behavior in behaviors) + { + var type = behavior.GetType(); + + if (!_behaviors.TryAdd(type, behavior)) + { + Logger.Warning($"Duplicate behavior in {nameof(SharedMechanismComponent)} for entity {Owner.Name}: {type}."); + continue; + } + + IoCManager.InjectDependencies(behavior); + } + }, + () => _behaviors.Values.ToList()); + } + } + + public override void Initialize() + { + base.Initialize(); + + foreach (var behavior in _behaviors.Values) + { + behavior.Initialize(this); + } + } + + protected override void Startup() + { + base.Startup(); + + foreach (var behavior in _behaviors.Values) + { + behavior.Startup(); + } + } + + public bool EnsureBehavior(out T behavior) where T : IMechanismBehavior, new() + { + if (_behaviors.TryGetValue(typeof(T), out var rawBehavior)) + { + behavior = (T) rawBehavior; + return true; + } + + behavior = new T(); + IoCManager.InjectDependencies(behavior); + _behaviors.Add(typeof(T), behavior); + behavior.Initialize(this); + behavior.Startup(); + + return false; + } + + public bool HasBehavior() where T : IMechanismBehavior + { + return _behaviors.ContainsKey(typeof(T)); + } + + public bool TryRemoveBehavior() where T : IMechanismBehavior + { + return _behaviors.Remove(typeof(T)); + } + + public void Update(float frameTime) + { + foreach (var behavior in _behaviors.Values) + { + behavior.Update(frameTime); + } } public void AddedToBody(IBody body) @@ -105,9 +197,7 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism DebugTools.AssertNotNull(Body); DebugTools.AssertNotNull(body); - OnAddedToBody(body); - - foreach (var behavior in Owner.GetAllComponents()) + foreach (var behavior in _behaviors.Values) { behavior.AddedToBody(body); } @@ -119,9 +209,8 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism DebugTools.AssertNotNull(part); Owner.Transform.AttachParent(part.Owner); - OnAddedToPart(part); - foreach (var behavior in Owner.GetAllComponents().ToArray()) + foreach (var behavior in _behaviors.Values) { behavior.AddedToPart(part); } @@ -135,9 +224,8 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism DebugTools.AssertNotNull(part); Owner.Transform.AttachParent(part.Owner); - OnAddedToPartInBody(body, part); - foreach (var behavior in Owner.GetAllComponents()) + foreach (var behavior in _behaviors.Values) { behavior.AddedToPartInBody(body, part); } @@ -148,9 +236,7 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism DebugTools.AssertNull(Body); DebugTools.AssertNotNull(old); - OnRemovedFromBody(old); - - foreach (var behavior in Owner.GetAllComponents()) + foreach (var behavior in _behaviors.Values) { behavior.RemovedFromBody(old); } @@ -162,9 +248,8 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism DebugTools.AssertNotNull(old); Owner.Transform.AttachToGridOrMap(); - OnRemovedFromPart(old); - foreach (var behavior in Owner.GetAllComponents()) + foreach (var behavior in _behaviors.Values) { behavior.RemovedFromPart(old); } @@ -178,24 +263,11 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism DebugTools.AssertNotNull(oldPart); Owner.Transform.AttachToGridOrMap(); - OnRemovedFromPartInBody(oldBody, oldPart); - foreach (var behavior in Owner.GetAllComponents()) + foreach (var behavior in _behaviors.Values) { behavior.RemovedFromPartInBody(oldBody, oldPart); } } - - protected virtual void OnAddedToBody(IBody body) { } - - protected virtual void OnAddedToPart(IBodyPart part) { } - - protected virtual void OnAddedToPartInBody(IBody body, IBodyPart part) { } - - protected virtual void OnRemovedFromBody(IBody old) { } - - protected virtual void OnRemovedFromPart(IBodyPart old) { } - - protected virtual void OnRemovedFromPartInBody(IBody oldBody, IBodyPart oldPart) { } } } diff --git a/Content.Shared/GameObjects/Components/Nutrition/SharedStomachComponent.cs b/Content.Shared/GameObjects/Components/Nutrition/SharedStomachComponent.cs deleted file mode 100644 index 030b1eae50..0000000000 --- a/Content.Shared/GameObjects/Components/Nutrition/SharedStomachComponent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Robust.Shared.GameObjects; - -namespace Content.Shared.GameObjects.Components.Nutrition -{ - /// - /// Shared class for stomach components - /// - public class SharedStomachComponent : Component - { - public override string Name => "Stomach"; - } -} diff --git a/Content.Shared/GameObjects/EntitySystems/MechanismSystem.cs b/Content.Shared/GameObjects/EntitySystems/MechanismSystem.cs new file mode 100644 index 0000000000..d3e9dd0daa --- /dev/null +++ b/Content.Shared/GameObjects/EntitySystems/MechanismSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.GameObjects.Components.Body.Behavior; +using Content.Shared.GameObjects.Components.Body.Mechanism; +using JetBrains.Annotations; +using Robust.Shared.GameObjects.Systems; + +namespace Content.Shared.GameObjects.EntitySystems +{ + [UsedImplicitly] + public class MechanismSystem : EntitySystem + { + public override void Update(float frameTime) + { + base.Update(frameTime); + + foreach (var mechanism in ComponentManager.EntityQuery()) + { + mechanism.Update(frameTime); + } + } + } +} diff --git a/Resources/Groups/groups.yml b/Resources/Groups/groups.yml index dbcc86b674..b9f90c5639 100644 --- a/Resources/Groups/groups.yml +++ b/Resources/Groups/groups.yml @@ -119,6 +119,7 @@ - attachtogrid - attachtograndparent - inrangeunoccluded + - hungry CanViewVar: true CanAdminPlace: true CanAdminMenu: true @@ -231,6 +232,7 @@ - attachtogrid - attachtograndparent - inrangeunoccluded + - hungry CanViewVar: true CanAdminPlace: true CanScript: true diff --git a/Resources/Prototypes/Body/Mechanisms/basic_human_organs.yml b/Resources/Prototypes/Body/Mechanisms/basic_human_organs.yml index e85f15d2f1..c4a85d1a40 100644 --- a/Resources/Prototypes/Body/Mechanisms/basic_human_organs.yml +++ b/Resources/Prototypes/Body/Mechanisms/basic_human_organs.yml @@ -11,7 +11,8 @@ durability: 10 size: 1 compatibility: Biological - - type: Brain + behaviors: + - !type:BrainBehavior {} - type: entity id: EyesHuman @@ -40,7 +41,8 @@ durability: 10 size: 1 compatibility: Biological - - type: Heart + behaviors: + - !type:HeartBehavior {} - type: entity id: LungsHuman @@ -55,7 +57,8 @@ durability: 13 size: 1 compatibility: Biological - - type: Lung + behaviors: + - !type:LungBehavior {} - type: entity id: StomachHuman @@ -70,7 +73,10 @@ durability: 13 size: 1 compatibility: Biological - - type: Stomach + behaviors: + - !type:StomachBehavior + max_volume: 250 + digestionDelay: 20 - type: entity id: LiverHuman diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 3fd79f3b08..c5b20bba9a 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -23,9 +23,6 @@ caps: AddTo, RemoveFrom, NoExamine - type: Bloodstream max_volume: 100 - - type: Stomach - max_volume: 250 - digestionDelay: 20 # StatusEffects - type: Stunnable # Other