Gravity well improvements (#35027)
* Gravity well improvements - Fixed persistence - Removed dummy fields - Performance * Update Content.Server/Singularity/Components/GravityWellComponent.cs --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
This commit is contained in:
@@ -7,22 +7,20 @@ namespace Content.Server.Singularity.Components;
|
|||||||
/// The server-side version of <see cref="SharedGravityWellComponent"/>.
|
/// The server-side version of <see cref="SharedGravityWellComponent"/>.
|
||||||
/// Primarily managed by <see cref="GravityWellSystem"/>.
|
/// Primarily managed by <see cref="GravityWellSystem"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent, AutoGenerateComponentPause]
|
||||||
public sealed partial class GravityWellComponent : Component
|
public sealed partial class GravityWellComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum range at which the gravity well can push/pull entities.
|
/// The maximum range at which the gravity well can push/pull entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("maxRange")]
|
[DataField]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public float MaxRange;
|
public float MaxRange;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The minimum range at which the gravity well can push/pull entities.
|
/// The minimum range at which the gravity well can push/pull entities.
|
||||||
/// This is effectively hardfloored at <see cref="GravityWellSystem.MinGravPulseRange"/>.
|
/// This is effectively hardfloored at <see cref="GravityWellSystem.MinGravPulseRange"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("minRange")]
|
[DataField]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public float MinRange = 0f;
|
public float MinRange = 0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -30,8 +28,7 @@ public sealed partial class GravityWellComponent : Component
|
|||||||
/// Negative values accelerate entities away from the gravity well.
|
/// Negative values accelerate entities away from the gravity well.
|
||||||
/// Actual acceleration scales with the inverse of the distance to the singularity.
|
/// Actual acceleration scales with the inverse of the distance to the singularity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("baseRadialAcceleration")]
|
[DataField]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public float BaseRadialAcceleration = 0.0f;
|
public float BaseRadialAcceleration = 0.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -39,8 +36,7 @@ public sealed partial class GravityWellComponent : Component
|
|||||||
/// Positive tangential acceleration is counter-clockwise.
|
/// Positive tangential acceleration is counter-clockwise.
|
||||||
/// Actual acceleration scales with the inverse of the distance to the singularity.
|
/// Actual acceleration scales with the inverse of the distance to the singularity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("baseTangentialAcceleration")]
|
[DataField]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public float BaseTangentialAcceleration = 0.0f;
|
public float BaseTangentialAcceleration = 0.0f;
|
||||||
|
|
||||||
#region Update Timing
|
#region Update Timing
|
||||||
@@ -56,16 +52,14 @@ public sealed partial class GravityWellComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The next time at which this gravity well should pulse.
|
/// The next time at which this gravity well should pulse.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[DataField, Access(typeof(GravityWellSystem)), AutoPausedField]
|
||||||
[Access(typeof(GravityWellSystem))]
|
|
||||||
public TimeSpan NextPulseTime { get; internal set; } = default!;
|
public TimeSpan NextPulseTime { get; internal set; } = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last time this gravity well pulsed.
|
/// The last time this gravity well pulsed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
[Access(typeof(GravityWellSystem))]
|
public TimeSpan LastPulseTime => NextPulseTime - TargetPulsePeriod;
|
||||||
public TimeSpan LastPulseTime { get; internal set; } = default!;
|
|
||||||
|
|
||||||
#endregion Update Timing
|
#endregion Update Timing
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
private EntityQuery<MapGridComponent> _gridQuery;
|
private EntityQuery<MapGridComponent> _gridQuery;
|
||||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||||
|
|
||||||
|
private HashSet<EntityUid> _entSet = new();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -46,12 +48,17 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
_mapQuery = GetEntityQuery<MapComponent>();
|
_mapQuery = GetEntityQuery<MapComponent>();
|
||||||
_gridQuery = GetEntityQuery<MapGridComponent>();
|
_gridQuery = GetEntityQuery<MapGridComponent>();
|
||||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||||
SubscribeLocalEvent<GravityWellComponent, ComponentStartup>(OnGravityWellStartup);
|
SubscribeLocalEvent<GravityWellComponent, MapInitEvent>(OnGravityWellMapInit);
|
||||||
|
|
||||||
var vvHandle = _vvManager.GetTypeHandler<GravityWellComponent>();
|
var vvHandle = _vvManager.GetTypeHandler<GravityWellComponent>();
|
||||||
vvHandle.AddPath(nameof(GravityWellComponent.TargetPulsePeriod), (_, comp) => comp.TargetPulsePeriod, SetPulsePeriod);
|
vvHandle.AddPath(nameof(GravityWellComponent.TargetPulsePeriod), (_, comp) => comp.TargetPulsePeriod, SetPulsePeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGravityWellMapInit(Entity<GravityWellComponent> ent, ref MapInitEvent args)
|
||||||
|
{
|
||||||
|
ent.Comp.NextPulseTime = _timing.CurTime + ent.Comp.TargetPulsePeriod;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
{
|
{
|
||||||
var vvHandle = _vvManager.GetTypeHandler<GravityWellComponent>();
|
var vvHandle = _vvManager.GetTypeHandler<GravityWellComponent>();
|
||||||
@@ -73,6 +80,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
while (query.MoveNext(out var uid, out var gravWell, out var xform))
|
while (query.MoveNext(out var uid, out var gravWell, out var xform))
|
||||||
{
|
{
|
||||||
var curTime = _timing.CurTime;
|
var curTime = _timing.CurTime;
|
||||||
|
|
||||||
if (gravWell.NextPulseTime <= curTime)
|
if (gravWell.NextPulseTime <= curTime)
|
||||||
Update(uid, curTime - gravWell.LastPulseTime, gravWell, xform);
|
Update(uid, curTime - gravWell.LastPulseTime, gravWell, xform);
|
||||||
}
|
}
|
||||||
@@ -103,8 +111,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
if(!Resolve(uid, ref gravWell))
|
if(!Resolve(uid, ref gravWell))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gravWell.LastPulseTime = _timing.CurTime;
|
gravWell.NextPulseTime += gravWell.TargetPulsePeriod;
|
||||||
gravWell.NextPulseTime = gravWell.LastPulseTime + gravWell.TargetPulsePeriod;
|
|
||||||
if (gravWell.MaxRange < 0.0f || !Resolve(uid, ref xform))
|
if (gravWell.MaxRange < 0.0f || !Resolve(uid, ref xform))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -195,15 +202,18 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
if (mapPos == MapCoordinates.Nullspace)
|
if (mapPos == MapCoordinates.Nullspace)
|
||||||
return; // No gravpulses in nullspace please.
|
return; // No gravpulses in nullspace please.
|
||||||
|
|
||||||
|
_entSet.Clear();
|
||||||
var epicenter = mapPos.Position;
|
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 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<PhysicsComponent>();
|
_lookup.GetEntitiesInRange(mapPos.MapId,
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
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)
|
if (!_physicsQuery.TryGetComponent(entity, out var physics))
|
||||||
|| physics.BodyType == BodyType.Static)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -214,7 +224,7 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
if(!CanGravPulseAffect(entity))
|
if(!CanGravPulseAffect(entity))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var displacement = epicenter - _transform.GetWorldPosition(entity, xformQuery);
|
var displacement = epicenter - _transform.GetWorldPosition(entity);
|
||||||
var distance2 = displacement.LengthSquared();
|
var distance2 = displacement.LengthSquared();
|
||||||
if (distance2 < minRange2)
|
if (distance2 < minRange2)
|
||||||
continue;
|
continue;
|
||||||
@@ -263,20 +273,4 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion Getters/Setters
|
#endregion Getters/Setters
|
||||||
|
|
||||||
#region Event Handlers
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resets the pulse timings of the gravity well when the components starts up.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uid">The uid of the gravity well to start up.</param>
|
|
||||||
/// <param name="comp">The state of the gravity well to start up.</param>
|
|
||||||
/// <param name="args">The startup prompt arguments.</param>
|
|
||||||
public void OnGravityWellStartup(EntityUid uid, GravityWellComponent comp, ComponentStartup args)
|
|
||||||
{
|
|
||||||
comp.LastPulseTime = _timing.CurTime;
|
|
||||||
comp.NextPulseTime = comp.LastPulseTime + comp.TargetPulsePeriod;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Event Handlers
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user