using Content.Shared.Charges.Components; using Content.Shared.Examine; namespace Content.Shared.Charges.Systems; public abstract class SharedChargesSystem : EntitySystem { protected EntityQuery Query; public override void Initialize() { base.Initialize(); Query = GetEntityQuery(); SubscribeLocalEvent(OnExamine); } protected virtual void OnExamine(EntityUid uid, LimitedChargesComponent comp, ExaminedEvent args) { if (!args.IsInDetailsRange) return; using (args.PushGroup(nameof(LimitedChargesComponent))) { args.PushMarkup(Loc.GetString("limited-charges-charges-remaining", ("charges", comp.Charges))); if (comp.Charges == comp.MaxCharges) { args.PushMarkup(Loc.GetString("limited-charges-max-charges")); } } } /// /// Tries to add a number of charges. If it over or underflows it will be clamped, wasting the extra charges. /// public virtual void AddCharges(EntityUid uid, int change, LimitedChargesComponent? comp = null) { if (!Query.Resolve(uid, ref comp, false)) return; var old = comp.Charges; comp.Charges = Math.Clamp(comp.Charges + change, 0, comp.MaxCharges); if (comp.Charges != old) Dirty(uid, comp); } /// /// Gets the limited charges component and returns true if there are no charges. Will return false if there is no limited charges component. /// public bool IsEmpty(EntityUid uid, LimitedChargesComponent? comp = null) { // can't be empty if there are no limited charges if (!Query.Resolve(uid, ref comp, false)) return false; return comp.Charges <= 0; } /// /// Uses a single charge. Must check IsEmpty beforehand to prevent using with 0 charge. /// public void UseCharge(EntityUid uid, LimitedChargesComponent? comp = null) { AddCharges(uid, -1, comp); } /// /// Checks IsEmpty and uses a charge if it isn't empty. /// public bool TryUseCharge(Entity ent) { if (!Query.Resolve(ent, ref ent.Comp, false)) return true; if (IsEmpty(ent, ent.Comp)) return false; UseCharge(ent, ent.Comp); return true; } /// /// Gets the limited charges component and returns true if the number of charges remaining is less than the specified value. /// Will return false if there is no limited charges component. /// public bool HasInsufficientCharges(EntityUid uid, int requiredCharges, LimitedChargesComponent? comp = null) { // can't be empty if there are no limited charges if (!Resolve(uid, ref comp, false)) return false; return comp.Charges < requiredCharges; } /// /// Uses up a specified number of charges. Must check HasInsufficentCharges beforehand to prevent using with insufficient remaining charges. /// public virtual void UseCharges(EntityUid uid, int chargesUsed, LimitedChargesComponent? comp = null) { AddCharges(uid, -chargesUsed, comp); } }