diff --git a/Content.Shared/Charges/Components/LimitedChargesComponent.cs b/Content.Shared/Charges/Components/LimitedChargesComponent.cs index e879e0f1df..7891857187 100644 --- a/Content.Shared/Charges/Components/LimitedChargesComponent.cs +++ b/Content.Shared/Charges/Components/LimitedChargesComponent.cs @@ -16,7 +16,7 @@ public sealed partial class LimitedChargesComponent : Component /// /// The max charges this action has. /// - [DataField, AutoNetworkedField, Access(Other = AccessPermissions.Read)] + [DataField, AutoNetworkedField] public int MaxCharges = 3; /// diff --git a/Content.Shared/Charges/Systems/SharedChargesSystem.cs b/Content.Shared/Charges/Systems/SharedChargesSystem.cs index e915580bae..504648c41d 100644 --- a/Content.Shared/Charges/Systems/SharedChargesSystem.cs +++ b/Content.Shared/Charges/Systems/SharedChargesSystem.cs @@ -94,6 +94,12 @@ public abstract class SharedChargesSystem : EntitySystem /// /// Adds the specified charges. Does not reset the accumulator. /// + /// + /// The action to add charges to. If it doesn't have , it will be added. + /// + /// + /// The number of charges to add. Can be negative. Resulting charge count is clamped to [0, MaxCharges]. + /// public void AddCharges(Entity action, int addCharges) { if (addCharges == 0) @@ -170,9 +176,21 @@ public abstract class SharedChargesSystem : EntitySystem Dirty(action); } + /// + /// Set the number of charges an action has. + /// + /// The action in question + /// + /// The number of charges. Clamped to [0, MaxCharges]. + /// + /// + /// This method doesn't implicitly add + /// unlike some other methods in this system. + /// public void SetCharges(Entity action, int value) { - action.Comp ??= EnsureComp(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); } + /// + /// Sets the maximum charges of a given action. + /// + /// The action being modified. + /// The new maximum charges of the action. Clamped to zero. + /// + /// Does not change the current charge count, or adjust the + /// accumulator for auto-recharge. It also doesn't implicitly add + /// unlike some other methods + /// in this system. + /// + public void SetMaxCharges(Entity 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); + } + /// /// The next time a charge will be considered to be filled. /// diff --git a/Content.Shared/Magic/SpellbookSystem.cs b/Content.Shared/Magic/SpellbookSystem.cs index ca01819bce..90038fa9ba 100644 --- a/Content.Shared/Magic/SpellbookSystem.cs +++ b/Content.Shared/Magic/SpellbookSystem.cs @@ -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(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(actionId, out var chargeComp)) + continue; + + _sharedCharges.SetMaxCharges((actionId.Value, chargeComp), count); + _sharedCharges.SetCharges((actionId.Value, chargeComp), count); } }