diff --git a/Content.IntegrationTests/Tests/Power/PowerTest.cs b/Content.IntegrationTests/Tests/Power/PowerTest.cs
index 569e279ef4..391ac2bae8 100644
--- a/Content.IntegrationTests/Tests/Power/PowerTest.cs
+++ b/Content.IntegrationTests/Tests/Power/PowerTest.cs
@@ -484,7 +484,7 @@ namespace Content.IntegrationTests.Tests.Power
supplier.MaxSupply = draw/2;
supplier.SupplyRampRate = rampRate;
supplier.SupplyRampTolerance = rampTol;
-
+
battery.MaxCharge = 100_000;
battery.CurrentCharge = 100_000;
netBattery.MaxSupply = draw/2;
@@ -817,7 +817,7 @@ namespace Content.IntegrationTests.Tests.Power
///
/// Checks that if there is insufficient supply to meet demand, generators will run at full power instead of
- /// having generators and batteries sharing the load.
+ /// having generators and batteries sharing the load.
///
[Test]
public async Task TestSupplyPrioritized()
@@ -1189,28 +1189,37 @@ namespace Content.IntegrationTests.Tests.Power
var extensionCableSystem = entityManager.EntitySysManager.GetEntitySystem();
PowerNetworkBatteryComponent apcNetBattery = default!;
ApcPowerReceiverComponent receiver = default!;
+ ApcPowerReceiverComponent unpoweredReceiver = default!;
await server.WaitAssertion(() =>
{
var map = mapManager.CreateMap();
var grid = mapManager.CreateGrid(map);
+ const int range = 5;
+
// Power only works when anchored
- for (var i = 0; i < 3; i++)
+ for (var i = 0; i < range; i++)
{
grid.SetTile(new Vector2i(0, i), new Tile(1));
}
var apcEnt = entityManager.SpawnEntity("ApcDummy", grid.ToCoordinates(0, 0));
var apcExtensionEnt = entityManager.SpawnEntity("CableApcExtension", grid.ToCoordinates(0, 0));
- var powerReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.ToCoordinates(0, 2));
+ // Create a powered receiver in range (range is 0 indexed)
+ var powerReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.ToCoordinates(0, range - 1));
receiver = entityManager.GetComponent(powerReceiverEnt);
+
+ // Create an unpowered receiver outside range
+ var unpoweredReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.ToCoordinates(0, range));
+ unpoweredReceiver = entityManager.GetComponent(unpoweredReceiverEnt);
+
var battery = entityManager.GetComponent(apcEnt);
apcNetBattery = entityManager.GetComponent(apcEnt);
- extensionCableSystem.SetProviderTransferRange(apcExtensionEnt, 5);
- extensionCableSystem.SetReceiverReceptionRange(powerReceiverEnt, 5);
+ extensionCableSystem.SetProviderTransferRange(apcExtensionEnt, range);
+ extensionCableSystem.SetReceiverReceptionRange(powerReceiverEnt, range);
battery.MaxCharge = 10000; //arbitrary nonzero amount of charge
battery.CurrentCharge = battery.MaxCharge; //fill battery
@@ -1220,13 +1229,17 @@ namespace Content.IntegrationTests.Tests.Power
server.RunTicks(1); //let run a tick for ApcNet to process power
- await server.WaitAssertion(() =>
- {
- Assert.That(receiver.Powered);
- Assert.That(apcNetBattery.CurrentSupply, Is.EqualTo(1).Within(0.1));
+ await server.WaitAssertion(() => {
+ Assert.Multiple(() =>
+ {
+ Assert.That(receiver.Powered, "Receiver in range should be powered");
+ Assert.That(!unpoweredReceiver.Powered, "Out of range receiver should not be powered");
+ Assert.That(apcNetBattery.CurrentSupply, Is.EqualTo(1).Within(0.1));
+ });
});
await pairTracker.CleanReturnAsync();
}
+
}
}
diff --git a/Content.Server/Power/EntitySystems/ExtensionCableSystem.cs b/Content.Server/Power/EntitySystems/ExtensionCableSystem.cs
index 23bad50dea..143192a811 100644
--- a/Content.Server/Power/EntitySystems/ExtensionCableSystem.cs
+++ b/Content.Server/Power/EntitySystems/ExtensionCableSystem.cs
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using Content.Server.Power.Components;
using Robust.Shared.Map;
using Robust.Shared.Physics;
@@ -247,24 +248,42 @@ namespace Content.Server.Power.EntitySystems
var coordinates = xform.Coordinates;
var nearbyEntities = grid.GetCellsInSquareArea(coordinates, (int) Math.Ceiling(range / grid.TileSize));
+ var cableQuery = GetEntityQuery();
+ var metaQuery = GetEntityQuery();
+ var xformQuery = GetEntityQuery();
+ ExtensionCableProviderComponent? closestCandidate = null;
+ var closestDistanceFound = float.MaxValue;
foreach (var entity in nearbyEntities)
{
- if (entity == owner || !EntityManager.TryGetComponent(entity, out var provider)) continue;
+ if (entity == owner || !cableQuery.TryGetComponent(entity, out var provider) || !provider.Connectable)
+ continue;
- if (EntityManager.IsQueuedForDeletion(entity)) continue;
+ if (EntityManager.IsQueuedForDeletion(entity))
+ continue;
- if (MetaData(entity).EntityLifeStage > EntityLifeStage.MapInitialized) continue;
+ if (!metaQuery.TryGetComponent(entity, out var meta) || meta.EntityLifeStage > EntityLifeStage.MapInitialized)
+ continue;
- if (!provider.Connectable) continue;
+ // Find the closest provider
+ if (!xformQuery.TryGetComponent(entity, out var entityXform))
+ continue;
+ var distance = (entityXform.LocalPosition - xform.LocalPosition).Length;
+ if (distance >= closestDistanceFound)
+ continue;
- if ((Transform(entity).LocalPosition - xform.LocalPosition).Length > Math.Min(range, provider.TransferRange)) continue;
+ closestCandidate = provider;
+ closestDistanceFound = distance;
+ }
- foundProvider = provider;
+ // Make sure the provider is in range before claiming success
+ if (closestCandidate != null && closestDistanceFound <= Math.Min(range, closestCandidate.TransferRange))
+ {
+ foundProvider = closestCandidate;
return true;
}
- foundProvider = default;
+ foundProvider = null;
return false;
}