Fixes singularity collision and consume range (#13424)
Co-authored-by: keronshb <keronshb@live.com>
This commit is contained in:
@@ -8,6 +8,7 @@ namespace Content.Shared.Singularity.Components;
|
||||
/// Also makes the associated entity destroy other entities upon contact.
|
||||
/// Primarily managed by <see cref="SharedEventHorizonSystem"/> and its server/client versions.
|
||||
/// </summary>
|
||||
[Access(friends: typeof(SharedEventHorizonSystem))]
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class EventHorizonComponent : Component
|
||||
{
|
||||
@@ -17,7 +18,6 @@ public sealed class EventHorizonComponent : Component
|
||||
/// If you want to set this go through <see cref="SharedEventHorizonSystem.SetRadius"/>.
|
||||
/// </summary>
|
||||
[DataField("radius")]
|
||||
[Access(friends:typeof(SharedEventHorizonSystem))]
|
||||
public float Radius;
|
||||
|
||||
/// <summary>
|
||||
@@ -25,7 +25,7 @@ public sealed class EventHorizonComponent : Component
|
||||
/// If you want to set this go through <see cref="SharedEventHorizonSystem.SetCanBreachContainment"/>.
|
||||
/// </summary>
|
||||
[DataField("canBreachContainment")]
|
||||
[Access(friends:typeof(SharedEventHorizonSystem))]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool CanBreachContainment = false;
|
||||
|
||||
/// <summary>
|
||||
@@ -33,9 +33,18 @@ public sealed class EventHorizonComponent : Component
|
||||
/// Can be set to null, in which case no such fixture is used.
|
||||
/// If you want to set this go through <see cref="SharedEventHorizonSystem.SetHorizonFixtureId"/>.
|
||||
/// </summary>
|
||||
[DataField("horizonFixtureId")]
|
||||
[Access(friends:typeof(SharedEventHorizonSystem))]
|
||||
public string? HorizonFixtureId = "EventHorizon";
|
||||
[DataField("consumerFixtureId")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? ConsumerFixtureId = "EventHorizonConsumer";
|
||||
|
||||
/// <summary>
|
||||
/// The ID of the fixture used to detect if the event horizon has collided with any physics objects.
|
||||
/// Can be set to null, in which case no such fixture is used.
|
||||
/// If you want to set this go through <see cref="SharedEventHorizonSystem.SetHorizonFixtureId"/>.
|
||||
/// </summary>
|
||||
[DataField("colliderFixtureId")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? ColliderFixtureId = "EventHorizonCollider";
|
||||
|
||||
/// <summary>
|
||||
/// Whether the entity this event horizon is attached to is being consumed by another event horizon.
|
||||
@@ -49,22 +58,19 @@ public sealed class EventHorizonComponent : Component
|
||||
/// The amount of time that should elapse between this event horizon consuming everything it overlaps with.
|
||||
/// </summary>
|
||||
[DataField("consumePeriod")]
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[Access(typeof(SharedEventHorizonSystem))]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan TargetConsumePeriod { get; set; } = TimeSpan.FromSeconds(0.5);
|
||||
|
||||
/// <summary>
|
||||
/// The last time at which this consumed everything it overlapped with.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[Access(typeof(SharedEventHorizonSystem))]
|
||||
public TimeSpan LastConsumeWaveTime { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The next time at which this consumed everything it overlapped with.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[Access(typeof(SharedEventHorizonSystem))]
|
||||
public TimeSpan NextConsumeWaveTime { get; set; } = default!;
|
||||
|
||||
#endregion Update Timing
|
||||
|
||||
@@ -18,8 +18,8 @@ public sealed class SingularityComponent : Component
|
||||
/// Used as a scaling factor for things like visual size, event horizon radius, gravity well radius, radiation output, etc.
|
||||
/// If you want to set this use <see cref="SharedSingularitySystem.SetLevel"/>().
|
||||
/// </summary>
|
||||
[Access(friends: typeof(SharedSingularitySystem), Other = AccessPermissions.Read, Self = AccessPermissions.Read)]
|
||||
[DataField("level")]
|
||||
[Access(friends:typeof(SharedSingularitySystem), Other=AccessPermissions.Read, Self=AccessPermissions.Read)]
|
||||
public byte Level = 1;
|
||||
|
||||
/// <summary>
|
||||
@@ -27,8 +27,8 @@ public sealed class SingularityComponent : Component
|
||||
/// Has to be on shared in case someone attaches a RadiationPulseComponent to the singularity.
|
||||
/// If you want to set this use <see cref="SharedSingularitySystem.SetRadsPerLevel"/>().
|
||||
/// </summary>
|
||||
[Access(friends: typeof(SharedSingularitySystem), Other = AccessPermissions.Read, Self = AccessPermissions.Read)]
|
||||
[DataField("radsPerLevel")]
|
||||
[Access(friends:typeof(SharedSingularitySystem), Other=AccessPermissions.Read, Self=AccessPermissions.Read)]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float RadsPerLevel = 2f;
|
||||
|
||||
@@ -88,7 +88,7 @@ public sealed class SingularityComponent : Component
|
||||
/// The amount of time that should elapse between automated updates to this singularity.
|
||||
/// </summary>
|
||||
[DataField("updatePeriod")]
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan TargetUpdatePeriod = TimeSpan.FromSeconds(1.0);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -31,7 +31,8 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
var vvHandle = Vvm.GetTypeHandler<EventHorizonComponent>();
|
||||
vvHandle.AddPath(nameof(EventHorizonComponent.Radius), (_, comp) => comp.Radius, (uid, value, comp) => SetRadius(uid, value, eventHorizon: comp));
|
||||
vvHandle.AddPath(nameof(EventHorizonComponent.CanBreachContainment), (_, comp) => comp.CanBreachContainment, (uid, value, comp) => SetCanBreachContainment(uid, value, eventHorizon: comp));
|
||||
vvHandle.AddPath(nameof(EventHorizonComponent.HorizonFixtureId), (_, comp) => comp.HorizonFixtureId, (uid, value, comp) => SetHorizonFixtureId(uid, value, eventHorizon: comp));
|
||||
vvHandle.AddPath(nameof(EventHorizonComponent.ColliderFixtureId), (_, comp) => comp.ColliderFixtureId, (uid, value, comp) => SetColliderFixtureId(uid, value, eventHorizon: comp));
|
||||
vvHandle.AddPath(nameof(EventHorizonComponent.ConsumerFixtureId), (_, comp) => comp.ConsumerFixtureId, (uid, value, comp) => SetConsumerFixtureId(uid, value, eventHorizon: comp));
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
@@ -39,12 +40,13 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
var vvHandle = Vvm.GetTypeHandler<EventHorizonComponent>();
|
||||
vvHandle.RemovePath(nameof(EventHorizonComponent.Radius));
|
||||
vvHandle.RemovePath(nameof(EventHorizonComponent.CanBreachContainment));
|
||||
vvHandle.RemovePath(nameof(EventHorizonComponent.HorizonFixtureId));
|
||||
vvHandle.RemovePath(nameof(EventHorizonComponent.ColliderFixtureId));
|
||||
vvHandle.RemovePath(nameof(EventHorizonComponent.ConsumerFixtureId));
|
||||
|
||||
base.Shutdown();
|
||||
}
|
||||
|
||||
#region Getters/Setters
|
||||
#region Getters/Setters
|
||||
|
||||
/// <summary>
|
||||
/// Setter for <see cref="EventHorizonComponent.Radius"/>
|
||||
@@ -56,7 +58,7 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
/// <param name="eventHorizon">The state of the event horizon to change the radius of.</param>
|
||||
public void SetRadius(EntityUid uid, float value, bool updateFixture = true, EventHorizonComponent? eventHorizon = null)
|
||||
{
|
||||
if(!Resolve(uid, ref eventHorizon))
|
||||
if (!Resolve(uid, ref eventHorizon))
|
||||
return;
|
||||
|
||||
var oldValue = eventHorizon.Radius;
|
||||
@@ -79,7 +81,7 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
/// <param name="eventHorizon">The state of the event horizon to make (in)capable of breaching containment.</param>
|
||||
public void SetCanBreachContainment(EntityUid uid, bool value, bool updateFixture = true, EventHorizonComponent? eventHorizon = null)
|
||||
{
|
||||
if(!Resolve(uid, ref eventHorizon))
|
||||
if (!Resolve(uid, ref eventHorizon))
|
||||
return;
|
||||
|
||||
var oldValue = eventHorizon.CanBreachContainment;
|
||||
@@ -100,16 +102,39 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
/// <param name="value">The new fixture ID to associate the event horizon with.</param>
|
||||
/// <param name="updateFixture">Whether to update the associated fixture upon changing whether the event horizon can breach containment.</param>
|
||||
/// <param name="eventHorizon">The state of the event horizon with the fixture ID to change.</param>
|
||||
public void SetHorizonFixtureId(EntityUid uid, string? value, bool updateFixture = true, EventHorizonComponent? eventHorizon = null)
|
||||
public void SetColliderFixtureId(EntityUid uid, string? value, bool updateFixture = true, EventHorizonComponent? eventHorizon = null)
|
||||
{
|
||||
if(!Resolve(uid, ref eventHorizon))
|
||||
if (!Resolve(uid, ref eventHorizon))
|
||||
return;
|
||||
|
||||
var oldValue = eventHorizon.HorizonFixtureId;
|
||||
var oldValue = eventHorizon.ColliderFixtureId;
|
||||
if (value == oldValue)
|
||||
return;
|
||||
|
||||
eventHorizon.HorizonFixtureId = value;
|
||||
eventHorizon.ColliderFixtureId = value;
|
||||
Dirty(eventHorizon);
|
||||
if (updateFixture)
|
||||
UpdateEventHorizonFixture(uid, eventHorizon: eventHorizon);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setter for <see cref="EventHorizonComponent.HorizonFixtureId"/>
|
||||
/// May also update the fixture associated with the event horizon.
|
||||
/// </summary>
|
||||
/// <param name="uid">The uid of the event horizon with the fixture ID to change.</param>
|
||||
/// <param name="value">The new fixture ID to associate the event horizon with.</param>
|
||||
/// <param name="updateFixture">Whether to update the associated fixture upon changing whether the event horizon can breach containment.</param>
|
||||
/// <param name="eventHorizon">The state of the event horizon with the fixture ID to change.</param>
|
||||
public void SetConsumerFixtureId(EntityUid uid, string? value, bool updateFixture = true, EventHorizonComponent? eventHorizon = null)
|
||||
{
|
||||
if (!Resolve(uid, ref eventHorizon))
|
||||
return;
|
||||
|
||||
var oldValue = eventHorizon.ConsumerFixtureId;
|
||||
if (value == oldValue)
|
||||
return;
|
||||
|
||||
eventHorizon.ConsumerFixtureId = value;
|
||||
Dirty(eventHorizon);
|
||||
if (updateFixture)
|
||||
UpdateEventHorizonFixture(uid, eventHorizon: eventHorizon);
|
||||
@@ -118,33 +143,48 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Updates the state of the fixture associated with the event horizon.
|
||||
/// </summary>
|
||||
/// <param name="eventHorizon">The uid of the event horizon associated with the fixture to update.</param>
|
||||
/// <param name="physics">The physics component containing the fixture to update.</param>
|
||||
/// <param name="uid">The uid of the event horizon associated with the fixture to update.</param>
|
||||
/// <param name="fixtures">The fixture manager component containing the fixture to update.</param>
|
||||
/// <param name="eventHorizon">The state of the event horizon associated with the fixture to update.</param>
|
||||
public void UpdateEventHorizonFixture(EntityUid uid, PhysicsComponent? physics = null, EventHorizonComponent? eventHorizon = null)
|
||||
public void UpdateEventHorizonFixture(EntityUid uid, FixturesComponent? fixtures = null, EventHorizonComponent? eventHorizon = null)
|
||||
{
|
||||
if(!Resolve(uid, ref eventHorizon))
|
||||
if (!Resolve(uid, ref eventHorizon))
|
||||
return;
|
||||
|
||||
var fixtureId = eventHorizon.HorizonFixtureId;
|
||||
FixturesComponent? manager = null;
|
||||
|
||||
if (fixtureId == null || !Resolve(uid, ref manager, ref physics, logMissing: false))
|
||||
var consumerId = eventHorizon.ConsumerFixtureId;
|
||||
var colliderId = eventHorizon.ColliderFixtureId;
|
||||
if (consumerId == null || colliderId == null
|
||||
|| !Resolve(uid, ref fixtures, logMissing: false))
|
||||
return;
|
||||
|
||||
var fixture = _fixtures.GetFixtureOrNull(uid, fixtureId, manager);
|
||||
if (fixture == null)
|
||||
return;
|
||||
// Update both fixtures the event horizon is associated with:
|
||||
if (consumerId != null)
|
||||
{
|
||||
var consumer = _fixtures.GetFixtureOrNull(uid, consumerId, fixtures);
|
||||
if (consumer != null)
|
||||
{
|
||||
_physics.SetRadius(uid, consumer, consumer.Shape, eventHorizon.Radius, fixtures);
|
||||
_physics.SetHard(uid, consumer, false, fixtures);
|
||||
}
|
||||
}
|
||||
|
||||
var shape = (PhysShapeCircle)fixture.Shape;
|
||||
_physics.SetRadius(uid, fixture, shape, eventHorizon.Radius, manager: manager, body: physics);
|
||||
_physics.SetHard(uid, fixture, true, manager);
|
||||
if (colliderId != null)
|
||||
{
|
||||
var collider = _fixtures.GetFixtureOrNull(uid, colliderId, fixtures);
|
||||
if (collider != null)
|
||||
{
|
||||
_physics.SetRadius(uid, collider, collider.Shape, eventHorizon.Radius, fixtures);
|
||||
_physics.SetHard(uid, collider, true, fixtures);
|
||||
}
|
||||
}
|
||||
|
||||
EntityManager.Dirty(uid, fixtures);
|
||||
}
|
||||
|
||||
#endregion Getters/Setters
|
||||
#endregion Getters/Setters
|
||||
|
||||
|
||||
#region EventHandlers
|
||||
#region EventHandlers
|
||||
|
||||
/// <summary>
|
||||
/// Syncs the state of the fixture associated with the event horizon upon startup.
|
||||
@@ -167,7 +207,7 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
/// <param name="args">The event arguments.</param>
|
||||
private void OnPreventCollide(EntityUid uid, EventHorizonComponent comp, ref PreventCollideEvent args)
|
||||
{
|
||||
if(!args.Cancelled)
|
||||
if (!args.Cancelled)
|
||||
PreventCollide(uid, comp, ref args);
|
||||
}
|
||||
|
||||
@@ -205,5 +245,5 @@ public abstract class SharedEventHorizonSystem : EntitySystem
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion EventHandlers
|
||||
#endregion EventHandlers
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user