diff --git a/Content.Client/_Rat/Overwatch/OverwatchWindow.xaml.cs b/Content.Client/_Rat/Overwatch/OverwatchWindow.xaml.cs index beb65b9e05..4b4b039c0f 100644 --- a/Content.Client/_Rat/Overwatch/OverwatchWindow.xaml.cs +++ b/Content.Client/_Rat/Overwatch/OverwatchWindow.xaml.cs @@ -58,6 +58,13 @@ public OverwatchWindow() StopWatchingButton.OnPressed += _ => { _ui?.StopWatching(); + + foreach (var row in _memberRows.Values) + { + row.SetWatching(false); + } + + _watchingStateCache.Clear(); StopWatchingButton.Visible = false; }; @@ -140,8 +147,11 @@ private void OnMemberStartWatching(OverwatchMemberRow selectedRow) if (row != selectedRow) { row.SetWatching(false); + _watchingStateCache[row.Member] = false; } } + + StopWatchingButton.Visible = true; } /// @@ -551,6 +561,11 @@ public sealed class OverwatchMemberRow : BoxContainer /// public bool IsWatching { get; private set; } + /// + /// Сущность участника. + /// + public NetEntity Member => _member; + /// /// Селектор отрядов для назначения участника. /// diff --git a/Content.Server/_Rat/Overwatch/OverwatchSystem.cs b/Content.Server/_Rat/Overwatch/OverwatchSystem.cs index 305aecfd55..ffd8ce79ae 100644 --- a/Content.Server/_Rat/Overwatch/OverwatchSystem.cs +++ b/Content.Server/_Rat/Overwatch/OverwatchSystem.cs @@ -167,13 +167,6 @@ private void OnUIOpenAttempt(Entity ent, ref Activata { if (args.User is not { Valid: true } user) return; - - var userFaction = GetUserFaction(user); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - { - args.Cancel(); - return; - } } /// @@ -310,10 +303,6 @@ private void OnCreateSquad(Entity ent, ref OverwatchC if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - var created = _squadSystem.CreateSquad(ent.Comp.Faction, args.SquadName); if (created) { @@ -329,10 +318,6 @@ private void OnDeleteSquad(Entity ent, ref OverwatchD if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - if (_squadSystem.RemoveSquad(ent.Comp.Faction, args.SquadId)) { RefreshData(ent); @@ -347,10 +332,6 @@ private void OnAssignSquad(Entity ent, ref OverwatchA if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - var player = GetEntity(args.Player); if (!player.Valid) return; @@ -373,10 +354,6 @@ private void OnRemoveSquadMember(Entity ent, ref Over if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - var player = GetEntity(args.Player); if (!player.Valid) return; @@ -397,10 +374,6 @@ private void OnSendAnnouncement(Entity ent, ref Overw if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - if (string.IsNullOrEmpty(args.Message)) return; @@ -474,10 +447,6 @@ private void OnViewCamera(Entity ent, ref OverwatchVi if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - var target = GetEntity(args.Target); if (!TryComp(target, out var factionComp) || factionComp.Faction != ent.Comp.Faction || @@ -530,10 +499,6 @@ private void OnStopWatching(Entity ent, ref Overwatch if (args.Actor is not { Valid: true } actor) return; - var userFaction = GetUserFaction(actor); - if (string.IsNullOrEmpty(userFaction) || userFaction != ent.Comp.Faction) - return; - if (TryComp(actor, out var watchingComp) && watchingComp.Watching.HasValue) { StopWatching(actor, watchingComp); @@ -716,17 +681,6 @@ public override void Update(float frameTime) _cacheInvalidationTimer = 0; } - /// - /// Получает фракцию игрока. - /// - private string? GetUserFaction(EntityUid user) - { - if (!TryComp(user, out var factionComp)) - return null; - - return factionComp.Faction; - } - /// /// Получает кэшированный список членов фракции. /// diff --git a/Resources/Locale/ru-RU/_Rat/overwatch.ftl b/Resources/Locale/ru-RU/_Rat/overwatch.ftl index 3dcc298971..cc9d318235 100644 --- a/Resources/Locale/ru-RU/_Rat/overwatch.ftl +++ b/Resources/Locale/ru-RU/_Rat/overwatch.ftl @@ -39,7 +39,7 @@ overwatch-member-status-alive = Жив overwatch-member-status-ssd = SSD overwatch-member-status-dead = Мёртв overwatch-member-status-unknown = Неизвестно -overwatch-member-coordinates = ({ $x }, { $y }) +overwatch-member-coordinates = ({ $x }; { $y }) overwatch-member-coordinates-none = — overwatch-stop-watching-button = Остановить наблюдение @@ -79,3 +79,24 @@ ent-GSCOverwatchComputer = консоль overwatch «ЧЕРНАЯ СЕТЬ» .desc = Консоль системы наблюдения «ЧЕРНАЯ СЕТЬ» GSC. Децентрализованная сеть наблюдения для независимых операторов. ent-CDOverwatchComputer = консоль overwatch «ЧЕРНАЯ СЕТЬ» .desc = Консоль системы наблюдения «ЧЕРНАЯ СЕТЬ» CD. Децентрализованная сеть наблюдения для независимых операторов. + +ent-BaseOverwatchClipboard = цифровой планшет overwatch + .desc = Громоздкий цифровой планшет, содержащий информацию о членах фракции. При таком количестве компрометирующих документов его следует беречь. +ent-DSMOverwatchClipboard = цифровой планшет overwatch «ОКО КАЙЗЕРА» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-NCWLOverwatchClipboard = цифровой планшет overwatch «ДОЗОРНЫЙ» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-SHIOverwatchClipboard = цифровой планшет overwatch «C.A.S.S.I.E.» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-TAPOverwatchClipboard = цифровой планшет overwatch «ЗВЕЗДНЫЙ ШЁПОТ» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-IPMOverwatchClipboard = цифровой планшет overwatch «ЧЕРНАЯ СЕТЬ» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-SAWOverwatchClipboard = цифровой планшет overwatch «ЧЕРНАЯ СЕТЬ» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-GSCOverwatchClipboard = цифровой планшет overwatch «ЧЕРНАЯ СЕТЬ» + .desc = { ent-BaseOverwatchClipboard.desc } +ent-CDOverwatchClipboard = цифровой планшет overwatch «ЧЕРНАЯ СЕТЬ» + .desc = { ent-BaseOverwatchClipboard.desc } + +overwatch-clipboard-computer-verb-text = Переключить меню overwatch diff --git a/Resources/Prototypes/_Rat/Entities/Structures/Machines/Computers/overwatch.yml b/Resources/Prototypes/_Rat/Entities/Structures/Machines/Computers/overwatch.yml index 8f32cb6ea0..2b66677055 100644 --- a/Resources/Prototypes/_Rat/Entities/Structures/Machines/Computers/overwatch.yml +++ b/Resources/Prototypes/_Rat/Entities/Structures/Machines/Computers/overwatch.yml @@ -1,5 +1,6 @@ - type: entity parent: BaseComputer + abstract: true id: BaseComputerOverwatch name: overwatch console description: A computer console used to track faction members via wearable cameras. @@ -225,3 +226,141 @@ # layers: # - map: ["computerLayerScreen"] # state: tsp + +- type: entity + parent: BoxFolderBase + abstract: true + id: BaseOverwatchClipboard + name: overwatc digi-board + description: A bulky electric clipboard, filled with shipping orders and financing details. With so many compromising documents, you ought to keep this safe. + components: + - type: Sprite + sprite: Objects/Misc/qm_clipboard.rsi + layers: + - state: qm_clipboard + - state: qm_clipboard_paper + map: ["qm_clipboard_paper"] + visible: false + - state: qm_clipboard_pen + map: ["qm_clipboard_pen"] + visible: false + - state: qm_clipboard_over + - type: ContainerContainer + containers: + storagebase: !type:Container + ents: [] + pen_slot: !type:ContainerSlot {} + - type: ItemSlots + slots: + pen_slot: + name: clipboard-slot-component-slot-name-pen + whitelist: + tags: + - Write + insertOnInteract: true + - type: Item + sprite: Objects/Misc/qm_clipboard.rsi + size: Small + - type: Clothing + slots: [belt] + quickEquip: false + sprite: Objects/Misc/qm_clipboard.rsi + - type: Storage + grid: + - 0,0,4,3 + quickInsert: true + whitelist: + tags: + - Document + - type: StorageFill + contents: [] + - type: ItemMapper + mapLayers: + qm_clipboard_paper: + whitelist: + tags: + - Document + qm_clipboard_pen: + whitelist: + tags: + - Write + - type: CargoOrderConsole + - type: BankClient + - type: ActivatableUI + verbText: overwatch-clipboard-computer-verb-text + key: enum.OverwatchUiKey.Key + - type: UserInterface + interfaces: + enum.OverwatchUiKey.Key: + type: Content.Client._Rat.Overwatch.OverwatchBoundUserInterface + enum.StorageUiKey.Key: + type: StorageBoundUserInterface + - type: MeleeWeapon + wideAnimationRotation: 180 + damage: + types: + Blunt: 10 + +- type: entity + parent: BaseOverwatchClipboard + id: DSMOverwatchClipboard + name: overwatch console DSM + components: + - type: OverwatchConsole + faction: DSM + +- type: entity + parent: BaseOverwatchClipboard + id: NCWLOverwatchClipboard + name: overwatch console NCWL + components: + - type: OverwatchConsole + faction: NCWL + +- type: entity + parent: BaseOverwatchClipboard + id: SHIOverwatchClipboard + name: overwatch console SHI + components: + - type: OverwatchConsole + faction: SHI + +- type: entity + parent: BaseOverwatchClipboard + id: TAPOverwatchClipboard + name: overwatch console TAP + components: + - type: OverwatchConsole + faction: TAP + +- type: entity + parent: BaseOverwatchClipboard + id: IPMOverwatchClipboard + name: overwatch console IPM + components: + - type: OverwatchConsole + faction: IPM + +- type: entity + parent: BaseOverwatchClipboard + id: SAWOverwatchClipboard + name: overwatch console SAW + components: + - type: OverwatchConsole + faction: SAW + +- type: entity + parent: BaseOverwatchClipboard + id: GSCOverwatchClipboard + name: overwatch clipboard GSC + components: + - type: OverwatchConsole + faction: GSC + +- type: entity + parent: BaseOverwatchClipboard + id: CDOverwatchClipboard + name: overwatch console CD + components: + - type: OverwatchConsole + faction: CD