]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
fix: spellbooks can have charges ≠ 3 (#38769)
authorPerry Fraser <perryprog@users.noreply.github.com>
Wed, 20 Aug 2025 22:47:31 +0000 (18:47 -0400)
committerGitHub <noreply@github.com>
Wed, 20 Aug 2025 22:47:31 +0000 (15:47 -0700)
* fix: spellbooks can have charges ≠ 3

* refactor: just make setting MaxCharges an api thing

* refactor: don't auto-add LimitedCharges

* Small stuff

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
Content.Shared/Charges/Components/LimitedChargesComponent.cs
Content.Shared/Charges/Systems/SharedChargesSystem.cs
Content.Shared/Magic/SpellbookSystem.cs

index e879e0f1df1303a3fa4ece25167d14d0cac919ba..789185718762bd68a9dc5f8ff152c75c5a58f5d4 100644 (file)
@@ -16,7 +16,7 @@ public sealed partial class LimitedChargesComponent : Component
     /// <summary>
     ///     The max charges this action has.
     /// </summary>
-    [DataField, AutoNetworkedField, Access(Other = AccessPermissions.Read)]
+    [DataField, AutoNetworkedField]
     public int MaxCharges = 3;
 
     /// <summary>
index e915580baeb0f400a6be10cf4d94303ac5a033f8..504648c41d684fed2ae1b98b0d9c36fa32a1f220 100644 (file)
@@ -94,6 +94,12 @@ public abstract class SharedChargesSystem : EntitySystem
     /// <summary>
     /// Adds the specified charges. Does not reset the accumulator.
     /// </summary>
+    /// <param name="action">
+    /// The action to add charges to. If it doesn't have <see cref="LimitedChargesComponent"/>, it will be added.
+    /// </param>
+    /// <param name="addCharges">
+    /// The number of charges to add. Can be negative. Resulting charge count is clamped to [0, MaxCharges].
+    /// </param>
     public void AddCharges(Entity<LimitedChargesComponent?, AutoRechargeComponent?> action, int addCharges)
     {
         if (addCharges == 0)
@@ -170,9 +176,21 @@ public abstract class SharedChargesSystem : EntitySystem
         Dirty(action);
     }
 
+    /// <summary>
+    /// Set the number of charges an action has.
+    /// </summary>
+    /// <param name="action">The action in question</param>
+    /// <param name="value">
+    /// The number of charges. Clamped to [0, MaxCharges].
+    /// </param>
+    /// <remarks>
+    /// This method doesn't implicitly add <see cref="LimitedChargesComponent"/>
+    /// unlike some other methods in this system.
+    /// </remarks>
     public void SetCharges(Entity<LimitedChargesComponent?> action, int value)
     {
-        action.Comp ??= EnsureComp<LimitedChargesComponent>(action.Owner);
+        if (!Resolve(action, ref action.Comp))
+            return;
 
         var adjusted = Math.Clamp(value, 0, action.Comp.MaxCharges);
 
@@ -186,6 +204,31 @@ public abstract class SharedChargesSystem : EntitySystem
         Dirty(action);
     }
 
+    /// <summary>
+    /// Sets the maximum charges of a given action.
+    /// </summary>
+    /// <param name="action">The action being modified.</param>
+    /// <param name="value">The new maximum charges of the action. Clamped to zero.</param>
+    /// <remarks>
+    /// Does not change the current charge count, or adjust the
+    /// accumulator for auto-recharge. It also doesn't implicitly add
+    /// <see cref="LimitedChargesComponent"/> unlike some other methods
+    /// in this system.
+    /// </remarks>
+    public void SetMaxCharges(Entity<LimitedChargesComponent?> action, int value)
+    {
+        if (!Resolve(action, ref action.Comp))
+            return;
+
+        // You can't have negative max charges (even zero is a bit goofy but eh)
+        var adjusted = Math.Max(0, value);
+        if (action.Comp.MaxCharges == adjusted)
+            return;
+
+        action.Comp.MaxCharges = adjusted;
+        Dirty(action);
+    }
+
     /// <summary>
     /// The next time a charge will be considered to be filled.
     /// </summary>
index ca01819bce5183df35fbcb9c4e64c446730864dd..90038fa9bae41ab4e1260738bcf6545ee91a0561 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Actions;
-using Content.Shared.Actions.Components;
+using Content.Shared.Actions.Components;
+using Content.Shared.Charges.Components;
 using Content.Shared.Charges.Systems;
 using Content.Shared.DoAfter;
 using Content.Shared.Interaction.Events;
@@ -29,14 +30,19 @@ public sealed class SpellbookSystem : EntitySystem
     {
         foreach (var (id, charges) in ent.Comp.SpellActions)
         {
-            var spell = _actionContainer.AddAction(ent, id);
-            if (spell == null)
+            var action = _actionContainer.AddAction(ent, id);
+            if (action is not { } spell)
                 continue;
 
             // Null means infinite charges.
             if (charges is { } count)
-                _sharedCharges.SetCharges(spell.Value, count);
-            ent.Comp.Spells.Add(spell.Value);
+            {
+                EnsureComp<LimitedChargesComponent>(spell, out var chargeComp);
+                _sharedCharges.SetMaxCharges((spell, chargeComp), count);
+                _sharedCharges.SetCharges((spell, chargeComp), count);
+            }
+
+            ent.Comp.Spells.Add(spell);
         }
     }
 
@@ -75,9 +81,13 @@ public sealed class SpellbookSystem : EntitySystem
             foreach (var (id, charges) in ent.Comp.SpellActions)
             {
                 EntityUid? actionId = null;
-                if (_actions.AddAction(args.Args.User, ref actionId, id)
-                    && charges is { } count) // Null means infinite charges
-                    _sharedCharges.SetCharges(actionId.Value, count);
+                if (!_actions.AddAction(args.Args.User, ref actionId, id)
+                    || charges is not { } count // Null means infinite charges
+                    || !TryComp<LimitedChargesComponent>(actionId, out var chargeComp))
+                    continue;
+
+                _sharedCharges.SetMaxCharges((actionId.Value, chargeComp), count);
+                _sharedCharges.SetCharges((actionId.Value, chargeComp), count);
             }
         }