using System.Diagnostics.CodeAnalysis; using Content.Shared.Containers.ItemSlots; using Content.Shared.Power.Components; using Content.Shared.PowerCell.Components; using JetBrains.Annotations; namespace Content.Shared.PowerCell; public sealed partial class PowerCellSystem { /// /// Checks if a power cell slot has a battery inside. /// [PublicAPI] public bool HasBattery(Entity ent) { if (!Resolve(ent, ref ent.Comp, false)) return false; if (!_itemSlots.TryGetSlot(ent.Owner, ent.Comp.CellSlotId, out var slot)) { return false; } return slot.Item != null; } /// /// Gets the power cell battery inside a power cell slot. /// [PublicAPI] public bool TryGetBatteryFromSlot( Entity ent, [NotNullWhen(true)] out Entity? battery) { if (!Resolve(ent, ref ent.Comp, false)) { battery = null; return false; } if (!_itemSlots.TryGetSlot(ent.Owner, ent.Comp.CellSlotId, out var slot)) { battery = null; return false; } if (!TryComp(slot.Item, out var batteryComp)) { battery = null; return false; } battery = (slot.Item.Value, batteryComp); return true; } /// /// First tries to get a battery from the entity's power cell slot. /// If that fails check if the entity itself is a battery with . /// [PublicAPI] public bool TryGetBatteryFromSlotOrEntity(Entity ent, [NotNullWhen(true)] out Entity? battery) { if (TryGetBatteryFromSlot(ent, out battery)) return true; if (TryComp(ent, out var batteryComp)) { battery = (ent.Owner, batteryComp); return true; } battery = null; return false; } /// /// First checks if the entity itself is a battery with . /// If that fails it will try to get a battery from the entity's power cell slot instead. /// [PublicAPI] public bool TryGetBatteryFromEntityOrSlot(Entity ent, [NotNullWhen(true)] out Entity? battery) { if (TryComp(ent, out var batteryComp)) { battery = (ent.Owner, batteryComp); return true; } if (TryGetBatteryFromSlot(ent, out battery)) return true; battery = null; return false; } /// /// Tries to eject the power cell battery inside a power cell slot. /// This checks if the user has a free hand to do the ejection and if the slot is locked. /// /// The entity with the power cell slot. /// The power cell that was ejected. /// The player trying to eject the power cell from the slot. /// If a power cell was sucessfully ejected. [PublicAPI] public bool TryEjectBatteryFromSlot( Entity ent, [NotNullWhen(true)] out EntityUid? battery, EntityUid? user = null) { if (!Resolve(ent, ref ent.Comp, false)) { battery = null; return false; } if (!_itemSlots.TryEject(ent.Owner, ent.Comp.CellSlotId, user, out battery, excludeUserAudio: true)) { battery = null; return false; } return true; } /// /// Returns whether the entity has a slotted battery and charge for the requested action. /// /// The entity with the power cell slot. /// The charge that is needed. /// Show a popup to this user with the relevant details if specified. /// Whether to predict the popup or not. [PublicAPI] public bool HasCharge(Entity ent, float charge, EntityUid? user = null, bool predicted = false) { if (!TryGetBatteryFromSlot(ent, out var battery)) { if (user == null) return false; if (predicted) _popup.PopupClient(Loc.GetString("power-cell-no-battery"), ent.Owner, user.Value); else _popup.PopupEntity(Loc.GetString("power-cell-no-battery"), ent.Owner, user.Value); return false; } if (_battery.GetCharge(battery.Value.AsNullable()) < charge) { if (user == null) return false; if (predicted) _popup.PopupClient(Loc.GetString("power-cell-insufficient"), ent.Owner, user.Value); else _popup.PopupEntity(Loc.GetString("power-cell-insufficient"), ent.Owner, user.Value); return false; } return true; } /// /// Tries to use charge from a slotted battery. /// /// The entity with the power cell slot. /// The charge that is needed. /// Show a popup to this user with the relevant details if specified. /// Whether to predict the popup or not. [PublicAPI] public bool TryUseCharge(Entity ent, float charge, EntityUid? user = null, bool predicted = false) { if (!TryGetBatteryFromSlot(ent, out var battery)) { if (user == null) return false; if (predicted) _popup.PopupClient(Loc.GetString("power-cell-no-battery"), ent.Owner, user.Value); else _popup.PopupEntity(Loc.GetString("power-cell-no-battery"), ent.Owner, user.Value); return false; } if (!_battery.TryUseCharge((battery.Value, battery), charge)) { if (user == null) return false; if (predicted) _popup.PopupClient(Loc.GetString("power-cell-insufficient"), ent.Owner, user.Value); else _popup.PopupEntity(Loc.GetString("power-cell-insufficient"), ent.Owner, user.Value); return false; } return true; } /// /// Gets number of remaining uses for the given charge cost. /// /// The entity with the power cell slot. /// The cost per use. [PublicAPI] public int GetRemainingUses(Entity ent, float cost) { if (!TryGetBatteryFromSlot(ent, out var battery)) return 0; return _battery.GetRemainingUses(battery.Value.AsNullable(), cost); } /// /// Gets number of maximum uses at full charge for the given charge cost. /// /// The entity with the power cell slot. /// The cost per use. [PublicAPI] public int GetMaxUses(Entity ent, float cost) { if (!TryGetBatteryFromSlot(ent, out var battery)) return 0; return _battery.GetMaxUses(battery.Value.AsNullable(), cost); } }