From dfcfded62fd845b64ae62b5634580f5822e0fa24 Mon Sep 17 00:00:00 2001 From: Viktor <125474183+OmntnsV@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:10:08 +0200 Subject: [PATCH] Body camera (#585) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial commit * removed jumpsuit slot component, system * sprite fixes * Локализация для телевизора и роутера * Removed separate router and tv for body cameras. Now they're public. Added localizations. * +cargo buying, sprites finale --- .../SurveillanceBodyCameraComponent.cs | 10 ++ .../Components/SurveillanceCameraComponent.cs | 2 +- .../Systems/SurveillanceBodyCameraSystem.cs | 116 ++++++++++++++++++ .../Containers/ItemSlot/ItemSlotsComponent.cs | 1 + .../catalog/fills/crates/security-crates.ftl | 2 + .../catalog/fills/boxes/security.ftl | 3 + .../entities/objects/weapons/security.ftl | 3 + .../machines/surveillance_camera_routers.ftl | 3 + .../surveillance-camera-ui.ftl | 2 + .../Catalog/Cargo/cargo_security.yml | 10 ++ .../Catalog/Fills/Boxes/security.yml | 17 +++ .../Catalog/Fills/Crates/security.yml | 11 +- .../Catalog/Fills/Lockers/security.yml | 2 + .../Objects/Specific/Security/body-camera.yml | 73 +++++++++++ .../Machines/surveillance_camera_routers.yml | 10 ++ Resources/Prototypes/White/tags.yml | 3 + .../Clothing/Uniforms/Overlay.rsi/camera.png | Bin 0 -> 173 bytes .../Clothing/Uniforms/Overlay.rsi/meta.json | 14 +++ .../body-camera.rsi/active-animated.png | Bin 0 -> 717 bytes .../Security/body-camera.rsi/active.png | Bin 0 -> 2179 bytes .../equipped-INNERCLOTHING.png | Bin 0 -> 211 bytes .../body-camera.rsi/equipped-NECK.png | Bin 0 -> 326 bytes .../Security/body-camera.rsi/inactive.png | Bin 0 -> 2181 bytes .../Security/body-camera.rsi/meta.json | 108 ++++++++++++++++ .../body-camera.rsi/off-equipped-NECK.png | Bin 0 -> 259 bytes .../body-camera.rsi/off-inhand-left.png | Bin 0 -> 200 bytes .../body-camera.rsi/off-inhand-right.png | Bin 0 -> 223 bytes .../body-camera.rsi/on-inhand-left.png | Bin 0 -> 239 bytes .../body-camera.rsi/on-inhand-right.png | Bin 0 -> 262 bytes .../Security/body-camera.rsi/unpowered.png | Bin 0 -> 636 bytes .../Objects/Storage/boxes.rsi/bodycam.png | Bin 0 -> 5625 bytes .../Objects/Storage/boxes.rsi/meta.json | 3 + .../Machines/computers.rsi/bodycammonitor.png | Bin 0 -> 459 bytes .../Machines/computers.rsi/bodycamprogram.png | Bin 0 -> 219 bytes .../Machines/computers.rsi/meta.json | 6 + 35 files changed, 397 insertions(+), 2 deletions(-) create mode 100644 Content.Server/SurveillanceCamera/Components/SurveillanceBodyCameraComponent.cs create mode 100644 Content.Server/SurveillanceCamera/Systems/SurveillanceBodyCameraSystem.cs create mode 100644 Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml create mode 100644 Resources/Textures/Clothing/Uniforms/Overlay.rsi/camera.png create mode 100644 Resources/Textures/Clothing/Uniforms/Overlay.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/active-animated.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/active.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/equipped-NECK.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/inactive.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-equipped-NECK.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-inhand-left.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-inhand-right.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/on-inhand-left.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/on-inhand-right.png create mode 100644 Resources/Textures/Objects/Specific/Security/body-camera.rsi/unpowered.png create mode 100644 Resources/Textures/Objects/Storage/boxes.rsi/bodycam.png create mode 100644 Resources/Textures/Structures/Machines/computers.rsi/bodycammonitor.png create mode 100644 Resources/Textures/Structures/Machines/computers.rsi/bodycamprogram.png diff --git a/Content.Server/SurveillanceCamera/Components/SurveillanceBodyCameraComponent.cs b/Content.Server/SurveillanceCamera/Components/SurveillanceBodyCameraComponent.cs new file mode 100644 index 0000000000..99235dd7a5 --- /dev/null +++ b/Content.Server/SurveillanceCamera/Components/SurveillanceBodyCameraComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Server.SurveillanceCamera; + +[RegisterComponent] +public sealed partial class SurveillanceBodyCameraComponent : Component +{ + [DataField("wattage"), ViewVariables(VVAccess.ReadWrite)] + public float Wattage = 0.3f; + + public bool lastState = false; +} diff --git a/Content.Server/SurveillanceCamera/Components/SurveillanceCameraComponent.cs b/Content.Server/SurveillanceCamera/Components/SurveillanceCameraComponent.cs index 8473462f80..0cbaba66ca 100644 --- a/Content.Server/SurveillanceCamera/Components/SurveillanceCameraComponent.cs +++ b/Content.Server/SurveillanceCamera/Components/SurveillanceCameraComponent.cs @@ -4,7 +4,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy namespace Content.Server.SurveillanceCamera; [RegisterComponent] -[Access(typeof(SurveillanceCameraSystem))] +[Access(typeof(SurveillanceCameraSystem), typeof(SurveillanceBodyCameraSystem))] public sealed partial class SurveillanceCameraComponent : Component { // List of active viewers. This is for bookkeeping purposes, diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceBodyCameraSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceBodyCameraSystem.cs new file mode 100644 index 0000000000..6435623dd5 --- /dev/null +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceBodyCameraSystem.cs @@ -0,0 +1,116 @@ +using Content.Server.Popups; +using Content.Server.PowerCell; +using Content.Shared.Clothing.EntitySystems; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Item; +using Content.Shared.PowerCell.Components; +using Content.Shared.Toggleable; + +namespace Content.Server.SurveillanceCamera; + +/// +/// This handles the bodycamera all itself. Activation, examine,init, powercell stuff. +/// +public sealed class SurveillanceBodyCameraSystem : EntitySystem +{ + [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly SurveillanceCameraSystem _surveillanceCameras = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly ClothingSystem _clothing = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnActivate); + SubscribeLocalEvent(OnPowerCellChanged); + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnInit); + } + + public void OnInit(EntityUid uid, SurveillanceBodyCameraComponent comp, ComponentInit args) + { + + if (!TryComp(uid, out var surComp)) + return; + + _surveillanceCameras.SetActive(uid, false, surComp); + surComp.NetworkSet = true; + AppearanceChange(uid, surComp.Active); + } + public override void Update(float frameTime) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var cam)) + { + if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery)) + continue; + + if (!TryComp(uid, out var surComp)) + continue; + + if (!surComp.Active) + continue; + + if (!battery.TryUseCharge(cam.Wattage * frameTime)) + { + _surveillanceCameras.SetActive(uid, false, surComp); + AppearanceChange(uid, surComp.Active); + } + } + } + public void OnActivate(EntityUid uid, SurveillanceBodyCameraComponent comp, ActivateInWorldEvent args) + { + if (!TryComp(uid, out var surComp)) + return; + + if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery)) + return; + + _surveillanceCameras.SetActive(uid, battery.CurrentCharge > comp.Wattage && !surComp.Active, surComp); + AppearanceChange(uid, surComp.Active); + + var message = Loc.GetString(surComp.Active ? "surveillance-body-camera-on" : "surveillance-body-camera-off"); + _popup.PopupEntity(message, args.User, args.User); + args.Handled = true; + } + + public void OnPowerCellChanged(EntityUid uid, SurveillanceBodyCameraComponent comp, PowerCellChangedEvent args) + { + if (!TryComp(uid, out var surComp)) + return; + + if (args.Ejected) + { + _surveillanceCameras.SetActive(uid, false, surComp); + AppearanceChange(uid, surComp.Active); + } + } + + public void OnExamine(EntityUid uid, SurveillanceBodyCameraComponent comp, ExaminedEvent args) + { + if (!TryComp(uid, out var surComp)) + return; + + if (args.IsInDetailsRange) + { + var message = + Loc.GetString(surComp.Active ? "surveillance-body-camera-on" : "surveillance-body-camera-off"); + args.PushMarkup(message); + } + } + + public void AppearanceChange(EntityUid uid, Boolean isActive) + { + if (TryComp(uid, out var appearance) && + TryComp(uid, out var item)) + { + _item.SetHeldPrefix(uid, isActive ? "on" : "off", false, item); + _clothing.SetEquippedPrefix(uid, isActive ? null : "off"); + _appearance.SetData(uid, ToggleVisuals.Toggled, isActive, appearance); + } + } +} diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs index c1b46c3d91..7c389f5a8d 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotsComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Clothing.EntitySystems; using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.Containers; diff --git a/Resources/Locale/ru-RU/prototypes/catalog/fills/crates/security-crates.ftl b/Resources/Locale/ru-RU/prototypes/catalog/fills/crates/security-crates.ftl index 14d20802f7..3213b1025d 100644 --- a/Resources/Locale/ru-RU/prototypes/catalog/fills/crates/security-crates.ftl +++ b/Resources/Locale/ru-RU/prototypes/catalog/fills/crates/security-crates.ftl @@ -14,3 +14,5 @@ ent-CrateSecurityBiosuit = ящик биокостюмов безопаснос .desc = Содержит 2 костюма биологической защиты, гарантирующих, что никакая болезнь не отвлечет вас от ваших обязанностей. Для открытия требуется доступ СБ. ent-CreateSecurityMindShield = ящик имплантов защиты разума .desc = Содержит в себе 5 имплантов защиты разума. Чтобы открыть необходим уровень доступа Служба безопасности. +ent-CrateSecurityBodyCamera = ящик нагрудных камер + .desc = Содержит 10 нагрудных камер. Чтобы открыть необходим уровень доступа Служба безопасности. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/boxes/security.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/boxes/security.ftl index 38a1b55087..2792ae52bf 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/boxes/security.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/boxes/security.ftl @@ -16,3 +16,6 @@ ent-BoxZiptie = коробка стяжек ent-BoxForensicPad = коробка криминалистических пластинок .desc = Коробка криминалистических пластинок. .suffix = { "" } +ent-BoxBodyCamera = коробка бодикамер + .desc = Коробка нагрудных камер службы безопасности. + .suffix = { "" } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/security.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/security.ftl index ceaccd2212..36c0645131 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/security.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/objects/weapons/security.ftl @@ -10,3 +10,6 @@ ent-PortableFlasher = переносная вспышка ent-DeskBell = настольный звонок .desc = Краеугольный камень любой работы по обслуживанию клиентов. Вы испытываете непреодолимое желание позвонить в него. .suffix = { "" } +ent-SurveillanceBodyCamera = бодикамера + .desc = Следи за собой! Или за другими. Или за всеми сразу. Или ни за кем. Как хочешь. Нательная камера, записывающая все, что происходит вокруг. + .suffix = { "" } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/machines/surveillance_camera_routers.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/machines/surveillance_camera_routers.ftl index 5da4e56c19..05bb76bc2e 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/machines/surveillance_camera_routers.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/machines/surveillance_camera_routers.ftl @@ -31,6 +31,9 @@ ent-SurveillanceCameraRouterGeneral = { ent-SurveillanceCameraRouterBase } ent-SurveillanceCameraWirelessRouterBase = маршрутизатор беспроводных камер .desc = Маршрутизатор для беспроводных камер наблюдения. Он маршрутизирует. Возможно. .suffix = { "" } +ent-SurveillanceCameraWirelessRouterSecurity = { ent-SurveillanceCameraWirelessRouterBase } + .suffix = Охранный + .desc = { ent-SurveillanceCameraWirelessRouterBase.desc } ent-SurveillanceCameraWirelessRouterConstructed = { ent-SurveillanceCameraWirelessRouterBase } .suffix = Построенный .desc = { ent-SurveillanceCameraWirelessRouterBase.desc } diff --git a/Resources/Locale/ru-RU/surveillance-camera/surveillance-camera-ui.ftl b/Resources/Locale/ru-RU/surveillance-camera/surveillance-camera-ui.ftl index 4b0c5535fa..4ab4bbecf0 100644 --- a/Resources/Locale/ru-RU/surveillance-camera/surveillance-camera-ui.ftl +++ b/Resources/Locale/ru-RU/surveillance-camera/surveillance-camera-ui.ftl @@ -9,3 +9,5 @@ surveillance-camera-monitor-ui-status-disconnected = Отключено surveillance-camera-monitor-ui-no-subnets = Нет подсетей surveillance-camera-setup = Настроить surveillance-camera-setup-ui-set = Установить +surveillance-body-camera-on = Камера включена +surveillance-body-camera-off = Камера выключена diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_security.yml b/Resources/Prototypes/Catalog/Cargo/cargo_security.yml index 091501b7fd..10fa382a3c 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_security.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_security.yml @@ -77,3 +77,13 @@ cost: 1000 category: Security group: market + +- type: cargoProduct + id: SecurityBodycam + icon: + sprite: Objects/Specific/Security/body-camera.rsi + state: unpowered + product: CrateSecurityBodyCamera + cost: 2000 + category: Security + group: market diff --git a/Resources/Prototypes/Catalog/Fills/Boxes/security.yml b/Resources/Prototypes/Catalog/Fills/Boxes/security.yml index 9975f4f3f0..2a4a444d23 100644 --- a/Resources/Prototypes/Catalog/Fills/Boxes/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Boxes/security.yml @@ -81,3 +81,20 @@ layers: - state: box_security - state: forensic + +#White + +- type: entity + name: body camera box + parent: BoxCardboard + id: BoxBodyCamera + description: A box full of body cameras. + components: + - type: StorageFill + contents: + - id: SurveillanceBodyCamera + amount: 5 + - type: Sprite + layers: + - state: box_security + - state: bodycam diff --git a/Resources/Prototypes/Catalog/Fills/Crates/security.yml b/Resources/Prototypes/Catalog/Fills/Crates/security.yml index ea8c7ce0d3..87b3344237 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/security.yml @@ -97,5 +97,14 @@ amount: 4 - id: TrackingImplanter amount: 4 - + # Cosmetic Crates + +- type: entity + id: CrateSecurityBodyCamera + parent: CrateSecgear + components: + - type: StorageFill + contents: + - id: BoxBodyCamera + amount: 2 diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index 1334ffd23e..ca35ae0952 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -21,6 +21,7 @@ - id: ClothingOuterHardsuitWarden - id: HoloprojectorSecurity - id: ClothingEyesHudSecurity + - id: BoxBodyCamera - type: entity id: LockerWardenFilled @@ -45,6 +46,7 @@ - id: DoorRemoteArmory - id: HoloprojectorSecurity - id: ClothingEyesHudSecurity + - id: BoxBodyCamera - type: entity id: LockerSecurityFilled diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml new file mode 100644 index 0000000000..65b71eed02 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml @@ -0,0 +1,73 @@ +- type: entity + parent: BaseItem + id: SurveillanceBodyCamera + name: Security Body Camera + description: MP3 player sized pocket camera for security officers. + components: + - type: SurveillanceBodyCamera + - type: Sprite # Sprites section + sprite: Objects/Specific/Security/body-camera.rsi + layers: + - state: unpowered + - state: active-animated + map: ["active"] + visible: false + - type: Clothing + sprite: Objects/Specific/Security/body-camera.rsi + quickEquip: false + slots: + - neck + - type: ToggleableLightVisuals + spriteLayer: active + inhandVisuals: + left: + - state: inhand-left-active + shader: unshaded + right: + - state: inhand-left-active + shader: unshaded + - type: Item + heldPrefix: off + sprite: Objects/Specific/Security/body-camera.rsi + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: { state: active-animated } + False: { state: unpowered } # END + - type: Eye + - type: WirelessNetworkConnection + range: 300 + - type: ActiveListener + range: 5 + - type: SurveillanceCameraMicrophone + blacklist: + components: + - SurveillanceCamera + - SurveillanceCameraMonitor + - RadioSpeaker + - type: DeviceNetwork + deviceNetId: Wireless + receiveFrequencyId: SurveillanceCameraSecurity + transmitFrequencyId: SurveillanceCamera + - type: SurveillanceCamera + setupAvailableNetworks: + - SurveillanceCameraSecurity + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium + - type: UserInterface + interfaces: + - key: enum.SurveillanceCameraSetupUiKey.Camera + type: SurveillanceCameraSetupBoundUi + - type: Tag + tags: + - SurveillanceBodyCamera diff --git a/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml b/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml index 1eeaec9b7c..f7021fbe52 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml @@ -135,6 +135,7 @@ - type: SurveillanceCameraRouter setupAvailableNetworks: - SurveillanceCameraEntertainment + - SurveillanceCameraSecurity - type: entity parent: SurveillanceCameraWirelessRouterBase @@ -143,3 +144,12 @@ components: - type: SurveillanceCameraRouter subnetFrequency: SurveillanceCameraEntertainment + +# Body Camera Separate Router +- type: entity + parent: SurveillanceCameraWirelessRouterBase + id: SurveillanceCameraWirelessRouterSecurity + suffix: Security + components: + - type: SurveillanceCameraRouter + subnetFrequency: SurveillanceCameraSecurity diff --git a/Resources/Prototypes/White/tags.yml b/Resources/Prototypes/White/tags.yml index 9b53e3b41c..febef3d7ce 100644 --- a/Resources/Prototypes/White/tags.yml +++ b/Resources/Prototypes/White/tags.yml @@ -42,3 +42,6 @@ - type: Tag id: Telecrystal + +- type: Tag + id: SurveillanceBodyCamera diff --git a/Resources/Textures/Clothing/Uniforms/Overlay.rsi/camera.png b/Resources/Textures/Clothing/Uniforms/Overlay.rsi/camera.png new file mode 100644 index 0000000000000000000000000000000000000000..32cb4e7ab2330b4b1c66dc0608f77318a9ef570a GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}>7Fi*ArY-_ z&n@I?FpxO%(K$yr(RH^5$EKXa_bB?H597A0)bKa(y|lklPLZ=bz`i;KzuKfQ0w zon=LarL#R*?p$ZwJby*$#64$KnVN!T9B$70e4nK!mziOO7w>*Oq3JFzE?<=Ow@epW UW|Cf83AB>I)78&qol`;+0GfL}eEPx%heJa(><6>jO_KG}TC*R8%A9S%gL9xBb}uM+(ZlG!wqs$} zxvQub1vj?YVI$M6iw&hUsoT=6wIv=#gO!aXr6HhsAdr0DoA(Lt_vK4I2nYxW2nY!H zUlE)JT9ySsLY}fBk;tWSwOWn6(t!XV2#(YH=66+qggj-%@63}z;Jf4lV&fb8M|&C-6)kzHJ1a{e9(dCGE{+fTpa0(7ZXtG0YKpGU9P zDHMwoibeE#oz;Av?Baskw7&UW7obZ#9tS|HR0vN@Fg=?Fpzx}^jt-k#uZi4rBx2b;n0+SI`RRtg-NxT}-fg>W41Yq|Kn#=q( zU8i|=)|cPa49Grv%JY{mu(UEOYwIlMa*T(=%*Zk`vdnlm%yKTr%G$b{w7&Wsf2U?| z%htokj}S$Xjm=Fehblrec44fgl>zvASQ^-O&?~>I86b)xk|ZICB6H~!mR4pdlOi4( zV=0qjDRbU7mrl7!>#N^!0ot7ohGC%VI=W$?8;0F?WEi}A{l>o54TE;4NWM58gbHa?s;m?kQq zZtd7HqoxTHH)$KXo7BGf-Mj*VS}dSxWit04U=0m{ATZi!Flw6i0njjXu8Y#(wt^n| z-Mj+b(<^sbUHRw2&Q+m~@!KB|5D*X$@DK7Eixk_(PSnwBd)K>b8xO@hPf!jK5Kx1$*T->kcRky}9n1~g zoY76xjfv0A=i+qJ88vQ8SvrKIE@nELpWXDJXAGf*25(1uNeA*gqQ zJ1bYsb)+(!y4uOFZxX#9krpXCY!6?O_Px6gvyuBt|0H*Z05j1Ju4w+i|0 zqFO;9-5?N{BB57ro2r&Op~ z5TLZv1+PC$>r+Bu0s+H6wTs)7a4<9d)X0ww4yoM3Q0Lz1uK1_sAF zp$D?Pw{4oL(Kw30aYZA(xTIe z>N%EXS&DL+P38_=;Ji)Z3bhDo=Q}HxmpH%?4idu~fpbQa88y+O2{jo>14@%5g^Hw! z;wjQ>rdhFzZMy6R9}nw!npIQ914aX9ph+`MptPPPP`yZUC`C~ON||ZWXrgdYB=iW( zbBrj-UKW&!+snEH%*IC^>XDdYOUlZ9x2@u&G$1Liru4jNS>uKld8@A?dqC=*iLFVaX1sj3Jim4F%dt;p zuNrmu+}yJEZ4HOcWE>sJ&B=+12<$`q4gDzyw=5gWo;!H?`)Q_MKK`ryqFG8@m@(Bp zw%NYn&6n`V!9Ah!xx=@KwxyG{F1|l|&ktX1w{D(4e)HP0G4t&^76g{tkP{CcwJa{G zj((%IUv1`{z}=G%<01X^xVG)@d>3DyMpUVrKN~XRzTvbbeNT4Fm4eD)X@}Fc=I%&O zXgzcDi>orf3+IRFEHn6b}%Grs0GH!M8;}x%dITxvWExXyAdqP~_ zH*yy47?fImectLdo{F>Wu~*mC*5UK*SGLEmY9Pz@w0Xx(@GQJs8RHcydu=%wXPG&% ziB$8ZG?Rk{F5oMV$@-Q3?;O~);=ra`W$5VET4GHE)1sRcHSEVD{d-J_$_XU&y8YX? zh1J7H{H|85je#D$Qg4if>h}MQ-XMqW%&q8s>4t9jrESs2oW#TCo~dc6{oX$g-QR6U z{b(aDUtA5Ddq!Mvxh&W2471nV9(^bwrs}M{Vw(C*UfnQwOK zq?Da2F2(7qD!E_f2busfg!4B85H_fMV+8UJSky3XZ1ZaTyZiW8kgTVxpUXO@geCyV CSyWg6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/equipped-NECK.png b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/equipped-NECK.png new file mode 100644 index 0000000000000000000000000000000000000000..66c5cdbfe2d35b35a48b94e82f71421248263731 GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!3HFEH|A#nDaPU;cPEB*=VV?2*$kd8jv*Cu z-rn8l#q21+_P}wnmck7dmTr?K1$PC-+*Kx(iSa62VMs`J*c+T!^CibUyWp7Fi5ka_1%`{~|O|3vy-OuKvJeUjkm-M@cS*o&GQZmj`24+%UtwWR(}@VWE9 z?B*}AWlHv}X7Li?Rd_2X;eAUvU{MCc>{8*?Z`ZA8)O^ki(G{L|<~GyT&zs}gkMGeH z5WJel?UKTm02C7pe7nuTj5a(sg5Ce%SLuLAqg(ah@us& zSI17l1M5*MY7gmnw4>rxv1qNeqGR#sVMS>jN2!X~vC~dpVA(nyb@->5dHcR3zxVro z-;r;2>6A$mdPhV@APCYsE!Ca@cT`_tJ>jofT-*w`a5;5`iXf5w^%a6ty*~&+dNhbx zIa-b*o#iEuffJ-$U?}p)5RD*X5{qPx&j%Ws3-Uy-4Qr`Af}x^d!?Mi|(jg}UmzY|t zfXw1aS$uIm&j?uJSaeJg3kf_x8x#}qVK zQUGc;Sa6;)nb8EsKv|3?h8cy@BxNN?D?u4?%EFpRmZs6bg+XtM;AAuG;{(3noegto zn#>Y}&*wAvj0Q=`BPfPp2$Cjf8ixp6^?Nn02=}VPIvMOh6 zv?BzM9HjNCfi%H{5k;I#PzF*DsT1gMJR9oq1ktLNG8cLY=zSuwn&p=PkpWbxP~kz! zT;SD)bvhIH;90p)akob*@C0xJ4}_^u7!`CSyCh9gUD8wH2)+(RBeTg0;513ek|cL$ zp{8`QpvlR4VHk9Hw&)ckpBk@=3Y-CUP6IZKCTUnQ3a6MXl441krK}@KBTJGUPzP)U zfz!CIfh9q7`nv*kIM_6=s&QT(q}gp46lD-aflc6Yoleqf!fBI}#{pw9;S6m}z@1hA z=mahyH-Vwsb;0v?i7(VMsGslXTtVU?M=(jO(dravvjv7H2o{`SOah)uab}z$fyH8` z&5V^ccd|`ZMELP=?#EemRRUx*8mR0+93>#qWTrl2h|>3K*9MGu@T`BA%vS<>o$Heb;LL z|Edopmv?dAJOC#sf$8xO`mE_F4e{TqwZD68E_K4;u+z=pl!Z6JISss!T7gqIQWa|v zBs3|_J}xV#?Dp#KCikD(r}Rj~*6FVou9>xLJ$`X(&t0Bt<6drvd>B_%)X?qbk@{WX z*~cynAGk6!W!cT>VOKA26MxK(^mMz~>_6)L^n+h^E^IxQX1TP%Z@ho|pg%D*V`6!H zV|i6ccQSNP2+}k^wx9FO@gFuUY%4x=rm^m=(m4l9H?17b)mIlt8#T7B_RxlfP4fr% zDqpJDezoPg6gf2Hq`@F7`+j~X3>>(&YC+Pm6(j#z*D_?sg*mhCU6?myd&B0O5mQH1 z%F(^2-}moc9(n5S-?ibr>yXVEJNvz3U%P)jG}{afN+(JMoK+ zcP1ij59jVE`7<}+Y4il?)m8L&*D#xT~NO~n|Qa99+`h@)UQf< zdEM!%xINpx7ObZg!--Ru4=Cw3z*@5D-re)Bx~l4%zaMa+#j@~X>wX?oKeu`B3nkN% z&YQHE6BE zX}QvOQO&Jc2BbARsnLXt`sUgi*V#F-{EPvmd9_;U{Sm9uPmQ&Vr`L7=?UOSp zTYgx4cXWC8eJ@57D8LW^e_UU=&hXi+==vsKuc4O?hty0gpZ`is$O@!9>i3v>vNifaqr(aR4Mc&QG^fLXjDU6+ VT>5n`^F4h_OPOS^d2RNhe*k&m1MUC- literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/meta.json b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/meta.json new file mode 100644 index 0000000000..6e6fd3aec3 --- /dev/null +++ b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/meta.json @@ -0,0 +1,108 @@ +{ + "version" : 1, + "license" : "CC-BY-SA-3.0", + "copyright" : "Copyright (c) White Dream Space Station 14", + "size" : { + "x" : 32, + "y" : 32 + }, + "states" : [ + { + "name" : "unpowered" + }, + { + "name" : "active" + }, + { + "name" : "active-animated", + "delays" : [ + [ + 1, + 2 + ] + ] + }, + { + "name" : "off-inhand-right", + "directions" : 4 + }, + { + "name" : "off-inhand-left", + "directions" : 4 + }, + { + "name" : "on-inhand-right", + "directions" : 4, + "delays" : [ + [ + 1, + 2 + ], + [ + 1, + 2 + ], + [ + 1, + 2 + ], + [ + 1, + 2 + ] + ] + }, + { + "name" : "on-inhand-left", + "directions" : 4, + "delays" : [ + [ + 1, + 2 + ], + [ + 1, + 2 + ], + [ + 1, + 2 + ], + [ + 1, + 2 + ] + ] + }, + { + "name": "equipped-NECK", + "directions": 4, + "delays" : [ + [ + 1, + 2 + ], + [ + 1, + 2 + ], + [ + 1, + 2 + ], + [ + 1, + 2 + ] + ] + }, + { + "name" : "off-equipped-NECK", + "directions" : 4 + }, + { + "name": "equipped-INNERCLOTHING", + "directions" : 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-equipped-NECK.png b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-equipped-NECK.png new file mode 100644 index 0000000000000000000000000000000000000000..7587e067f3ba5c184440ee861e170db3559107d1 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|_IkQFhE&XX zdut>6VF!`pAD7R1sS)e+a>B+doSkcCZhG>5{iT(wLXHRZxwMs786A7NGpyGB_vgBK zx8JEV0ktz2U-h+?>nmF`yX;Tdw58V+o%_Fg&)dG5=UB$`&OA}0DHiIr*F7K2DVz7A zDb8VHv}Di3lFd_3|6DSc6Qmmg>iXYv9l5jerZ2}Y*?FI08)v-hy4$j#?!XkF@RFOp w5j71;+b2z(>Nf4>rcIMdw)gK62J8FN&+q!#h-GGSjx31p>FVdQ&MBb@051V-w*UYD literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-inhand-left.png b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..043847e22be4d71f50ed47efe57b3a5fd84500e2 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|nmk<`Ln`LH zy=BOC$U%Vh!o^D_FT;Y)30`6?syV24T;R=~gHaLDJGnXcl{cLKu>7weP!Gcf?U|9! zOIPmwbbfDBwB&N3^~a5kHhXiP)78&qol`;+04YOD4FCWD literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-inhand-right.png b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/off-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..ecae3b2b5604dafe8e2c097bfb02ffee126aa1ef GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|>OEZ?Ln`LH zy=BP7S2($w?|J` zDJre(|J&p`U8P%(%k+;I`<`9SWZ@HRb+NwMc31i_X3_asg=ofeRNs<~Ekw z<#o)-^4)Gwbt#yEVL`w8i+dtL+tu#K0u}J3MtG+A`Z8z%*&HApKyWE|GKlhY^>bP0 Hl+XkKcQH!* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/on-inhand-left.png b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/on-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..87e1b4346bafe16ec3d86a2f0cddb9311c74bcb1 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^4nW+%!3HFEH|A#nDaPU;cPEB*=VV?2IV(L~978JR zyuG`T_mF{rL!h&#Mo{9EPi_mCQ)^VLjyYV|=(s{-0jEZ%&xLB{AM@|ry0nx9sExtE z!KLJN_A9S%;h|p(>n*=Aluo|kk8! z{4Mep416NA?A`ac13xRGY}hpymdHaCGdyrTx!z>|1$GGcLH^m?`3H6%{LT7Cn1LZ- Yo}Bn|)#*$h?E*m3p00i_>zopr0MbQS5dZ)H literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Security/body-camera.rsi/on-inhand-right.png b/Resources/Textures/Objects/Specific/Security/body-camera.rsi/on-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..e5e017579b57dc42fb09ac709682e58d3544b785 GIT binary patch literal 262 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 B%C-Oi literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/computers.rsi/bodycamprogram.png b/Resources/Textures/Structures/Machines/computers.rsi/bodycamprogram.png new file mode 100644 index 0000000000000000000000000000000000000000..1282216d16182792703a5eb19995b3356c74b6b2 GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Q$1ZALn2z= zUf#&dWXRL{P~OFHKHKXfOn1y~Hp#BrvoXVn#Z