* Cleanup warnings in MagazineVisualsSpriteTest * Cleanup warnings in WiresVisualizerSystem * Cleanup warnings in GunSystem.SpentAmmo * Cleanup warnings in GunSystem * Cleanup warnings in GunSystem.ChamberMagazine * Cleanup warnings in MeleeWeaponSystem.Effects * Cleanup warnings in ToggleableLightVisualsSystem * Cleanup warnings in StatusIconOverlay * Cleanup warnings in SpriteFadeSystem * Cleanup warnings in PdaVisualizerSystem * Cleanup warnings in EnvelopeSystem * Cleanup warnings in MechSystem * Cleanup warnings in MappingOverlay * Cleanup warnings in LockVisualizerSystem * Cleanup warnings in DragDropSystem * Cleanup warnings in GhostSystem * Cleanup warnings in TriggerSystem.Proximity * Cleanup warnings in DragonSystem * Cleanup warnings in PortableScrubberVisualsSystem * File-scoped namespace for PortableScrubberVisualsSystem
206 lines
7.6 KiB
C#
206 lines
7.6 KiB
C#
using Content.Client.Movement.Systems;
|
|
using Content.Shared.Actions;
|
|
using Content.Shared.Ghost;
|
|
using Robust.Client.Console;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.Player;
|
|
|
|
namespace Content.Client.Ghost
|
|
{
|
|
public sealed class GhostSystem : SharedGhostSystem
|
|
{
|
|
[Dependency] private readonly IClientConsoleHost _console = default!;
|
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
|
[Dependency] private readonly PointLightSystem _pointLightSystem = default!;
|
|
[Dependency] private readonly ContentEyeSystem _contentEye = default!;
|
|
[Dependency] private readonly SpriteSystem _sprite = default!;
|
|
|
|
public int AvailableGhostRoleCount { get; private set; }
|
|
|
|
private bool _ghostVisibility = true;
|
|
|
|
private bool GhostVisibility
|
|
{
|
|
get => _ghostVisibility;
|
|
set
|
|
{
|
|
if (_ghostVisibility == value)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_ghostVisibility = value;
|
|
|
|
var query = AllEntityQuery<GhostComponent, SpriteComponent>();
|
|
while (query.MoveNext(out var uid, out _, out var sprite))
|
|
{
|
|
_sprite.SetVisible((uid, sprite), value || uid == _playerManager.LocalEntity);
|
|
}
|
|
}
|
|
}
|
|
|
|
public GhostComponent? Player => CompOrNull<GhostComponent>(_playerManager.LocalEntity);
|
|
public bool IsGhost => Player != null;
|
|
|
|
public event Action<GhostComponent>? PlayerRemoved;
|
|
public event Action<GhostComponent>? PlayerUpdated;
|
|
public event Action<GhostComponent>? PlayerAttached;
|
|
public event Action? PlayerDetached;
|
|
public event Action<GhostWarpsResponseEvent>? GhostWarpsResponse;
|
|
public event Action<GhostUpdateGhostRoleCountEvent>? GhostRoleCountUpdated;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<GhostComponent, ComponentStartup>(OnStartup);
|
|
SubscribeLocalEvent<GhostComponent, ComponentRemove>(OnGhostRemove);
|
|
SubscribeLocalEvent<GhostComponent, AfterAutoHandleStateEvent>(OnGhostState);
|
|
|
|
SubscribeLocalEvent<GhostComponent, LocalPlayerAttachedEvent>(OnGhostPlayerAttach);
|
|
SubscribeLocalEvent<GhostComponent, LocalPlayerDetachedEvent>(OnGhostPlayerDetach);
|
|
|
|
SubscribeNetworkEvent<GhostWarpsResponseEvent>(OnGhostWarpsResponse);
|
|
SubscribeNetworkEvent<GhostUpdateGhostRoleCountEvent>(OnUpdateGhostRoleCount);
|
|
|
|
SubscribeLocalEvent<EyeComponent, ToggleLightingActionEvent>(OnToggleLighting);
|
|
SubscribeLocalEvent<EyeComponent, ToggleFoVActionEvent>(OnToggleFoV);
|
|
SubscribeLocalEvent<GhostComponent, ToggleGhostsActionEvent>(OnToggleGhosts);
|
|
}
|
|
|
|
private void OnStartup(EntityUid uid, GhostComponent component, ComponentStartup args)
|
|
{
|
|
if (TryComp(uid, out SpriteComponent? sprite))
|
|
_sprite.SetVisible((uid, sprite), GhostVisibility || uid == _playerManager.LocalEntity);
|
|
}
|
|
|
|
private void OnToggleLighting(EntityUid uid, EyeComponent component, ToggleLightingActionEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
|
|
TryComp<PointLightComponent>(uid, out var light);
|
|
|
|
if (!component.DrawLight)
|
|
{
|
|
// normal lighting
|
|
Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-lighting-manager-popup-normal"), args.Performer);
|
|
_contentEye.RequestEye(component.DrawFov, true);
|
|
}
|
|
else if (!light?.Enabled ?? false) // skip this option if we have no PointLightComponent
|
|
{
|
|
// enable personal light
|
|
Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-lighting-manager-popup-personal-light"), args.Performer);
|
|
_pointLightSystem.SetEnabled(uid, true, light);
|
|
}
|
|
else
|
|
{
|
|
// fullbright mode
|
|
Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-lighting-manager-popup-fullbright"), args.Performer);
|
|
_contentEye.RequestEye(component.DrawFov, false);
|
|
_pointLightSystem.SetEnabled(uid, false, light);
|
|
}
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void OnToggleFoV(EntityUid uid, EyeComponent component, ToggleFoVActionEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
|
|
Popup.PopupEntity(Loc.GetString("ghost-gui-toggle-fov-popup"), args.Performer);
|
|
_contentEye.RequestToggleFov(uid, component);
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void OnToggleGhosts(EntityUid uid, GhostComponent component, ToggleGhostsActionEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
|
|
var locId = GhostVisibility ? "ghost-gui-toggle-ghost-visibility-popup-off" : "ghost-gui-toggle-ghost-visibility-popup-on";
|
|
Popup.PopupEntity(Loc.GetString(locId), args.Performer);
|
|
if (uid == _playerManager.LocalEntity)
|
|
ToggleGhostVisibility();
|
|
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void OnGhostRemove(EntityUid uid, GhostComponent component, ComponentRemove args)
|
|
{
|
|
_actions.RemoveAction(uid, component.ToggleLightingActionEntity);
|
|
_actions.RemoveAction(uid, component.ToggleFoVActionEntity);
|
|
_actions.RemoveAction(uid, component.ToggleGhostsActionEntity);
|
|
_actions.RemoveAction(uid, component.ToggleGhostHearingActionEntity);
|
|
|
|
if (uid != _playerManager.LocalEntity)
|
|
return;
|
|
|
|
GhostVisibility = false;
|
|
PlayerRemoved?.Invoke(component);
|
|
}
|
|
|
|
private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent)
|
|
{
|
|
GhostVisibility = true;
|
|
PlayerAttached?.Invoke(component);
|
|
}
|
|
|
|
private void OnGhostState(EntityUid uid, GhostComponent component, ref AfterAutoHandleStateEvent args)
|
|
{
|
|
if (TryComp<SpriteComponent>(uid, out var sprite))
|
|
_sprite.LayerSetColor((uid, sprite), 0, component.Color);
|
|
|
|
if (uid != _playerManager.LocalEntity)
|
|
return;
|
|
|
|
PlayerUpdated?.Invoke(component);
|
|
}
|
|
|
|
private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, LocalPlayerDetachedEvent args)
|
|
{
|
|
GhostVisibility = false;
|
|
PlayerDetached?.Invoke();
|
|
}
|
|
|
|
private void OnGhostWarpsResponse(GhostWarpsResponseEvent msg)
|
|
{
|
|
if (!IsGhost)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GhostWarpsResponse?.Invoke(msg);
|
|
}
|
|
|
|
private void OnUpdateGhostRoleCount(GhostUpdateGhostRoleCountEvent msg)
|
|
{
|
|
AvailableGhostRoleCount = msg.AvailableGhostRoles;
|
|
GhostRoleCountUpdated?.Invoke(msg);
|
|
}
|
|
|
|
public void RequestWarps()
|
|
{
|
|
RaiseNetworkEvent(new GhostWarpsRequestEvent());
|
|
}
|
|
|
|
public void ReturnToBody()
|
|
{
|
|
var msg = new GhostReturnToBodyRequest();
|
|
RaiseNetworkEvent(msg);
|
|
}
|
|
|
|
public void OpenGhostRoles()
|
|
{
|
|
_console.RemoteExecuteCommand(null, "ghostroles");
|
|
}
|
|
|
|
public void ToggleGhostVisibility(bool? visibility = null)
|
|
{
|
|
GhostVisibility = visibility ?? !GhostVisibility;
|
|
}
|
|
}
|
|
}
|