Power System (Complete) (#25)
* Power Commit 1 * Commit 2 * Powernet Part2, All components essentially complete * Commit 4 * Commit 5 * Commit 6 Creates prototypes * Finishes powernet code alpha Adds prototypes and logic for powernet updating and regeneration * Adds onremove functionality to all components Without these bits of logic nothing makes any sense! * And this * Fixes a lot of bugs * Fix powernet thinking devices are duplicates * Fix bug and add comments * woop woop thats the sound of the police
This commit is contained in:
@@ -18,6 +18,12 @@ namespace Content.Client
|
|||||||
factory.RegisterIgnore("Damageable");
|
factory.RegisterIgnore("Damageable");
|
||||||
factory.RegisterIgnore("Destructible");
|
factory.RegisterIgnore("Destructible");
|
||||||
factory.RegisterIgnore("Temperature");
|
factory.RegisterIgnore("Temperature");
|
||||||
|
factory.RegisterIgnore("PowerTransfer");
|
||||||
|
factory.RegisterIgnore("PowerNode");
|
||||||
|
factory.RegisterIgnore("PowerProvider");
|
||||||
|
factory.RegisterIgnore("PowerDevice");
|
||||||
|
factory.RegisterIgnore("PowerStorage");
|
||||||
|
factory.RegisterIgnore("PowerGenerator");
|
||||||
|
|
||||||
factory.Register<HandsComponent>();
|
factory.Register<HandsComponent>();
|
||||||
factory.RegisterReference<HandsComponent, IHandsComponent>();
|
factory.RegisterReference<HandsComponent, IHandsComponent>();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
@@ -39,14 +39,14 @@
|
|||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System"/>
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core"/>
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xml.Linq"/>
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions"/>
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp"/>
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Data"/>
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Net.Http"/>
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Xml"/>
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="YamlDotNet">
|
<Reference Include="YamlDotNet">
|
||||||
<HintPath>$(SolutionDir)packages\YamlDotNet.4.2.1\lib\net35\YamlDotNet.dll</HintPath>
|
<HintPath>$(SolutionDir)packages\YamlDotNet.4.2.1\lib\net35\YamlDotNet.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
@@ -55,22 +55,30 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="EntryPoint.cs"/>
|
<Compile Include="EntryPoint.cs" />
|
||||||
<Compile Include="GameObjects\Components\Doors\ServerDoorComponent.cs" />
|
<Compile Include="GameObjects\Components\Doors\ServerDoorComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Interactable\InteractableComponent.cs" />
|
<Compile Include="GameObjects\Components\Interactable\InteractableComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerStorageComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerGeneratorComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerDevice.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\Powernet.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerNodeComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerProviderComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Power\PowerTransferComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\EntitySystems\PowerSystem.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Interactable\IInteractableComponent.cs" />
|
<Compile Include="Interfaces\GameObjects\Components\Interactable\IInteractableComponent.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs"/>
|
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Items\IInventoryComponent.cs"/>
|
<Compile Include="Interfaces\GameObjects\Components\Items\IInventoryComponent.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Items\IItemComponent.cs"/>
|
<Compile Include="Interfaces\GameObjects\Components\Items\IItemComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Items\ServerHandsComponent.cs"/>
|
<Compile Include="GameObjects\Components\Items\ServerHandsComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Items\InventoryComponent.cs"/>
|
<Compile Include="GameObjects\Components\Items\InventoryComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Items\ItemComponent.cs"/>
|
<Compile Include="GameObjects\Components\Items\ItemComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Damage\DamageableComponent.cs"/>
|
<Compile Include="GameObjects\Components\Damage\DamageableComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Damage\DestructibleComponent.cs"/>
|
<Compile Include="GameObjects\Components\Damage\DestructibleComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Damage\ResistanceSet.cs"/>
|
<Compile Include="GameObjects\Components\Damage\ResistanceSet.cs" />
|
||||||
<Compile Include="GameObjects\Components\Temperature\TemperatureComponent.cs"/>
|
<Compile Include="GameObjects\Components\Temperature\TemperatureComponent.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\IOnDamageBehavior.cs"/>
|
<Compile Include="Interfaces\GameObjects\IOnDamageBehavior.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs"/>
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Temperature\ITemperatureComponent.cs" />
|
<Compile Include="Interfaces\GameObjects\Components\Temperature\ITemperatureComponent.cs" />
|
||||||
<Compile Include="Interfaces\GameObjects\Components\Damage\IDamageableComponent.cs" />
|
<Compile Include="Interfaces\GameObjects\Components\Damage\IDamageableComponent.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -92,13 +100,13 @@
|
|||||||
<Name>SS14.Shared</Name>
|
<Name>SS14.Shared</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\SS14.Content.targets"/>
|
<Import Project="..\SS14.Content.targets" />
|
||||||
<Target Name="AfterBuild" DependsOnTargets="CopyContentAssemblies"/>
|
<Target Name="AfterBuild" DependsOnTargets="CopyContentAssemblies" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ContentAssemblies Include="$(OutputPath)Content.Server.dll"/>
|
<ContentAssemblies Include="$(OutputPath)Content.Server.dll" />
|
||||||
<ContentAssemblies Include="$(OutputPath)Content.Shared.dll"/>
|
<ContentAssemblies Include="$(OutputPath)Content.Shared.dll" />
|
||||||
<ContentAssemblies Include="$(OutputPath)Content.Server.pdb" Condition="'$(Configuration)' == 'Debug'"/>
|
<ContentAssemblies Include="$(OutputPath)Content.Server.pdb" Condition="'$(Configuration)' == 'Debug'" />
|
||||||
<ContentAssemblies Include="$(OutputPath)Content.Shared.pdb" Condition="'$(Configuration)' == 'Debug'"/>
|
<ContentAssemblies Include="$(OutputPath)Content.Shared.pdb" Condition="'$(Configuration)' == 'Debug'" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
using Content.Server.GameObjects;
|
using Content.Server.GameObjects;
|
||||||
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using SS14.Server;
|
using SS14.Server;
|
||||||
using SS14.Server.Interfaces;
|
using SS14.Server.Interfaces;
|
||||||
@@ -59,6 +60,12 @@ namespace Content.Server
|
|||||||
factory.Register<DestructibleComponent>();
|
factory.Register<DestructibleComponent>();
|
||||||
factory.Register<TemperatureComponent>();
|
factory.Register<TemperatureComponent>();
|
||||||
factory.Register<ServerDoorComponent>();
|
factory.Register<ServerDoorComponent>();
|
||||||
|
factory.Register<PowerTransferComponent>();
|
||||||
|
factory.Register<PowerProviderComponent>();
|
||||||
|
factory.Register<PowerNodeComponent>();
|
||||||
|
factory.Register<PowerStorageComponent>();
|
||||||
|
factory.Register<PowerDeviceComponent>();
|
||||||
|
factory.Register<PowerGeneratorComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
294
Content.Server/GameObjects/Components/Power/PowerDevice.cs
Normal file
294
Content.Server/GameObjects/Components/Power/PowerDevice.cs
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Component that requires power to function
|
||||||
|
/// </summary>
|
||||||
|
public class PowerDeviceComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PowerDevice";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method of draw we will try to use to place our load set via component parameter, defaults to using power providers
|
||||||
|
/// </summary>
|
||||||
|
public virtual DrawTypes Drawtype { get; protected set; } = DrawTypes.Provider;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The power draw method we are currently connected to and using
|
||||||
|
/// </summary>
|
||||||
|
public DrawTypes Connected { get; protected set; } = DrawTypes.None;
|
||||||
|
|
||||||
|
public bool _powered = false;
|
||||||
|
/// <summary>
|
||||||
|
/// Status indicator variable for powered
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool Powered
|
||||||
|
{
|
||||||
|
get => _powered;
|
||||||
|
set => SetPowered(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Priority for powernet draw, lower will draw first, defined in powernet.cs
|
||||||
|
/// </summary>
|
||||||
|
public virtual Powernet.Priority Priority { get; protected set; } = Powernet.Priority.Medium;
|
||||||
|
|
||||||
|
|
||||||
|
private float _load = 100; //arbitrary magic number to start
|
||||||
|
/// <summary>
|
||||||
|
/// Power load from this entity
|
||||||
|
/// </summary>
|
||||||
|
public float Load
|
||||||
|
{
|
||||||
|
get => _load;
|
||||||
|
set { UpdateLoad(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All the power providers that we are within range of
|
||||||
|
/// </summary>
|
||||||
|
public List<PowerProviderComponent> AvailableProviders = new List<PowerProviderComponent>();
|
||||||
|
|
||||||
|
|
||||||
|
private PowerProviderComponent _provider;
|
||||||
|
/// <summary>
|
||||||
|
/// A power provider that will handle our load, if we are linked to any
|
||||||
|
/// </summary>
|
||||||
|
public PowerProviderComponent Provider
|
||||||
|
{
|
||||||
|
get => _provider;
|
||||||
|
set {
|
||||||
|
Connected = DrawTypes.Provider;
|
||||||
|
if (_provider != null)
|
||||||
|
{
|
||||||
|
_provider.RemoveDevice(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(value != null)
|
||||||
|
{
|
||||||
|
_provider = value;
|
||||||
|
_provider.AddDevice(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Connected = DrawTypes.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnAdd(IEntity owner)
|
||||||
|
{
|
||||||
|
base.OnAdd(owner);
|
||||||
|
|
||||||
|
if (Drawtype == DrawTypes.Both || Drawtype == DrawTypes.Node)
|
||||||
|
{
|
||||||
|
if (!owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||||
|
node = factory.GetComponent<PowerNodeComponent>();
|
||||||
|
owner.AddComponent(node);
|
||||||
|
}
|
||||||
|
node.OnPowernetConnect += PowernetConnect;
|
||||||
|
node.OnPowernetDisconnect += PowernetDisconnect;
|
||||||
|
node.OnPowernetRegenerate += PowernetRegenerate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
if(node.Parent != null)
|
||||||
|
{
|
||||||
|
node.Parent.RemoveDevice(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.OnPowernetConnect -= PowernetConnect;
|
||||||
|
node.OnPowernetDisconnect -= PowernetDisconnect;
|
||||||
|
node.OnPowernetRegenerate -= PowernetRegenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadParameters(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
if (mapping.TryGetNode("Drawtype", out YamlNode node))
|
||||||
|
{
|
||||||
|
Drawtype = node.AsEnum<DrawTypes>();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("Load", out node))
|
||||||
|
{
|
||||||
|
Load = node.AsFloat();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("Priority", out node))
|
||||||
|
{
|
||||||
|
Priority = node.AsEnum<Powernet.Priority>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLoad(float value)
|
||||||
|
{
|
||||||
|
var oldLoad = _load;
|
||||||
|
_load = value;
|
||||||
|
if(Connected == DrawTypes.Node)
|
||||||
|
{
|
||||||
|
var node = Owner.GetComponent<PowerNodeComponent>();
|
||||||
|
node.Parent.UpdateDevice(this, oldLoad);
|
||||||
|
}
|
||||||
|
else if(Connected == DrawTypes.Provider)
|
||||||
|
{
|
||||||
|
Provider.UpdateDevice(this, oldLoad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes behavior when receiving a command to become powered or depowered
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public virtual void SetPowered(bool value)
|
||||||
|
{
|
||||||
|
//Let them set us to true
|
||||||
|
if (value == true)
|
||||||
|
{
|
||||||
|
_powered = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//A powernet has decided we will not be powered this tick, lets try to power ourselves
|
||||||
|
if (value == false && Owner.TryGetComponent(out PowerStorageComponent storage))
|
||||||
|
{
|
||||||
|
if (storage.CanDeductCharge(Load))
|
||||||
|
{
|
||||||
|
storage.DeductCharge(Load);
|
||||||
|
_powered = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//For some reason above we could not power ourselves, we depower
|
||||||
|
_powered = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a new power provider as a possible connection to this device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="provider"></param>
|
||||||
|
public void AddProvider(PowerProviderComponent provider)
|
||||||
|
{
|
||||||
|
AvailableProviders.Add(provider);
|
||||||
|
|
||||||
|
if(Connected != DrawTypes.Node)
|
||||||
|
{
|
||||||
|
ConnectToBestProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the nearest registered power provider and connect to it
|
||||||
|
/// </summary>
|
||||||
|
private void ConnectToBestProvider()
|
||||||
|
{
|
||||||
|
//Any values we can connect to or are we already connected to a node, cancel!
|
||||||
|
if (!AvailableProviders.Any() || Connected == DrawTypes.Node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Get the starting value for our loop
|
||||||
|
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||||
|
var bestprovider = AvailableProviders[0];
|
||||||
|
|
||||||
|
//If we are already connected to a power provider we need to do a loop to find the nearest one, otherwise skip it and use first entry
|
||||||
|
if (Connected == DrawTypes.Provider)
|
||||||
|
{
|
||||||
|
var bestdistance = (bestprovider.Owner.GetComponent<TransformComponent>().WorldPosition - position).LengthSquared;
|
||||||
|
|
||||||
|
foreach (var availprovider in AvailableProviders)
|
||||||
|
{
|
||||||
|
//Find distance to new provider
|
||||||
|
var distance = (availprovider.Owner.GetComponent<TransformComponent>().WorldPosition - position).LengthSquared;
|
||||||
|
|
||||||
|
//If new provider distance is shorter it becomes new best possible provider
|
||||||
|
if (distance < bestdistance)
|
||||||
|
{
|
||||||
|
bestdistance = distance;
|
||||||
|
bestprovider = availprovider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Provider != bestprovider)
|
||||||
|
Provider = bestprovider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a power provider from being a possible connection to this device
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="provider"></param>
|
||||||
|
public void RemoveProvider(PowerProviderComponent provider)
|
||||||
|
{
|
||||||
|
if (!AvailableProviders.Contains(provider))
|
||||||
|
return;
|
||||||
|
|
||||||
|
AvailableProviders.Remove(provider);
|
||||||
|
|
||||||
|
if (Connected != DrawTypes.Node)
|
||||||
|
{
|
||||||
|
ConnectToBestProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has become anchored to a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetConnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
//This sets connected = none so it must be first
|
||||||
|
Provider = null;
|
||||||
|
|
||||||
|
eventarg.Powernet.AddDevice(this);
|
||||||
|
Connected = DrawTypes.Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Powernet wire was remove so we need to regenerate the powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddDevice(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has become unanchored from a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.RemoveDevice(this);
|
||||||
|
Connected = DrawTypes.None;
|
||||||
|
|
||||||
|
ConnectToBestProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DrawTypes
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Node = 1,
|
||||||
|
Provider = 2,
|
||||||
|
Both = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using System;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Component that creates power and supplies it to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public class PowerGeneratorComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PowerGenerator";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Power supply from this entity
|
||||||
|
/// </summary>
|
||||||
|
private float _supply = 1000; //arbitrary initial magic number to start
|
||||||
|
public float Supply
|
||||||
|
{
|
||||||
|
get => _supply;
|
||||||
|
set { UpdateSupply(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadParameters(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
if (mapping.TryGetNode("Supply", out YamlNode node))
|
||||||
|
{
|
||||||
|
Supply = node.AsFloat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnAdd(IEntity owner)
|
||||||
|
{
|
||||||
|
base.OnAdd(owner);
|
||||||
|
|
||||||
|
if (!owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||||
|
node = factory.GetComponent<PowerNodeComponent>();
|
||||||
|
owner.AddComponent(node);
|
||||||
|
}
|
||||||
|
node.OnPowernetConnect += PowernetConnect;
|
||||||
|
node.OnPowernetDisconnect += PowernetDisconnect;
|
||||||
|
node.OnPowernetRegenerate += PowernetRegenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
if (node.Parent != null)
|
||||||
|
{
|
||||||
|
node.Parent.RemoveGenerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.OnPowernetConnect -= PowernetConnect;
|
||||||
|
node.OnPowernetDisconnect -= PowernetDisconnect;
|
||||||
|
node.OnPowernetRegenerate -= PowernetRegenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSupply(float value)
|
||||||
|
{
|
||||||
|
_supply = value;
|
||||||
|
var node = Owner.GetComponent<PowerNodeComponent>();
|
||||||
|
node.Parent.UpdateGenerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has become anchored to a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetConnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddGenerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has had its powernet regenerated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddGenerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has become unanchored from a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.RemoveGenerator(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Component that connects to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public class PowerNodeComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PowerNode";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The powernet this node is connected to
|
||||||
|
/// </summary>
|
||||||
|
public Powernet Parent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An event handling when this node connects to a powernet
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PowernetEventArgs> OnPowernetConnect;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An event handling when this node disconnects from a powernet
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PowernetEventArgs> OnPowernetDisconnect;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An event that registers us to a regenerating powernet
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PowernetEventArgs> OnPowernetRegenerate;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
TryCreatePowernetConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
DisconnectFromPowernet();
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find a nearby wire which will have a powernet and connect ourselves to its powernet
|
||||||
|
/// </summary>
|
||||||
|
public void TryCreatePowernetConnection()
|
||||||
|
{
|
||||||
|
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||||
|
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||||
|
var wires = _emanager.GetEntitiesIntersecting(Owner)
|
||||||
|
.Where(x => x.HasComponent<PowerTransferComponent>())
|
||||||
|
.OrderByDescending(x => (x.GetComponent<TransformComponent>().WorldPosition - position).Length);
|
||||||
|
var choose = wires.FirstOrDefault();
|
||||||
|
if(choose != null)
|
||||||
|
ConnectToPowernet(choose.GetComponent<PowerTransferComponent>().Parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers event telling power components that we connected to a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="toconnect"></param>
|
||||||
|
public void ConnectToPowernet(Powernet toconnect)
|
||||||
|
{
|
||||||
|
Parent = toconnect;
|
||||||
|
Parent.Nodelist.Add(this);
|
||||||
|
OnPowernetConnect?.Invoke(this, new PowernetEventArgs(Parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers event telling power components that we haven't disconnected but have readded ourselves to a regenerated powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="toconnect"></param>
|
||||||
|
public void RegeneratePowernet(Powernet toconnect)
|
||||||
|
{
|
||||||
|
//This removes the device from things that will be powernet disconnected when dirty powernet is killed
|
||||||
|
Parent.Nodelist.Remove(this);
|
||||||
|
|
||||||
|
Parent = toconnect;
|
||||||
|
Parent.Nodelist.Add(this);
|
||||||
|
OnPowernetRegenerate?.Invoke(this, new PowernetEventArgs(Parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers event telling power components we have exited any powernets
|
||||||
|
/// </summary>
|
||||||
|
public void DisconnectFromPowernet()
|
||||||
|
{
|
||||||
|
Parent.Nodelist.Remove(this);
|
||||||
|
OnPowernetDisconnect?.Invoke(this, new PowernetEventArgs(Parent));
|
||||||
|
Parent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PowernetEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public PowernetEventArgs(Powernet powernet)
|
||||||
|
{
|
||||||
|
Powernet = powernet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Powernet Powernet { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Component that wirelessly connects and powers devices, connects to powernet via node and can be combined with internal storage component
|
||||||
|
/// </summary>
|
||||||
|
public class PowerProviderComponent : PowerDeviceComponent
|
||||||
|
{
|
||||||
|
public override string Name => "PowerProvider";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DrawTypes Drawtype { get; protected set; } = DrawTypes.Node;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Variable that determines the range that the power provider will try to supply power to
|
||||||
|
/// </summary>
|
||||||
|
public int PowerRange { get; private set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List storing all the power devices that we are currently providing power to
|
||||||
|
/// </summary>
|
||||||
|
public SortedSet<PowerDeviceComponent> Deviceloadlist = new SortedSet<PowerDeviceComponent>(new Powernet.DevicePriorityCompare());
|
||||||
|
|
||||||
|
public List<PowerDeviceComponent> DepoweredDevices = new List<PowerDeviceComponent>();
|
||||||
|
|
||||||
|
public override Powernet.Priority Priority { get; protected set; } = Powernet.Priority.Provider;
|
||||||
|
|
||||||
|
public override void LoadParameters(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
if (mapping.TryGetNode("Range", out YamlNode node))
|
||||||
|
{
|
||||||
|
PowerRange = node.AsInt();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("Priority", out node))
|
||||||
|
{
|
||||||
|
Priority = node.AsEnum<Powernet.Priority>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void SetPowered(bool value)
|
||||||
|
{
|
||||||
|
//Let them set us true, we must now power all the devices that rely on us for energy
|
||||||
|
if (value == true)
|
||||||
|
{
|
||||||
|
PowerAllDevices();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//A powernet has decided we will not be powered this tick, lets try to power ourselves
|
||||||
|
if (value == false && Owner.TryGetComponent(out PowerStorageComponent storage))
|
||||||
|
{
|
||||||
|
//Can the storage cover powering all our devices and us? If so power all
|
||||||
|
if (storage.CanDeductCharge(Load))
|
||||||
|
{
|
||||||
|
storage.DeductCharge(Load);
|
||||||
|
_powered = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Does the storage even have any power to give us? If so power as much as we can
|
||||||
|
else if (storage.RequestAllCharge() != 0)
|
||||||
|
{
|
||||||
|
var depowervalue = storage.RequestAllCharge() - Load;
|
||||||
|
_powered = true;
|
||||||
|
//See code in powernet for same functionality
|
||||||
|
foreach (var device in Deviceloadlist)
|
||||||
|
{
|
||||||
|
device.Powered = false;
|
||||||
|
DepoweredDevices.Add(device);
|
||||||
|
depowervalue -= device.Load;
|
||||||
|
if (depowervalue < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Storage doesn't have anything, depower everything
|
||||||
|
else if(storage.RequestAllCharge() == 0)
|
||||||
|
{
|
||||||
|
DepowerAllDevices();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//For some reason above we could not power ourselves, we depower ourselves and all devices
|
||||||
|
DepowerAllDevices();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PowerAllDevices()
|
||||||
|
{
|
||||||
|
_powered = true;
|
||||||
|
foreach (var device in DepoweredDevices)
|
||||||
|
{
|
||||||
|
device.Powered = true;
|
||||||
|
}
|
||||||
|
DepoweredDevices.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DepowerAllDevices()
|
||||||
|
{
|
||||||
|
_powered = false;
|
||||||
|
foreach (var device in DepoweredDevices)
|
||||||
|
{
|
||||||
|
device.Powered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PowernetConnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddDevice(this);
|
||||||
|
Connected = DrawTypes.Node;
|
||||||
|
|
||||||
|
//Find devices within range to take under our control
|
||||||
|
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||||
|
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||||
|
var entities = _emanager.GetEntitiesInRange(Owner, PowerRange)
|
||||||
|
.Where(x => x.HasComponent<PowerDeviceComponent>());
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var entity in entities)
|
||||||
|
{
|
||||||
|
var device = entity.GetComponent<PowerDeviceComponent>();
|
||||||
|
|
||||||
|
//Make sure the device can accept power providers to give it power
|
||||||
|
if (device.Drawtype == DrawTypes.Provider || device.Drawtype == DrawTypes.Both)
|
||||||
|
{
|
||||||
|
device.AddProvider(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddDevice(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.RemoveDevice(this);
|
||||||
|
Connected = DrawTypes.None;
|
||||||
|
|
||||||
|
//We don't want to make the devices under us think we're still a valid provider if we have no powernet to connect to
|
||||||
|
foreach (var device in Deviceloadlist)
|
||||||
|
{
|
||||||
|
device.RemoveProvider(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a continuous load from a device connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void AddDevice(PowerDeviceComponent device)
|
||||||
|
{
|
||||||
|
Deviceloadlist.Add(device);
|
||||||
|
Load += device.Load;
|
||||||
|
if (!device.Powered)
|
||||||
|
DepoweredDevices.Add(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update one of the loads from a deviceconnected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateDevice(PowerDeviceComponent device, float oldLoad)
|
||||||
|
{
|
||||||
|
if (Deviceloadlist.Contains(device))
|
||||||
|
{
|
||||||
|
Load -= oldLoad;
|
||||||
|
Load += device.Load;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a continuous load from a device connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveDevice(PowerDeviceComponent device)
|
||||||
|
{
|
||||||
|
if (Deviceloadlist.Contains(device))
|
||||||
|
{
|
||||||
|
Load -= device.Load;
|
||||||
|
Deviceloadlist.Remove(device);
|
||||||
|
if (DepoweredDevices.Contains(device))
|
||||||
|
DepoweredDevices.Remove(device);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var name = device.Owner.Prototype.Name;
|
||||||
|
Logger.Log(String.Format("We tried to remove a device twice from the same {0} somehow, prototype {1}", Name, name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using System;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Feeds energy from the powernet and may have the ability to supply back into it
|
||||||
|
/// </summary>
|
||||||
|
public class PowerStorageComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PowerStorage";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum amount of energy the internal battery can store
|
||||||
|
/// </summary>
|
||||||
|
public float Capacity { get; private set; } = 10000; //arbitrary value replace
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Energy the battery is currently storing
|
||||||
|
/// </summary>
|
||||||
|
public float Charge { get; private set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rate at which energy will be taken to charge internal battery
|
||||||
|
/// </summary>
|
||||||
|
public float ChargeRate { get; private set; } = 1000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rate at which energy will be distributed to the powernet if needed
|
||||||
|
/// </summary>
|
||||||
|
public float DistributionRate { get; private set; } = 1000;
|
||||||
|
|
||||||
|
private bool _chargepowernet = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do we distribute power into the powernet from our stores if the powernet requires it?
|
||||||
|
/// </summary>
|
||||||
|
public bool ChargePowernet
|
||||||
|
{
|
||||||
|
get => _chargepowernet;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_chargepowernet = value;
|
||||||
|
if (Owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
if (node.Parent != null)
|
||||||
|
node.Parent.UpdateStorageType(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void LoadParameters(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
if (mapping.TryGetNode("Capacity", out YamlNode node))
|
||||||
|
{
|
||||||
|
Capacity = node.AsFloat();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("Charge", out node))
|
||||||
|
{
|
||||||
|
Charge = node.AsFloat();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("ChargeRate", out node))
|
||||||
|
{
|
||||||
|
ChargeRate = node.AsFloat();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("DistributionRate", out node))
|
||||||
|
{
|
||||||
|
DistributionRate = node.AsFloat();
|
||||||
|
}
|
||||||
|
if (mapping.TryGetNode("ChargePowernet", out node))
|
||||||
|
{
|
||||||
|
_chargepowernet = node.AsBool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnAdd(IEntity owner)
|
||||||
|
{
|
||||||
|
base.OnAdd(owner);
|
||||||
|
|
||||||
|
if (!owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||||
|
node = factory.GetComponent<PowerNodeComponent>();
|
||||||
|
owner.AddComponent(node);
|
||||||
|
}
|
||||||
|
node.OnPowernetConnect += PowernetConnect;
|
||||||
|
node.OnPowernetDisconnect += PowernetDisconnect;
|
||||||
|
node.OnPowernetRegenerate += PowernetRegenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
if (Owner.TryGetComponent(out PowerNodeComponent node))
|
||||||
|
{
|
||||||
|
if (node.Parent != null)
|
||||||
|
{
|
||||||
|
node.Parent.RemovePowerStorage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.OnPowernetConnect -= PowernetConnect;
|
||||||
|
node.OnPowernetDisconnect -= PowernetDisconnect;
|
||||||
|
node.OnPowernetRegenerate -= PowernetRegenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the storage can supply the amount of charge directly requested
|
||||||
|
/// </summary>
|
||||||
|
public bool CanDeductCharge(float todeduct)
|
||||||
|
{
|
||||||
|
if (Charge > todeduct)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deducts the requested charge from the energy storage
|
||||||
|
/// </summary>
|
||||||
|
public void DeductCharge(float todeduct)
|
||||||
|
{
|
||||||
|
Charge = Math.Min(0, Charge - todeduct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns all possible charge available from the energy storage
|
||||||
|
/// </summary>
|
||||||
|
public float RequestAllCharge()
|
||||||
|
{
|
||||||
|
return Math.Min(ChargeRate, Capacity - Charge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the charge available from the energy storage
|
||||||
|
/// </summary>
|
||||||
|
public float RequestCharge()
|
||||||
|
{
|
||||||
|
return Math.Min(ChargeRate, Capacity - Charge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the charge available from the energy storage
|
||||||
|
/// </summary>
|
||||||
|
public float AvailableCharge()
|
||||||
|
{
|
||||||
|
return Math.Min(DistributionRate, Charge);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gives the storage one full tick of charging its energy storage
|
||||||
|
/// </summary>
|
||||||
|
public void ChargePowerTick()
|
||||||
|
{
|
||||||
|
Charge = Math.Max(Charge + ChargeRate, Capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Takes from the storage one full tick of energy
|
||||||
|
/// </summary>
|
||||||
|
public void RetrievePassiveStorage()
|
||||||
|
{
|
||||||
|
Charge = Math.Min(Charge - DistributionRate, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has become anchored to a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetConnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddPowerStorage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has had its powernet regenerated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.AddPowerStorage(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Node has become unanchored from a powernet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="eventarg"></param>
|
||||||
|
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
|
||||||
|
{
|
||||||
|
eventarg.Powernet.RemovePowerStorage(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Component to transfer power to nearby components, can create powernets and connect to nodes
|
||||||
|
/// </summary>
|
||||||
|
public class PowerTransferComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PowerTransfer";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The powernet this component is connected to
|
||||||
|
/// </summary>
|
||||||
|
public Powernet Parent;
|
||||||
|
|
||||||
|
public bool Regenerating { get; set; } = false;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
if(Parent == null)
|
||||||
|
{
|
||||||
|
SpreadPowernet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
DisconnectFromPowernet();
|
||||||
|
|
||||||
|
base.OnRemove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Searches for local powernets to connect to, otherwise creates its own, and spreads powernet to nearby entities
|
||||||
|
/// </summary>
|
||||||
|
public void SpreadPowernet()
|
||||||
|
{
|
||||||
|
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||||
|
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||||
|
var wires = _emanager.GetEntitiesInRange(Owner, 0.1f) //arbitrarily low, just scrape things //wip
|
||||||
|
.Where(x => x.HasComponent<PowerTransferComponent>());
|
||||||
|
|
||||||
|
//we have no parent so lets find a partner we can join his powernet
|
||||||
|
if(Parent == null || Regenerating)
|
||||||
|
{
|
||||||
|
foreach (var wire in wires)
|
||||||
|
{
|
||||||
|
var ptc = wire.GetComponent<PowerTransferComponent>();
|
||||||
|
if (ptc.CanConnectTo())
|
||||||
|
{
|
||||||
|
ConnectToPowernet(ptc.Parent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//we couldn't find a partner so none must have spread yet, lets make our own powernet to spread
|
||||||
|
if (Parent == null || Regenerating)
|
||||||
|
{
|
||||||
|
var powernew = new Powernet();
|
||||||
|
ConnectToPowernet(powernew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find nodes intersecting us and if not already assigned to a powernet assign them to us
|
||||||
|
var nodes = _emanager.GetEntitiesIntersecting(Owner)
|
||||||
|
.Where(x => x.HasComponent<PowerNodeComponent>())
|
||||||
|
.Select(x => x.GetComponent<PowerNodeComponent>());
|
||||||
|
|
||||||
|
foreach(var node in nodes)
|
||||||
|
{
|
||||||
|
if(node.Parent == null)
|
||||||
|
{
|
||||||
|
node.ConnectToPowernet(Parent);
|
||||||
|
}
|
||||||
|
else if(node.Parent.Dirty)
|
||||||
|
{
|
||||||
|
node.RegeneratePowernet(Parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//spread powernet to nearby wires which haven't got one yet, and tell them to spread as well
|
||||||
|
foreach (var wire in wires)
|
||||||
|
{
|
||||||
|
var ptc = wire.GetComponent<PowerTransferComponent>();
|
||||||
|
if (ptc.Parent == null || Regenerating)
|
||||||
|
{
|
||||||
|
ptc.ConnectToPowernet(Parent);
|
||||||
|
SpreadPowernet();
|
||||||
|
}
|
||||||
|
else if(ptc.Parent != Parent && !ptc.Parent.Dirty)
|
||||||
|
{
|
||||||
|
Parent.MergePowernets(ptc.Parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when connecting to a new powernet, either on creation or on regeneration
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="toconnect"></param>
|
||||||
|
public void ConnectToPowernet(Powernet toconnect)
|
||||||
|
{
|
||||||
|
Parent = toconnect;
|
||||||
|
Parent.Wirelist.Add(this);
|
||||||
|
Regenerating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when we are removed and telling the powernet that it is now dirty and must regenerate
|
||||||
|
/// </summary>
|
||||||
|
public void DisconnectFromPowernet()
|
||||||
|
{
|
||||||
|
Parent.Wirelist.Remove(this);
|
||||||
|
Parent.Dirty = true;
|
||||||
|
Parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool CanConnectTo()
|
||||||
|
{
|
||||||
|
return Parent != null && Parent.Dirty == false && !Regenerating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
402
Content.Server/GameObjects/Components/Power/Powernet.cs
Normal file
402
Content.Server/GameObjects/Components/Power/Powernet.cs
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Master class for group of powertransfercomponents, takes in and distributes power via nodes
|
||||||
|
/// </summary>
|
||||||
|
public class Powernet
|
||||||
|
{
|
||||||
|
public Powernet()
|
||||||
|
{
|
||||||
|
var EntitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
||||||
|
EntitySystemManager.GetEntitySystem<PowerSystem>().Powernets.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The entities that make up the powernet's physical location and allow powernet connection
|
||||||
|
/// </summary>
|
||||||
|
public List<PowerTransferComponent> Wirelist { get; set; } = new List<PowerTransferComponent>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entities that connect directly to the powernet through PTC above to add power or add power load
|
||||||
|
/// </summary>
|
||||||
|
public List<PowerNodeComponent> Nodelist { get; set; } = new List<PowerNodeComponent>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subset of nodelist that adds a continuous power supply to the network
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<PowerGeneratorComponent, float> Generatorlist { get; set; } = new Dictionary<PowerGeneratorComponent, float>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Subset of nodelist that draw power, stores information on current continuous powernet load
|
||||||
|
/// </summary>
|
||||||
|
public SortedSet<PowerDeviceComponent> Deviceloadlist { get; set; } = new SortedSet<PowerDeviceComponent>(new DevicePriorityCompare());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Comparer that keeps the device dictionary sorted by powernet priority
|
||||||
|
/// </summary>
|
||||||
|
public class DevicePriorityCompare : IComparer<PowerDeviceComponent>
|
||||||
|
{
|
||||||
|
public int Compare(PowerDeviceComponent x, PowerDeviceComponent y)
|
||||||
|
{
|
||||||
|
int compare = y.Priority.CompareTo(x.Priority);
|
||||||
|
|
||||||
|
//If the comparer returns 0 sortedset will believe it is a duplicate and return 0, so return 1 instead
|
||||||
|
if (compare == 0 && !x.Equals(y))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return compare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Priority that a device will receive power if powernet cannot supply every device
|
||||||
|
/// </summary>
|
||||||
|
public enum Priority
|
||||||
|
{
|
||||||
|
Necessary,
|
||||||
|
High,
|
||||||
|
Medium,
|
||||||
|
Low,
|
||||||
|
Provider,
|
||||||
|
Unnecessary
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All the devices that have been depowered by this powernet or depowered prior to being absorted into this powernet
|
||||||
|
/// </summary>
|
||||||
|
public List<PowerDeviceComponent> DepoweredDevices { get; set; } = new List<PowerDeviceComponent>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of the energy storage components that will feed the powernet if necessary, and if there is enough power feed itself
|
||||||
|
/// </summary>
|
||||||
|
public List<PowerStorageComponent> PowerStorageSupplierlist { get; set; } = new List<PowerStorageComponent>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of energy storage components that will never feed the powernet, will try to draw energy to feed themselves if possible
|
||||||
|
/// </summary>
|
||||||
|
public List<PowerStorageComponent> PowerStorageConsumerlist { get; set; } = new List<PowerStorageComponent>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Static counter of all continuous load placed from devices on this power network
|
||||||
|
/// </summary>
|
||||||
|
public float Load { get; private set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Static counter of all continiuous supply from generators on this power network
|
||||||
|
/// </summary>
|
||||||
|
public float Supply { get; private set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Variable that causes powernet to be regenerated from its wires during the next update cycle
|
||||||
|
/// </summary>
|
||||||
|
public bool Dirty { get; set; } = false;
|
||||||
|
|
||||||
|
public void Update(float frametime)
|
||||||
|
{
|
||||||
|
float activesupply = Supply;
|
||||||
|
float activeload = Load;
|
||||||
|
|
||||||
|
float storagedemand = 0;
|
||||||
|
|
||||||
|
foreach (var supply in PowerStorageConsumerlist)
|
||||||
|
{
|
||||||
|
storagedemand += supply.RequestCharge();
|
||||||
|
}
|
||||||
|
|
||||||
|
float passivesupply = 0;
|
||||||
|
float passivedemand = 0;
|
||||||
|
|
||||||
|
foreach (var supply in PowerStorageSupplierlist)
|
||||||
|
{
|
||||||
|
passivesupply += supply.AvailableCharge();
|
||||||
|
passivedemand += supply.RequestCharge();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//If we have enough power to feed all load and storage demand, then feed everything
|
||||||
|
if (activesupply > activeload + storagedemand + passivedemand)
|
||||||
|
{
|
||||||
|
PowerAllDevices();
|
||||||
|
ChargeActiveStorage();
|
||||||
|
ChargePassiveStorage();
|
||||||
|
}
|
||||||
|
//We don't have enough power for the storage powernet suppliers, ignore powering them
|
||||||
|
else if (activesupply > activeload + storagedemand)
|
||||||
|
{
|
||||||
|
PowerAllDevices();
|
||||||
|
ChargeActiveStorage();
|
||||||
|
}
|
||||||
|
//We require the storage powernet suppliers to power the remaining storage components and device load
|
||||||
|
else if (activesupply + passivesupply > activeload + storagedemand)
|
||||||
|
{
|
||||||
|
PowerAllDevices();
|
||||||
|
ChargeActiveStorage();
|
||||||
|
RetrievePassiveStorage();
|
||||||
|
}
|
||||||
|
//We cant afford to fund the storage components, so lets try to power the basic load using our supply and storage supply
|
||||||
|
else if (activesupply + passivesupply > activeload)
|
||||||
|
{
|
||||||
|
PowerAllDevices();
|
||||||
|
RetrievePassiveStorage();
|
||||||
|
}
|
||||||
|
//We cant even cover the basic device load, start disabling devices in order of priority until the remaining load is lowered enough to be met
|
||||||
|
else if (activesupply + passivesupply < activeload)
|
||||||
|
{
|
||||||
|
PowerAllDevices(); //This merely makes our inevitable betrayal all the sweeter
|
||||||
|
RetrievePassiveStorage();
|
||||||
|
|
||||||
|
var depowervalue = activeload - (activesupply + passivesupply);
|
||||||
|
|
||||||
|
//Providers use same method to recreate functionality
|
||||||
|
foreach(var device in Deviceloadlist)
|
||||||
|
{
|
||||||
|
device.Powered = false;
|
||||||
|
DepoweredDevices.Add(device);
|
||||||
|
depowervalue -= device.Load;
|
||||||
|
if (depowervalue < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PowerAllDevices()
|
||||||
|
{
|
||||||
|
foreach(var device in DepoweredDevices)
|
||||||
|
{
|
||||||
|
device.Powered = true;
|
||||||
|
}
|
||||||
|
DepoweredDevices.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChargeActiveStorage()
|
||||||
|
{
|
||||||
|
foreach (var storage in PowerStorageConsumerlist)
|
||||||
|
{
|
||||||
|
storage.ChargePowerTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChargePassiveStorage()
|
||||||
|
{
|
||||||
|
foreach (var storage in PowerStorageSupplierlist)
|
||||||
|
{
|
||||||
|
storage.ChargePowerTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RetrievePassiveStorage()
|
||||||
|
{
|
||||||
|
foreach (var storage in PowerStorageSupplierlist)
|
||||||
|
{
|
||||||
|
storage.ChargePowerTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Kills a powernet after it is marked dirty and its component have already been regenerated by the powernet system
|
||||||
|
/// </summary>
|
||||||
|
public void DirtyKill()
|
||||||
|
{
|
||||||
|
Wirelist.Clear();
|
||||||
|
while(Nodelist.Count != 0)
|
||||||
|
{
|
||||||
|
Nodelist[0].DisconnectFromPowernet();
|
||||||
|
}
|
||||||
|
Generatorlist.Clear();
|
||||||
|
Deviceloadlist.Clear();
|
||||||
|
DepoweredDevices.Clear();
|
||||||
|
PowerStorageSupplierlist.Clear();
|
||||||
|
PowerStorageConsumerlist.Clear();
|
||||||
|
|
||||||
|
RemoveFromSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Combines two powernets when they connect via powertransfer components
|
||||||
|
/// </summary>
|
||||||
|
public void MergePowernets(Powernet toMerge)
|
||||||
|
{
|
||||||
|
//TODO: load balance reconciliation between powernets on merge tick here
|
||||||
|
|
||||||
|
foreach (var wire in toMerge.Wirelist)
|
||||||
|
{
|
||||||
|
wire.Parent = this;
|
||||||
|
}
|
||||||
|
Wirelist.AddRange(toMerge.Wirelist);
|
||||||
|
toMerge.Wirelist.Clear();
|
||||||
|
|
||||||
|
foreach (var node in toMerge.Nodelist)
|
||||||
|
{
|
||||||
|
node.Parent = this;
|
||||||
|
}
|
||||||
|
Nodelist.AddRange(toMerge.Nodelist);
|
||||||
|
toMerge.Nodelist.Clear();
|
||||||
|
|
||||||
|
foreach (var generator in toMerge.Generatorlist)
|
||||||
|
{
|
||||||
|
Generatorlist.Add(generator.Key, generator.Value);
|
||||||
|
}
|
||||||
|
toMerge.Generatorlist.Clear();
|
||||||
|
|
||||||
|
foreach (var device in toMerge.Deviceloadlist)
|
||||||
|
{
|
||||||
|
Deviceloadlist.Add(device);
|
||||||
|
}
|
||||||
|
toMerge.Deviceloadlist.Clear();
|
||||||
|
|
||||||
|
DepoweredDevices.AddRange(toMerge.DepoweredDevices);
|
||||||
|
toMerge.DepoweredDevices.Clear();
|
||||||
|
|
||||||
|
PowerStorageSupplierlist.AddRange(toMerge.PowerStorageSupplierlist);
|
||||||
|
toMerge.PowerStorageSupplierlist.Clear();
|
||||||
|
|
||||||
|
PowerStorageConsumerlist.AddRange(toMerge.PowerStorageConsumerlist);
|
||||||
|
toMerge.PowerStorageConsumerlist.Clear();
|
||||||
|
|
||||||
|
toMerge.RemoveFromSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes reference from the powernets list on the powernet system
|
||||||
|
/// </summary>
|
||||||
|
private void RemoveFromSystem()
|
||||||
|
{
|
||||||
|
var EntitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
|
||||||
|
EntitySystemManager.GetEntitySystem<PowerSystem>().Powernets.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Registration
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a continuous load from a device connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void AddDevice(PowerDeviceComponent device)
|
||||||
|
{
|
||||||
|
Deviceloadlist.Add(device);
|
||||||
|
Load += device.Load;
|
||||||
|
if (!device.Powered)
|
||||||
|
DepoweredDevices.Add(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update one of the loads from a deviceconnected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateDevice(PowerDeviceComponent device, float oldLoad)
|
||||||
|
{
|
||||||
|
if(Deviceloadlist.Contains(device))
|
||||||
|
{
|
||||||
|
Load -= oldLoad;
|
||||||
|
Load += device.Load;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a continuous load from a device connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveDevice(PowerDeviceComponent device)
|
||||||
|
{
|
||||||
|
if(Deviceloadlist.Contains(device))
|
||||||
|
{
|
||||||
|
Load -= device.Load;
|
||||||
|
Deviceloadlist.Remove(device);
|
||||||
|
if (DepoweredDevices.Contains(device))
|
||||||
|
DepoweredDevices.Remove(device);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var name = device.Owner.Prototype.Name;
|
||||||
|
Logger.Log(String.Format("We tried to remove a device twice from the same powernet somehow, prototype {0}", name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a power supply from a generator connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void AddGenerator(PowerGeneratorComponent generator)
|
||||||
|
{
|
||||||
|
Generatorlist.Add(generator, generator.Supply);
|
||||||
|
Supply += generator.Supply;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the value supplied from a generator connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateGenerator(PowerGeneratorComponent generator)
|
||||||
|
{
|
||||||
|
if (Generatorlist.ContainsKey(generator))
|
||||||
|
{
|
||||||
|
Supply -= Generatorlist[generator];
|
||||||
|
Generatorlist[generator] = generator.Supply;
|
||||||
|
Supply += generator.Supply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a power supply from a generator connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void RemoveGenerator(PowerGeneratorComponent generator)
|
||||||
|
{
|
||||||
|
if (Generatorlist.ContainsKey(generator))
|
||||||
|
{
|
||||||
|
Supply -= Generatorlist[generator];
|
||||||
|
Generatorlist.Remove(generator);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var name = generator.Owner.Prototype.Name;
|
||||||
|
Logger.Log(String.Format("We tried to remove a device twice from the same power somehow, prototype {1}", name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register a power supply from a generator connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void AddPowerStorage(PowerStorageComponent storage)
|
||||||
|
{
|
||||||
|
if(storage.ChargePowernet)
|
||||||
|
PowerStorageSupplierlist.Add(storage);
|
||||||
|
else
|
||||||
|
PowerStorageConsumerlist.Add(storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//How do I even call this? TODO: fix
|
||||||
|
public void UpdateStorageType(PowerStorageComponent storage)
|
||||||
|
{
|
||||||
|
//If our chargepowernet settings change we need to tell the powernet of this new setting and remove traces of our old setting
|
||||||
|
if (PowerStorageSupplierlist.Contains(storage))
|
||||||
|
PowerStorageSupplierlist.Remove(storage);
|
||||||
|
if (PowerStorageConsumerlist.Contains(storage))
|
||||||
|
PowerStorageConsumerlist.Remove(storage);
|
||||||
|
|
||||||
|
//Apply new setting
|
||||||
|
if (storage.ChargePowernet)
|
||||||
|
PowerStorageSupplierlist.Add(storage);
|
||||||
|
else
|
||||||
|
PowerStorageConsumerlist.Add(storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a power supply from a generator connected to the powernet
|
||||||
|
/// </summary>
|
||||||
|
public void RemovePowerStorage(PowerStorageComponent storage)
|
||||||
|
{
|
||||||
|
if (PowerStorageSupplierlist.Contains(storage))
|
||||||
|
{
|
||||||
|
PowerStorageSupplierlist.Remove(storage);
|
||||||
|
}
|
||||||
|
if (PowerStorageConsumerlist.Contains(storage))
|
||||||
|
{
|
||||||
|
PowerStorageSupplierlist.Remove(storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion Registration
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Content.Server/GameObjects/EntitySystems/PowerSystem.cs
Normal file
47
Content.Server/GameObjects/EntitySystems/PowerSystem.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using Content.Server.GameObjects.Components.Power;
|
||||||
|
using SS14.Shared.GameObjects.System;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Content.Shared.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
public class PowerSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public List<Powernet> Powernets = new List<Powernet>();
|
||||||
|
|
||||||
|
public override void Update(float frametime)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Powernets.Count; i++)
|
||||||
|
{
|
||||||
|
var powernet = Powernets[i];
|
||||||
|
if (powernet.Dirty)
|
||||||
|
{
|
||||||
|
//Tell all the wires of this net to be prepared to create/join new powernets
|
||||||
|
foreach (var wire in powernet.Wirelist)
|
||||||
|
{
|
||||||
|
wire.Regenerating = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var wire in powernet.Wirelist)
|
||||||
|
{
|
||||||
|
//Only a few wires should pass this if check since each will create and take all the others into its powernet
|
||||||
|
if (wire.Regenerating)
|
||||||
|
wire.SpreadPowernet();
|
||||||
|
}
|
||||||
|
|
||||||
|
//At this point all wires will have found/joined new powernet, all capable nodes will have joined them as well and removed themselves from nodelist
|
||||||
|
powernet.DirtyKill();
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var powernet in Powernets)
|
||||||
|
{
|
||||||
|
powernet.Update(frametime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,14 +4,15 @@
|
|||||||
components:
|
components:
|
||||||
- type: Transform
|
- type: Transform
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
|
- type: BoundingBox
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
drawdepth: FloorPlaceable
|
drawdepth: FloorPlaceable
|
||||||
color: Red
|
color: Red
|
||||||
sprites:
|
sprites:
|
||||||
- eightdirwire
|
- eightdirwire
|
||||||
|
|
||||||
- type: Icon
|
- type: Icon
|
||||||
icon: eightdirwire
|
icon: eightdirwire
|
||||||
|
- type: PowerTransfer
|
||||||
|
|
||||||
snap:
|
snap:
|
||||||
- Wire
|
- Wire
|
||||||
@@ -22,4 +23,104 @@
|
|||||||
name: BlueWire
|
name: BlueWire
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
color: Blue
|
color: Blue
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: Generator
|
||||||
|
name: Generator
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Clickable
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Sprite
|
||||||
|
drawdepth: FloorPlaceable
|
||||||
|
sprites:
|
||||||
|
- generator
|
||||||
|
- type: Icon
|
||||||
|
icon: generator
|
||||||
|
- type: PowerGenerator
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: WPPnobattery
|
||||||
|
name: WPPnobattery
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Clickable
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Sprite
|
||||||
|
drawdepth: FloorPlaceable
|
||||||
|
sprites:
|
||||||
|
- provider
|
||||||
|
- type: Icon
|
||||||
|
icon: provider
|
||||||
|
- type: PowerProvider
|
||||||
|
Range: 5
|
||||||
|
Priority: Provider
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: WPPnobattery
|
||||||
|
id: WPP
|
||||||
|
name: WPP
|
||||||
|
components:
|
||||||
|
- type: PowerStorage
|
||||||
|
Capacity: 1000
|
||||||
|
Charge: 1000
|
||||||
|
ChargeRate: 200
|
||||||
|
ChargePowernet: false
|
||||||
|
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SMES
|
||||||
|
name: SMES
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Clickable
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Sprite
|
||||||
|
drawdepth: FloorPlaceable
|
||||||
|
sprites:
|
||||||
|
- storage
|
||||||
|
- type: Icon
|
||||||
|
icon: storage
|
||||||
|
- type: PowerStorage
|
||||||
|
Capacity: 3000
|
||||||
|
Charge: 1000
|
||||||
|
ChargeRate: 200
|
||||||
|
DistributionRate: 400
|
||||||
|
ChargePowernet: true
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: WiredMachine
|
||||||
|
name: WiredMachine
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Clickable
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Sprite
|
||||||
|
drawdepth: FloorPlaceable
|
||||||
|
sprites:
|
||||||
|
- wiredmachine
|
||||||
|
- type: Icon
|
||||||
|
icon: wiredmachine
|
||||||
|
- type: PowerDevice
|
||||||
|
Drawtype: Node
|
||||||
|
Load: 100
|
||||||
|
Priority: High
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: WirelessMachine
|
||||||
|
name: WirelessMachine
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Clickable
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Sprite
|
||||||
|
drawdepth: FloorPlaceable
|
||||||
|
sprites:
|
||||||
|
- wirelessmachine
|
||||||
|
- type: Icon
|
||||||
|
icon: wirelessmachine
|
||||||
|
- type: PowerDevice
|
||||||
|
Drawtype: Both
|
||||||
|
Load: 200
|
||||||
|
Priority: Low
|
||||||
BIN
Resources/textures/Objects/generator.png
Normal file
BIN
Resources/textures/Objects/generator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 452 B |
BIN
Resources/textures/Objects/provider.png
Normal file
BIN
Resources/textures/Objects/provider.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 195 B |
BIN
Resources/textures/Objects/storage.png
Normal file
BIN
Resources/textures/Objects/storage.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 869 B |
BIN
Resources/textures/Objects/wiredmachine.png
Normal file
BIN
Resources/textures/Objects/wiredmachine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 742 B |
BIN
Resources/textures/Objects/wirelessmachine.png
Normal file
BIN
Resources/textures/Objects/wirelessmachine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 324 B |
Reference in New Issue
Block a user