Cleanup for ChargerComponent (#11907)
This commit is contained in:
10
Content.Server/Power/Components/ActiveChargerComponent.cs
Normal file
10
Content.Server/Power/Components/ActiveChargerComponent.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Power;
|
||||
|
||||
namespace Content.Server.Power.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class ActiveChargerComponent : Component
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -6,104 +6,15 @@ namespace Content.Server.Power.Components
|
||||
[RegisterComponent]
|
||||
public sealed class ChargerComponent : Component
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[ViewVariables]
|
||||
public CellChargerStatus Status;
|
||||
|
||||
[ViewVariables]
|
||||
public BatteryComponent? HeldBattery;
|
||||
|
||||
[ViewVariables]
|
||||
private CellChargerStatus _status;
|
||||
|
||||
[DataField("chargeRate")]
|
||||
public int ChargeRate = 20;
|
||||
|
||||
[DataField("chargerSlot", required: true)]
|
||||
public ItemSlot ChargerSlot = new();
|
||||
|
||||
private CellChargerStatus GetStatus()
|
||||
{
|
||||
if (!_entMan.TryGetComponent<TransformComponent>(Owner, out var xform) ||
|
||||
!xform.Anchored ||
|
||||
_entMan.TryGetComponent(Owner, out ApcPowerReceiverComponent? receiver) && !receiver.Powered)
|
||||
{
|
||||
return CellChargerStatus.Off;
|
||||
}
|
||||
|
||||
if (!ChargerSlot.HasItem)
|
||||
return CellChargerStatus.Empty;
|
||||
|
||||
if (HeldBattery != null && Math.Abs(HeldBattery.MaxCharge - HeldBattery.CurrentCharge) < 0.01)
|
||||
return CellChargerStatus.Charged;
|
||||
|
||||
return CellChargerStatus.Charging;
|
||||
}
|
||||
|
||||
public void UpdateStatus()
|
||||
{
|
||||
// Not called UpdateAppearance just because it messes with the load
|
||||
var status = GetStatus();
|
||||
if (_status == status ||
|
||||
!_entMan.TryGetComponent(Owner, out ApcPowerReceiverComponent? receiver))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_status = status;
|
||||
_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance);
|
||||
|
||||
switch (_status)
|
||||
{
|
||||
// Update load just in case
|
||||
case CellChargerStatus.Off:
|
||||
receiver.Load = 0;
|
||||
appearance?.SetData(CellVisual.Light, CellChargerStatus.Off);
|
||||
break;
|
||||
case CellChargerStatus.Empty:
|
||||
receiver.Load = 0;
|
||||
appearance?.SetData(CellVisual.Light, CellChargerStatus.Empty);
|
||||
break;
|
||||
case CellChargerStatus.Charging:
|
||||
receiver.Load = ChargeRate;
|
||||
appearance?.SetData(CellVisual.Light, CellChargerStatus.Charging);
|
||||
break;
|
||||
case CellChargerStatus.Charged:
|
||||
receiver.Load = 0;
|
||||
appearance?.SetData(CellVisual.Light, CellChargerStatus.Charged);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
appearance?.SetData(CellVisual.Occupied, ChargerSlot.HasItem);
|
||||
}
|
||||
|
||||
public void OnUpdate(float frameTime) //todo: make single system for this
|
||||
{
|
||||
if (_status == CellChargerStatus.Empty || _status == CellChargerStatus.Charged || !ChargerSlot.HasItem)
|
||||
return;
|
||||
|
||||
TransferPower(frameTime);
|
||||
}
|
||||
|
||||
private void TransferPower(float frameTime)
|
||||
{
|
||||
if (_entMan.TryGetComponent(Owner, out ApcPowerReceiverComponent? receiver) &&
|
||||
!receiver.Powered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HeldBattery == null)
|
||||
return;
|
||||
|
||||
HeldBattery.CurrentCharge += ChargeRate * frameTime;
|
||||
// Just so the sprite won't be set to 99.99999% visibility
|
||||
if (HeldBattery.MaxCharge - HeldBattery.CurrentCharge < 0.01)
|
||||
{
|
||||
HeldBattery.CurrentCharge = HeldBattery.MaxCharge;
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
[ViewVariables]
|
||||
[DataField("slotId", required: true)]
|
||||
public string SlotId = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Shared.Examine;
|
||||
using Content.Shared.PowerCell.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Containers;
|
||||
using Content.Shared.Power;
|
||||
|
||||
namespace Content.Server.Power.EntitySystems;
|
||||
|
||||
@@ -13,11 +14,11 @@ internal sealed class ChargerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
||||
[Dependency] private readonly PowerCellSystem _cellSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _sharedAppearanceSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<ChargerComponent, ComponentInit>(OnChargerInit);
|
||||
SubscribeLocalEvent<ChargerComponent, ComponentRemove>(OnChargerRemove);
|
||||
SubscribeLocalEvent<ChargerComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<ChargerComponent, PowerChangedEvent>(OnPowerChanged);
|
||||
SubscribeLocalEvent<ChargerComponent, EntInsertedIntoContainerMessage>(OnInserted);
|
||||
SubscribeLocalEvent<ChargerComponent, EntRemovedFromContainerMessage>(OnRemoved);
|
||||
@@ -25,6 +26,11 @@ internal sealed class ChargerSystem : EntitySystem
|
||||
SubscribeLocalEvent<ChargerComponent, ExaminedEvent>(OnChargerExamine);
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, ChargerComponent component, ComponentStartup args)
|
||||
{
|
||||
UpdateStatus(uid, component);
|
||||
}
|
||||
|
||||
private void OnChargerExamine(EntityUid uid, ChargerComponent component, ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("charger-examine", ("color", "yellow"), ("chargeRate", component.ChargeRate)));
|
||||
@@ -32,24 +38,21 @@ internal sealed class ChargerSystem : EntitySystem
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var comp in EntityManager.EntityQuery<ChargerComponent>())
|
||||
foreach (var (_, charger, slotComp) in EntityManager.EntityQuery<ActiveChargerComponent, ChargerComponent, ItemSlotsComponent>())
|
||||
{
|
||||
comp.OnUpdate(frameTime);
|
||||
}
|
||||
}
|
||||
private void OnChargerInit(EntityUid uid, ChargerComponent component, ComponentInit args)
|
||||
{
|
||||
_itemSlotsSystem.AddItemSlot(uid, "charger-slot", component.ChargerSlot);
|
||||
}
|
||||
if (!_itemSlotsSystem.TryGetSlot(charger.Owner, charger.SlotId, out ItemSlot? slot, slotComp))
|
||||
continue;
|
||||
|
||||
private void OnChargerRemove(EntityUid uid, ChargerComponent component, ComponentRemove args)
|
||||
{
|
||||
_itemSlotsSystem.RemoveItemSlot(uid, component.ChargerSlot);
|
||||
if (charger.Status == CellChargerStatus.Empty || charger.Status == CellChargerStatus.Charged || !slot.HasItem)
|
||||
continue;
|
||||
|
||||
TransferPower(charger.Owner, charger, frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPowerChanged(EntityUid uid, ChargerComponent component, ref PowerChangedEvent args)
|
||||
{
|
||||
component.UpdateStatus();
|
||||
UpdateStatus(uid, component);
|
||||
}
|
||||
|
||||
private void OnInserted(EntityUid uid, ChargerComponent component, EntInsertedIntoContainerMessage args)
|
||||
@@ -57,25 +60,18 @@ internal sealed class ChargerSystem : EntitySystem
|
||||
if (!component.Initialized)
|
||||
return;
|
||||
|
||||
if (args.Container.ID != component.ChargerSlot.ID)
|
||||
if (args.Container.ID != component.SlotId)
|
||||
return;
|
||||
|
||||
// try get a battery directly on the inserted entity
|
||||
if (!TryComp(args.Entity, out component.HeldBattery))
|
||||
{
|
||||
// or by checking for a power cell slot on the inserted entity
|
||||
_cellSystem.TryGetBatteryFromSlot(args.Entity, out component.HeldBattery);
|
||||
}
|
||||
|
||||
component.UpdateStatus();
|
||||
UpdateStatus(uid, component);
|
||||
}
|
||||
|
||||
private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFromContainerMessage args)
|
||||
{
|
||||
if (args.Container.ID != component.ChargerSlot.ID)
|
||||
if (args.Container.ID != component.SlotId)
|
||||
return;
|
||||
|
||||
component.UpdateStatus();
|
||||
UpdateStatus(uid, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,16 +82,113 @@ internal sealed class ChargerSystem : EntitySystem
|
||||
if (!component.Initialized)
|
||||
return;
|
||||
|
||||
if (args.Container.ID != component.ChargerSlot.ID)
|
||||
if (args.Container.ID != component.SlotId)
|
||||
return;
|
||||
|
||||
if (!TryComp(args.EntityUid, out PowerCellSlotComponent? cellSlot))
|
||||
return;
|
||||
|
||||
if (!_itemSlotsSystem.TryGetSlotById(args.EntityUid, cellSlot.CellSlotId, out ItemSlot? itemSlot))
|
||||
if (!_itemSlotsSystem.TryGetSlot(args.EntityUid, cellSlot.CellSlotId, out ItemSlot? itemSlot))
|
||||
return;
|
||||
|
||||
if (!cellSlot.FitsInCharger || !itemSlot.HasItem)
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void UpdateStatus(EntityUid uid, ChargerComponent component)
|
||||
{
|
||||
var status = GetStatus(uid, component);
|
||||
if (component.Status == status || !TryComp(uid, out ApcPowerReceiverComponent? receiver))
|
||||
return;
|
||||
|
||||
if (!_itemSlotsSystem.TryGetSlot(uid, component.SlotId, out ItemSlot? slot))
|
||||
return;
|
||||
|
||||
TryComp(uid, out AppearanceComponent? appearance);
|
||||
|
||||
component.Status = status;
|
||||
|
||||
if (component.Status == CellChargerStatus.Charging)
|
||||
{
|
||||
AddComp<ActiveChargerComponent>(uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemComp<ActiveChargerComponent>(uid);
|
||||
}
|
||||
|
||||
switch (component.Status)
|
||||
{
|
||||
case CellChargerStatus.Off:
|
||||
receiver.Load = 0;
|
||||
_sharedAppearanceSystem.SetData(uid, CellVisual.Light, CellChargerStatus.Off, appearance);
|
||||
break;
|
||||
case CellChargerStatus.Empty:
|
||||
receiver.Load = 0;
|
||||
_sharedAppearanceSystem.SetData(uid, CellVisual.Light, CellChargerStatus.Empty, appearance);
|
||||
break;
|
||||
case CellChargerStatus.Charging:
|
||||
receiver.Load = component.ChargeRate;
|
||||
_sharedAppearanceSystem.SetData(uid, CellVisual.Light, CellChargerStatus.Charging, appearance);
|
||||
break;
|
||||
case CellChargerStatus.Charged:
|
||||
receiver.Load = 0;
|
||||
_sharedAppearanceSystem.SetData(uid, CellVisual.Light, CellChargerStatus.Charged, appearance);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
_sharedAppearanceSystem.SetData(uid, CellVisual.Occupied, slot.HasItem, appearance);
|
||||
}
|
||||
|
||||
private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component)
|
||||
{
|
||||
if (!TryComp(uid, out TransformComponent? transformComponent))
|
||||
return CellChargerStatus.Off;
|
||||
|
||||
if (!transformComponent.Anchored)
|
||||
return CellChargerStatus.Off;
|
||||
|
||||
if (!TryComp(uid, out ApcPowerReceiverComponent? apcPowerReceiverComponent))
|
||||
return CellChargerStatus.Off;
|
||||
|
||||
if (!apcPowerReceiverComponent.Powered)
|
||||
return CellChargerStatus.Off;
|
||||
|
||||
if (!_itemSlotsSystem.TryGetSlot(uid, component.SlotId, out ItemSlot? slot))
|
||||
return CellChargerStatus.Off;
|
||||
|
||||
if (!_cellSystem.TryGetBatteryFromSlot(uid, out BatteryComponent? heldBattery))
|
||||
return CellChargerStatus.Off;
|
||||
|
||||
if (!slot.HasItem)
|
||||
return CellChargerStatus.Empty;
|
||||
|
||||
if (heldBattery != null && Math.Abs(heldBattery.MaxCharge - heldBattery.CurrentCharge) < 0.01)
|
||||
return CellChargerStatus.Charged;
|
||||
|
||||
return CellChargerStatus.Charging;
|
||||
}
|
||||
|
||||
private void TransferPower(EntityUid uid, ChargerComponent component, float frameTime)
|
||||
{
|
||||
if (!TryComp(uid, out ApcPowerReceiverComponent? receiverComponent))
|
||||
return;
|
||||
|
||||
if (!receiverComponent.Powered)
|
||||
return;
|
||||
|
||||
if (!_cellSystem.TryGetBatteryFromSlot(uid, out BatteryComponent? heldBattery))
|
||||
return;
|
||||
|
||||
heldBattery.CurrentCharge += component.ChargeRate * frameTime;
|
||||
// Just so the sprite won't be set to 99.99999% visibility
|
||||
if (heldBattery.MaxCharge - heldBattery.CurrentCharge < 0.01)
|
||||
{
|
||||
heldBattery.CurrentCharge = heldBattery.MaxCharge;
|
||||
}
|
||||
|
||||
UpdateStatus(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public sealed class PowerCellSystem : SharedPowerCellSystem
|
||||
|
||||
private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args)
|
||||
{
|
||||
if (_itemSlotsSystem.TryGetSlotById(uid, component.CellSlotId, out ItemSlot? slot))
|
||||
if (_itemSlotsSystem.TryGetSlot(uid, component.CellSlotId, out ItemSlot? slot))
|
||||
{
|
||||
if (slot.Item == null)
|
||||
return;
|
||||
@@ -80,7 +80,7 @@ public sealed class PowerCellSystem : SharedPowerCellSystem
|
||||
// If this power cell is inside a cell-slot, inform that entity that the power has changed (for updating visuals n such).
|
||||
if (_containerSystem.TryGetContainingContainer(uid, out var container)
|
||||
&& TryComp(container.Owner, out PowerCellSlotComponent? slot)
|
||||
&& _itemSlotsSystem.TryGetSlotById(container.Owner, slot.CellSlotId, out ItemSlot? itemSlot))
|
||||
&& _itemSlotsSystem.TryGetSlot(container.Owner, slot.CellSlotId, out ItemSlot? itemSlot))
|
||||
{
|
||||
if (itemSlot.Item == uid)
|
||||
RaiseLocalEvent(container.Owner, new PowerCellChangedEvent(false), false);
|
||||
@@ -108,7 +108,7 @@ public sealed class PowerCellSystem : SharedPowerCellSystem
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_itemSlotsSystem.TryGetSlotById(uid, component.CellSlotId, out ItemSlot? slot))
|
||||
if (_itemSlotsSystem.TryGetSlot(uid, component.CellSlotId, out ItemSlot? slot))
|
||||
{
|
||||
return TryComp(slot.Item, out battery);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Content.Shared.Containers.ItemSlots
|
||||
Dirty(itemSlots);
|
||||
}
|
||||
|
||||
public bool TryGetSlotById(EntityUid uid, string slotId, [NotNullWhen(true)] out ItemSlot? itemSlot, ItemSlotsComponent? component = null)
|
||||
public bool TryGetSlot(EntityUid uid, string slotId, [NotNullWhen(true)] out ItemSlot? itemSlot, ItemSlotsComponent? component = null)
|
||||
{
|
||||
itemSlot = null;
|
||||
|
||||
|
||||
@@ -12,12 +12,7 @@
|
||||
drawdepth: SmallObjects
|
||||
snapCardinals: true
|
||||
- type: Charger
|
||||
chargerSlot:
|
||||
ejectOnInteract: true
|
||||
name: Power cell # used for verbs: "Eject > Power cell "
|
||||
whitelist:
|
||||
components:
|
||||
- PowerCell
|
||||
slotId: charger_slot
|
||||
- type: ApcPowerReceiver
|
||||
- type: ExtensionCableReceiver
|
||||
- type: Appearance
|
||||
@@ -40,9 +35,16 @@
|
||||
layer:
|
||||
- HighImpassable
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
charger_slot:
|
||||
ejectOnInteract: true
|
||||
name: Power cell
|
||||
whitelist:
|
||||
components:
|
||||
- PowerCell
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
charger-slot: !type:ContainerSlot
|
||||
charger_slot: !type:ContainerSlot
|
||||
|
||||
- type: entity
|
||||
name: recharger
|
||||
@@ -52,8 +54,10 @@
|
||||
- type: Sprite
|
||||
sprite: Structures/Power/recharger.rsi
|
||||
- type: Charger
|
||||
chargerSlot:
|
||||
ejectOnInteract: true
|
||||
slotId: charger_slot
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
charger_slot:
|
||||
whitelist:
|
||||
components:
|
||||
- HitscanBatteryAmmoProvider
|
||||
@@ -70,10 +74,3 @@
|
||||
- type: WallMount
|
||||
- type: Charger
|
||||
chargeRate: 25
|
||||
chargerSlot:
|
||||
ejectOnInteract: true
|
||||
whitelist:
|
||||
components:
|
||||
- HitscanBatteryAmmoProvider
|
||||
- ProjectileBatteryAmmoProvider
|
||||
- Stunbaton
|
||||
|
||||
Reference in New Issue
Block a user