From e4b1a363f5f07cdaa4ccf690578f03136bafcdb3 Mon Sep 17 00:00:00 2001 From: Slava0135 <40753025+Slava0135@users.noreply.github.com> Date: Tue, 7 Mar 2023 00:11:36 +0300 Subject: [PATCH] Add telecommunication server (#14415) --- .../Radio/EntitySystems/TelecomSystem.cs | 5 + .../Components/TelecomServerComponent.cs | 6 ++ .../EntitySystems/EncryptionKeySystem.cs | 90 +++++++++++------- .../en-US/headset/headset-component.ftl | 17 +--- .../components/encryption-key-component.ftl | 9 ++ .../Catalog/Research/technologies.yml | 1 + .../Circuitboards/Machine/production.yml | 15 +++ .../Entities/Structures/Machines/lathe.yml | 1 + .../Structures/Machines/telecomms.yml | 81 ++++++++++++++++ .../Prototypes/Recipes/Lathes/electronics.yml | 8 ++ .../Machines/telecomms.rsi/icon.png | Bin 0 -> 341 bytes .../Machines/telecomms.rsi/meta.json | 34 +++++++ .../Machines/telecomms.rsi/panel.png | Bin 0 -> 860 bytes .../Machines/telecomms.rsi/unlit.png | Bin 0 -> 1885 bytes 14 files changed, 215 insertions(+), 52 deletions(-) create mode 100644 Content.Server/Radio/EntitySystems/TelecomSystem.cs create mode 100644 Content.Shared/Radio/Components/TelecomServerComponent.cs create mode 100644 Resources/Locale/en-US/radio/components/encryption-key-component.ftl create mode 100644 Resources/Prototypes/Entities/Structures/Machines/telecomms.yml create mode 100644 Resources/Textures/Structures/Machines/telecomms.rsi/icon.png create mode 100644 Resources/Textures/Structures/Machines/telecomms.rsi/meta.json create mode 100644 Resources/Textures/Structures/Machines/telecomms.rsi/panel.png create mode 100644 Resources/Textures/Structures/Machines/telecomms.rsi/unlit.png diff --git a/Content.Server/Radio/EntitySystems/TelecomSystem.cs b/Content.Server/Radio/EntitySystems/TelecomSystem.cs new file mode 100644 index 0000000000..b4d8897a73 --- /dev/null +++ b/Content.Server/Radio/EntitySystems/TelecomSystem.cs @@ -0,0 +1,5 @@ +namespace Content.Server.Radio.EntitySystems; + +public sealed class TelecomSystem : EntitySystem +{ +} diff --git a/Content.Shared/Radio/Components/TelecomServerComponent.cs b/Content.Shared/Radio/Components/TelecomServerComponent.cs new file mode 100644 index 0000000000..2aa003a1e7 --- /dev/null +++ b/Content.Shared/Radio/Components/TelecomServerComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Shared.Radio.Components; + +[RegisterComponent] +public sealed class TelecomServerComponent : Component +{ +} \ No newline at end of file diff --git a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs index e3c60b99f9..96e7863c86 100644 --- a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs +++ b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs @@ -8,7 +8,6 @@ using Content.Shared.Radio.Components; using Content.Shared.Tools; using Content.Shared.Tools.Components; using Robust.Shared.Containers; -using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Timing; @@ -56,7 +55,7 @@ public sealed class EncryptionKeySystem : EntitySystem } // if tool use ever gets predicted this needs changing. - _popupSystem.PopupEntity(Loc.GetString("headset-encryption-keys-all-extracted"), uid, args.User); + _popupSystem.PopupEntity(Loc.GetString("encryption-keys-all-extracted"), uid, args.User); _audio.PlayPvs(component.KeyExtractionSound, uid); component.Removing = false; } @@ -89,45 +88,55 @@ public sealed class EncryptionKeySystem : EntitySystem private void OnInteractUsing(EntityUid uid, EncryptionKeyHolderComponent component, InteractUsingEvent args) { - if (!TryComp(uid, out var storage) || args.Handled || component.Removing) + if (!TryComp(uid, out var _) || args.Handled || component.Removing) return; - + if (!component.KeysUnlocked) + { + if (_timing.IsFirstTimePredicted) + _popupSystem.PopupEntity(Loc.GetString("encryption-keys-are-locked"), uid, args.User); + return; + } if (TryComp(args.Used, out var key)) { - args.Handled = true; + TryInsertKey(uid, component, args); + } + else + { + TryRemoveKey(uid, component, args); + } + } - if (!component.KeysUnlocked) - { - if (_timing.IsFirstTimePredicted) - _popupSystem.PopupEntity(Loc.GetString("headset-encryption-keys-are-locked"), uid, Filter.Local(), false); - return; - } + private void TryInsertKey(EntityUid uid, EncryptionKeyHolderComponent component, InteractUsingEvent args) + { + args.Handled = true; - if (component.KeySlots <= component.KeyContainer.ContainedEntities.Count) - { - if (_timing.IsFirstTimePredicted) - _popupSystem.PopupEntity(Loc.GetString("headset-encryption-key-slots-already-full"), uid, Filter.Local(), false); - return; - } + if (component.KeySlots <= component.KeyContainer.ContainedEntities.Count) + { + if (_timing.IsFirstTimePredicted) + _popupSystem.PopupEntity(Loc.GetString("encryption-key-slots-already-full"), uid, args.User); + return; + } - if (component.KeyContainer.Insert(args.Used)) - { - if (_timing.IsFirstTimePredicted) - _popupSystem.PopupEntity(Loc.GetString("headset-encryption-key-successfully-installed"), uid, Filter.Local(), false); - _audio.PlayPredicted(component.KeyInsertionSound, args.Target, args.User); - return; - } + if (component.KeyContainer.Insert(args.Used)) + { + if (_timing.IsFirstTimePredicted) + _popupSystem.PopupEntity(Loc.GetString("encryption-key-successfully-installed"), uid, args.User); + _audio.PlayPredicted(component.KeyInsertionSound, args.Target, args.User); + return; } + } + private void TryRemoveKey(EntityUid uid, EncryptionKeyHolderComponent component, InteractUsingEvent args) + { if (!TryComp(args.Used, out var tool) || !tool.Qualities.Contains(component.KeysExtractionMethod)) return; - + args.Handled = true; if (component.KeyContainer.ContainedEntities.Count == 0) { if (_timing.IsFirstTimePredicted) - _popupSystem.PopupEntity(Loc.GetString("headset-encryption-keys-no-keys"), uid, Filter.Local(), false); + _popupSystem.PopupEntity(Loc.GetString("encryption-keys-no-keys"), uid, args.User); return; } @@ -136,8 +145,7 @@ public sealed class EncryptionKeySystem : EntitySystem var toolEvData = new ToolEventData(new EncryptionRemovalFinishedEvent(args.User), cancelledEv: new EncryptionRemovalCancelledEvent(), targetEntity: uid); - if(!_toolSystem.UseTool(args.Used, args.User, uid, 1f, new[] { component.KeysExtractionMethod }, toolEvData, toolComponent: tool)) - return; + _toolSystem.UseTool(args.Used, args.User, uid, 1f, new[] { component.KeysExtractionMethod }, toolEvData, toolComponent: tool); } private void OnStartup(EntityUid uid, EncryptionKeyHolderComponent component, ComponentStartup args) @@ -153,14 +161,14 @@ public sealed class EncryptionKeySystem : EntitySystem if (component.KeyContainer.ContainedEntities.Count == 0) { - args.PushMarkup(Loc.GetString("examine-headset-no-keys")); + args.PushMarkup(Loc.GetString("encryption-keys-no-keys")); return; } if (component.Channels.Count > 0) { - args.PushMarkup(Loc.GetString("examine-headset-channels-prefix")); - AddChannelsExamine(component.Channels, component.DefaultChannel, args, _protoManager, "examine-headset-channel"); + args.PushMarkup(Loc.GetString("examine-encryption-channels-prefix")); + AddChannelsExamine(component.Channels, component.DefaultChannel, args, _protoManager, "examine-encryption-channel"); } } @@ -171,8 +179,8 @@ public sealed class EncryptionKeySystem : EntitySystem if(component.Channels.Count > 0) { - args.PushMarkup(Loc.GetString("examine-encryption-key-channels-prefix")); - AddChannelsExamine(component.Channels, component.DefaultChannel, args, _protoManager, "examine-headset-channel"); + args.PushMarkup(Loc.GetString("examine-encryption-channels-prefix")); + AddChannelsExamine(component.Channels, component.DefaultChannel, args, _protoManager, "examine-encryption-channel"); } } @@ -187,7 +195,7 @@ public sealed class EncryptionKeySystem : EntitySystem RadioChannelPrototype? proto; foreach (var id in channels) { - proto = protoManager.Index(id); + proto = _protoManager.Index(id); var key = id == SharedChatSystem.CommonChannel ? SharedChatSystem.RadioCommonPrefix.ToString() @@ -202,11 +210,21 @@ public sealed class EncryptionKeySystem : EntitySystem if (defaultChannel != null && _protoManager.TryIndex(defaultChannel, out proto)) { - var msg = Loc.GetString("examine-default-channel", + if (HasComp(examineEvent.Examined)) + { + var msg = Loc.GetString("examine-headset-default-channel", ("prefix", SharedChatSystem.DefaultChannelPrefix), ("channel", defaultChannel), ("color", proto.Color)); - examineEvent.PushMarkup(msg); + examineEvent.PushMarkup(msg); + } + if (HasComp(examineEvent.Examined)) + { + var msg = Loc.GetString("examine-encryption-default-channel", + ("channel", defaultChannel), + ("color", proto.Color)); + examineEvent.PushMarkup(msg); + } } } diff --git a/Resources/Locale/en-US/headset/headset-component.ftl b/Resources/Locale/en-US/headset/headset-component.ftl index e4706ecad2..7a1637c9d3 100644 --- a/Resources/Locale/en-US/headset/headset-component.ftl +++ b/Resources/Locale/en-US/headset/headset-component.ftl @@ -1,22 +1,7 @@ # Chat window radio wrap (prefix and postfix) chat-radio-message-wrap = [color={$color}]{$channel} {$name} says: "{$message}"[/color] -headset-encryption-key-successfully-installed = You put the key into the headset. -headset-encryption-key-slots-already-full = There is no place for another key. -headset-encryption-keys-all-extracted = You pop out the encryption keys from the headset! -headset-encryption-keys-no-keys = This headset has no encryption keys! -headset-encryption-keys-are-locked = The headset's key slots are locked, you cannot add or remove any keys. - -examine-encryption-key-channels-prefix = It is providing these frequencies to the headset: - -examine-radio-frequency = It's set to broadcast over the {$frequency} frequency. - -examine-headset-channels-prefix = A small screen on the headset displays the following available frequencies: -examine-headset-channel = [color={$color}]{$key} for {$id} ({$freq})[/color] -examine-headset-no-keys = It seems broken. There are no encryption keys in it. -examine-default-channel = Use {$prefix} for the default channel ([color={$color}]{$channel}[/color]). -examine-headset-default-channel = It indicates that the default channel of this headset is [color={$color}]{$channel}[/color]. -examine-encryption-key-default-channel = The default channel is [color={$color}]{$channel}[/color]. +examine-headset-default-channel = Use {$prefix} for the default channel ([color={$color}]{$channel}[/color]). chat-radio-common = Common chat-radio-centcom = CentCom diff --git a/Resources/Locale/en-US/radio/components/encryption-key-component.ftl b/Resources/Locale/en-US/radio/components/encryption-key-component.ftl new file mode 100644 index 0000000000..6d9dc5261c --- /dev/null +++ b/Resources/Locale/en-US/radio/components/encryption-key-component.ftl @@ -0,0 +1,9 @@ +encryption-key-successfully-installed = You put the encryption key inside. +encryption-key-slots-already-full = There is no place for another encryption key. +encryption-keys-all-extracted = You pop out the encryption keys! +encryption-keys-no-keys = This device has no encryption keys! +encryption-keys-are-locked = Encryption key slots are locked! + +examine-encryption-channels-prefix = Available frequencies: +examine-encryption-channel = [color={$color}]{$key} for {$id} ({$freq})[/color] +examine-encryption-default-channel = The default channel is [color={$color}]{$channel}[/color]. diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml index 03b1edbb52..08156f9437 100644 --- a/Resources/Prototypes/Catalog/Research/technologies.yml +++ b/Resources/Prototypes/Catalog/Research/technologies.yml @@ -376,6 +376,7 @@ - SignalTrigger - VoiceTrigger - TimerTrigger + - TelecomServerCircuitboard - type: technology name: technologies-electrical-engineering diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index 42125ea3e4..616a7293f7 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -762,3 +762,18 @@ Amount: 1 DefaultPrototype: Beaker ExamineName: Glass Beaker + +- type: entity + id: TelecomServerCircuitboard + parent: BaseMachineCircuitboard + name: telecommunication server machine board + description: A machine printed circuit board for an telecommunication server + components: + - type: MachineBoard + prototype: TelecomServer + requirements: + Capacitor: 1 + ScanningModule: 2 + materialRequirements: + Steel: 1 + Cable: 2 diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 6f7401b449..582b9ce04b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -326,6 +326,7 @@ - TraversalDistorterMachineCircuitboard - BoozeDispenserMachineCircuitboard - SodaDispenserMachineCircuitboard + - TelecomServerCircuitboard - type: MaterialStorage whitelist: tags: diff --git a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml new file mode 100644 index 0000000000..e3197202d7 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml @@ -0,0 +1,81 @@ +- type: entity + parent: [ BaseMachinePowered, ConstructibleMachine ] + id: TelecomServer + name: telecommunication server + description: When powered and filled with encryption keys it allows radio headset communication + components: + - type: Sprite + sprite: Structures/Machines/telecomms.rsi + snapCardinals: true + netsync: false + layers: + - state: icon + - state: unlit + shader: unshaded + map: ["enum.PowerDeviceVisualLayers.Powered"] + - state: panel + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.Powered: + enum.PowerDeviceVisualLayers.Powered: + True: { visible: true } + False: { visible: false } + - type: Appearance + - type: WiresVisuals + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + density: 190 + mask: + - MachineMask + layer: + - MachineLayer + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] + - type: Machine + board: TelecomServerCircuitboard + - type: Wires + BoardName: "TelecomServer" + LayoutId: TelecomServer + - type: Transform + anchored: true + - type: Pullable + - type: EncryptionKeyHolder + keysExtractionMethod: Prying + keySlots: 10 + - type: TelecomServer + - type: ContainerContainer + containers: + key_slots: !type:Container + machine_board: !type:Container + machine_parts: !type:Container + +- type: entity + parent: TelecomServer + id: TelecomServerFilled + suffix: Filled + components: + - type: ContainerFill + containers: + key_slots: + - EncryptionKeyCommon + - EncryptionKeyCargo + - EncryptionKeyEngineering + - EncryptionKeyMedical + - EncryptionKeyScience + - EncryptionKeySecurity + - EncryptionKeyService + - EncryptionKeyCommand diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml index c2d8d6f1a9..c5aea71800 100644 --- a/Resources/Prototypes/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml @@ -527,3 +527,11 @@ materials: Steel: 100 Glass: 900 + +- type: latheRecipe + id: TelecomServerCircuitboard + result: TelecomServerCircuitboard + completetime: 4 + materials: + Steel: 100 + Glass: 900 diff --git a/Resources/Textures/Structures/Machines/telecomms.rsi/icon.png b/Resources/Textures/Structures/Machines/telecomms.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0f78e94bdd6a58509bd04791e8e0c466fa434d5d GIT binary patch literal 341 zcmV-b0jmCqP)eqkA3m}U2NOT^6rYSe7s&6ezpR_Q`%DxK#WCZ{eMUe{-9RNtv n_h)u;!1Hj(0PK*2NS}clIb?I@W|D@E00000NkvXXu0mjf7;%GS literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/telecomms.rsi/meta.json b/Resources/Textures/Structures/Machines/telecomms.rsi/meta.json new file mode 100644 index 0000000000..d26455cea6 --- /dev/null +++ b/Resources/Textures/Structures/Machines/telecomms.rsi/meta.json @@ -0,0 +1,34 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/blob/9c3494fd79e6bf8dc532300b9de4f688ff276ac9/icons/obj/machines/telecomms.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "unlit", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "icon" + }, + { + "name": "panel" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Structures/Machines/telecomms.rsi/panel.png b/Resources/Textures/Structures/Machines/telecomms.rsi/panel.png new file mode 100644 index 0000000000000000000000000000000000000000..1ab3cfb29ca1384da618a4e162889cf88380ceaa GIT binary patch literal 860 zcmV-i1Ec(jP)xukZV{egQD5XdpT{ zcmn_c010qNS#tmY4#WTe4#WYKD-Ig~00ERqL_t(o31eUw1tUEK7?A@&LP7$WOEdP1 z7cbyu!yN#!+{ed<;oZA;a7kJ)goK0`wrttL0CNNrEi56$%uxr7hQMeDu%KrdP(Gz6 zfIHyp*WV2H?%kt{-5|SQV8GJ=JOp4adh_NDjER>P5fK5)-@0`RuR3H&H8nM4E|`ts z0FWqiF7tn|?6fQ}1tadI2+SccHKfwmqX1+v2xm=W09o3~x*LpDR5}<| zYC2=sAugp279&JsXaoviguts;uYk4UNr>8$#tg>c#tiGAI*l1l0@-{FueQ8mK=%2E z4euP$&!sfMh|r;n}liC<8F|axSByVG5gQN_> zM9-=wCMF0;0xWdBAmun6fK4$r^NCf5O)p3co|<`ig~4jLxmj_kMG;3XOi(0<FX zg-?Wih72fttMo*T-xOzR{H554M&`k;dU`TVoM>V#YvhH;guVG(NvqGJzQmO(EG6((77Cj|TjxCk@ z|2)m~)MTx@D*(<{%laIFu6?MKE$jExvMOibc!BFe!@nUp&3ubqZfM?PaPPq7O+!l@ zz|}4cKI?HKUX>iO?dddpTtHt8`tPA*>U6Z zdsgn7<^215_xbvKw)0-16h0sT0w4eau@bnGZTQN{N_Muf>64Qa@3CXlHwNg&@9gZT z^Ye2roKOoF7Z=t3{=TwJh*ke?D6lxrYy@DyY}|tF1p|Viob5m`U^Z^S_JRSyP|kKB z7%&^RV0*!UU?^uh&^>!MeV;D*iA~=aaC!Mh_4|Dm_FBvS#Hx==kbNdF&zl}Vx~He7 zG+A0MEiI+%kB^T_x67_vTU*P{dZ%O4cMQ-}wzjssaA@J-;UP_`#E5IvO~#FJ@(zhg zv(}j~@1C4BnFTTFdkxTI!C)}RAel_|dcDbvo=Tv1UVTwl?_Q|R%Ma@6^;326A70&t*c*yAL`=SUOJ!Ov3Rbo{&IIU)s@n}P5ZqDXf)f~+g?J>K%JcV-#&g;>%;y{ znauw@I#7?2y+@-_dJLNP9H5#)eS2?K<{lPnA%5<(>m5CTuKFn~x1l`udEJjucUA|X^d zUrELmpKo*LZoe@g*7$rfK&t(?1d#(mrRf2rUo|X{BG`~0P%l5iF+dv;Q+z(1c-b;| z`zLu5=G`0Vc?}31pWk_NpsscwljhX2uKsP}^L>@6tDnnH7!PmqCz8Ag-^Xi!-Y{f* z{@3?=X}*B30!7Q}=-(zjzX|Ibjx5ERu!V;-XZP7Od=!(S{pHGHJwI5HySqB8B zoiQM`_0YpNmgaJa}NfrhW384}O2!SVA7(gV1 zO6My{?)Z4S-LdH#1Ek{P$$(h(aS5U`K&Ui5fb^?|B~k<(@&k|`(Ek4~;LZ=QHiCyL0DI}>OicwMScMC1N3_c~VRS#GG=Fs(qX6+UPUlKE|Y)(Wpo(U!2kxxWfCx;j1I#(7{CCz zOaca!(P3Bz0~jEeNjP6gO2_AyRdycN83Ux_^XCz6l{VoLRE1K5+n63e8dbv*DS|9? zegM@YmeMgmH=OhL^J4*B)K0GfLF4nM#K#v^ESBY719anq#ph3nkB_dHaZAq`1Ek~gt@_RVEP8;j#m*SOQ6CJz9F(B}0w4eaQwjV7 Xw8emBZZj!{00000NkvXXu0mjfK@x89 literal 0 HcmV?d00001 -- 2.52.0