using Content.Server.Administration.Logs; using Content.Server.Power.Components; using Content.Shared.Database; using Content.Shared.Power; using Content.Shared.Power.Components; using Robust.Server.GameObjects; namespace Content.Server.Power.EntitySystems; /// /// Handles logic for the battery interface on SMES/substations. /// /// /// /// These devices have interfaces that allow user to toggle input and output, /// and configure charge/discharge power limits. /// /// /// This system is not responsible for any power logic on its own, /// it merely reconfigures parameters on from the UI. /// /// public sealed class BatteryInterfaceSystem : EntitySystem { [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = null!; public override void Initialize() { base.Initialize(); UpdatesAfter.Add(typeof(PowerNetSystem)); Subs.BuiEvents( BatteryUiKey.Key, subs => { subs.Event(HandleSetInputBreaker); subs.Event(HandleSetOutputBreaker); subs.Event(HandleSetChargeRate); subs.Event(HandleSetDischargeRate); }); } private void HandleSetInputBreaker(Entity ent, ref BatterySetInputBreakerMessage args) { var netBattery = Comp(ent); netBattery.CanCharge = args.On; _adminLog.Add(LogType.Action,$"{ToPrettyString(args.Actor):actor} set input breaker to {args.On} on {ToPrettyString(ent):target}"); } private void HandleSetOutputBreaker(Entity ent, ref BatterySetOutputBreakerMessage args) { var netBattery = Comp(ent); netBattery.CanDischarge = args.On; _adminLog.Add(LogType.Action,$"{ToPrettyString(args.Actor):actor} set output breaker to {args.On} on {ToPrettyString(ent):target}"); } private void HandleSetChargeRate(Entity ent, ref BatterySetChargeRateMessage args) { var netBattery = Comp(ent); netBattery.MaxChargeRate = Math.Clamp(args.Rate, ent.Comp.MinChargeRate, ent.Comp.MaxChargeRate); } private void HandleSetDischargeRate(Entity ent, ref BatterySetDischargeRateMessage args) { var netBattery = Comp(ent); netBattery.MaxSupply = Math.Clamp(args.Rate, ent.Comp.MinSupply, ent.Comp.MaxSupply); } public override void Update(float frameTime) { var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var batteryInterface, out var battery, out var netBattery)) { UpdateUI(uid, batteryInterface, battery, netBattery); } } private void UpdateUI( EntityUid uid, BatteryInterfaceComponent batteryInterface, BatteryComponent battery, PowerNetworkBatteryComponent netBattery) { if (!_uiSystem.IsUiOpen(uid, BatteryUiKey.Key)) return; _uiSystem.SetUiState( uid, BatteryUiKey.Key, new BatteryBuiState { Capacity = battery.MaxCharge, Charge = battery.CurrentCharge, CanCharge = netBattery.CanCharge, CanDischarge = netBattery.CanDischarge, CurrentReceiving = netBattery.CurrentReceiving, CurrentSupply = netBattery.CurrentSupply, MaxSupply = netBattery.MaxSupply, MaxChargeRate = netBattery.MaxChargeRate, Efficiency = netBattery.Efficiency, MaxMaxSupply = batteryInterface.MaxSupply, MinMaxSupply = batteryInterface.MinSupply, MaxMaxChargeRate = batteryInterface.MaxChargeRate, MinMaxChargeRate = batteryInterface.MinChargeRate, SupplyingNetworkHasPower = CheckHasPower(uid), LoadingNetworkHasPower = CheckHasPower(uid), }); return; bool CheckHasPower(EntityUid entity) where TComp : BasePowerNetComponent { if (!TryComp(entity, out TComp? comp)) return false; if (comp.Net == null) return false; return comp.Net.NetworkNode.LastCombinedMaxSupply > 0; } } }