]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Sericulture fixes (#19193)
authorPixelTK <85175107+PixelTheKermit@users.noreply.github.com>
Sun, 1 Oct 2023 20:46:09 +0000 (21:46 +0100)
committerGitHub <noreply@github.com>
Sun, 1 Oct 2023 20:46:09 +0000 (16:46 -0400)
* redone

* I FUCKING HATE SPAWNING STUFF IN SHARED

* inheritdoc

* owo

* fly broken wings

* From a server event to just an event.

* more info

* a comment and a different comment

* Partial

* Emo's requested changes.

* wuh

* head ache

* they call me mean names (laugh track)

Content.Client/Sericulture/SericultureSystem.cs [new file with mode: 0644]
Content.Server/Sericulture/SericultureComponent.cs [deleted file]
Content.Server/Sericulture/SericultureSystem.cs
Content.Shared/Nutrition/EntitySystems/HungerSystem.cs
Content.Shared/Sericulture/SericultureComponent.cs [new file with mode: 0644]
Content.Shared/Sericulture/SericultureEvents.cs [deleted file]
Content.Shared/Sericulture/SericultureSystem.cs [new file with mode: 0644]

diff --git a/Content.Client/Sericulture/SericultureSystem.cs b/Content.Client/Sericulture/SericultureSystem.cs
new file mode 100644 (file)
index 0000000..6b2ad2f
--- /dev/null
@@ -0,0 +1,8 @@
+using Content.Shared.Sericulture;
+
+namespace Content.Client.Sericulture;
+
+/// <summary>
+/// <inheritdoc/>
+/// </summary>
+public sealed partial class SericultureSystem : SharedSericultureSystem { }
diff --git a/Content.Server/Sericulture/SericultureComponent.cs b/Content.Server/Sericulture/SericultureComponent.cs
deleted file mode 100644 (file)
index 2d258ac..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Server.Sericulture;
-
-[RegisterComponent]
-public sealed partial class SericultureComponent : Component
-{
-    [DataField("popupText")]
-    public string PopupText = "sericulture-failure-hunger";
-
-    /// <summary>
-    /// What will be produced at the end of the action.
-    /// </summary>
-    [DataField("entityProduced", required: true)]
-    public string EntityProduced = "";
-
-    [DataField("action", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-    public string Action = "ActionSericulture";
-
-    [DataField("actionEntity")] public EntityUid? ActionEntity;
-
-    /// <summary>
-    /// How long will it take to make.
-    /// </summary>
-    [DataField("productionLength", required: true), ViewVariables(VVAccess.ReadWrite)]
-    public float ProductionLength = 0;
-
-    [DataField("hungerCost"), ViewVariables(VVAccess.ReadWrite)]
-    public float HungerCost = 0f;
-}
index c100d3d4a5f97548096d7f1e21f4e56c531fe761..672c0b914bb09099fa27b47bdd4907697e8fcf94 100644 (file)
@@ -1,89 +1,7 @@
-using Content.Server.Actions;
-using Content.Server.DoAfter;
-using Content.Server.Popups;
-using Content.Server.Stack;
-using Content.Shared.DoAfter;
-using Content.Shared.Nutrition.Components;
-using Content.Shared.Nutrition.EntitySystems;
 using Content.Shared.Sericulture;
 
 namespace Content.Server.Sericulture;
 
-public sealed partial class SericultureSystem : EntitySystem
+public sealed partial class SericultureSystem : SharedSericultureSystem
 {
-    [Dependency] private readonly ActionsSystem _actionsSystem = default!;
-    [Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
-    [Dependency] private readonly HungerSystem _hungerSystem = default!;
-    [Dependency] private readonly PopupSystem _popupSystem = default!;
-    [Dependency] private readonly StackSystem _stackSystem = default!;
-
-    public override void Initialize()
-    {
-        base.Initialize();
-
-        SubscribeLocalEvent<SericultureComponent, MapInitEvent>(OnCompMapInit);
-        SubscribeLocalEvent<SericultureComponent, ComponentShutdown>(OnCompRemove);
-        SubscribeLocalEvent<SericultureComponent, SericultureActionEvent>(OnSericultureStart);
-        SubscribeLocalEvent<SericultureComponent, SericultureDoAfterEvent>(OnSericultureDoAfter);
-    }
-
-    private void OnCompMapInit(EntityUid uid, SericultureComponent comp, MapInitEvent args)
-    {
-        _actionsSystem.AddAction(uid, ref comp.ActionEntity, comp.Action, uid);
-    }
-
-    private void OnCompRemove(EntityUid uid, SericultureComponent comp, ComponentShutdown args)
-    {
-        _actionsSystem.RemoveAction(uid, comp.ActionEntity);
-    }
-
-    private void OnSericultureStart(EntityUid uid, SericultureComponent comp, SericultureActionEvent args)
-    {
-        if (IsHungry(uid))
-        {
-            _popupSystem.PopupEntity(Loc.GetString(comp.PopupText), uid, uid);
-            return;
-        }
-
-        var doAfter = new DoAfterArgs(EntityManager, uid, comp.ProductionLength, new SericultureDoAfterEvent(), uid)
-        {
-            BreakOnUserMove = true,
-            BlockDuplicate = true,
-            BreakOnDamage = true,
-            CancelDuplicate = true,
-        };
-
-        _doAfterSystem.TryStartDoAfter(doAfter);
-    }
-
-    private void OnSericultureDoAfter(EntityUid uid, SericultureComponent comp, SericultureDoAfterEvent args)
-    {
-        if (args.Cancelled || args.Handled || comp.Deleted)
-            return;
-
-        if (IsHungry(uid))
-        {
-            _popupSystem.PopupEntity(Loc.GetString(comp.PopupText), uid, uid);
-            return;
-        }
-
-        _hungerSystem.ModifyHunger(uid, -comp.HungerCost);
-
-        var newEntity = Spawn(comp.EntityProduced, Transform(uid).Coordinates);
-
-        _stackSystem.TryMergeToHands(newEntity, uid);
-
-        args.Repeat = true;
-    }
-
-    private bool IsHungry(EntityUid uid, HungerComponent? comp = null)
-    {
-        if (!Resolve(uid, ref comp))
-            return false;
-
-        if (_hungerSystem.GetHungerThreshold(comp) <= HungerThreshold.Peckish)
-            return true;
-
-        return false;
-    }
 }
index 8baee3e379947990f0ad4ac63d6482b49a6b6789..9c096035104ad7bcdb5d8b2f3f403f5ad138d6ed 100644 (file)
@@ -173,6 +173,17 @@ public sealed class HungerSystem : EntitySystem
         return result;
     }
 
+    /// <summary>
+    /// A check that returns if the entity is below a hunger threshold.
+    /// </summary>
+    public bool IsHungerBelowState(EntityUid uid, HungerThreshold threshold, float? food = null, HungerComponent? comp = null)
+    {
+        if (!Resolve(uid, ref comp))
+            return false; // It's never going to go hungry, so it's probably fine to assume that it's not... you know, hungry.
+
+        return GetHungerThreshold(comp, food) < threshold;
+    }
+
     private bool GetMovementThreshold(HungerThreshold threshold)
     {
         switch (threshold)
diff --git a/Content.Shared/Sericulture/SericultureComponent.cs b/Content.Shared/Sericulture/SericultureComponent.cs
new file mode 100644 (file)
index 0000000..23143f5
--- /dev/null
@@ -0,0 +1,66 @@
+using Content.Shared.Nutrition.Components;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Shared.Sericulture;
+
+/// <summary>
+/// Should be applied to any mob that you want to be able to produce any material with an action and the cost of hunger.
+/// TODO: Probably adjust this to utilize organs?
+/// </summary>
+[RegisterComponent, NetworkedComponent, Access(typeof(SharedSericultureSystem))]
+public sealed partial class SericultureComponent : Component
+{
+    /// <summary>
+    /// The text that pops up whenever sericulture fails for not having enough hunger.
+    /// </summary>
+    [DataField("popupText")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public string PopupText = "sericulture-failure-hunger";
+
+    /// <summary>
+    /// What will be produced at the end of the action.
+    /// </summary>
+    [DataField("entityProduced", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public string EntityProduced = string.Empty;
+
+    /// <summary>
+    /// The entity needed to actually preform sericulture. This will be granted (and removed) upon the entity's creation.
+    /// </summary>
+    [DataField("action", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public string Action = string.Empty;
+
+    [AutoNetworkedField]
+    [DataField("actionEntity")]
+    public EntityUid? ActionEntity;
+
+    /// <summary>
+    /// How long will it take to make.
+    /// </summary>
+    [DataField("productionLength")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public float ProductionLength = 3f;
+
+    /// <summary>
+    /// This will subtract (not add, don't get this mixed up) from the current hunger of the mob doing sericulture.
+    /// </summary>
+    [DataField("hungerCost")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public float HungerCost = 5f;
+
+    /// <summary>
+    /// The lowest hunger threshold that this mob can be in before it's allowed to spin silk.
+    /// </summary>
+    [DataField("minHungerThreshold")]
+    [ViewVariables(VVAccess.ReadWrite)]
+    [AutoNetworkedField]
+    public HungerThreshold MinHungerThreshold = HungerThreshold.Okay;
+}
diff --git a/Content.Shared/Sericulture/SericultureEvents.cs b/Content.Shared/Sericulture/SericultureEvents.cs
deleted file mode 100644 (file)
index 9a497d1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-using Content.Shared.Actions;
-using Content.Shared.DoAfter;
-using Robust.Shared.Serialization;
-
-namespace Content.Shared.Sericulture;
-
-[Serializable, NetSerializable]
-public sealed partial class SericultureDoAfterEvent : SimpleDoAfterEvent { }
-
-public sealed partial class SericultureActionEvent : InstantActionEvent { }
diff --git a/Content.Shared/Sericulture/SericultureSystem.cs b/Content.Shared/Sericulture/SericultureSystem.cs
new file mode 100644 (file)
index 0000000..514ec79
--- /dev/null
@@ -0,0 +1,109 @@
+using Content.Shared.Actions;
+using Content.Shared.DoAfter;
+using Content.Shared.Nutrition.EntitySystems;
+using Robust.Shared.Serialization;
+using Content.Shared.Popups;
+using Robust.Shared.Network;
+using Content.Shared.Nutrition.Components;
+using Content.Shared.Stacks;
+
+namespace Content.Shared.Sericulture;
+
+/// <summary>
+/// Allows mobs to produce materials with <see cref="SericultureComponent"/>.
+/// </summary>
+public abstract partial class SharedSericultureSystem : EntitySystem
+{
+    // Managers
+    [Dependency] private readonly INetManager _netManager = default!;
+
+    // Systems
+    [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
+    [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
+    [Dependency] private readonly HungerSystem _hungerSystem = default!;
+    [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+    [Dependency] private readonly SharedStackSystem _stackSystem = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<SericultureComponent, MapInitEvent>(OnMapInit);
+        SubscribeLocalEvent<SericultureComponent, ComponentShutdown>(OnCompRemove);
+        SubscribeLocalEvent<SericultureComponent, SericultureActionEvent>(OnSericultureStart);
+        SubscribeLocalEvent<SericultureComponent, SericultureDoAfterEvent>(OnSericultureDoAfter);
+    }
+
+    /// <summary>
+    /// Giveths the action to preform sericulture on the entity
+    /// </summary>
+    private void OnMapInit(EntityUid uid, SericultureComponent comp, MapInitEvent args)
+    {
+        _actionsSystem.AddAction(uid, ref comp.ActionEntity, comp.Action);
+    }
+
+    /// <summary>
+    /// Takeths away the action to preform sericulture from the entity.
+    /// </summary>
+    private void OnCompRemove(EntityUid uid, SericultureComponent comp, ComponentShutdown args)
+    {
+        _actionsSystem.RemoveAction(uid, comp.ActionEntity);
+    }
+
+    private void OnSericultureStart(EntityUid uid, SericultureComponent comp, SericultureActionEvent args)
+    {
+        if (TryComp<HungerComponent>(uid, out var hungerComp)
+        && _hungerSystem.IsHungerBelowState(uid, comp.MinHungerThreshold, hungerComp.CurrentHunger - comp.HungerCost, hungerComp))
+        {
+            _popupSystem.PopupClient(Loc.GetString(comp.PopupText), uid, uid);
+            return;
+        }
+
+        var doAfter = new DoAfterArgs(EntityManager, uid, comp.ProductionLength, new SericultureDoAfterEvent(), uid)
+        { // I'm not sure if more things should be put here, but imo ideally it should probably be set in the component/YAML. Not sure if this is currently possible.
+            BreakOnUserMove = true,
+            BlockDuplicate = true,
+            BreakOnDamage = true,
+            CancelDuplicate = true,
+        };
+
+        _doAfterSystem.TryStartDoAfter(doAfter);
+    }
+
+
+    private void OnSericultureDoAfter(EntityUid uid, SericultureComponent comp, SericultureDoAfterEvent args)
+    {
+        if (args.Cancelled || args.Handled || comp.Deleted)
+            return;
+
+        if (TryComp<HungerComponent>(uid, out var hungerComp) // A check, just incase the doafter is somehow performed when the entity is not in the right hunger state.
+        && _hungerSystem.IsHungerBelowState(uid, comp.MinHungerThreshold, hungerComp.CurrentHunger - comp.HungerCost, hungerComp))
+        {
+            _popupSystem.PopupClient(Loc.GetString(comp.PopupText), uid, uid);
+            return;
+        }
+
+        _hungerSystem.ModifyHunger(uid, -comp.HungerCost);
+
+        if (!_netManager.IsClient) // Have to do this because spawning stuff in shared is CBT.
+        {
+            var newEntity = Spawn(comp.EntityProduced, Transform(uid).Coordinates);
+
+            _stackSystem.TryMergeToHands(newEntity, uid);
+        }
+
+        args.Repeat = true;
+    }
+}
+
+/// <summary>
+/// Should be relayed upon using the action.
+/// </summary>
+public sealed partial class SericultureActionEvent : InstantActionEvent { }
+
+/// <summary>
+/// Is relayed at the end of the sericulturing doafter.
+/// </summary>
+[Serializable, NetSerializable]
+public sealed partial class SericultureDoAfterEvent : SimpleDoAfterEvent { }
+