From a68c6cb29ea4a3e3d78e16c867366e488c699fff Mon Sep 17 00:00:00 2001 From: Saphire Date: Sun, 17 Nov 2024 03:58:15 +0600 Subject: [PATCH 1/7] Temporarily make singularity a bit harder to loose as non-antag --- .../SingularityGeneratorComponent.cs | 49 +++++++++-- .../SingularityGeneratorSystem.cs | 87 +++++++++++++++++-- .../components/generator-component.ftl | 2 + .../Generation/Singularity/generator.yml | 2 +- .../Power/Generation/Tesla/generator.yml | 4 +- 5 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 Resources/Locale/en-US/singularity/components/generator-component.ftl diff --git a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs b/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs index ea2628e5cb8286..180b84995846d2 100644 --- a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs +++ b/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs @@ -2,32 +2,69 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Content.Server.Singularity.EntitySystems; +using Content.Shared.Physics; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Server.Singularity.Components; -[RegisterComponent] +[RegisterComponent, AutoGenerateComponentPause] +[Access(typeof(SingularityGeneratorSystem))] public sealed partial class SingularityGeneratorComponent : Component { /// /// The amount of power this generator has accumulated. /// If you want to set this use /// - [DataField("power")] - [Access(friends:typeof(SingularityGeneratorSystem))] + [DataField] public float Power = 0; /// /// The power threshold at which this generator will spawn a singularity. /// If you want to set this use /// - [DataField("threshold")] - [Access(friends:typeof(SingularityGeneratorSystem))] + [DataField] public float Threshold = 16; + /// + /// Allows the generator to ignore all the failsafe stuff, e.g. when emagged + /// + [DataField] + public bool FailsafeDisabled = false; + + /// + /// Maximum distance at which the generator will check for a field at + /// + [DataField] + public float FailsafeDistance = 16; + /// /// The prototype ID used to spawn a singularity. /// [DataField("spawnId", customTypeSerializer: typeof(PrototypeIdSerializer))] - [ViewVariables(VVAccess.ReadWrite)] public string? SpawnPrototype = "Singularity"; + + /// + /// The masks the raycast should not go through + /// + [DataField] + public int CollisionMask = (int)CollisionGroup.FullTileMask; + + /// + /// Message to use when there's no containment field on cardinal directions + /// + [DataField] + public LocId ContainmentFailsafeMessage; + + /// + /// For how long the failsafe will cause the generator to stop working and not issue a failsafe warning + /// + [DataField] + public TimeSpan FailsafeCooldown = TimeSpan.FromSeconds(30); + + /// + /// How long until the generator can issue a failsafe warning again + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + [AutoPausedField] + public TimeSpan NextFailsafe; } diff --git a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs index a0c0262794824b..be0c5e49b5f612 100644 --- a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs @@ -1,7 +1,15 @@ +using System.Diagnostics; using Content.Server.ParticleAccelerator.Components; +using Content.Server.Popups; using Content.Server.Singularity.Components; +using Content.Shared.Emag.Systems; +using Content.Shared.Popups; using Content.Shared.Singularity.Components; +using Robust.Server.GameObjects; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; +using Robust.Shared.Timing; namespace Content.Server.Singularity.EntitySystems; @@ -9,6 +17,11 @@ public sealed class SingularityGeneratorSystem : EntitySystem { #region Dependencies [Dependency] private readonly IViewVariablesManager _vvm = default!; + [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly PhysicsSystem _physics = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly MetaDataSystem _metadata = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; #endregion Dependencies public override void Initialize() @@ -16,6 +29,7 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(HandleParticleCollide); + SubscribeLocalEvent(OnEmagged); var vvHandle = _vvm.GetTypeHandler(); vvHandle.AddPath(nameof(SingularityGeneratorComponent.Power), (_, comp) => comp.Power, SetPower); @@ -100,11 +114,33 @@ public void SetThreshold(EntityUid uid, float value, SingularityGeneratorCompone /// The state of the beginning of the collision. private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent component, ref StartCollideEvent args) { - if (EntityManager.TryGetComponent(args.OtherEntity, out var singularityGeneratorComponent)) + if (!EntityManager.TryGetComponent(args.OtherEntity, out var generatorComp)) + return; + + if (_timing.CurTime < _metadata.GetPauseTime(uid) + generatorComp.NextFailsafe) + { + EntityManager.QueueDeleteEntity(uid); + return; + } + + var contained = true; + var transform = Transform(args.OtherEntity); + var directions = Enum.GetValues().Length; + for (var i = 0; i < directions - 1; i += 2) // Skip every other direction, checking only cardinals + { + if (!CheckContainmentField((Direction)i, new Entity(args.OtherEntity, generatorComp), transform)) + contained = false; + } + + if (!contained) { + generatorComp.NextFailsafe = _timing.CurTime + generatorComp.FailsafeCooldown; + _popupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe", ("target", args.OtherEntity)), args.OtherEntity, PopupType.LargeCaution); + } + else SetPower( args.OtherEntity, - singularityGeneratorComponent.Power + component.State switch + generatorComp.Power + component.State switch { ParticleAcceleratorPowerState.Standby => 0, ParticleAcceleratorPowerState.Level0 => 1, @@ -113,10 +149,51 @@ private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent co ParticleAcceleratorPowerState.Level3 => 8, _ => 0 }, - singularityGeneratorComponent + generatorComp ); - EntityManager.QueueDeleteEntity(uid); - } + EntityManager.QueueDeleteEntity(uid); + } + + private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args) + { + _popupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe-disabled", ("target", uid)), uid); + component.FailsafeDisabled = true; + args.Handled = true; } #endregion Event Handlers + + /// + /// Checks whether there's a containment field in a given direction away from the generator + /// + /// The transform component of the singularity generator. + /// Mostly copied from + private bool CheckContainmentField(Direction dir, Entity generator, TransformComponent transform) + { + var component = generator.Comp; + + var (worldPosition, worldRotation) = _transformSystem.GetWorldPositionRotation(transform); + var dirRad = dir.ToAngle() + worldRotation; + + var ray = new CollisionRay(worldPosition, dirRad.ToVec(), component.CollisionMask); + var rayCastResults = _physics.IntersectRay(transform.MapID, ray, component.FailsafeDistance, generator, false); + var genQuery = GetEntityQuery(); + + RayCastResults? closestResult = null; + + foreach (var result in rayCastResults) + { + if (genQuery.HasComponent(result.HitEntity)) + closestResult = result; + + break; + } + + if (closestResult == null) + return false; + + var ent = closestResult.Value.HitEntity; + + // Check that the field can't be moved. The fields' transform parenting is weird, so skip that + return TryComp(ent, out var collidableComponent) && collidableComponent.BodyType == BodyType.Static; + } } diff --git a/Resources/Locale/en-US/singularity/components/generator-component.ftl b/Resources/Locale/en-US/singularity/components/generator-component.ftl new file mode 100644 index 00000000000000..f3a2254c38d60e --- /dev/null +++ b/Resources/Locale/en-US/singularity/components/generator-component.ftl @@ -0,0 +1,2 @@ +comp-generator-failsafe = The {$target} shakes as the containment failsafe triggers! +comp-generator-failsafe = Something fizzles out inside of {$target}... \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml index 647eae27724774..45a40bf0faf315 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml @@ -1,7 +1,7 @@ - type: entity id: SingularityGenerator name: gravitational singularity generator - description: An Odd Device which produces a Gravitational Singularity when set up. + description: An Odd Device which produces a Gravitational Singularity when set up. Comes with a temporary shutdown containment failsafe. placement: mode: SnapgridCenter components: diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/generator.yml index d45e6c58ea753a..bdd90f2f16afba 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/generator.yml @@ -2,12 +2,12 @@ id: TeslaGenerator name: tesla generator parent: BaseStructureDynamic - description: An Odd Device which produces a powerful Tesla ball when set up. + description: An Odd Device which produces a powerful Tesla ball when set up. Comes with a temporary shutdown containment failsafe. components: - type: Sprite noRot: true sprite: Structures/Power/Generation/Tesla/generator.rsi - state: icon + state: icon - type: SingularityGenerator # TODO: rename the generator spawnId: TeslaEnergyBall - type: InteractionOutline From 01d6df3d0ace170438aae3931339be539bd8b38e Mon Sep 17 00:00:00 2001 From: Saphire Date: Sun, 17 Nov 2024 04:18:00 +0600 Subject: [PATCH 2/7] Fix Fluent string ID copypaste fail --- .../Locale/en-US/singularity/components/generator-component.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Locale/en-US/singularity/components/generator-component.ftl b/Resources/Locale/en-US/singularity/components/generator-component.ftl index f3a2254c38d60e..d2a04f9cbc098c 100644 --- a/Resources/Locale/en-US/singularity/components/generator-component.ftl +++ b/Resources/Locale/en-US/singularity/components/generator-component.ftl @@ -1,2 +1,2 @@ comp-generator-failsafe = The {$target} shakes as the containment failsafe triggers! -comp-generator-failsafe = Something fizzles out inside of {$target}... \ No newline at end of file +comp-generator-failsafe-disabled = Something fizzles out inside of {$target}... \ No newline at end of file From 476f90df095502089d9f60ad59099f405be36cd2 Mon Sep 17 00:00:00 2001 From: Saphire Date: Sun, 17 Nov 2024 04:31:34 +0600 Subject: [PATCH 3/7] Fix the component defaults --- .../Singularity/Components/SingularityGeneratorComponent.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs b/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs index 180b84995846d2..8b9b4e74466ff5 100644 --- a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs +++ b/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs @@ -53,7 +53,7 @@ public sealed partial class SingularityGeneratorComponent : Component /// Message to use when there's no containment field on cardinal directions /// [DataField] - public LocId ContainmentFailsafeMessage; + public LocId ContainmentFailsafeMessage = "comp-generator-failsafe"; /// /// For how long the failsafe will cause the generator to stop working and not issue a failsafe warning @@ -66,5 +66,5 @@ public sealed partial class SingularityGeneratorComponent : Component /// [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] [AutoPausedField] - public TimeSpan NextFailsafe; + public TimeSpan NextFailsafe = TimeSpan.Zero; } From 68eaf6ff254e49789696f5a79691c119e26cbb18 Mon Sep 17 00:00:00 2001 From: Saphire Date: Tue, 19 Nov 2024 08:11:10 +0600 Subject: [PATCH 4/7] Bump the failsafe timer down --- .../Singularity/Components/SingularityGeneratorComponent.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs b/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs index 8b9b4e74466ff5..c8feeb5d5dbf33 100644 --- a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs +++ b/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Prototypes; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Content.Server.Singularity.EntitySystems; @@ -59,7 +59,7 @@ public sealed partial class SingularityGeneratorComponent : Component /// For how long the failsafe will cause the generator to stop working and not issue a failsafe warning /// [DataField] - public TimeSpan FailsafeCooldown = TimeSpan.FromSeconds(30); + public TimeSpan FailsafeCooldown = TimeSpan.FromSeconds(10); /// /// How long until the generator can issue a failsafe warning again From 6e53cd98a400466640586bf19b41ec281944795e Mon Sep 17 00:00:00 2001 From: SlamBamActionman Date: Tue, 19 Nov 2024 16:28:58 +0100 Subject: [PATCH 5/7] Add emag functionality --- .../SingularityGeneratorSystem.cs | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs index be0c5e49b5f612..cfca86bf4af7d4 100644 --- a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs @@ -117,27 +117,31 @@ private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent co if (!EntityManager.TryGetComponent(args.OtherEntity, out var generatorComp)) return; - if (_timing.CurTime < _metadata.GetPauseTime(uid) + generatorComp.NextFailsafe) + if (_timing.CurTime < _metadata.GetPauseTime(uid) + generatorComp.NextFailsafe && !generatorComp.FailsafeDisabled) { EntityManager.QueueDeleteEntity(uid); return; } var contained = true; - var transform = Transform(args.OtherEntity); - var directions = Enum.GetValues().Length; - for (var i = 0; i < directions - 1; i += 2) // Skip every other direction, checking only cardinals + if (!generatorComp.FailsafeDisabled) { - if (!CheckContainmentField((Direction)i, new Entity(args.OtherEntity, generatorComp), transform)) - contained = false; + var transform = Transform(args.OtherEntity); + var directions = Enum.GetValues().Length; + for (var i = 0; i < directions - 1; i += 2) // Skip every other direction, checking only cardinals + { + if (!CheckContainmentField((Direction)i, new Entity(args.OtherEntity, generatorComp), transform)) + contained = false; + } } - if (!contained) + if (!contained && !generatorComp.FailsafeDisabled) { generatorComp.NextFailsafe = _timing.CurTime + generatorComp.FailsafeCooldown; _popupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe", ("target", args.OtherEntity)), args.OtherEntity, PopupType.LargeCaution); } else + { SetPower( args.OtherEntity, generatorComp.Power + component.State switch @@ -151,6 +155,8 @@ private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent co }, generatorComp ); + } + EntityManager.QueueDeleteEntity(uid); } From 9c666457c2c13505725b7d3c336cae50f0666460 Mon Sep 17 00:00:00 2001 From: Saphire Date: Wed, 20 Nov 2024 07:49:45 +0600 Subject: [PATCH 6/7] Move some of the new singularity code into shared Hopefully without explosions yay --- .../SingularityGeneratorSystem.cs | 18 ++---------- .../SingularityGeneratorComponent.cs | 8 ++--- .../SharedSingularityGeneratorSystem.cs | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 20 deletions(-) rename {Content.Server => Content.Shared}/Singularity/Components/SingularityGeneratorComponent.cs (91%) create mode 100644 Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs diff --git a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs index cfca86bf4af7d4..95722449b87799 100644 --- a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs @@ -1,10 +1,7 @@ -using System.Diagnostics; using Content.Server.ParticleAccelerator.Components; -using Content.Server.Popups; -using Content.Server.Singularity.Components; -using Content.Shared.Emag.Systems; using Content.Shared.Popups; using Content.Shared.Singularity.Components; +using Content.Shared.Singularity.EntitySystems; using Robust.Server.GameObjects; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; @@ -13,7 +10,7 @@ namespace Content.Server.Singularity.EntitySystems; -public sealed class SingularityGeneratorSystem : EntitySystem +public sealed class SingularityGeneratorSystem : SharedSingularityGeneratorSystem { #region Dependencies [Dependency] private readonly IViewVariablesManager _vvm = default!; @@ -21,7 +18,6 @@ public sealed class SingularityGeneratorSystem : EntitySystem [Dependency] private readonly PhysicsSystem _physics = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly MetaDataSystem _metadata = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; #endregion Dependencies public override void Initialize() @@ -29,7 +25,6 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(HandleParticleCollide); - SubscribeLocalEvent(OnEmagged); var vvHandle = _vvm.GetTypeHandler(); vvHandle.AddPath(nameof(SingularityGeneratorComponent.Power), (_, comp) => comp.Power, SetPower); @@ -138,7 +133,7 @@ private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent co if (!contained && !generatorComp.FailsafeDisabled) { generatorComp.NextFailsafe = _timing.CurTime + generatorComp.FailsafeCooldown; - _popupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe", ("target", args.OtherEntity)), args.OtherEntity, PopupType.LargeCaution); + PopupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe", ("target", args.OtherEntity)), args.OtherEntity, PopupType.LargeCaution); } else { @@ -159,13 +154,6 @@ private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent co EntityManager.QueueDeleteEntity(uid); } - - private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args) - { - _popupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe-disabled", ("target", uid)), uid); - component.FailsafeDisabled = true; - args.Handled = true; - } #endregion Event Handlers /// diff --git a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs b/Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs similarity index 91% rename from Content.Server/Singularity/Components/SingularityGeneratorComponent.cs rename to Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs index c8feeb5d5dbf33..3643ed31a6f068 100644 --- a/Content.Server/Singularity/Components/SingularityGeneratorComponent.cs +++ b/Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs @@ -1,14 +1,12 @@ using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using Content.Server.Singularity.EntitySystems; using Content.Shared.Physics; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; -namespace Content.Server.Singularity.Components; +namespace Content.Shared.Singularity.Components; -[RegisterComponent, AutoGenerateComponentPause] -[Access(typeof(SingularityGeneratorSystem))] +[RegisterComponent, AutoGenerateComponentPause, AutoGenerateComponentState] public sealed partial class SingularityGeneratorComponent : Component { /// @@ -28,7 +26,7 @@ public sealed partial class SingularityGeneratorComponent : Component /// /// Allows the generator to ignore all the failsafe stuff, e.g. when emagged /// - [DataField] + [DataField, AutoNetworkedField] public bool FailsafeDisabled = false; /// diff --git a/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs b/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs new file mode 100644 index 00000000000000..8830cb0624cf77 --- /dev/null +++ b/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs @@ -0,0 +1,29 @@ +using Content.Shared.Emag.Systems; +using Content.Shared.Popups; +using Content.Shared.Singularity.Components; + +namespace Content.Shared.Singularity.EntitySystems; + +/// +/// Shared part of SingularitySingularityGeneratorSystem +/// +public abstract class SharedSingularityGeneratorSystem : EntitySystem +{ + #region Dependencies + [Dependency] protected readonly SharedPopupSystem PopupSystem = default!; + #endregion Dependencies + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEmagged); + } + + private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args) + { + PopupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe-disabled", ("target", uid)), uid); + component.FailsafeDisabled = true; + args.Handled = true; + } +} \ No newline at end of file From 44db676b24c8781e3290d499c7233125d7789cf6 Mon Sep 17 00:00:00 2001 From: Saphire Date: Wed, 20 Nov 2024 09:32:50 +0600 Subject: [PATCH 7/7] Actually make the emagging popup work properly --- .../Singularity/Systems/EventHorizonSystem.cs | 2 +- .../Systems/SingularityGeneratorSystem.cs | 12 ++++++++++++ .../Singularity/Systems/SingularitySystem.cs | 2 +- Content.Shared/Emag/Systems/EmagSystem.cs | 7 +++++++ .../Components/SingularityGeneratorComponent.cs | 3 ++- .../SharedSingularityGeneratorSystem.cs | 1 - 6 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 Content.Client/Singularity/Systems/SingularityGeneratorSystem.cs diff --git a/Content.Client/Singularity/Systems/EventHorizonSystem.cs b/Content.Client/Singularity/Systems/EventHorizonSystem.cs index 3dd63a0c9c889e..606116fced45af 100644 --- a/Content.Client/Singularity/Systems/EventHorizonSystem.cs +++ b/Content.Client/Singularity/Systems/EventHorizonSystem.cs @@ -1,7 +1,7 @@ using Content.Shared.Singularity.EntitySystems; using Content.Shared.Singularity.Components; -namespace Content.Client.Singularity.EntitySystems; +namespace Content.Client.Singularity.Systems; /// /// The client-side version of . diff --git a/Content.Client/Singularity/Systems/SingularityGeneratorSystem.cs b/Content.Client/Singularity/Systems/SingularityGeneratorSystem.cs new file mode 100644 index 00000000000000..f5b85f8b3cfead --- /dev/null +++ b/Content.Client/Singularity/Systems/SingularityGeneratorSystem.cs @@ -0,0 +1,12 @@ +using Content.Shared.Singularity.EntitySystems; +using Content.Shared.Singularity.Components; + +namespace Content.Client.Singularity.Systems; + +/// +/// The client-side version of . +/// Manages s. +/// Exists to make relevant signal handlers (ie: ) work on the client. +/// +public sealed class SingularityGeneratorSystem : SharedSingularityGeneratorSystem +{} diff --git a/Content.Client/Singularity/Systems/SingularitySystem.cs b/Content.Client/Singularity/Systems/SingularitySystem.cs index 5293ad499d07b8..50a12466be1397 100644 --- a/Content.Client/Singularity/Systems/SingularitySystem.cs +++ b/Content.Client/Singularity/Systems/SingularitySystem.cs @@ -5,7 +5,7 @@ using Robust.Shared.GameStates; using Robust.Shared.Utility; -namespace Content.Client.Singularity.EntitySystems; +namespace Content.Client.Singularity.Systems; /// /// The client-side version of . diff --git a/Content.Shared/Emag/Systems/EmagSystem.cs b/Content.Shared/Emag/Systems/EmagSystem.cs index 4d3bbcbb8e9d84..3a556b47063b75 100644 --- a/Content.Shared/Emag/Systems/EmagSystem.cs +++ b/Content.Shared/Emag/Systems/EmagSystem.cs @@ -96,6 +96,13 @@ public bool DoEmagEffect(EntityUid user, EntityUid target) } } +/// +/// Shows a popup to emag user (client side only!) and adds to the entity when handled +/// +/// Emag user +/// Did the emagging succeed? Causes a user-only popup to show on client side +/// Can the entity be emagged more than once? Prevents adding of +/// Needs to be handled in shared/client, not just the server, to actually show the emagging popup [ByRefEvent] public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false); diff --git a/Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs b/Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs index 3643ed31a6f068..715584b5bc64d7 100644 --- a/Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs +++ b/Content.Shared/Singularity/Components/SingularityGeneratorComponent.cs @@ -3,10 +3,11 @@ using Content.Shared.Physics; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Robust.Shared.GameStates; namespace Content.Shared.Singularity.Components; -[RegisterComponent, AutoGenerateComponentPause, AutoGenerateComponentState] +[RegisterComponent, AutoGenerateComponentPause, NetworkedComponent, AutoGenerateComponentState] public sealed partial class SingularityGeneratorComponent : Component { /// diff --git a/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs b/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs index 8830cb0624cf77..ee6dc89bb8478b 100644 --- a/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs +++ b/Content.Shared/Singularity/EntitySystems/SharedSingularityGeneratorSystem.cs @@ -22,7 +22,6 @@ public override void Initialize() private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args) { - PopupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe-disabled", ("target", uid)), uid); component.FailsafeDisabled = true; args.Handled = true; }