Some work on the mess that is this power code.

Jesus.

Tons of fixes, refactors and other things.
The powernet's code is still awful though.
This commit is contained in:
Pieter-Jan Briers
2018-05-27 16:44:50 +02:00
parent f1ec10e3e1
commit 147aad5064
24 changed files with 444 additions and 172 deletions

View File

@@ -75,6 +75,7 @@
<Compile Include="GameObjects\Components\Items\ClientHandsComponent.cs" /> <Compile Include="GameObjects\Components\Items\ClientHandsComponent.cs" />
<Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" /> <Compile Include="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
<Compile Include="UserInterface\HandsGui.cs" /> <Compile Include="UserInterface\HandsGui.cs" />
<Compile Include="GameObjects\Components\Power\PowerDebugTool.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj"> <ProjectReference Include="..\Content.Shared\Content.Shared.csproj">

View File

@@ -1,4 +1,5 @@
using Content.Client.GameObjects; using Content.Client.GameObjects;
using Content.Client.GameObjects.Components.Power;
using Content.Client.GameObjects.Components.Storage; using Content.Client.GameObjects.Components.Storage;
using Content.Client.Interfaces.GameObjects; using Content.Client.Interfaces.GameObjects;
using SS14.Shared.ContentPack; using SS14.Shared.ContentPack;
@@ -43,6 +44,7 @@ namespace Content.Client
factory.RegisterReference<HandsComponent, IHandsComponent>(); factory.RegisterReference<HandsComponent, IHandsComponent>();
factory.Register<ClientStorageComponent>(); factory.Register<ClientStorageComponent>();
factory.Register<ClientInventoryComponent>(); factory.Register<ClientInventoryComponent>();
factory.Register<PowerDebugTool>();
} }
} }
} }

View File

@@ -0,0 +1,28 @@
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Power;
using SS14.Client.UserInterface.Controls;
using SS14.Client.UserInterface.CustomControls;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Network;
namespace Content.Client.GameObjects.Components.Power
{
public class PowerDebugTool : SharedPowerDebugTool
{
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
{
base.HandleMessage(message, netChannel, component);
switch (message)
{
case OpenDataWindowMsg msg:
var window = new SS14Window();
window.Contents.AddChild(new Label() { Text = msg.Data });
window.AddToScreen();
window.Open();
break;
}
}
}
}

View File

@@ -107,6 +107,8 @@
<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" />
<Compile Include="GameObjects\Components\Power\PoweredLightComponent.cs" />
<Compile Include="GameObjects\Components\Power\PowerDebugTool.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj"> <ProjectReference Include="..\Content.Shared\Content.Shared.csproj">
@@ -139,5 +141,4 @@
<None Include="app.config" /> <None Include="app.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup />
</Project> </Project>

View File

@@ -68,6 +68,7 @@ namespace Content.Server
//Power Components //Power Components
factory.Register<PowerTransferComponent>(); factory.Register<PowerTransferComponent>();
factory.Register<PowerProviderComponent>(); factory.Register<PowerProviderComponent>();
factory.RegisterReference<PowerProviderComponent, PowerDeviceComponent>();
factory.Register<PowerNodeComponent>(); factory.Register<PowerNodeComponent>();
factory.Register<PowerStorageComponent>(); factory.Register<PowerStorageComponent>();
factory.Register<PowerDeviceComponent>(); factory.Register<PowerDeviceComponent>();
@@ -87,6 +88,9 @@ namespace Content.Server
factory.Register<MeleeWeaponComponent>(); factory.Register<MeleeWeaponComponent>();
factory.Register<ServerStorageComponent>(); factory.Register<ServerStorageComponent>();
factory.Register<PowerDebugTool>();
factory.Register<PoweredLightComponent>();
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -0,0 +1,80 @@
using System.Text;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Power;
using SS14.Server.Interfaces.GameObjects;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Map;
namespace Content.Server.GameObjects.Components.Power
{
public class PowerDebugTool : SharedPowerDebugTool, IAfterAttack
{
void IAfterAttack.Afterattack(IEntity user, LocalCoordinates clicklocation, IEntity attacked)
{
if (attacked == null)
{
return;
}
var builder = new StringBuilder();
if (attacked.TryGetComponent<PowerNodeComponent>(out var node))
{
builder.AppendFormat("Power Node:\n");
if (node.Parent == null)
{
builder.Append(" No Powernet!\n");
}
else
{
builder.AppendFormat(" Powernet: {0}\n", node.Parent.Uid);
}
}
if (attacked.TryGetComponent<PowerDeviceComponent>(out var device))
{
builder.AppendFormat(@"Power Device:
Load: {0} W
Priority: {1}
Drawtype: {2}, Connected: {3}
Powered: {4}
", device.Load, device.Priority, device.DrawType, device.Connected, device.Powered);
if (device.Connected == DrawTypes.Provider || device.Connected == DrawTypes.Both)
{
builder.Append(" Providers:\n");
foreach (var provider in device.AvailableProviders)
{
var providerTransform = provider.Owner.GetComponent<IServerTransformComponent>();
builder.AppendFormat(" {0} @ {1}", provider.Name, providerTransform.LocalPosition);
if (device.Provider == provider)
{
builder.Append(" (CURRENT)");
}
builder.Append('\n');
}
}
}
if (attacked.TryGetComponent<PowerStorageComponent>(out var storage))
{
builder.AppendFormat(@"Power Storage:
Capacity: {0}, Charge: {1}, ChargeRate: {2}, DistributionRate: {3}, ChargePowernet: {4}
", storage.Capacity, storage.Charge, storage.ChargeRate, storage.DistributionRate, storage.ChargePowernet);
}
OpenDataWindowClientSide(user, builder.ToString());
}
private void OpenDataWindowClientSide(IEntity user, string data)
{
if (!user.TryGetComponent<IActorComponent>(out var actor))
{
return;
}
SendNetworkMessage(new OpenDataWindowMsg(data), actor.playerSession.ConnectedClient);
}
}
}

View File

@@ -4,6 +4,7 @@ using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects; using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC; using SS14.Shared.IoC;
using SS14.Shared.Utility; using SS14.Shared.Utility;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using YamlDotNet.RepresentationModel; using YamlDotNet.RepresentationModel;
@@ -20,22 +21,43 @@ namespace Content.Server.GameObjects.Components.Power
/// <summary> /// <summary>
/// The method of draw we will try to use to place our load set via component parameter, defaults to using power providers /// The method of draw we will try to use to place our load set via component parameter, defaults to using power providers
/// </summary> /// </summary>
public virtual DrawTypes Drawtype { get; protected set; } = DrawTypes.Provider; public virtual DrawTypes DrawType { get; protected set; } = DrawTypes.Provider;
/// <summary> /// <summary>
/// The power draw method we are currently connected to and using /// The power draw method we are currently connected to and using
/// </summary> /// </summary>
public DrawTypes Connected { get; protected set; } = DrawTypes.None; public DrawTypes Connected { get; protected set; } = DrawTypes.None;
public bool _powered = false; public bool Powered { get; private set; } = false;
/// <summary> /// <summary>
/// Status indicator variable for powered /// Is an external power source currently available?
/// </summary> /// </summary>
public virtual bool Powered public bool ExternalPowered
{ {
get => _powered; get => _externalPowered;
set => SetPowered(value); set
{
_externalPowered = value;
UpdatePowered();
} }
}
private bool _externalPowered = false;
/// <summary>
/// Is an internal power source currently available?
/// </summary>
public bool InternalPowered
{
get => _internalPowered;
set
{
_internalPowered = value;
UpdatePowered();
}
}
private bool _internalPowered = false;
/// <summary> /// <summary>
/// Priority for powernet draw, lower will draw first, defined in powernet.cs /// Priority for powernet draw, lower will draw first, defined in powernet.cs
@@ -50,7 +72,7 @@ namespace Content.Server.GameObjects.Components.Power
public float Load public float Load
{ {
get => _load; get => _load;
set { UpdateLoad(value); } set => UpdateLoad(value);
} }
/// <summary> /// <summary>
@@ -60,20 +82,22 @@ namespace Content.Server.GameObjects.Components.Power
private PowerProviderComponent _provider; private PowerProviderComponent _provider;
/// <summary> /// <summary>
/// A power provider that will handle our load, if we are linked to any /// A power provider that will handle our load, if we are linked to any
/// </summary> /// </summary>
public PowerProviderComponent Provider public PowerProviderComponent Provider
{ {
get => _provider; get => _provider;
set { set
{
Connected = DrawTypes.Provider; Connected = DrawTypes.Provider;
if (_provider != null) if (_provider != null)
{ {
_provider.RemoveDevice(this); _provider.RemoveDevice(this);
} }
if(value != null) if (value != null)
{ {
_provider = value; _provider = value;
_provider.AddDevice(this); _provider.AddDevice(this);
@@ -85,11 +109,13 @@ namespace Content.Server.GameObjects.Components.Power
} }
} }
public event EventHandler<PowerStateEventArgs> OnPowerStateChanged;
public override void OnAdd() public override void OnAdd()
{ {
base.OnAdd(); base.OnAdd();
if (Drawtype == DrawTypes.Both || Drawtype == DrawTypes.Node) if (DrawType == DrawTypes.Node || DrawType == DrawTypes.Both)
{ {
if (!Owner.TryGetComponent(out PowerNodeComponent node)) if (!Owner.TryGetComponent(out PowerNodeComponent node))
{ {
@@ -106,7 +132,7 @@ namespace Content.Server.GameObjects.Components.Power
{ {
if (Owner.TryGetComponent(out PowerNodeComponent node)) if (Owner.TryGetComponent(out PowerNodeComponent node))
{ {
if(node.Parent != null) if (node.Parent != null)
{ {
node.Parent.RemoveDevice(this); node.Parent.RemoveDevice(this);
} }
@@ -123,7 +149,7 @@ namespace Content.Server.GameObjects.Components.Power
{ {
if (mapping.TryGetNode("Drawtype", out YamlNode node)) if (mapping.TryGetNode("Drawtype", out YamlNode node))
{ {
Drawtype = node.AsEnum<DrawTypes>(); DrawType = node.AsEnum<DrawTypes>();
} }
if (mapping.TryGetNode("Load", out node)) if (mapping.TryGetNode("Load", out node))
{ {
@@ -137,7 +163,7 @@ namespace Content.Server.GameObjects.Components.Power
string IExamine.Examine() string IExamine.Examine()
{ {
if(!Powered) if (!Powered)
{ {
return "The device is not powered"; return "The device is not powered";
} }
@@ -148,44 +174,32 @@ namespace Content.Server.GameObjects.Components.Power
{ {
var oldLoad = _load; var oldLoad = _load;
_load = value; _load = value;
if(Connected == DrawTypes.Node) if (Connected == DrawTypes.Node)
{ {
var node = Owner.GetComponent<PowerNodeComponent>(); var node = Owner.GetComponent<PowerNodeComponent>();
node.Parent.UpdateDevice(this, oldLoad); node.Parent.UpdateDevice(this, oldLoad);
} }
else if(Connected == DrawTypes.Provider) else if (Connected == DrawTypes.Provider)
{ {
Provider.UpdateDevice(this, oldLoad); Provider.UpdateDevice(this, oldLoad);
} }
} }
/// <summary> private void UpdatePowered()
/// 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 var oldPowered = Powered;
if (value == true) Powered = ExternalPowered || InternalPowered;
if (oldPowered != Powered)
{ {
_powered = true; if (Powered)
return; {
OnPowerStateChanged?.Invoke(this, new PowerStateEventArgs(true));
} }
else
//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)) OnPowerStateChanged?.Invoke(this, new PowerStateEventArgs(false));
{
storage.DeductCharge(Load);
_powered = true;
return;
} }
} }
//For some reason above we could not power ourselves, we depower
_powered = false;
return;
} }
/// <summary> /// <summary>
@@ -196,7 +210,7 @@ namespace Content.Server.GameObjects.Components.Power
{ {
AvailableProviders.Add(provider); AvailableProviders.Add(provider);
if(Connected != DrawTypes.Node) if (Connected != DrawTypes.Node)
{ {
ConnectToBestProvider(); ConnectToBestProvider();
} }
@@ -234,7 +248,7 @@ namespace Content.Server.GameObjects.Components.Power
} }
} }
if(Provider != bestprovider) if (Provider != bestprovider)
Provider = bestprovider; Provider = bestprovider;
} }
@@ -249,6 +263,12 @@ namespace Content.Server.GameObjects.Components.Power
AvailableProviders.Remove(provider); AvailableProviders.Remove(provider);
if (provider == Provider)
{
Provider = null;
ExternalPowered = false;
}
if (Connected != DrawTypes.Node) if (Connected != DrawTypes.Node)
{ {
ConnectToBestProvider(); ConnectToBestProvider();
@@ -260,7 +280,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="eventarg"></param> /// <param name="eventarg"></param>
private void PowernetConnect(object sender, PowernetEventArgs eventarg) protected virtual void PowernetConnect(object sender, PowernetEventArgs eventarg)
{ {
//This sets connected = none so it must be first //This sets connected = none so it must be first
Provider = null; Provider = null;
@@ -274,7 +294,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="eventarg"></param> /// <param name="eventarg"></param>
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg) protected virtual void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
{ {
eventarg.Powernet.AddDevice(this); eventarg.Powernet.AddDevice(this);
} }
@@ -284,13 +304,31 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="eventarg"></param> /// <param name="eventarg"></param>
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg) protected virtual void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
{ {
eventarg.Powernet.RemoveDevice(this); eventarg.Powernet.RemoveDevice(this);
Connected = DrawTypes.None; Connected = DrawTypes.None;
ConnectToBestProvider(); ConnectToBestProvider();
} }
internal virtual void ProcessInternalPower(float frametime)
{
if (Owner.TryGetComponent<PowerStorageComponent>(out var storage) && storage.CanDeductCharge(Load))
{
// We still keep InternalPowered correct if connected externally,
// but don't use it.
if (!ExternalPowered)
{
storage.DeductCharge(Load);
}
InternalPowered = true;
}
else
{
InternalPowered = false;
}
}
} }
public enum DrawTypes public enum DrawTypes
@@ -298,6 +336,16 @@ namespace Content.Server.GameObjects.Components.Power
None = 0, None = 0,
Node = 1, Node = 1,
Provider = 2, Provider = 2,
Both = 3 Both = 3,
}
public class PowerStateEventArgs : EventArgs
{
public readonly bool Powered;
public PowerStateEventArgs(bool powered)
{
Powered = powered;
}
} }
} }

View File

@@ -57,7 +57,7 @@ namespace Content.Server.GameObjects.Components.Power
.Where(x => x.HasComponent<PowerTransferComponent>()) .Where(x => x.HasComponent<PowerTransferComponent>())
.OrderByDescending(x => (x.GetComponent<TransformComponent>().WorldPosition - position).Length); .OrderByDescending(x => (x.GetComponent<TransformComponent>().WorldPosition - position).Length);
var choose = wires.FirstOrDefault(); var choose = wires.FirstOrDefault();
if(choose != null) if (choose != null)
ConnectToPowernet(choose.GetComponent<PowerTransferComponent>().Parent); ConnectToPowernet(choose.GetComponent<PowerTransferComponent>().Parent);
} }
@@ -68,7 +68,7 @@ namespace Content.Server.GameObjects.Components.Power
public void ConnectToPowernet(Powernet toconnect) public void ConnectToPowernet(Powernet toconnect)
{ {
Parent = toconnect; Parent = toconnect;
Parent.Nodelist.Add(this); Parent.NodeList.Add(this);
OnPowernetConnect?.Invoke(this, new PowernetEventArgs(Parent)); OnPowernetConnect?.Invoke(this, new PowernetEventArgs(Parent));
} }
@@ -79,10 +79,10 @@ namespace Content.Server.GameObjects.Components.Power
public void RegeneratePowernet(Powernet toconnect) public void RegeneratePowernet(Powernet toconnect)
{ {
//This removes the device from things that will be powernet disconnected when dirty powernet is killed //This removes the device from things that will be powernet disconnected when dirty powernet is killed
Parent.Nodelist.Remove(this); Parent.NodeList.Remove(this);
Parent = toconnect; Parent = toconnect;
Parent.Nodelist.Add(this); Parent.NodeList.Add(this);
OnPowernetRegenerate?.Invoke(this, new PowernetEventArgs(Parent)); OnPowernetRegenerate?.Invoke(this, new PowernetEventArgs(Parent));
} }
@@ -91,7 +91,11 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void DisconnectFromPowernet() public void DisconnectFromPowernet()
{ {
Parent.Nodelist.Remove(this); if (Parent == null)
{
return;
}
Parent.NodeList.Remove(this);
OnPowernetDisconnect?.Invoke(this, new PowernetEventArgs(Parent)); OnPowernetDisconnect?.Invoke(this, new PowernetEventArgs(Parent));
Parent = null; Parent = null;
} }

View File

@@ -19,7 +19,7 @@ namespace Content.Server.GameObjects.Components.Power
public override string Name => "PowerProvider"; public override string Name => "PowerProvider";
/// <inheritdoc /> /// <inheritdoc />
public override DrawTypes Drawtype { get; protected set; } = DrawTypes.Node; public override DrawTypes DrawType { get; protected set; } = DrawTypes.Node;
/// <summary> /// <summary>
/// Variable that determines the range that the power provider will try to supply power to /// Variable that determines the range that the power provider will try to supply power to
@@ -29,12 +29,22 @@ namespace Content.Server.GameObjects.Components.Power
/// <summary> /// <summary>
/// List storing all the power devices that we are currently providing power to /// List storing all the power devices that we are currently providing power to
/// </summary> /// </summary>
public SortedSet<PowerDeviceComponent> Deviceloadlist = new SortedSet<PowerDeviceComponent>(new Powernet.DevicePriorityCompare()); public SortedSet<PowerDeviceComponent> DeviceLoadList = new SortedSet<PowerDeviceComponent>(new Powernet.DevicePriorityCompare());
public List<PowerDeviceComponent> DepoweredDevices = new List<PowerDeviceComponent>(); public List<PowerDeviceComponent> DepoweredDevices = new List<PowerDeviceComponent>();
public override Powernet.Priority Priority { get; protected set; } = Powernet.Priority.Provider; public override Powernet.Priority Priority { get; protected set; } = Powernet.Priority.Provider;
public override void OnRemove()
{
base.OnRemove();
foreach (var device in DeviceLoadList)
{
device.RemoveProvider(this);
}
}
public override void LoadParameters(YamlMappingNode mapping) public override void LoadParameters(YamlMappingNode mapping)
{ {
if (mapping.TryGetNode("Range", out YamlNode node)) if (mapping.TryGetNode("Range", out YamlNode node))
@@ -47,78 +57,71 @@ namespace Content.Server.GameObjects.Components.Power
} }
} }
/// <inheritdoc /> internal override void ProcessInternalPower(float frametime)
public override void SetPowered(bool value)
{ {
//Let them set us true, we must now power all the devices that rely on us for energy // Right now let's just assume that APCs don't have a power demand themselves and as such they're always marked as powered.
if (value == true) InternalPowered = true;
if (!Owner.TryGetComponent<PowerStorageComponent>(out var storage))
{
return;
}
if (ExternalPowered)
{ {
PowerAllDevices(); PowerAllDevices();
return; 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)) if (storage.CanDeductCharge(Load))
{ {
PowerAllDevices();
storage.DeductCharge(Load); storage.DeductCharge(Load);
_powered = true;
return; 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 remainingLoad = storage.AvailableCharge();
var usedLoad = 0f;
foreach (var device in DeviceLoadList)
{ {
var depowervalue = storage.RequestAllCharge() - Load; if (device.Load > remainingLoad)
_powered = true;
//See code in powernet for same functionality
foreach (var device in Deviceloadlist)
{ {
device.Powered = false; device.ExternalPowered = false;
DepoweredDevices.Add(device); DepoweredDevices.Add(device);
depowervalue -= device.Load;
if (depowervalue < 0)
break;
} }
return; else
}
//Storage doesn't have anything, depower everything
else if (storage.RequestAllCharge() == 0)
{ {
DepowerAllDevices(); if (!device.ExternalPowered)
return; {
device.ExternalPowered = true;
DepoweredDevices.Remove(device);
}
usedLoad += device.Load;
remainingLoad -= device.Load;
} }
} }
//For some reason above we could not power ourselves, we depower ourselves and all devices storage.DeductCharge(usedLoad);
DepowerAllDevices();
return;
} }
private void PowerAllDevices() private void PowerAllDevices()
{ {
_powered = true;
foreach (var device in DepoweredDevices) foreach (var device in DepoweredDevices)
{ {
device.Powered = true; device.ExternalPowered = true;
} }
DepoweredDevices.Clear(); DepoweredDevices.Clear();
} }
private void DepowerAllDevices() private void DepowerAllDevices()
{ {
_powered = false; foreach (var device in DeviceLoadList)
foreach (var device in DepoweredDevices)
{ {
device.Powered = false; device.ExternalPowered = false;
} }
} }
private void PowernetConnect(object sender, PowernetEventArgs eventarg) protected override void PowernetConnect(object sender, PowernetEventArgs eventarg)
{ {
eventarg.Powernet.AddDevice(this); base.PowernetConnect(sender, eventarg);
Connected = DrawTypes.Node;
//Find devices within range to take under our control //Find devices within range to take under our control
var _emanager = IoCManager.Resolve<IServerEntityManager>(); var _emanager = IoCManager.Resolve<IServerEntityManager>();
@@ -132,25 +135,20 @@ namespace Content.Server.GameObjects.Components.Power
var device = entity.GetComponent<PowerDeviceComponent>(); var device = entity.GetComponent<PowerDeviceComponent>();
//Make sure the device can accept power providers to give it power //Make sure the device can accept power providers to give it power
if (device.Drawtype == DrawTypes.Provider || device.Drawtype == DrawTypes.Both) if (device.DrawType == DrawTypes.Provider || device.DrawType == DrawTypes.Both)
{ {
device.AddProvider(this); device.AddProvider(this);
} }
} }
} }
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
{
eventarg.Powernet.AddDevice(this);
}
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg) protected override void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
{ {
eventarg.Powernet.RemoveDevice(this); base.PowernetDisconnect(sender, eventarg);
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 //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) foreach (var device in DeviceLoadList.ToList())
{ {
device.RemoveProvider(this); device.RemoveProvider(this);
} }
@@ -161,7 +159,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void AddDevice(PowerDeviceComponent device) public void AddDevice(PowerDeviceComponent device)
{ {
Deviceloadlist.Add(device); DeviceLoadList.Add(device);
Load += device.Load; Load += device.Load;
if (!device.Powered) if (!device.Powered)
DepoweredDevices.Add(device); DepoweredDevices.Add(device);
@@ -172,7 +170,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void UpdateDevice(PowerDeviceComponent device, float oldLoad) public void UpdateDevice(PowerDeviceComponent device, float oldLoad)
{ {
if (Deviceloadlist.Contains(device)) if (DeviceLoadList.Contains(device))
{ {
Load -= oldLoad; Load -= oldLoad;
Load += device.Load; Load += device.Load;
@@ -184,10 +182,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void RemoveDevice(PowerDeviceComponent device) public void RemoveDevice(PowerDeviceComponent device)
{ {
if (Deviceloadlist.Contains(device)) if (DeviceLoadList.Contains(device))
{ {
Load -= device.Load; Load -= device.Load;
Deviceloadlist.Remove(device); DeviceLoadList.Remove(device);
if (DepoweredDevices.Contains(device)) if (DepoweredDevices.Contains(device))
DepoweredDevices.Remove(device); DepoweredDevices.Remove(device);
} }

View File

@@ -156,7 +156,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void ChargePowerTick() public void ChargePowerTick()
{ {
Charge = Math.Max(Charge + ChargeRate, Capacity); Charge = Math.Min(Charge + ChargeRate, Capacity);
} }
/// <summary> /// <summary>

View File

@@ -25,7 +25,7 @@ namespace Content.Server.GameObjects.Components.Power
public override void Initialize() public override void Initialize()
{ {
if(Parent == null) if (Parent == null)
{ {
SpreadPowernet(); SpreadPowernet();
} }
@@ -49,7 +49,7 @@ namespace Content.Server.GameObjects.Components.Power
.Where(x => x.HasComponent<PowerTransferComponent>()); .Where(x => x.HasComponent<PowerTransferComponent>());
//we have no parent so lets find a partner we can join his powernet //we have no parent so lets find a partner we can join his powernet
if(Parent == null || Regenerating) if (Parent == null || Regenerating)
{ {
foreach (var wire in wires) foreach (var wire in wires)
{ {
@@ -74,13 +74,13 @@ namespace Content.Server.GameObjects.Components.Power
.Where(x => x.HasComponent<PowerNodeComponent>()) .Where(x => x.HasComponent<PowerNodeComponent>())
.Select(x => x.GetComponent<PowerNodeComponent>()); .Select(x => x.GetComponent<PowerNodeComponent>());
foreach(var node in nodes) foreach (var node in nodes)
{ {
if(node.Parent == null) if (node.Parent == null)
{ {
node.ConnectToPowernet(Parent); node.ConnectToPowernet(Parent);
} }
else if(node.Parent.Dirty) else if (node.Parent.Dirty)
{ {
node.RegeneratePowernet(Parent); node.RegeneratePowernet(Parent);
} }
@@ -95,7 +95,7 @@ namespace Content.Server.GameObjects.Components.Power
ptc.ConnectToPowernet(Parent); ptc.ConnectToPowernet(Parent);
SpreadPowernet(); SpreadPowernet();
} }
else if(ptc.Parent != Parent && !ptc.Parent.Dirty) else if (ptc.Parent != Parent && !ptc.Parent.Dirty)
{ {
Parent.MergePowernets(ptc.Parent); Parent.MergePowernets(ptc.Parent);
} }
@@ -109,7 +109,7 @@ namespace Content.Server.GameObjects.Components.Power
public void ConnectToPowernet(Powernet toconnect) public void ConnectToPowernet(Powernet toconnect)
{ {
Parent = toconnect; Parent = toconnect;
Parent.Wirelist.Add(this); Parent.WireList.Add(this);
Regenerating = false; Regenerating = false;
} }
@@ -118,7 +118,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void DisconnectFromPowernet() public void DisconnectFromPowernet()
{ {
Parent.Wirelist.Remove(this); Parent.WireList.Remove(this);
Parent.Dirty = true; Parent.Dirty = true;
Parent = null; Parent = null;
} }
@@ -131,7 +131,7 @@ namespace Content.Server.GameObjects.Components.Power
public bool Attackby(IEntity user, IEntity attackwith) public bool Attackby(IEntity user, IEntity attackwith)
{ {
if(attackwith.TryGetComponent(out WirecutterComponent wirecutter)) if (attackwith.TryGetComponent(out WirecutterComponent wirecutter))
{ {
Owner.Delete(); Owner.Delete();
return true; return true;

View File

@@ -0,0 +1,33 @@
using SS14.Server.GameObjects;
using SS14.Shared.Enums;
using SS14.Shared.GameObjects;
namespace Content.Server.GameObjects.Components.Power
{
public class PoweredLightComponent : Component
{
public override string Name => "PoweredLight";
public override void Initialize()
{
base.Initialize();
var device = Owner.GetComponent<PowerDeviceComponent>();
var sprite = Owner.GetComponent<SpriteComponent>();
var light = Owner.GetComponent<PointLightComponent>();
device.OnPowerStateChanged += (sender, args) =>
{
if (args.Powered)
{
sprite.LayerSetTexture(0, "Objects/wall_light.png");
light.State = LightState.On;
}
else
{
sprite.LayerSetTexture(0, "Objects/wall_light_off.png");
light.State = LightState.Off;
}
};
}
}
}

View File

@@ -15,28 +15,32 @@ namespace Content.Server.GameObjects.Components.Power
public Powernet() public Powernet()
{ {
var EntitySystemManager = IoCManager.Resolve<IEntitySystemManager>(); var EntitySystemManager = IoCManager.Resolve<IEntitySystemManager>();
EntitySystemManager.GetEntitySystem<PowerSystem>().Powernets.Add(this); var powerSystem = EntitySystemManager.GetEntitySystem<PowerSystem>();
powerSystem.Powernets.Add(this);
Uid = powerSystem.NewUid();
} }
public int Uid { get; }
/// <summary> /// <summary>
/// The entities that make up the powernet's physical location and allow powernet connection /// The entities that make up the powernet's physical location and allow powernet connection
/// </summary> /// </summary>
public List<PowerTransferComponent> Wirelist { get; set; } = new List<PowerTransferComponent>(); public List<PowerTransferComponent> WireList { get; set; } = new List<PowerTransferComponent>();
/// <summary> /// <summary>
/// Entities that connect directly to the powernet through PTC above to add power or add power load /// Entities that connect directly to the powernet through PTC above to add power or add power load
/// </summary> /// </summary>
public List<PowerNodeComponent> Nodelist { get; set; } = new List<PowerNodeComponent>(); public List<PowerNodeComponent> NodeList { get; set; } = new List<PowerNodeComponent>();
/// <summary> /// <summary>
/// Subset of nodelist that adds a continuous power supply to the network /// Subset of nodelist that adds a continuous power supply to the network
/// </summary> /// </summary>
public Dictionary<PowerGeneratorComponent, float> Generatorlist { get; set; } = new Dictionary<PowerGeneratorComponent, float>(); public Dictionary<PowerGeneratorComponent, float> GeneratorList { get; set; } = new Dictionary<PowerGeneratorComponent, float>();
/// <summary> /// <summary>
/// Subset of nodelist that draw power, stores information on current continuous powernet load /// Subset of nodelist that draw power, stores information on current continuous powernet load
/// </summary> /// </summary>
public SortedSet<PowerDeviceComponent> Deviceloadlist { get; set; } = new SortedSet<PowerDeviceComponent>(new DevicePriorityCompare()); public SortedSet<PowerDeviceComponent> DeviceLoadList { get; set; } = new SortedSet<PowerDeviceComponent>(new DevicePriorityCompare());
/// <summary> /// <summary>
/// Comparer that keeps the device dictionary sorted by powernet priority /// Comparer that keeps the device dictionary sorted by powernet priority
@@ -156,9 +160,9 @@ namespace Content.Server.GameObjects.Components.Power
var depowervalue = activeload - (activesupply + passivesupply); var depowervalue = activeload - (activesupply + passivesupply);
//Providers use same method to recreate functionality //Providers use same method to recreate functionality
foreach (var device in Deviceloadlist) foreach (var device in DeviceLoadList)
{ {
device.Powered = false; device.ExternalPowered = false;
DepoweredDevices.Add(device); DepoweredDevices.Add(device);
depowervalue -= device.Load; depowervalue -= device.Load;
if (depowervalue < 0) if (depowervalue < 0)
@@ -171,7 +175,7 @@ namespace Content.Server.GameObjects.Components.Power
{ {
foreach (var device in DepoweredDevices) foreach (var device in DepoweredDevices)
{ {
device.Powered = true; device.ExternalPowered = true;
} }
DepoweredDevices.Clear(); DepoweredDevices.Clear();
} }
@@ -205,13 +209,13 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void DirtyKill() public void DirtyKill()
{ {
Wirelist.Clear(); WireList.Clear();
while (Nodelist.Count != 0) while (NodeList.Count != 0)
{ {
Nodelist[0].DisconnectFromPowernet(); NodeList[0].DisconnectFromPowernet();
} }
Generatorlist.Clear(); GeneratorList.Clear();
Deviceloadlist.Clear(); DeviceLoadList.Clear();
DepoweredDevices.Clear(); DepoweredDevices.Clear();
PowerStorageSupplierlist.Clear(); PowerStorageSupplierlist.Clear();
PowerStorageConsumerlist.Clear(); PowerStorageConsumerlist.Clear();
@@ -226,31 +230,31 @@ namespace Content.Server.GameObjects.Components.Power
{ {
//TODO: load balance reconciliation between powernets on merge tick here //TODO: load balance reconciliation between powernets on merge tick here
foreach (var wire in toMerge.Wirelist) foreach (var wire in toMerge.WireList)
{ {
wire.Parent = this; wire.Parent = this;
} }
Wirelist.AddRange(toMerge.Wirelist); WireList.AddRange(toMerge.WireList);
toMerge.Wirelist.Clear(); toMerge.WireList.Clear();
foreach (var node in toMerge.Nodelist) foreach (var node in toMerge.NodeList)
{ {
node.Parent = this; node.Parent = this;
} }
Nodelist.AddRange(toMerge.Nodelist); NodeList.AddRange(toMerge.NodeList);
toMerge.Nodelist.Clear(); toMerge.NodeList.Clear();
foreach (var generator in toMerge.Generatorlist) foreach (var generator in toMerge.GeneratorList)
{ {
Generatorlist.Add(generator.Key, generator.Value); GeneratorList.Add(generator.Key, generator.Value);
} }
toMerge.Generatorlist.Clear(); toMerge.GeneratorList.Clear();
foreach (var device in toMerge.Deviceloadlist) foreach (var device in toMerge.DeviceLoadList)
{ {
Deviceloadlist.Add(device); DeviceLoadList.Add(device);
} }
toMerge.Deviceloadlist.Clear(); toMerge.DeviceLoadList.Clear();
DepoweredDevices.AddRange(toMerge.DepoweredDevices); DepoweredDevices.AddRange(toMerge.DepoweredDevices);
toMerge.DepoweredDevices.Clear(); toMerge.DepoweredDevices.Clear();
@@ -280,7 +284,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void AddDevice(PowerDeviceComponent device) public void AddDevice(PowerDeviceComponent device)
{ {
Deviceloadlist.Add(device); DeviceLoadList.Add(device);
Load += device.Load; Load += device.Load;
if (!device.Powered) if (!device.Powered)
DepoweredDevices.Add(device); DepoweredDevices.Add(device);
@@ -291,7 +295,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void UpdateDevice(PowerDeviceComponent device, float oldLoad) public void UpdateDevice(PowerDeviceComponent device, float oldLoad)
{ {
if (Deviceloadlist.Contains(device)) if (DeviceLoadList.Contains(device))
{ {
Load -= oldLoad; Load -= oldLoad;
Load += device.Load; Load += device.Load;
@@ -303,10 +307,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void RemoveDevice(PowerDeviceComponent device) public void RemoveDevice(PowerDeviceComponent device)
{ {
if (Deviceloadlist.Contains(device)) if (DeviceLoadList.Contains(device))
{ {
Load -= device.Load; Load -= device.Load;
Deviceloadlist.Remove(device); DeviceLoadList.Remove(device);
if (DepoweredDevices.Contains(device)) if (DepoweredDevices.Contains(device))
DepoweredDevices.Remove(device); DepoweredDevices.Remove(device);
} }
@@ -322,7 +326,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void AddGenerator(PowerGeneratorComponent generator) public void AddGenerator(PowerGeneratorComponent generator)
{ {
Generatorlist.Add(generator, generator.Supply); GeneratorList.Add(generator, generator.Supply);
Supply += generator.Supply; Supply += generator.Supply;
} }
@@ -331,10 +335,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void UpdateGenerator(PowerGeneratorComponent generator) public void UpdateGenerator(PowerGeneratorComponent generator)
{ {
if (Generatorlist.ContainsKey(generator)) if (GeneratorList.ContainsKey(generator))
{ {
Supply -= Generatorlist[generator]; Supply -= GeneratorList[generator];
Generatorlist[generator] = generator.Supply; GeneratorList[generator] = generator.Supply;
Supply += generator.Supply; Supply += generator.Supply;
} }
} }
@@ -344,10 +348,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary> /// </summary>
public void RemoveGenerator(PowerGeneratorComponent generator) public void RemoveGenerator(PowerGeneratorComponent generator)
{ {
if (Generatorlist.ContainsKey(generator)) if (GeneratorList.ContainsKey(generator))
{ {
Supply -= Generatorlist[generator]; Supply -= GeneratorList[generator];
Generatorlist.Remove(generator); GeneratorList.Remove(generator);
} }
else else
{ {

View File

@@ -31,18 +31,18 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
} }
void IAfterAttack.Afterattack(IEntity user, LocalCoordinates clicklocation) void IAfterAttack.Afterattack(IEntity user, LocalCoordinates clicklocation, IEntity attacked)
{ {
var location = user.GetComponent<TransformComponent>().LocalPosition; var location = user.GetComponent<TransformComponent>().LocalPosition;
var angle = new Angle(clicklocation.ToWorld().Position - location.ToWorld().Position); var angle = new Angle(clicklocation.ToWorld().Position - location.ToWorld().Position);
var entities = IoCManager.Resolve<IServerEntityManager>().GetEntitiesInArc(user.GetComponent<TransformComponent>().LocalPosition, Range, angle, ArcWidth); var entities = IoCManager.Resolve<IServerEntityManager>().GetEntitiesInArc(user.GetComponent<TransformComponent>().LocalPosition, Range, angle, ArcWidth);
foreach(var entity in entities) foreach (var entity in entities)
{ {
if (!entity.GetComponent<TransformComponent>().IsMapTransform || entity == user) if (!entity.GetComponent<TransformComponent>().IsMapTransform || entity == user)
continue; continue;
if(entity.TryGetComponent(out DamageableComponent damagecomponent)) if (entity.TryGetComponent(out DamageableComponent damagecomponent))
{ {
damagecomponent.TakeDamage(DamageType.Brute, Damage); damagecomponent.TakeDamage(DamageType.Brute, Damage);
} }

View File

@@ -9,9 +9,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
{ {
public override string Name => "RangedWeapon"; public override string Name => "RangedWeapon";
void IAfterAttack.Afterattack(IEntity user, LocalCoordinates clicklocation) void IAfterAttack.Afterattack(IEntity user, LocalCoordinates clicklocation, IEntity attacked)
{ {
if(UserCanFire(user) && WeaponCanFire()) if (UserCanFire(user) && WeaponCanFire())
{ {
Fire(user, clicklocation); Fire(user, clicklocation);
} }

View File

@@ -65,7 +65,8 @@ namespace Content.Server.GameObjects.EntitySystems
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
/// <param name="clicklocation"></param> /// <param name="clicklocation"></param>
void Afterattack(IEntity user, LocalCoordinates clicklocation); /// <param name="attacked">The entity that was clicked on out of range. May be null if no entity was clicked on.true</param>
void Afterattack(IEntity user, LocalCoordinates clicklocation, IEntity attacked);
} }
/// <summary> /// <summary>
@@ -198,7 +199,7 @@ namespace Content.Server.GameObjects.EntitySystems
for (var i = 0; i < afterattacks.Count; i++) for (var i = 0; i < afterattacks.Count; i++)
{ {
afterattacks[i].Afterattack(user, clicklocation); afterattacks[i].Afterattack(user, clicklocation, null);
} }
} }
@@ -229,7 +230,7 @@ namespace Content.Server.GameObjects.EntitySystems
for (var i = 0; i < afterattacks.Count; i++) for (var i = 0; i < afterattacks.Count; i++)
{ {
afterattacks[i].Afterattack(user, clicklocation); afterattacks[i].Afterattack(user, clicklocation, attacked);
} }
} }
@@ -315,7 +316,7 @@ namespace Content.Server.GameObjects.EntitySystems
//See if we have a ranged attack interaction //See if we have a ranged attack interaction
for (var i = 0; i < afterattacks.Count; i++) for (var i = 0; i < afterattacks.Count; i++)
{ {
afterattacks[i].Afterattack(user, clicklocation); afterattacks[i].Afterattack(user, clicklocation, attacked);
} }
} }
} }

View File

@@ -1,5 +1,7 @@
using Content.Server.GameObjects.Components.Power; using Content.Server.GameObjects.Components.Power;
using SS14.Shared.GameObjects.System; using SS14.Shared.GameObjects.System;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -12,6 +14,21 @@ namespace Content.Shared.GameObjects.EntitySystems
{ {
public List<Powernet> Powernets = new List<Powernet>(); public List<Powernet> Powernets = new List<Powernet>();
private IComponentManager componentManager;
private int _lastUid = 0;
public override void Initialize()
{
base.Initialize();
componentManager = IoCManager.Resolve<IComponentManager>();
}
public int NewUid()
{
return ++_lastUid;
}
public override void Update(float frametime) public override void Update(float frametime)
{ {
for (int i = 0; i < Powernets.Count; i++) for (int i = 0; i < Powernets.Count; i++)
@@ -20,12 +37,12 @@ namespace Content.Shared.GameObjects.EntitySystems
if (powernet.Dirty) if (powernet.Dirty)
{ {
//Tell all the wires of this net to be prepared to create/join new powernets //Tell all the wires of this net to be prepared to create/join new powernets
foreach (var wire in powernet.Wirelist) foreach (var wire in powernet.WireList)
{ {
wire.Regenerating = true; wire.Regenerating = true;
} }
foreach (var wire in powernet.Wirelist) 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 //Only a few wires should pass this if check since each will create and take all the others into its powernet
if (wire.Regenerating) if (wire.Regenerating)
@@ -38,10 +55,16 @@ namespace Content.Shared.GameObjects.EntitySystems
} }
} }
foreach(var powernet in Powernets) foreach (var powernet in Powernets)
{ {
powernet.Update(frametime); powernet.Update(frametime);
} }
// Draw power for devices not connected to anything.
foreach (var device in componentManager.GetComponents<PowerDeviceComponent>())
{
device.ProcessInternalPower(frametime);
}
} }
} }
} }

View File

@@ -72,6 +72,7 @@
<Compile Include="GameObjects\PhysicalConstants.cs" /> <Compile Include="GameObjects\PhysicalConstants.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GameObjects\Components\Items\SharedHandsComponent.cs" /> <Compile Include="GameObjects\Components\Items\SharedHandsComponent.cs" />
<Compile Include="GameObjects\Components\Power\SharedPowerDebugTool.cs" />
<Compile Include="Maths\PhysicalConstants.cs" /> <Compile Include="Maths\PhysicalConstants.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,24 @@
using System;
using SS14.Shared.GameObjects;
using SS14.Shared.Serialization;
namespace Content.Shared.GameObjects.Components.Power
{
public class SharedPowerDebugTool : Component
{
public override string Name => "PowerDebugTool";
public override uint? NetID => ContentNetIDs.POWER_DEBUG_TOOL;
[Serializable, NetSerializable]
protected class OpenDataWindowMsg : ComponentMessage
{
public string Data { get; }
public OpenDataWindowMsg(string data)
{
Directed = true;
Data = data;
}
}
}
}

View File

@@ -9,5 +9,6 @@
public const uint HANDS = 1003; public const uint HANDS = 1003;
public const uint STORAGE = 1005; public const uint STORAGE = 1005;
public const uint INVENTORY = 1006; public const uint INVENTORY = 1006;
public const uint POWER_DEBUG_TOOL = 1007;
} }
} }

View File

@@ -57,6 +57,7 @@
- type: PowerProvider - type: PowerProvider
Range: 5 Range: 5
Priority: Provider Priority: Provider
Load: 0
- type: entity - type: entity
parent: WPPnobattery parent: WPPnobattery

View File

@@ -0,0 +1,17 @@
- type: entity
name: Light
id: poweredlight
parent: __engine_wall_light
components:
# So we can click on it for deletion.
- type: BoundingBox
- type: Sprite
texture: Objects/wall_light_off.png
- type: PowerDevice
load: 1
priority: Low
- type: PoweredLight
- type: PointLight
state: Off

View File

@@ -81,3 +81,4 @@
texture: Objects/multitool.png texture: Objects/multitool.png
- type: Icon - type: Icon
texture: Objects/multitool.png texture: Objects/multitool.png
- type: PowerDebugTool

2
engine

Submodule engine updated: dc80060757...6f4ea205ef