]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Ghost hearing action (#19722)
authorKara <lunarautomaton6@gmail.com>
Sun, 24 Sep 2023 20:34:08 +0000 (13:34 -0700)
committerGitHub <noreply@github.com>
Sun, 24 Sep 2023 20:34:08 +0000 (16:34 -0400)
Content.Client/Ghost/GhostSystem.cs
Content.Server/Chat/Systems/ChatSystem.cs
Content.Server/Ghost/GhostSystem.cs
Content.Shared/Ghost/GhostComponent.cs
Content.Shared/Ghost/GhostHearingComponent.cs [new file with mode: 0644]
Content.Shared/Ghost/SharedGhostSystem.cs
Resources/Locale/en-US/ghost/ghost-gui.ftl
Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml
Resources/Prototypes/Entities/Mobs/Player/observer.yml
Resources/Textures/Interface/Actions/ghostHearingToggled.png [new file with mode: 0644]
Resources/Textures/Interface/Actions/meta.json

index a5353921fa16ec0952dcc7c25f58dd0153d64a9f..3ace889f278740927f619f2fb19725aa22f0b29e 100644 (file)
@@ -15,7 +15,6 @@ namespace Content.Client.Ghost
         [Dependency] private readonly IPlayerManager _playerManager = default!;
         [Dependency] private readonly SharedActionsSystem _actions = default!;
         [Dependency] private readonly ILightManager _lightManager = default!;
-        [Dependency] private readonly SharedPopupSystem _popup = default!;
         [Dependency] private readonly ContentEyeSystem _contentEye = default!;
 
         public int AvailableGhostRoleCount { get; private set; }
@@ -83,7 +82,7 @@ namespace Content.Client.Ghost
             if (args.Handled)
                 return;
 
-            _popup.PopupEntity(Loc.GetString("ghost-gui-toggle-lighting-manager-popup"), args.Performer);
+            Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-lighting-manager-popup"), args.Performer);
             _lightManager.Enabled = !_lightManager.Enabled;
             args.Handled = true;
         }
@@ -93,7 +92,7 @@ namespace Content.Client.Ghost
             if (args.Handled)
                 return;
 
-            _popup.PopupEntity(Loc.GetString("ghost-gui-toggle-fov-popup"), args.Performer);
+            Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-fov-popup"), args.Performer);
             _contentEye.RequestToggleFov(uid);
             args.Handled = true;
         }
@@ -103,7 +102,7 @@ namespace Content.Client.Ghost
             if (args.Handled)
                 return;
 
-            _popup.PopupEntity(Loc.GetString("ghost-gui-toggle-ghost-visibility-popup"), args.Performer);
+            Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-ghost-visibility-popup"), args.Performer);
             ToggleGhostVisibility();
             args.Handled = true;
         }
@@ -113,6 +112,7 @@ namespace Content.Client.Ghost
             _actions.RemoveAction(uid, component.ToggleLightingActionEntity);
             _actions.RemoveAction(uid, component.ToggleFoVActionEntity);
             _actions.RemoveAction(uid, component.ToggleGhostsActionEntity);
+            _actions.RemoveAction(uid, component.ToggleGhostHearingActionEntity);
 
             if (uid != _playerManager.LocalPlayer?.ControlledEntity)
                 return;
index acc375b8b11d59d0c015af35df652add0a4a51e9..b8f4e116a45d6ab73f8fa055c97986750156ff5f 100644 (file)
@@ -739,7 +739,7 @@ public sealed partial class ChatSystem : SharedChatSystem
         // TODO proper speech occlusion
 
         var recipients = new Dictionary<ICommonSession, ICChatRecipientData>();
-        var ghosts = GetEntityQuery<GhostComponent>();
+        var ghostHearing = GetEntityQuery<GhostHearingComponent>();
         var xforms = GetEntityQuery<TransformComponent>();
 
         var transformSource = xforms.GetComponent(source);
@@ -756,9 +756,9 @@ public sealed partial class ChatSystem : SharedChatSystem
             if (transformEntity.MapID != sourceMapId)
                 continue;
 
-            var observer = ghosts.HasComponent(playerEntity);
+            var observer = ghostHearing.HasComponent(playerEntity);
 
-            // even if they are an observer, in some situations we still need the range
+            // even if they are a ghost hearer, in some situations we still need the range
             if (sourceCoords.TryDistance(EntityManager, transformEntity.Coordinates, out var distance) && distance < voiceGetRange)
             {
                 recipients.Add(player, new ICChatRecipientData(distance, observer));
index c8a410b91fcfad0f30a6331812f30fd770a87065..78818039017be10462354671b95b26dc2ee6f437 100644 (file)
@@ -16,6 +16,7 @@ using Content.Shared.Mind.Components;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Mobs.Systems;
 using Content.Shared.Movement.Events;
+using Content.Shared.Popups;
 using Content.Shared.Storage.Components;
 using Robust.Server.GameObjects;
 using Robust.Server.Player;
@@ -64,11 +65,35 @@ namespace Content.Server.Ghost
             SubscribeNetworkEvent<GhostWarpToTargetRequestEvent>(OnGhostWarpToTargetRequest);
 
             SubscribeLocalEvent<GhostComponent, BooActionEvent>(OnActionPerform);
+            SubscribeLocalEvent<GhostComponent, ToggleGhostHearingActionEvent>(OnGhostHearingAction);
             SubscribeLocalEvent<GhostComponent, InsertIntoEntityStorageAttemptEvent>(OnEntityStorageInsertAttempt);
 
             SubscribeLocalEvent<RoundEndTextAppendEvent>(_ => MakeVisible(true));
         }
 
+        private void OnGhostHearingAction(EntityUid uid, GhostComponent component, ToggleGhostHearingActionEvent args)
+        {
+            args.Handled = true;
+
+            if (HasComp<GhostHearingComponent>(uid))
+            {
+                RemComp<GhostHearingComponent>(uid);
+                _actions.SetToggled(component.ToggleGhostHearingActionEntity, true);
+            }
+            else
+            {
+                AddComp<GhostHearingComponent>(uid);
+                _actions.SetToggled(component.ToggleGhostHearingActionEntity, false);
+            }
+
+            var str = HasComp<GhostHearingComponent>(uid)
+                ? Loc.GetString("ghost-gui-toggle-hearing-popup-on")
+                : Loc.GetString("ghost-gui-toggle-hearing-popup-off");
+
+            Popup.PopupEntity(str, uid, uid);
+            Dirty(uid, component);
+        }
+
         private void OnActionPerform(EntityUid uid, GhostComponent component, BooActionEvent args)
         {
             if (args.Handled)
@@ -164,6 +189,7 @@ namespace Content.Server.Ghost
                 _actions.SetCooldown(component.BooActionEntity.Value, start, end);
             }
 
+            _actions.AddAction(uid, ref component.ToggleGhostHearingActionEntity, component.ToggleGhostHearingAction);
             _actions.AddAction(uid, ref component.ToggleLightingActionEntity, component.ToggleLightingAction);
             _actions.AddAction(uid, ref component.ToggleFoVActionEntity, component.ToggleFoVAction);
             _actions.AddAction(uid, ref component.ToggleGhostsActionEntity, component.ToggleGhostsAction);
index e58cb3a16f3fe55c4790bd3ffaa43d9042a41df2..9090af4dbaae2528f6ded12208b1bc861ff12bad 100644 (file)
@@ -1,8 +1,6 @@
 using Content.Shared.Actions;
 using Robust.Shared.GameStates;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
 
 namespace Content.Shared.Ghost;
 
@@ -14,32 +12,30 @@ public sealed partial class GhostComponent : Component
     [ViewVariables]
     public bool IsAttached;
 
-    [DataField("toggleLightingAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-    public string ToggleLightingAction = "ActionToggleLighting";
+    // Actions
+    [DataField]
+    public EntProtoId ToggleLightingAction = "ActionToggleLighting";
 
     [DataField, AutoNetworkedField]
     public EntityUid? ToggleLightingActionEntity;
 
-    [DataField("toggleFovAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-    public string ToggleFoVAction = "ActionToggleFov";
+    [DataField]
+    public EntProtoId ToggleFoVAction = "ActionToggleFov";
 
     [DataField, AutoNetworkedField]
     public EntityUid? ToggleFoVActionEntity;
 
-    [DataField("toggleGhostsAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
-    public string ToggleGhostsAction = "ActionToggleGhosts";
+    [DataField]
+    public EntProtoId ToggleGhostsAction = "ActionToggleGhosts";
 
     [DataField, AutoNetworkedField]
     public EntityUid? ToggleGhostsActionEntity;
 
-    [ViewVariables(VVAccess.ReadWrite), DataField("timeOfDeath", customTypeSerializer:typeof(TimeOffsetSerializer))]
-    public TimeSpan TimeOfDeath = TimeSpan.Zero;
-
-    [DataField("booRadius")]
-    public float BooRadius = 3;
+    [DataField]
+    public EntProtoId ToggleGhostHearingAction = "ActionToggleGhostHearing";
 
-    [DataField("booMaxTargets")]
-    public int BooMaxTargets = 3;
+    [DataField]
+    public EntityUid? ToggleGhostHearingActionEntity;
 
     [DataField]
     public EntProtoId BooAction = "ActionGhostBoo";
@@ -47,6 +43,17 @@ public sealed partial class GhostComponent : Component
     [DataField, AutoNetworkedField]
     public EntityUid? BooActionEntity;
 
+    // End actions
+
+    [ViewVariables(VVAccess.ReadWrite), DataField]
+    public TimeSpan TimeOfDeath = TimeSpan.Zero;
+
+    [DataField("booRadius")]
+    public float BooRadius = 3;
+
+    [DataField("booMaxTargets")]
+    public int BooMaxTargets = 3;
+
     // TODO: instead of this funny stuff just give it access and update in system dirtying when needed
     [ViewVariables(VVAccess.ReadWrite)]
     public bool CanGhostInteract
@@ -90,10 +97,12 @@ public sealed partial class GhostComponent : Component
     private bool _canReturnToBody;
 }
 
-public sealed partial class BooActionEvent : InstantActionEvent { }
+public sealed partial class ToggleFoVActionEvent : InstantActionEvent { }
 
-public sealed partial class ToggleFoVActionEvent : InstantActionEvent { };
+public sealed partial class ToggleGhostsActionEvent : InstantActionEvent { }
 
-public sealed partial class ToggleGhostsActionEvent : InstantActionEvent { };
+public sealed partial class ToggleLightingActionEvent : InstantActionEvent { }
 
-public sealed partial class ToggleLightingActionEvent : InstantActionEvent { };
+public sealed partial class ToggleGhostHearingActionEvent : InstantActionEvent { }
+
+public sealed partial class BooActionEvent : InstantActionEvent { }
diff --git a/Content.Shared/Ghost/GhostHearingComponent.cs b/Content.Shared/Ghost/GhostHearingComponent.cs
new file mode 100644 (file)
index 0000000..c50a1f6
--- /dev/null
@@ -0,0 +1,9 @@
+namespace Content.Shared.Ghost;
+
+/// <summary>
+/// This is used for marking entities which should receive all local chat message, even when out of range
+/// </summary>
+[RegisterComponent]
+public sealed partial class GhostHearingComponent : Component
+{
+}
index 1bd0bbacb9e927a4826b64944cb108d548bcdfe5..c1c2c3c71e898b3877aed5707a67f68abd50848f 100644 (file)
@@ -2,6 +2,7 @@ using Content.Shared.Emoting;
 using Content.Shared.Hands;
 using Content.Shared.Interaction.Events;
 using Content.Shared.Item;
+using Content.Shared.Popups;
 using Robust.Shared.Serialization;
 
 namespace Content.Shared.Ghost
@@ -12,6 +13,8 @@ namespace Content.Shared.Ghost
     /// </summary>
     public abstract class SharedGhostSystem : EntitySystem
     {
+        [Dependency] protected readonly SharedPopupSystem Popup = default!;
+
         public override void Initialize()
         {
             base.Initialize();
index 8275d7e5d61208712805e5a1ee5c4444ce12765b..909513e96caab27cd4c036c6abc2fdb9cbd78ae9 100644 (file)
@@ -5,6 +5,9 @@ ghost-gui-toggle-ghost-visibility-popup = Toggled visibility of ghosts.
 ghost-gui-toggle-lighting-manager-popup = Toggled all lighting.
 ghost-gui-toggle-fov-popup = Toggled field-of-view.
 
+ghost-gui-toggle-hearing-popup-on = You can now hear all messages.
+ghost-gui-toggle-hearing-popup-off = You can now only hear radio and nearby messages.
+
 ghost-target-window-title = Ghost Warp
 ghost-target-window-current-button = Warp: {$name}
 
index 851ddacdda28a5cb90ba27f392721e34970ebdea..c07d62946e70c4ff06cb73adf09b39732a80f541 100644 (file)
@@ -15,6 +15,7 @@
     context: "aghost"
   - type: Ghost
     canInteract: true
+  - type: GhostHearing
   - type: Hands
   - type: Puller
   - type: CombatMode
index 66e0e42978fa2353f06951845791d775c3c2152e..c7cac426a41b7ddd4efdf91b96d601a2ae4ad5f7 100644 (file)
@@ -32,6 +32,7 @@
   - type: Examiner
     skipChecks: true
   - type: Ghost
+  - type: GhostHearing
   - type: MovementSpeedModifier
     baseSprintSpeed: 12
     baseWalkSpeed: 8
     clientExclusive: true
     checkCanInteract: false
     event: !type:ToggleGhostsActionEvent
+
+- type: entity
+  id: ActionToggleGhostHearing
+  name: Toggle Ghost Hearing
+  description: Toggle between hearing all messages and hearing only radio & nearby messages.
+  noSpawn: true
+  components:
+  - type: InstantAction
+    checkCanInteract: false
+    icon:
+      sprite: Clothing/Ears/Headsets/base.rsi
+      state: icon
+    iconOn: Interface/Actions/ghostHearingToggled.png
+    event: !type:ToggleGhostHearingActionEvent
diff --git a/Resources/Textures/Interface/Actions/ghostHearingToggled.png b/Resources/Textures/Interface/Actions/ghostHearingToggled.png
new file mode 100644 (file)
index 0000000..2c619ee
Binary files /dev/null and b/Resources/Textures/Interface/Actions/ghostHearingToggled.png differ
index 6a6cb732190cf0d84a822cb051a0f6f52036cba9..97d48fa9fc03d9d01c9f8fe899f76c2c215953e6 100644 (file)
@@ -48,6 +48,9 @@
         },
         {
             "name": "web"
+        },
+        {
+            "name": "ghostHearingToggled"
         }
     ]
 }