using Content.Shared.Ninja.Components; using Content.Shared.DoAfter; using Robust.Shared.Serialization; namespace Content.Shared.Ninja.Systems; /// /// Basic draining prediction and API, all real logic is handled serverside. /// public abstract class SharedBatteryDrainerSystem : EntitySystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent>(OnDoAfterAttempt); SubscribeLocalEvent(OnDoAfter); } /// /// Cancel any drain doafters if the battery is removed or, on the server, gets filled. /// protected virtual void OnDoAfterAttempt(Entity ent, ref DoAfterAttemptEvent args) { if (ent.Comp.BatteryUid == null) args.Cancel(); } /// /// Drain power from a power source (on server) and repeat if it succeeded. /// Client will predict always succeeding since power is serverside. /// private void OnDoAfter(Entity ent, ref DrainDoAfterEvent args) { if (args.Cancelled || args.Handled || args.Target is not {} target) return; // repeat if there is still power to drain args.Repeat = TryDrainPower(ent, target); } /// /// Attempt to drain as much power as possible into the powercell. /// Client always predicts this as succeeding since power is serverside and it can only fail once, when the powercell is filled or the target is emptied. /// protected virtual bool TryDrainPower(Entity ent, EntityUid target) { return true; } /// /// Sets the battery field on the drainer. /// public void SetBattery(Entity ent, EntityUid? battery) { if (!Resolve(ent, ref ent.Comp) || ent.Comp.BatteryUid == battery) return; ent.Comp.BatteryUid = battery; Dirty(ent, ent.Comp); } } /// /// DoAfter event for . /// [Serializable, NetSerializable] public sealed partial class DrainDoAfterEvent : SimpleDoAfterEvent;