From fb175a520dfd8a3ad1a3e8d210a8597a713f788f Mon Sep 17 00:00:00 2001 From: Kara Date: Sun, 24 Sep 2023 13:34:08 -0700 Subject: [PATCH] Ghost hearing action (#19722) --- Content.Client/Ghost/GhostSystem.cs | 8 +-- Content.Server/Chat/Systems/ChatSystem.cs | 6 +-- Content.Server/Ghost/GhostSystem.cs | 26 ++++++++++ Content.Shared/Ghost/GhostComponent.cs | 47 +++++++++++------- Content.Shared/Ghost/GhostHearingComponent.cs | 9 ++++ Content.Shared/Ghost/SharedGhostSystem.cs | 3 ++ Resources/Locale/en-US/ghost/ghost-gui.ftl | 3 ++ .../Entities/Mobs/Player/admin_ghost.yml | 1 + .../Entities/Mobs/Player/observer.yml | 15 ++++++ .../Interface/Actions/ghostHearingToggled.png | Bin 0 -> 654 bytes .../Textures/Interface/Actions/meta.json | 3 ++ 11 files changed, 95 insertions(+), 26 deletions(-) create mode 100644 Content.Shared/Ghost/GhostHearingComponent.cs create mode 100644 Resources/Textures/Interface/Actions/ghostHearingToggled.png diff --git a/Content.Client/Ghost/GhostSystem.cs b/Content.Client/Ghost/GhostSystem.cs index a5353921fa..3ace889f27 100644 --- a/Content.Client/Ghost/GhostSystem.cs +++ b/Content.Client/Ghost/GhostSystem.cs @@ -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; diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index acc375b8b1..b8f4e116a4 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -739,7 +739,7 @@ public sealed partial class ChatSystem : SharedChatSystem // TODO proper speech occlusion var recipients = new Dictionary(); - var ghosts = GetEntityQuery(); + var ghostHearing = GetEntityQuery(); var xforms = GetEntityQuery(); 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)); diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index c8a410b91f..7881803901 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -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(OnGhostWarpToTargetRequest); SubscribeLocalEvent(OnActionPerform); + SubscribeLocalEvent(OnGhostHearingAction); SubscribeLocalEvent(OnEntityStorageInsertAttempt); SubscribeLocalEvent(_ => MakeVisible(true)); } + private void OnGhostHearingAction(EntityUid uid, GhostComponent component, ToggleGhostHearingActionEvent args) + { + args.Handled = true; + + if (HasComp(uid)) + { + RemComp(uid); + _actions.SetToggled(component.ToggleGhostHearingActionEntity, true); + } + else + { + AddComp(uid); + _actions.SetToggled(component.ToggleGhostHearingActionEntity, false); + } + + var str = HasComp(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); diff --git a/Content.Shared/Ghost/GhostComponent.cs b/Content.Shared/Ghost/GhostComponent.cs index e58cb3a16f..9090af4dba 100644 --- a/Content.Shared/Ghost/GhostComponent.cs +++ b/Content.Shared/Ghost/GhostComponent.cs @@ -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))] - public string ToggleLightingAction = "ActionToggleLighting"; + // Actions + [DataField] + public EntProtoId ToggleLightingAction = "ActionToggleLighting"; [DataField, AutoNetworkedField] public EntityUid? ToggleLightingActionEntity; - [DataField("toggleFovAction", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string ToggleFoVAction = "ActionToggleFov"; + [DataField] + public EntProtoId ToggleFoVAction = "ActionToggleFov"; [DataField, AutoNetworkedField] public EntityUid? ToggleFoVActionEntity; - [DataField("toggleGhostsAction", customTypeSerializer: typeof(PrototypeIdSerializer))] - 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 index 0000000000..c50a1f6c74 --- /dev/null +++ b/Content.Shared/Ghost/GhostHearingComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Shared.Ghost; + +/// +/// This is used for marking entities which should receive all local chat message, even when out of range +/// +[RegisterComponent] +public sealed partial class GhostHearingComponent : Component +{ +} diff --git a/Content.Shared/Ghost/SharedGhostSystem.cs b/Content.Shared/Ghost/SharedGhostSystem.cs index 1bd0bbacb9..c1c2c3c71e 100644 --- a/Content.Shared/Ghost/SharedGhostSystem.cs +++ b/Content.Shared/Ghost/SharedGhostSystem.cs @@ -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 /// public abstract class SharedGhostSystem : EntitySystem { + [Dependency] protected readonly SharedPopupSystem Popup = default!; + public override void Initialize() { base.Initialize(); diff --git a/Resources/Locale/en-US/ghost/ghost-gui.ftl b/Resources/Locale/en-US/ghost/ghost-gui.ftl index 8275d7e5d6..909513e96c 100644 --- a/Resources/Locale/en-US/ghost/ghost-gui.ftl +++ b/Resources/Locale/en-US/ghost/ghost-gui.ftl @@ -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} diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 851ddacdda..c07d62946e 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -15,6 +15,7 @@ context: "aghost" - type: Ghost canInteract: true + - type: GhostHearing - type: Hands - type: Puller - type: CombatMode diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index 66e0e42978..c7cac426a4 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -32,6 +32,7 @@ - type: Examiner skipChecks: true - type: Ghost + - type: GhostHearing - type: MovementSpeedModifier baseSprintSpeed: 12 baseWalkSpeed: 8 @@ -106,3 +107,17 @@ 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 index 0000000000000000000000000000000000000000..2c619ee496c2678e2933e5608b6bc159046f84df GIT binary patch literal 654 zcmV;90&)F`P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0wYO8K~z{r?Ug-C zBS9F)|Hi@u31XFyASRre!geqGBPg z(MsV8(TKUsJ^#tNnf4BUz6z)lX)Dqss=0VPt_J%16?-H049ZZJI@F~N zv*Zn?a1r=JLkekSA)=OL{B>$d<#IWd&*xt_F%NvE3}vZ9UE1(dLJd>NXsQN3s0)O( z6XWUh3nv&k*C<0->QI+9v@yTbGyFroCsV0^4t$cxIali_b&VNE95>-HaMTT)-l05` zKnXoaAc+Tre&1mK=?S;z=a?>)X0iy&S`wGI#-_;aO5_FEyv9uH40Uzs$SsMkfoVhK^+(f|Me07*qoM6N<$f@m5e%m4rY literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/meta.json b/Resources/Textures/Interface/Actions/meta.json index 6a6cb73219..97d48fa9fc 100644 --- a/Resources/Textures/Interface/Actions/meta.json +++ b/Resources/Textures/Interface/Actions/meta.json @@ -48,6 +48,9 @@ }, { "name": "web" + }, + { + "name": "ghostHearingToggled" } ] } -- 2.51.2