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);
}
}