Connect to the closest ExtensionCable instead of the first (#17271)
This commit is contained in:
@@ -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
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestSupplyPrioritized()
|
||||
@@ -1189,28 +1189,37 @@ namespace Content.IntegrationTests.Tests.Power
|
||||
var extensionCableSystem = entityManager.EntitySysManager.GetEntitySystem<ExtensionCableSystem>();
|
||||
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<ApcPowerReceiverComponent>(powerReceiverEnt);
|
||||
|
||||
// Create an unpowered receiver outside range
|
||||
var unpoweredReceiverEnt = entityManager.SpawnEntity("ApcPowerReceiverDummy", grid.ToCoordinates(0, range));
|
||||
unpoweredReceiver = entityManager.GetComponent<ApcPowerReceiverComponent>(unpoweredReceiverEnt);
|
||||
|
||||
var battery = entityManager.GetComponent<BatteryComponent>(apcEnt);
|
||||
apcNetBattery = entityManager.GetComponent<PowerNetworkBatteryComponent>(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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ExtensionCableProviderComponent>();
|
||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
|
||||
ExtensionCableProviderComponent? closestCandidate = null;
|
||||
var closestDistanceFound = float.MaxValue;
|
||||
foreach (var entity in nearbyEntities)
|
||||
{
|
||||
if (entity == owner || !EntityManager.TryGetComponent<ExtensionCableProviderComponent?>(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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user