From 7c385de1fb5c0854f6926db5b2684ac22f734c63 Mon Sep 17 00:00:00 2001 From: Hero010h <163765999+Hero010h@users.noreply.github.com> Date: Sat, 4 Apr 2026 02:23:45 +0300 Subject: [PATCH] Invisibility added --- .../UI/Tabs/AdminTab/AdminTab.xaml | 2 + .../Administration/InvisibilitySystem.cs | 63 +++++++++++++++++++ .../_Amour/Commands/InvisibilityCommand.cs | 33 ++++++++++ .../InvisibilityComponent.cs | 14 +++++ .../SharedInvisibilitySystem.cs | 30 +++++++++ .../tabs/admin-tab/player-actions-window.ftl | 2 + .../Entities/Mobs/Player/admin_ghost.yml | 1 + 7 files changed, 145 insertions(+) create mode 100644 Content.Server/_Amour/Administration/InvisibilitySystem.cs create mode 100644 Content.Server/_Amour/Commands/InvisibilityCommand.cs create mode 100644 Content.Shared/_Amour/Administration/InvisibilitySystem/InvisibilityComponent.cs create mode 100644 Content.Shared/_Amour/Administration/InvisibilitySystem/SharedInvisibilitySystem.cs diff --git a/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml b/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml index 9dda6b2be14..74ea62cfaa6 100644 --- a/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml +++ b/Content.Client/Administration/UI/Tabs/AdminTab/AdminTab.xaml @@ -28,6 +28,8 @@ SPDX-License-Identifier: AGPL-3.0-or-later + + diff --git a/Content.Server/_Amour/Administration/InvisibilitySystem.cs b/Content.Server/_Amour/Administration/InvisibilitySystem.cs new file mode 100644 index 00000000000..0a34ddadce4 --- /dev/null +++ b/Content.Server/_Amour/Administration/InvisibilitySystem.cs @@ -0,0 +1,63 @@ +using Content.Shared._Amour.Administration; +using Content.Shared.Eye; +using Content.Shared.Follower; +using Content.Shared.Follower.Components; +using Content.Shared.Ghost; +using Robust.Server.GameObjects; +using InvisibilityComponent = Content.Shared._Amour.Administration.InvisibilityComponent; + +namespace Content.Server._Amour.Administration; + +public sealed class InvisibilitySystem : SharedInvisibilitySystem +{ + [Dependency] private readonly VisibilitySystem _visibilitySystem = default!; + [Dependency] private readonly FollowerSystem _followerSystem = default!; + [Dependency] private readonly SharedEyeSystem _eyeSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInvisibilityStartup); + SubscribeLocalEvent(OnInvisibilityShutdown); + } + + private void OnInvisibilityStartup(EntityUid uid, InvisibilityComponent component, ComponentStartup args) + { + if (EntityManager.TryGetComponent(uid, out EyeComponent? eye)) + { + _eyeSystem.SetVisibilityMask(uid, eye.VisibilityMask | (int) VisibilityFlags.Admin, eye); + } + } + + private void OnInvisibilityShutdown(EntityUid uid, InvisibilityComponent component, ComponentShutdown args) + { + if (EntityManager.TryGetComponent(uid, out VisibilityComponent? visibility)) + { + _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Admin); + } + + if (EntityManager.TryGetComponent(uid, out EyeComponent? eye)) + { + _eyeSystem.SetVisibilityMask(uid, eye.VisibilityMask & ~(int) VisibilityFlags.Admin, eye); + } + } + + public void ToggleInvisibility(EntityUid uid, InvisibilityComponent component) + { + if (!EntityManager.TryGetComponent(uid, out VisibilityComponent? visibility)) + return; + + if (TryComp(uid, out FollowedComponent? followed)) + _followerSystem.StopAllFollowers(uid, followed); + + component.Invisible = !component.Invisible; + + _visibilitySystem.SetLayer((uid, visibility), + (ushort) (component.Invisible ? VisibilityFlags.Admin : + EntityManager.HasComponent(uid) ? VisibilityFlags.Ghost : VisibilityFlags.Normal + )); + + RaiseNetworkEvent(new InvisibilityToggleEvent(GetNetEntity(uid), component.Invisible)); + } +} diff --git a/Content.Server/_Amour/Commands/InvisibilityCommand.cs b/Content.Server/_Amour/Commands/InvisibilityCommand.cs new file mode 100644 index 00000000000..cce76fb1f8a --- /dev/null +++ b/Content.Server/_Amour/Commands/InvisibilityCommand.cs @@ -0,0 +1,33 @@ +using Content.Server.Administration; +using Content.Server._Amour.Administration; +using Content.Shared.Administration; +using Robust.Shared.Console; +using InvisibilityComponent = Content.Shared._Amour.Administration.InvisibilityComponent; + +namespace Content.Server._Amour.Commands; + +[AdminCommand(AdminFlags.Admin)] +public sealed class InvisibilityCommand : IConsoleCommand +{ + public string Command => "invisibility"; + public string Description => "Amour. Переключает режим невидимости."; + public string Help => "invisibility"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player == null) + shell.WriteLine("You can only toggle invisibility on a client."); + + var entityManager = IoCManager.Resolve(); + var uid = shell.Player?.AttachedEntity; + if (uid == null + || !entityManager.TryGetComponent(uid, out var invisibilityComponent)) + return; + + entityManager.System().ToggleInvisibility(uid.Value, invisibilityComponent); + + shell.WriteLine(invisibilityComponent.Invisible + ? "Теперь вы в режиме невидимости" + : "Теперь вы не в режиме невидимости"); + } +} diff --git a/Content.Shared/_Amour/Administration/InvisibilitySystem/InvisibilityComponent.cs b/Content.Shared/_Amour/Administration/InvisibilitySystem/InvisibilityComponent.cs new file mode 100644 index 00000000000..198464a4355 --- /dev/null +++ b/Content.Shared/_Amour/Administration/InvisibilitySystem/InvisibilityComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; + +namespace Content.Shared._Amour.Administration; + +[RegisterComponent] +[Access(typeof(SharedInvisibilitySystem))] +public sealed partial class InvisibilityComponent : Component +{ + [ViewVariables] + public bool Invisible; + + public float? DefaultAlpha; +} diff --git a/Content.Shared/_Amour/Administration/InvisibilitySystem/SharedInvisibilitySystem.cs b/Content.Shared/_Amour/Administration/InvisibilitySystem/SharedInvisibilitySystem.cs new file mode 100644 index 00000000000..eba11cfa36c --- /dev/null +++ b/Content.Shared/_Amour/Administration/InvisibilitySystem/SharedInvisibilitySystem.cs @@ -0,0 +1,30 @@ +using Content.Shared.Actions; +using Content.Shared.Examine; +using Robust.Shared.Serialization; + +namespace Content.Shared._Amour.Administration; + +public abstract class SharedInvisibilitySystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actions = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + } + + private void OnExamined(EntityUid uid, InvisibilityComponent component, ExaminedEvent args) + { + if (component.Invisible) + args.PushMarkup("[color=lightsteelblue]Оно доступно лишь взору богов.[/color]"); + } +} + +[Serializable, NetSerializable] +public sealed class InvisibilityToggleEvent(NetEntity uid, bool invisible) : EntityEventArgs +{ + public NetEntity Uid { get; } = uid; + public bool Invisible { get; } = invisible; +} diff --git a/Resources/Locale/ru-RU/administration/ui/tabs/admin-tab/player-actions-window.ftl b/Resources/Locale/ru-RU/administration/ui/tabs/admin-tab/player-actions-window.ftl index bc1972ecaca..dd4c6c06340 100644 --- a/Resources/Locale/ru-RU/administration/ui/tabs/admin-tab/player-actions-window.ftl +++ b/Resources/Locale/ru-RU/administration/ui/tabs/admin-tab/player-actions-window.ftl @@ -1,6 +1,8 @@ admin-player-actions-window-title = Действия с игроками admin-player-actions-window-ban = Панель банов admin-player-actions-window-admin-ghost = Админ призрак +admin-player-actions-window-admin-stealthmin = Спрятаться/показаться +admin-player-actions-window-admin-invisibility = Переключить инвиз admin-player-actions-window-teleport = Телепорт admin-player-actions-window-permissions = Панель доступов admin-player-actions-window-announce = Сделать объявление diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 6476cff06ce..9b018dd1ab8 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -268,6 +268,7 @@ allowedVerbs: [] - type: ExplosionResistance damageCoefficient: 0 + - type: Invisibility # Amour edit - type: entity abstract: true