diff --git a/Content.Server/Solar/EntitySystems/PowerSolarSystem.cs b/Content.Server/Solar/EntitySystems/PowerSolarSystem.cs
index a2400f1469..366cab3885 100644
--- a/Content.Server/Solar/EntitySystems/PowerSolarSystem.cs
+++ b/Content.Server/Solar/EntitySystems/PowerSolarSystem.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using Content.Server.Power.Components;
using Content.Server.Solar.Components;
@@ -10,7 +11,6 @@ using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Random;
-using Robust.Shared.Timing;
namespace Content.Server.Solar.EntitySystems
{
@@ -20,8 +20,8 @@ namespace Content.Server.Solar.EntitySystems
[UsedImplicitly]
internal sealed class PowerSolarSystem : EntitySystem
{
- [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
+ [Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
///
/// Maximum panel angular velocity range - used to stop people rotating panels fast enough that the lag prevention becomes noticable
@@ -44,19 +44,6 @@ namespace Content.Server.Solar.EntitySystems
///
public float SunOcclusionCheckDistance = 20;
- ///
- /// This is the per-second value used to reduce solar panel coverage updates
- /// (and the resulting occlusion raycasts)
- /// to within sane boundaries.
- /// Keep in mind, this is not exact, as the random interval is also applied.
- ///
- public TimeSpan SolarCoverageUpdateInterval = TimeSpan.FromSeconds(5);
-
- ///
- /// A random interval used to stagger solar coverage updates reliably.
- ///
- public TimeSpan SolarCoverageUpdateRandomInterval = TimeSpan.FromSeconds(5);
-
///
/// TODO: *Should be moved into the solar tracker when powernet allows for it.*
/// The current target panel rotation.
@@ -75,6 +62,12 @@ namespace Content.Server.Solar.EntitySystems
///
public float TotalPanelPower = 0;
+ ///
+ /// Queue of panels to update each cycle.
+ ///
+ private readonly Queue _updateQueue = new();
+
+
public override void Initialize()
{
SubscribeLocalEvent(OnMapInit);
@@ -110,21 +103,21 @@ namespace Content.Server.Solar.EntitySystems
TargetPanelRotation += TargetPanelVelocity * frameTime;
TargetPanelRotation = TargetPanelRotation.Reduced();
- TotalPanelPower = 0;
-
- foreach (var panel in EntityManager.EntityQuery())
+ if (_updateQueue.Count > 0)
{
- if (panel.TimeOfNextCoverageUpdate < _gameTiming.CurTime)
- {
- // Coverage update time!
- // There's supposed to be rotational logic here, but that implies putting it somewhere.
- panel.Owner.Transform.WorldRotation = TargetPanelRotation;
- // Setup the next coverage check.
- TimeSpan future = SolarCoverageUpdateInterval + (SolarCoverageUpdateRandomInterval * _robustRandom.NextDouble());
- panel.TimeOfNextCoverageUpdate = _gameTiming.CurTime + future;
+ var panel = _updateQueue.Dequeue();
+ if (panel.Running)
UpdatePanelCoverage(panel);
+ }
+ else
+ {
+ TotalPanelPower = 0;
+ foreach (var panel in EntityManager.EntityQuery())
+ {
+ TotalPanelPower += panel.MaxSupply * panel.Coverage;
+ panel.Owner.Transform.WorldRotation = TargetPanelRotation;
+ _updateQueue.Enqueue(panel);
}
- TotalPanelPower += panel.Coverage * panel.MaxSupply;
}
}
@@ -163,7 +156,11 @@ namespace Content.Server.Solar.EntitySystems
// Determine if the solar panel is occluded, and zero out coverage if so.
// FIXME: The "Opaque" collision group doesn't seem to work right now.
var ray = new CollisionRay(entity.Transform.WorldPosition, TowardsSun.ToWorldVec(), (int) CollisionGroup.Opaque);
- var rayCastResults = Get().IntersectRay(entity.Transform.MapID, ray, SunOcclusionCheckDistance, entity);
+ var rayCastResults = _physicsSystem.IntersectRayWithPredicate(
+ entity.Transform.MapID,
+ ray,
+ SunOcclusionCheckDistance,
+ e => !e.Transform.Anchored || e == entity);
if (rayCastResults.Any())
coverage = 0;
}