Files
tbd-station-14/Content.Server/GameObjects/Components/NodeContainer/NodeGroups/ApcNetNodeGroup.cs
DrSmugleaf b9196d0a10 Add a test that puts all components on an entity and checks for no exceptions (#1815)
* Add test that puts all components on an entity and checks for no exceptions

Also fix all the exceptions that happened because of this

* Add comments to the test

* Fix nullable errors

* Fix more nullable errors

* More nullable error fixes

* Unignore basic actor component

* Fix more nullable errors

* NULLABLE ERROR

* Add string interpolation

* Merge if checks

* Remove redundant pragma warning disable 649

* Address reviews

* Remove null wrappers around TryGetComponent

* Merge conflict fixes

* APC battery component error fix

* Fix power test

* Fix atmos mapgrid usages
2020-08-22 22:29:20 +02:00

128 lines
4.3 KiB
C#

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Content.Server.GameObjects.Components.Power;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
{
public interface IApcNet
{
void AddApc(ApcComponent apc);
void RemoveApc(ApcComponent apc);
void AddPowerProvider(PowerProviderComponent provider);
void RemovePowerProvider(PowerProviderComponent provider);
void UpdatePowerProviderReceivers(PowerProviderComponent provider);
void Update(float frameTime);
}
[NodeGroup(NodeGroupID.Apc)]
public class ApcNetNodeGroup : BaseNetConnectorNodeGroup<BaseApcNetComponent, IApcNet>, IApcNet
{
[ViewVariables]
private readonly Dictionary<ApcComponent, BatteryComponent> _apcBatteries = new Dictionary<ApcComponent, BatteryComponent>();
[ViewVariables]
private readonly Dictionary<PowerProviderComponent, List<PowerReceiverComponent>> _providerReceivers = new Dictionary<PowerProviderComponent, List<PowerReceiverComponent>>();
//Debug property
[ViewVariables]
private int TotalReceivers => _providerReceivers.SelectMany(kvp => kvp.Value).Count();
private IEnumerable<BatteryComponent> AvailableBatteries => _apcBatteries.Where(kvp => kvp.Key.MainBreakerEnabled).Select(kvp => kvp.Value);
public static readonly IApcNet NullNet = new NullApcNet();
#region IApcNet Methods
protected override void SetNetConnectorNet(BaseApcNetComponent netConnectorComponent)
{
netConnectorComponent.Net = this;
}
public void AddApc(ApcComponent apc)
{
if (!apc.Owner.TryGetComponent(out BatteryComponent battery))
{
return;
}
_apcBatteries.Add(apc, battery);
}
public void RemoveApc(ApcComponent apc)
{
_apcBatteries.Remove(apc);
if (!_apcBatteries.Any())
{
foreach (var receiver in _providerReceivers.SelectMany(kvp => kvp.Value))
{
receiver.HasApcPower = false;
}
}
}
public void AddPowerProvider(PowerProviderComponent provider)
{
_providerReceivers.Add(provider, provider.LinkedReceivers.ToList());
}
public void RemovePowerProvider(PowerProviderComponent provider)
{
_providerReceivers.Remove(provider);
}
public void UpdatePowerProviderReceivers(PowerProviderComponent provider)
{
Debug.Assert(_providerReceivers.ContainsKey(provider));
_providerReceivers[provider] = provider.LinkedReceivers.ToList();
}
public void Update(float frameTime)
{
var totalCharge = 0.0;
var totalMaxCharge = 0;
foreach (var battery in AvailableBatteries)
{
totalCharge += battery.CurrentCharge;
totalMaxCharge += battery.MaxCharge;
}
var availablePowerFraction = totalCharge / totalMaxCharge;
foreach (var receiver in _providerReceivers.SelectMany(kvp => kvp.Value))
{
receiver.HasApcPower = TryUsePower(receiver.Load * frameTime);
}
}
private bool TryUsePower(float neededCharge)
{
foreach (var battery in AvailableBatteries)
{
if (battery.TryUseCharge(neededCharge)) //simplification - all power needed must come from one battery
{
return true;
}
}
return false;
}
#endregion
private class NullApcNet : IApcNet
{
public void AddApc(ApcComponent apc) { }
public void AddPowerProvider(PowerProviderComponent provider) { }
public void RemoveApc(ApcComponent apc) { }
public void RemovePowerProvider(PowerProviderComponent provider) { }
public void UpdatePowerProviderReceivers(PowerProviderComponent provider) { }
public void Update(float frameTime) { }
}
}
}