From 4f0b1f377eeb8533488ebf0ecb2a0bc7eabc7609 Mon Sep 17 00:00:00 2001 From: Justin Pfeifler Date: Thu, 6 Nov 2025 18:53:27 -0600 Subject: [PATCH] Gravity Generators cannot be unanchored while active (#41256) * Add unanchor attempt check * Combine shared component and server component - Combines SharedGravityGeneratorComponent and GravityGeneratorComponent - AutoNetworked the GravityActiveBool * Remove SharedGravityGeneratorComponent * Update to SharedGravityGeneratorComponent * Fix to be a complete sentence * Dirty GravityActive whenever changed * Rename component and remove view variables * Update referenced component name * Move unanchor attempt to shared system * Add client system * Revert popup to PopupEntity * Fix popup to be PopupClient * Set access restriction on GravityActive --- Content.Client/Entry/EntryPoint.cs | 1 - .../Gravity/GravityGeneratorSystem.cs | 8 +++++ Content.Client/Gravity/GravitySystem.cs | 4 +-- .../Tests/GravityGridTest.cs | 1 - .../Gravity/GravityGeneratorComponent.cs | 20 ------------ .../Gravity/GravityGeneratorSystem.cs | 4 ++- ...ponent.cs => GravityGeneratorComponent.cs} | 31 ++++++++++--------- .../Gravity/SharedGravityGeneratorSystem.cs | 29 +++++++++++++++++ .../components/station-anchor-component.ftl | 2 +- .../gravity/gravity-generator-component.ftl | 6 ++-- 10 files changed, 63 insertions(+), 43 deletions(-) create mode 100644 Content.Client/Gravity/GravityGeneratorSystem.cs delete mode 100644 Content.Server/Gravity/GravityGeneratorComponent.cs rename Content.Shared/Gravity/{SharedGravityGeneratorComponent.cs => GravityGeneratorComponent.cs} (59%) create mode 100644 Content.Shared/Gravity/SharedGravityGeneratorSystem.cs diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index ac08547859..b9f0e0e8e6 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -98,7 +98,6 @@ namespace Content.Client.Entry _componentFactory.IgnoreMissingComponents(); // Do not add to these, they are legacy. - _componentFactory.RegisterClass(); _componentFactory.RegisterClass(); // Do not add to the above, they are legacy diff --git a/Content.Client/Gravity/GravityGeneratorSystem.cs b/Content.Client/Gravity/GravityGeneratorSystem.cs new file mode 100644 index 0000000000..b74ea35daa --- /dev/null +++ b/Content.Client/Gravity/GravityGeneratorSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Gravity; + +namespace Content.Client.Gravity; + +public sealed class GravityGeneratorSystem : SharedGravityGeneratorSystem +{ + +} diff --git a/Content.Client/Gravity/GravitySystem.cs b/Content.Client/Gravity/GravitySystem.cs index 60e043cc99..f1e09fdb44 100644 --- a/Content.Client/Gravity/GravitySystem.cs +++ b/Content.Client/Gravity/GravitySystem.cs @@ -12,14 +12,14 @@ public sealed partial class GravitySystem : SharedGravitySystem public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnAppearanceChange); + SubscribeLocalEvent(OnAppearanceChange); InitializeShake(); } /// /// Ensures that the visible state of gravity generators are synced with their sprites. /// - private void OnAppearanceChange(EntityUid uid, SharedGravityGeneratorComponent comp, ref AppearanceChangeEvent args) + private void OnAppearanceChange(EntityUid uid, GravityGeneratorComponent comp, ref AppearanceChangeEvent args) { if (args.Sprite == null) return; diff --git a/Content.IntegrationTests/Tests/GravityGridTest.cs b/Content.IntegrationTests/Tests/GravityGridTest.cs index 8257035de6..047ec0259a 100644 --- a/Content.IntegrationTests/Tests/GravityGridTest.cs +++ b/Content.IntegrationTests/Tests/GravityGridTest.cs @@ -1,4 +1,3 @@ -using Content.Server.Gravity; using Content.Server.Power.Components; using Content.Shared.Gravity; using Robust.Shared.GameObjects; diff --git a/Content.Server/Gravity/GravityGeneratorComponent.cs b/Content.Server/Gravity/GravityGeneratorComponent.cs deleted file mode 100644 index c715a5e5f3..0000000000 --- a/Content.Server/Gravity/GravityGeneratorComponent.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Content.Shared.Gravity; -using Content.Shared.Construction.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.Gravity -{ - [RegisterComponent] - [Access(typeof(GravityGeneratorSystem))] - public sealed partial class GravityGeneratorComponent : SharedGravityGeneratorComponent - { - [DataField("lightRadiusMin")] public float LightRadiusMin { get; set; } - [DataField("lightRadiusMax")] public float LightRadiusMax { get; set; } - - /// - /// Is the gravity generator currently "producing" gravity? - /// - [ViewVariables] - public bool GravityActive { get; set; } = false; - } -} diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 9d58b82d69..8e714cf884 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -4,7 +4,7 @@ using Content.Shared.Gravity; namespace Content.Server.Gravity; -public sealed class GravityGeneratorSystem : EntitySystem +public sealed class GravityGeneratorSystem : SharedGravityGeneratorSystem { [Dependency] private readonly GravitySystem _gravitySystem = default!; [Dependency] private readonly SharedPointLightSystem _lights = default!; @@ -36,6 +36,7 @@ public sealed class GravityGeneratorSystem : EntitySystem private void OnActivated(Entity ent, ref ChargedMachineActivatedEvent args) { ent.Comp.GravityActive = true; + Dirty(ent, ent.Comp); var xform = Transform(ent); @@ -48,6 +49,7 @@ public sealed class GravityGeneratorSystem : EntitySystem private void OnDeactivated(Entity ent, ref ChargedMachineDeactivatedEvent args) { ent.Comp.GravityActive = false; + Dirty(ent, ent.Comp); var xform = Transform(ent); diff --git a/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs b/Content.Shared/Gravity/GravityGeneratorComponent.cs similarity index 59% rename from Content.Shared/Gravity/SharedGravityGeneratorComponent.cs rename to Content.Shared/Gravity/GravityGeneratorComponent.cs index 75b636b2fa..f7b1240f1a 100644 --- a/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs +++ b/Content.Shared/Gravity/GravityGeneratorComponent.cs @@ -3,42 +3,45 @@ using Robust.Shared.GameStates; namespace Content.Shared.Gravity; -[NetworkedComponent()] -[Virtual] -public partial class SharedGravityGeneratorComponent : Component +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class GravityGeneratorComponent : Component { + [DataField] public float LightRadiusMin { get; set; } + [DataField] public float LightRadiusMax { get; set; } + /// /// A map of the sprites used by the gravity generator given its status. /// - [DataField("spriteMap")] - [Access(typeof(SharedGravitySystem))] - public Dictionary SpriteMap = new(); + [DataField, Access(typeof(SharedGravitySystem))] + public Dictionary SpriteMap = []; /// /// The sprite used by the core of the gravity generator when the gravity generator is starting up. /// - [DataField("coreStartupState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreStartupState = "startup"; /// /// The sprite used by the core of the gravity generator when the gravity generator is idle. /// - [DataField("coreIdleState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreIdleState = "idle"; /// /// The sprite used by the core of the gravity generator when the gravity generator is activating. /// - [DataField("coreActivatingState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreActivatingState = "activating"; /// /// The sprite used by the core of the gravity generator when the gravity generator is active. /// - [DataField("coreActivatedState")] - [ViewVariables(VVAccess.ReadWrite)] + [DataField] public string CoreActivatedState = "activated"; + + /// + /// Is the gravity generator currently "producing" gravity? + /// + [DataField, AutoNetworkedField, Access(typeof(SharedGravityGeneratorSystem))] + public bool GravityActive = false; } diff --git a/Content.Shared/Gravity/SharedGravityGeneratorSystem.cs b/Content.Shared/Gravity/SharedGravityGeneratorSystem.cs new file mode 100644 index 0000000000..b2b2e72b62 --- /dev/null +++ b/Content.Shared/Gravity/SharedGravityGeneratorSystem.cs @@ -0,0 +1,29 @@ +using Content.Shared.Popups; +using Content.Shared.Construction.Components; + +namespace Content.Shared.Gravity; + +public abstract class SharedGravityGeneratorSystem : EntitySystem +{ + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUnanchorAttempt); + } + + /// + /// Prevent unanchoring when gravity is active + /// + private void OnUnanchorAttempt(Entity ent, ref UnanchorAttemptEvent args) + { + if (!ent.Comp.GravityActive) + return; + + _popupSystem.PopupClient(Loc.GetString("gravity-generator-unanchoring-failed"), ent.Owner, args.User, PopupType.Medium); + + args.Cancel(); + } +} diff --git a/Resources/Locale/en-US/components/station-anchor-component.ftl b/Resources/Locale/en-US/components/station-anchor-component.ftl index fd9d5ea4ae..18221e945a 100644 --- a/Resources/Locale/en-US/components/station-anchor-component.ftl +++ b/Resources/Locale/en-US/components/station-anchor-component.ftl @@ -1,2 +1,2 @@ -station-anchor-unanchoring-failed = Can't unanchor an active station anchor +station-anchor-unanchoring-failed = Can't unanchor an active station anchor. station-anchor-window-title = Station Anchor diff --git a/Resources/Locale/en-US/gravity/gravity-generator-component.ftl b/Resources/Locale/en-US/gravity/gravity-generator-component.ftl index b4e6cddcd5..fa3783fc34 100644 --- a/Resources/Locale/en-US/gravity/gravity-generator-component.ftl +++ b/Resources/Locale/en-US/gravity/gravity-generator-component.ftl @@ -1,11 +1,9 @@ ### Gravity Generator ## UI - gravity-generator-window-title = Gravity Generator ## UI field names - gravity-generator-window-status = Status: gravity-generator-window-power = Power: gravity-generator-window-eta = ETA: @@ -23,6 +21,8 @@ gravity-generator-window-power-off = Off gravity-generator-window-power-label = { $draw } / { $max } W ## UI ETA label - gravity-generator-window-eta-none = N/A gravity-generator-window-eta-value = { TOSTRING($left, "m\\:ss") } + +## Popup +gravity-generator-unanchoring-failed = Can't unanchor an active gravity generator.