[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; }
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;
}
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;
}
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;
}
_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;
// 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);
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));
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;
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)
_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);
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;
[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";
[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
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 { }
--- /dev/null
+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
+{
+}
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
/// </summary>
public abstract class SharedGhostSystem : EntitySystem
{
+ [Dependency] protected readonly SharedPopupSystem Popup = default!;
+
public override void Initialize()
{
base.Initialize();
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}
context: "aghost"
- type: Ghost
canInteract: true
+ - type: GhostHearing
- type: Hands
- type: Puller
- type: CombatMode
- 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
},
{
"name": "web"
+ },
+ {
+ "name": "ghostHearingToggled"
}
]
}