diff --git a/Content.Server/Singularity/Components/GravityWellComponent.cs b/Content.Server/Singularity/Components/GravityWellComponent.cs
index 58a314fa8b..fb419d8831 100644
--- a/Content.Server/Singularity/Components/GravityWellComponent.cs
+++ b/Content.Server/Singularity/Components/GravityWellComponent.cs
@@ -7,22 +7,20 @@ namespace Content.Server.Singularity.Components;
/// The server-side version of .
/// Primarily managed by .
///
-[RegisterComponent]
+[RegisterComponent, AutoGenerateComponentPause]
public sealed partial class GravityWellComponent : Component
{
///
/// The maximum range at which the gravity well can push/pull entities.
///
- [DataField("maxRange")]
- [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
public float MaxRange;
///
/// The minimum range at which the gravity well can push/pull entities.
/// This is effectively hardfloored at .
///
- [DataField("minRange")]
- [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
public float MinRange = 0f;
///
@@ -30,8 +28,7 @@ public sealed partial class GravityWellComponent : Component
/// Negative values accelerate entities away from the gravity well.
/// Actual acceleration scales with the inverse of the distance to the singularity.
///
- [DataField("baseRadialAcceleration")]
- [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
public float BaseRadialAcceleration = 0.0f;
///
@@ -39,8 +36,7 @@ public sealed partial class GravityWellComponent : Component
/// Positive tangential acceleration is counter-clockwise.
/// Actual acceleration scales with the inverse of the distance to the singularity.
///
- [DataField("baseTangentialAcceleration")]
- [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
public float BaseTangentialAcceleration = 0.0f;
#region Update Timing
@@ -56,16 +52,14 @@ public sealed partial class GravityWellComponent : Component
///
/// The next time at which this gravity well should pulse.
///
- [ViewVariables(VVAccess.ReadOnly)]
- [Access(typeof(GravityWellSystem))]
+ [DataField, Access(typeof(GravityWellSystem)), AutoPausedField]
public TimeSpan NextPulseTime { get; internal set; } = default!;
///
/// The last time this gravity well pulsed.
///
[ViewVariables(VVAccess.ReadOnly)]
- [Access(typeof(GravityWellSystem))]
- public TimeSpan LastPulseTime { get; internal set; } = default!;
+ public TimeSpan LastPulseTime => NextPulseTime - TargetPulsePeriod;
#endregion Update Timing
}
diff --git a/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs b/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs
index 7dcf3ef1ae..6f2137b0d0 100644
--- a/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs
+++ b/Content.Server/Singularity/EntitySystems/GravityWellSystem.cs
@@ -39,6 +39,8 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
private EntityQuery _gridQuery;
private EntityQuery _physicsQuery;
+ private HashSet _entSet = new();
+
public override void Initialize()
{
base.Initialize();
@@ -46,12 +48,17 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
_mapQuery = GetEntityQuery();
_gridQuery = GetEntityQuery();
_physicsQuery = GetEntityQuery();
- SubscribeLocalEvent(OnGravityWellStartup);
+ SubscribeLocalEvent(OnGravityWellMapInit);
var vvHandle = _vvManager.GetTypeHandler();
vvHandle.AddPath(nameof(GravityWellComponent.TargetPulsePeriod), (_, comp) => comp.TargetPulsePeriod, SetPulsePeriod);
}
+ private void OnGravityWellMapInit(Entity ent, ref MapInitEvent args)
+ {
+ ent.Comp.NextPulseTime = _timing.CurTime + ent.Comp.TargetPulsePeriod;
+ }
+
public override void Shutdown()
{
var vvHandle = _vvManager.GetTypeHandler();
@@ -73,6 +80,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
while (query.MoveNext(out var uid, out var gravWell, out var xform))
{
var curTime = _timing.CurTime;
+
if (gravWell.NextPulseTime <= curTime)
Update(uid, curTime - gravWell.LastPulseTime, gravWell, xform);
}
@@ -103,8 +111,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
if(!Resolve(uid, ref gravWell))
return;
- gravWell.LastPulseTime = _timing.CurTime;
- gravWell.NextPulseTime = gravWell.LastPulseTime + gravWell.TargetPulsePeriod;
+ gravWell.NextPulseTime += gravWell.TargetPulsePeriod;
if (gravWell.MaxRange < 0.0f || !Resolve(uid, ref xform))
return;
@@ -195,15 +202,18 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
if (mapPos == MapCoordinates.Nullspace)
return; // No gravpulses in nullspace please.
+ _entSet.Clear();
var epicenter = mapPos.Position;
var minRange2 = MathF.Max(minRange * minRange, MinGravPulseRange); // Cache square value for speed. Also apply a sane minimum value to the minimum value so that div/0s don't happen.
- var bodyQuery = GetEntityQuery();
- var xformQuery = GetEntityQuery();
+ _lookup.GetEntitiesInRange(mapPos.MapId,
+ epicenter,
+ maxRange,
+ _entSet,
+ flags: LookupFlags.Dynamic | LookupFlags.Sundries);
- foreach(var entity in _lookup.GetEntitiesInRange(mapPos.MapId, epicenter, maxRange, flags: LookupFlags.Dynamic | LookupFlags.Sundries))
+ foreach (var entity in _entSet)
{
- if (!bodyQuery.TryGetComponent(entity, out var physics)
- || physics.BodyType == BodyType.Static)
+ if (!_physicsQuery.TryGetComponent(entity, out var physics))
{
continue;
}
@@ -214,7 +224,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
if(!CanGravPulseAffect(entity))
continue;
- var displacement = epicenter - _transform.GetWorldPosition(entity, xformQuery);
+ var displacement = epicenter - _transform.GetWorldPosition(entity);
var distance2 = displacement.LengthSquared();
if (distance2 < minRange2)
continue;
@@ -263,20 +273,4 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
}
#endregion Getters/Setters
-
- #region Event Handlers
-
- ///
- /// Resets the pulse timings of the gravity well when the components starts up.
- ///
- /// The uid of the gravity well to start up.
- /// The state of the gravity well to start up.
- /// The startup prompt arguments.
- public void OnGravityWellStartup(EntityUid uid, GravityWellComponent comp, ComponentStartup args)
- {
- comp.LastPulseTime = _timing.CurTime;
- comp.NextPulseTime = comp.LastPulseTime + comp.TargetPulsePeriod;
- }
-
- #endregion Event Handlers
}