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 }