Files
wwdpublic/Content.Server/Power/Components/ApcPowerReceiverComponent.cs
RedFoxIV 17ea2b7853 EE - Power Supply and Load Stuff (#1033)
* Power Supply and Load Stuff (#2505)

# Description

Changes how `ApcPowerReceiverComponent` works a bit.
Separated the `Load` variable into main and side power loads.
If main power demand is not met, the machine is considered unpowered.
Side power demand is "optional", as can be met only partially (or not at
all) and the device will continue to operate.
Depending on the device, this may have different negative effects on its
operaton. such as lights dimming and weapon rechargers not charging at
full speed.

This was first intended to fix an annoying bug with `ChargerComponent`
and `ApcPowerReceiverBatteryComponent`, that made the powernet spaz out
for a while if their power demand was too high.
This is now fixed.

---

<details><summary><h1>Media</h1></summary>
<p>

<details><summary>Before (heavy flashing lights)</summary>
<p>


https://github.com/user-attachments/assets/de7fb84f-54d0-4c8a-ba9e-7a97e8489980

</p>
</details>

<details><summary>After</summary>
<p>


https://github.com/user-attachments/assets/9cece608-24f7-4ec9-95cd-0c719c7beddb

</p>
</details>

</p>
</details>

---

# Changelog

🆑
- fix: Chargers and energy turrets no longer make the lights flash
rapidly if their power draw is too high
- add: Lights dim if the powernet they're connected to is overloaded

* больно много жрёт

---------

Co-authored-by: VMSolidus <evilexecutive@gmail.com>
2026-01-18 00:39:43 +03:00

85 lines
2.7 KiB
C#

using Content.Server.Power.NodeGroups;
using Content.Server.Power.Pow3r;
using Content.Shared.Power.Components;
namespace Content.Server.Power.Components
{
/// <summary>
/// Attempts to link with a nearby <see cref="ApcPowerProviderComponent"/>s
/// so that it can receive power from a <see cref="IApcNet"/>.
/// </summary>
[RegisterComponent]
public sealed partial class ApcPowerReceiverComponent : SharedApcPowerReceiverComponent
{
/// <summary>
/// Amount of charge this needs from an APC per second to function.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
private float _mainLoad = 5;
private float _sideLoad;
[DataField("powerLoad")]
public float Load { get => _mainLoad;
set { _mainLoad = value; NetworkLoad.DesiredPower = _mainLoad + _sideLoad; }
}
[DataField("sidePowerLoad")]
public float SideLoad
{
get => _sideLoad;
set { _sideLoad = value; NetworkLoad.DesiredPower = _mainLoad + _sideLoad; }
}
[ViewVariables(VVAccess.ReadOnly)]
public float FullLoad => _mainLoad + _sideLoad;
public ApcPowerProviderComponent? Provider = null;
/// <summary>
/// When false, causes this to appear powered even if not receiving power from an Apc.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool NeedsPower
{
get => _needsPower;
set
{
_needsPower = value;
// Reset this so next tick will do a power update.
Recalculate = true;
}
}
[DataField("needsPower")]
private bool _needsPower = true;
/// <summary>
/// When true, causes this to never appear powered.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("powerDisabled")]
public bool PowerDisabled {
get => !NetworkLoad.Enabled;
set => NetworkLoad.Enabled = !value;
}
// TODO Is this needed? It forces a PowerChangedEvent when NeedsPower is toggled even if it changes to the same state.
public bool Recalculate;
[ViewVariables]
public PowerState.Load NetworkLoad { get; } = new PowerState.Load
{
DesiredPower = 5
};
public float PowerReceived => NetworkLoad.ReceivingPower;
[ViewVariables(VVAccess.ReadOnly)]
public float SideLoadFraction => _sideLoad > 0 && _needsPower ? MathHelper.Clamp01((NetworkLoad.ReceivingPower - _mainLoad) / _sideLoad) : 1;
public float LastSideLoadFraction;
}
}