Files
tbd-station-14/Content.Server/GameObjects/Components/Power/PowerTransferComponent.cs
clusterfack 1f22f8ab6a 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
2018-02-03 21:35:42 -07:00

130 lines
4.2 KiB
C#

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;
}
}
}