2020-08-13 14:40:27 +02:00
using System ;
2020-06-28 09:23:26 -06:00
using System.Collections.Generic ;
using System.Diagnostics ;
2020-08-13 14:40:27 +02:00
using Content.Server.GameObjects.Components.Power.PowerNetComponents ;
using Robust.Shared.IoC ;
using Robust.Shared.ViewVariables ;
2020-06-28 09:23:26 -06:00
namespace Content.Server.GameObjects.Components.NodeContainer.NodeGroups
{
public interface IPowerNet
{
void AddSupplier ( PowerSupplierComponent supplier ) ;
void RemoveSupplier ( PowerSupplierComponent supplier ) ;
void UpdateSupplierSupply ( PowerSupplierComponent supplier , int oldSupplyRate , int newSupplyRate ) ;
void AddConsumer ( PowerConsumerComponent consumer ) ;
void RemoveConsumer ( PowerConsumerComponent consumer ) ;
void UpdateConsumerDraw ( PowerConsumerComponent consumer , int oldDrawRate , int newDrawRate ) ;
void UpdateConsumerPriority ( PowerConsumerComponent consumer , Priority oldPriority , Priority newPriority ) ;
2020-07-26 04:14:03 -06:00
void UpdateConsumerReceivedPower ( ) ;
2020-06-28 09:23:26 -06:00
}
[NodeGroup(NodeGroupID.HVPower, NodeGroupID.MVPower)]
public class PowerNetNodeGroup : BaseNetConnectorNodeGroup < BasePowerNetComponent , IPowerNet > , IPowerNet
{
2020-08-24 14:10:28 +02:00
[Dependency] private readonly IPowerNetManager _powerNetManager = default ! ;
2020-06-28 09:23:26 -06:00
[ViewVariables]
2020-11-27 11:00:49 +01:00
private readonly List < PowerSupplierComponent > _suppliers = new ( ) ;
2020-06-28 09:23:26 -06:00
[ViewVariables]
private int _totalSupply = 0 ;
[ViewVariables]
2020-11-27 11:00:49 +01:00
private readonly Dictionary < Priority , List < PowerConsumerComponent > > _consumersByPriority = new ( ) ;
2020-06-28 09:23:26 -06:00
[ViewVariables]
2020-11-27 11:00:49 +01:00
private readonly Dictionary < Priority , int > _drawByPriority = new ( ) ;
2020-06-28 09:23:26 -06:00
public static readonly IPowerNet NullNet = new NullPowerNet ( ) ;
public PowerNetNodeGroup ( )
{
2020-07-26 04:14:03 -06:00
foreach ( Priority priority in Enum . GetValues ( typeof ( Priority ) ) )
2020-06-28 09:23:26 -06:00
{
_consumersByPriority . Add ( priority , new List < PowerConsumerComponent > ( ) ) ;
_drawByPriority . Add ( priority , 0 ) ;
}
}
protected override void SetNetConnectorNet ( BasePowerNetComponent netConnectorComponent )
{
netConnectorComponent . Net = this ;
}
#region IPowerNet Methods
public void AddSupplier ( PowerSupplierComponent supplier )
{
_suppliers . Add ( supplier ) ;
_totalSupply + = supplier . SupplyRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
public void RemoveSupplier ( PowerSupplierComponent supplier )
{
Debug . Assert ( _suppliers . Contains ( supplier ) ) ;
_suppliers . Remove ( supplier ) ;
_totalSupply - = supplier . SupplyRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
public void UpdateSupplierSupply ( PowerSupplierComponent supplier , int oldSupplyRate , int newSupplyRate )
{
Debug . Assert ( _suppliers . Contains ( supplier ) ) ;
_totalSupply - = oldSupplyRate ;
_totalSupply + = newSupplyRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
public void AddConsumer ( PowerConsumerComponent consumer )
{
_consumersByPriority [ consumer . Priority ] . Add ( consumer ) ;
_drawByPriority [ consumer . Priority ] + = consumer . DrawRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
public void RemoveConsumer ( PowerConsumerComponent consumer )
{
Debug . Assert ( _consumersByPriority [ consumer . Priority ] . Contains ( consumer ) ) ;
2020-07-02 04:02:29 -06:00
consumer . ReceivedPower = 0 ;
_consumersByPriority [ consumer . Priority ] . Remove ( consumer ) ;
2020-06-28 09:23:26 -06:00
_drawByPriority [ consumer . Priority ] - = consumer . DrawRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
public void UpdateConsumerDraw ( PowerConsumerComponent consumer , int oldDrawRate , int newDrawRate )
{
Debug . Assert ( _consumersByPriority [ consumer . Priority ] . Contains ( consumer ) ) ;
_drawByPriority [ consumer . Priority ] - = oldDrawRate ;
_drawByPriority [ consumer . Priority ] + = newDrawRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
public void UpdateConsumerPriority ( PowerConsumerComponent consumer , Priority oldPriority , Priority newPriority )
{
Debug . Assert ( _consumersByPriority [ oldPriority ] . Contains ( consumer ) ) ;
_consumersByPriority [ oldPriority ] . Remove ( consumer ) ;
_drawByPriority [ oldPriority ] - = consumer . DrawRate ;
_consumersByPriority [ newPriority ] . Add ( consumer ) ;
_drawByPriority [ newPriority ] + = consumer . DrawRate ;
2020-07-26 04:14:03 -06:00
_powerNetManager . AddDirtyPowerNet ( this ) ;
2020-06-28 09:23:26 -06:00
}
2020-07-26 04:14:03 -06:00
public void UpdateConsumerReceivedPower ( )
2020-06-28 09:23:26 -06:00
{
var remainingSupply = _totalSupply ;
foreach ( Priority priority in Enum . GetValues ( typeof ( Priority ) ) )
{
var categoryPowerDemand = _drawByPriority [ priority ] ;
2020-07-26 04:14:03 -06:00
if ( remainingSupply > = categoryPowerDemand ) //can fully power all in category
2020-06-28 09:23:26 -06:00
{
remainingSupply - = categoryPowerDemand ;
foreach ( var consumer in _consumersByPriority [ priority ] )
{
consumer . ReceivedPower = consumer . DrawRate ;
}
}
2020-07-26 04:14:03 -06:00
else //cannot fully power all, split power
2020-06-28 09:23:26 -06:00
{
var availiablePowerFraction = ( float ) remainingSupply / categoryPowerDemand ;
remainingSupply = 0 ;
foreach ( var consumer in _consumersByPriority [ priority ] )
{
consumer . ReceivedPower = ( int ) ( consumer . DrawRate * availiablePowerFraction ) ; //give each consumer a fraction of what they requested (rounded down to nearest int)
}
}
}
}
#endregion
private class NullPowerNet : IPowerNet
{
public void AddConsumer ( PowerConsumerComponent consumer ) { }
public void AddSupplier ( PowerSupplierComponent supplier ) { }
public void UpdateSupplierSupply ( PowerSupplierComponent supplier , int oldSupplyRate , int newSupplyRate ) { }
public void RemoveConsumer ( PowerConsumerComponent consumer ) { }
public void RemoveSupplier ( PowerSupplierComponent supplier ) { }
public void UpdateConsumerDraw ( PowerConsumerComponent consumer , int oldDrawRate , int newDrawRate ) { }
public void UpdateConsumerPriority ( PowerConsumerComponent consumer , Priority oldPriority , Priority newPriority ) { }
2020-07-26 04:14:03 -06:00
public void UpdateConsumerReceivedPower ( ) { }
2020-06-28 09:23:26 -06:00
}
}
}