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="Interfaces\GameObjects\Components\Items\IHandsComponent.cs" />
<Compile Include="UserInterface\HandsGui.cs" />
<Compile Include="GameObjects\Components\Power\PowerDebugTool.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj">

View File

@@ -1,4 +1,5 @@
using Content.Client.GameObjects;
using Content.Client.GameObjects.Components.Power;
using Content.Client.GameObjects.Components.Storage;
using Content.Client.Interfaces.GameObjects;
using SS14.Shared.ContentPack;
@@ -43,6 +44,7 @@ namespace Content.Client
factory.RegisterReference<HandsComponent, IHandsComponent>();
factory.Register<ClientStorageComponent>();
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="Interfaces\GameObjects\Components\Temperature\ITemperatureComponent.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>
<ProjectReference Include="..\Content.Shared\Content.Shared.csproj">
@@ -139,5 +141,4 @@
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
</Project>

View File

@@ -68,6 +68,7 @@ namespace Content.Server
//Power Components
factory.Register<PowerTransferComponent>();
factory.Register<PowerProviderComponent>();
factory.RegisterReference<PowerProviderComponent, PowerDeviceComponent>();
factory.Register<PowerNodeComponent>();
factory.Register<PowerStorageComponent>();
factory.Register<PowerDeviceComponent>();
@@ -87,6 +88,9 @@ namespace Content.Server
factory.Register<MeleeWeaponComponent>();
factory.Register<ServerStorageComponent>();
factory.Register<PowerDebugTool>();
factory.Register<PoweredLightComponent>();
}
/// <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.IoC;
using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using YamlDotNet.RepresentationModel;
@@ -20,22 +21,43 @@ namespace Content.Server.GameObjects.Components.Power
/// <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;
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;
public bool Powered { get; private set; } = false;
/// <summary>
/// Status indicator variable for powered
/// Is an external power source currently available?
/// </summary>
public virtual bool Powered
public bool ExternalPowered
{
get => _powered;
set => SetPowered(value);
get => _externalPowered;
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>
/// 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
{
get => _load;
set { UpdateLoad(value); }
set => UpdateLoad(value);
}
/// <summary>
@@ -60,20 +82,22 @@ namespace Content.Server.GameObjects.Components.Power
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 {
set
{
Connected = DrawTypes.Provider;
if (_provider != null)
{
_provider.RemoveDevice(this);
}
if(value != null)
if (value != null)
{
_provider = value;
_provider.AddDevice(this);
@@ -85,11 +109,13 @@ namespace Content.Server.GameObjects.Components.Power
}
}
public event EventHandler<PowerStateEventArgs> OnPowerStateChanged;
public override void OnAdd()
{
base.OnAdd();
if (Drawtype == DrawTypes.Both || Drawtype == DrawTypes.Node)
if (DrawType == DrawTypes.Node || DrawType == DrawTypes.Both)
{
if (!Owner.TryGetComponent(out PowerNodeComponent node))
{
@@ -106,7 +132,7 @@ namespace Content.Server.GameObjects.Components.Power
{
if (Owner.TryGetComponent(out PowerNodeComponent node))
{
if(node.Parent != null)
if (node.Parent != null)
{
node.Parent.RemoveDevice(this);
}
@@ -123,7 +149,7 @@ namespace Content.Server.GameObjects.Components.Power
{
if (mapping.TryGetNode("Drawtype", out YamlNode node))
{
Drawtype = node.AsEnum<DrawTypes>();
DrawType = node.AsEnum<DrawTypes>();
}
if (mapping.TryGetNode("Load", out node))
{
@@ -137,7 +163,7 @@ namespace Content.Server.GameObjects.Components.Power
string IExamine.Examine()
{
if(!Powered)
if (!Powered)
{
return "The device is not powered";
}
@@ -148,44 +174,32 @@ namespace Content.Server.GameObjects.Components.Power
{
var oldLoad = _load;
_load = value;
if(Connected == DrawTypes.Node)
if (Connected == DrawTypes.Node)
{
var node = Owner.GetComponent<PowerNodeComponent>();
node.Parent.UpdateDevice(this, oldLoad);
}
else if(Connected == DrawTypes.Provider)
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)
private void UpdatePowered()
{
//Let them set us to true
if (value == true)
var oldPowered = Powered;
Powered = ExternalPowered || InternalPowered;
if (oldPowered != Powered)
{
_powered = true;
return;
if (Powered)
{
OnPowerStateChanged?.Invoke(this, new PowerStateEventArgs(true));
}
//A powernet has decided we will not be powered this tick, lets try to power ourselves
if (value == false && Owner.TryGetComponent(out PowerStorageComponent storage))
else
{
if (storage.CanDeductCharge(Load))
{
storage.DeductCharge(Load);
_powered = true;
return;
OnPowerStateChanged?.Invoke(this, new PowerStateEventArgs(false));
}
}
//For some reason above we could not power ourselves, we depower
_powered = false;
return;
}
/// <summary>
@@ -196,7 +210,7 @@ namespace Content.Server.GameObjects.Components.Power
{
AvailableProviders.Add(provider);
if(Connected != DrawTypes.Node)
if (Connected != DrawTypes.Node)
{
ConnectToBestProvider();
}
@@ -234,7 +248,7 @@ namespace Content.Server.GameObjects.Components.Power
}
}
if(Provider != bestprovider)
if (Provider != bestprovider)
Provider = bestprovider;
}
@@ -249,6 +263,12 @@ namespace Content.Server.GameObjects.Components.Power
AvailableProviders.Remove(provider);
if (provider == Provider)
{
Provider = null;
ExternalPowered = false;
}
if (Connected != DrawTypes.Node)
{
ConnectToBestProvider();
@@ -260,7 +280,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
/// <param name="sender"></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
Provider = null;
@@ -274,7 +294,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
/// <param name="sender"></param>
/// <param name="eventarg"></param>
private void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
protected virtual void PowernetRegenerate(object sender, PowernetEventArgs eventarg)
{
eventarg.Powernet.AddDevice(this);
}
@@ -284,13 +304,31 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
/// <param name="sender"></param>
/// <param name="eventarg"></param>
private void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
protected virtual void PowernetDisconnect(object sender, PowernetEventArgs eventarg)
{
eventarg.Powernet.RemoveDevice(this);
Connected = DrawTypes.None;
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
@@ -298,6 +336,16 @@ namespace Content.Server.GameObjects.Components.Power
None = 0,
Node = 1,
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>())
.OrderByDescending(x => (x.GetComponent<TransformComponent>().WorldPosition - position).Length);
var choose = wires.FirstOrDefault();
if(choose != null)
if (choose != null)
ConnectToPowernet(choose.GetComponent<PowerTransferComponent>().Parent);
}
@@ -68,7 +68,7 @@ namespace Content.Server.GameObjects.Components.Power
public void ConnectToPowernet(Powernet toconnect)
{
Parent = toconnect;
Parent.Nodelist.Add(this);
Parent.NodeList.Add(this);
OnPowernetConnect?.Invoke(this, new PowernetEventArgs(Parent));
}
@@ -79,10 +79,10 @@ namespace Content.Server.GameObjects.Components.Power
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.NodeList.Remove(this);
Parent = toconnect;
Parent.Nodelist.Add(this);
Parent.NodeList.Add(this);
OnPowernetRegenerate?.Invoke(this, new PowernetEventArgs(Parent));
}
@@ -91,7 +91,11 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void DisconnectFromPowernet()
{
Parent.Nodelist.Remove(this);
if (Parent == null)
{
return;
}
Parent.NodeList.Remove(this);
OnPowernetDisconnect?.Invoke(this, new PowernetEventArgs(Parent));
Parent = null;
}

View File

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

View File

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

View File

@@ -25,7 +25,7 @@ namespace Content.Server.GameObjects.Components.Power
public override void Initialize()
{
if(Parent == null)
if (Parent == null)
{
SpreadPowernet();
}
@@ -49,7 +49,7 @@ namespace Content.Server.GameObjects.Components.Power
.Where(x => x.HasComponent<PowerTransferComponent>());
//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)
{
@@ -74,13 +74,13 @@ namespace Content.Server.GameObjects.Components.Power
.Where(x => x.HasComponent<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);
}
else if(node.Parent.Dirty)
else if (node.Parent.Dirty)
{
node.RegeneratePowernet(Parent);
}
@@ -95,7 +95,7 @@ namespace Content.Server.GameObjects.Components.Power
ptc.ConnectToPowernet(Parent);
SpreadPowernet();
}
else if(ptc.Parent != Parent && !ptc.Parent.Dirty)
else if (ptc.Parent != Parent && !ptc.Parent.Dirty)
{
Parent.MergePowernets(ptc.Parent);
}
@@ -109,7 +109,7 @@ namespace Content.Server.GameObjects.Components.Power
public void ConnectToPowernet(Powernet toconnect)
{
Parent = toconnect;
Parent.Wirelist.Add(this);
Parent.WireList.Add(this);
Regenerating = false;
}
@@ -118,7 +118,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void DisconnectFromPowernet()
{
Parent.Wirelist.Remove(this);
Parent.WireList.Remove(this);
Parent.Dirty = true;
Parent = null;
}
@@ -131,7 +131,7 @@ namespace Content.Server.GameObjects.Components.Power
public bool Attackby(IEntity user, IEntity attackwith)
{
if(attackwith.TryGetComponent(out WirecutterComponent wirecutter))
if (attackwith.TryGetComponent(out WirecutterComponent wirecutter))
{
Owner.Delete();
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()
{
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>
/// The entities that make up the powernet's physical location and allow powernet connection
/// </summary>
public List<PowerTransferComponent> Wirelist { get; set; } = new List<PowerTransferComponent>();
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>();
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>();
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());
public SortedSet<PowerDeviceComponent> DeviceLoadList { get; set; } = new SortedSet<PowerDeviceComponent>(new DevicePriorityCompare());
/// <summary>
/// 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);
//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);
depowervalue -= device.Load;
if (depowervalue < 0)
@@ -171,7 +175,7 @@ namespace Content.Server.GameObjects.Components.Power
{
foreach (var device in DepoweredDevices)
{
device.Powered = true;
device.ExternalPowered = true;
}
DepoweredDevices.Clear();
}
@@ -205,13 +209,13 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void DirtyKill()
{
Wirelist.Clear();
while (Nodelist.Count != 0)
WireList.Clear();
while (NodeList.Count != 0)
{
Nodelist[0].DisconnectFromPowernet();
NodeList[0].DisconnectFromPowernet();
}
Generatorlist.Clear();
Deviceloadlist.Clear();
GeneratorList.Clear();
DeviceLoadList.Clear();
DepoweredDevices.Clear();
PowerStorageSupplierlist.Clear();
PowerStorageConsumerlist.Clear();
@@ -226,31 +230,31 @@ namespace Content.Server.GameObjects.Components.Power
{
//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;
}
Wirelist.AddRange(toMerge.Wirelist);
toMerge.Wirelist.Clear();
WireList.AddRange(toMerge.WireList);
toMerge.WireList.Clear();
foreach (var node in toMerge.Nodelist)
foreach (var node in toMerge.NodeList)
{
node.Parent = this;
}
Nodelist.AddRange(toMerge.Nodelist);
toMerge.Nodelist.Clear();
NodeList.AddRange(toMerge.NodeList);
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);
toMerge.DepoweredDevices.Clear();
@@ -280,7 +284,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void AddDevice(PowerDeviceComponent device)
{
Deviceloadlist.Add(device);
DeviceLoadList.Add(device);
Load += device.Load;
if (!device.Powered)
DepoweredDevices.Add(device);
@@ -291,7 +295,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void UpdateDevice(PowerDeviceComponent device, float oldLoad)
{
if (Deviceloadlist.Contains(device))
if (DeviceLoadList.Contains(device))
{
Load -= oldLoad;
Load += device.Load;
@@ -303,10 +307,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void RemoveDevice(PowerDeviceComponent device)
{
if (Deviceloadlist.Contains(device))
if (DeviceLoadList.Contains(device))
{
Load -= device.Load;
Deviceloadlist.Remove(device);
DeviceLoadList.Remove(device);
if (DepoweredDevices.Contains(device))
DepoweredDevices.Remove(device);
}
@@ -322,7 +326,7 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void AddGenerator(PowerGeneratorComponent generator)
{
Generatorlist.Add(generator, generator.Supply);
GeneratorList.Add(generator, generator.Supply);
Supply += generator.Supply;
}
@@ -331,10 +335,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void UpdateGenerator(PowerGeneratorComponent generator)
{
if (Generatorlist.ContainsKey(generator))
if (GeneratorList.ContainsKey(generator))
{
Supply -= Generatorlist[generator];
Generatorlist[generator] = generator.Supply;
Supply -= GeneratorList[generator];
GeneratorList[generator] = generator.Supply;
Supply += generator.Supply;
}
}
@@ -344,10 +348,10 @@ namespace Content.Server.GameObjects.Components.Power
/// </summary>
public void RemoveGenerator(PowerGeneratorComponent generator)
{
if (Generatorlist.ContainsKey(generator))
if (GeneratorList.ContainsKey(generator))
{
Supply -= Generatorlist[generator];
Generatorlist.Remove(generator);
Supply -= GeneratorList[generator];
GeneratorList.Remove(generator);
}
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 angle = new Angle(clicklocation.ToWorld().Position - location.ToWorld().Position);
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)
continue;
if(entity.TryGetComponent(out DamageableComponent damagecomponent))
if (entity.TryGetComponent(out DamageableComponent damagecomponent))
{
damagecomponent.TakeDamage(DamageType.Brute, Damage);
}

View File

@@ -9,9 +9,9 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged
{
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);
}

View File

@@ -65,7 +65,8 @@ namespace Content.Server.GameObjects.EntitySystems
/// </summary>
/// <param name="user"></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>
@@ -198,7 +199,7 @@ namespace Content.Server.GameObjects.EntitySystems
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++)
{
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
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 SS14.Shared.GameObjects.System;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,6 +14,21 @@ namespace Content.Shared.GameObjects.EntitySystems
{
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)
{
for (int i = 0; i < Powernets.Count; i++)
@@ -20,12 +37,12 @@ namespace Content.Shared.GameObjects.EntitySystems
if (powernet.Dirty)
{
//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;
}
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
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);
}
// 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="Properties\AssemblyInfo.cs" />
<Compile Include="GameObjects\Components\Items\SharedHandsComponent.cs" />
<Compile Include="GameObjects\Components\Power\SharedPowerDebugTool.cs" />
<Compile Include="Maths\PhysicalConstants.cs" />
</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 STORAGE = 1005;
public const uint INVENTORY = 1006;
public const uint POWER_DEBUG_TOOL = 1007;
}
}

View File

@@ -57,6 +57,7 @@
- type: PowerProvider
Range: 5
Priority: Provider
Load: 0
- type: entity
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
- type: Icon
texture: Objects/multitool.png
- type: PowerDebugTool

2
engine

Submodule engine updated: dc80060757...6f4ea205ef