using Content.Shared.Alert; using Content.Shared.Corvax.Ipc; using Content.Shared.Power.EntitySystems; using Content.Shared.PowerCell; using Robust.Client.Player; using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Client.Corvax.Ipc; public sealed partial class IpcSystem : EntitySystem { [Dependency] private PowerCellSystem _powerCell = default!; [Dependency] private SharedBatterySystem _battery = default!; [Dependency] private AlertsSystem _alerts = default!; [Dependency] private IGameTiming _timing = default!; [Dependency] private IPlayerManager _player = default!; private static readonly TimeSpan AlertUpdateDelay = TimeSpan.FromSeconds(0.5f); private TimeSpan _nextAlertUpdate = TimeSpan.Zero; private EntityQuery _ipcQuery; public override void Initialize() { base.Initialize(); _ipcQuery = GetEntityQuery(); SubscribeLocalEvent(OnPlayerAttached); SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnPowerCellChanged); SubscribeLocalEvent(OnPowerCellEmpty); } private void OnPowerCellChanged(EntityUid uid, IpcComponent component, ref PowerCellChangedEvent args) { if (_player.LocalEntity != uid) return; UpdateBatteryAlert((uid, component)); } private void OnPowerCellEmpty(EntityUid uid, IpcComponent component, ref PowerCellSlotEmptyEvent args) { if (_player.LocalEntity != uid) return; UpdateBatteryAlert((uid, component)); } private void OnPlayerAttached(Entity ent, ref LocalPlayerAttachedEvent args) { UpdateBatteryAlert(ent); } private void OnPlayerDetached(Entity ent, ref LocalPlayerDetachedEvent args) { _alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert); _alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert); } private void UpdateBatteryAlert(Entity ent) { if (!_powerCell.TryGetBatteryFromSlot(ent.Owner, out var battery) || battery.Value.Comp.MaxCharge <= 0 || _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge < 0.01f) { _alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert); _alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert); return; } var chargePercent = (short)MathF.Round( _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge * 10f); if (chargePercent == 0 && _powerCell.HasDrawCharge(ent.Owner)) chargePercent = 1; _alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert); _alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent); } public override void Update(float frameTime) { base.Update(frameTime); if (_player.LocalEntity is not { } localPlayer) return; var curTime = _timing.CurTime; if (curTime < _nextAlertUpdate) return; _nextAlertUpdate = curTime + AlertUpdateDelay; if (!_ipcQuery.TryComp(localPlayer, out var ipc)) return; UpdateBatteryAlert((localPlayer, ipc)); } }