From 876bd21bd2efa0b7b259372f6265b45260a9175c Mon Sep 17 00:00:00 2001 From: Viktor <125474183+OmntnsV@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:17:04 +0200 Subject: [PATCH] Voice recorder (#20) *added voice recorder --- .../VoiceRecorder/VoiceRecorderComponent.cs | 68 +++++++ .../VoiceRecorder/VoiceRecorderSystem.cs | 178 ++++++++++++++++++ .../Locale/en-US/white/voice-recorder.ftl | 15 ++ .../Locale/ru-RU/white/voice-recorder.ftl | 17 ++ .../Catalog/Cargo/cargo_security.yml | 10 + .../Catalog/Fills/Crates/security.yml | 9 + .../Entities/White/voice_recorder.yml | 29 +++ .../Objects/Misc/bureaucracy.rsi/meta.json | 5 +- .../paper_stamp-transcript.png | Bin 0 -> 1929 bytes .../voicerecorder.rsi/icon-on.png | Bin 0 -> 4002 bytes .../VoiceRecorder/voicerecorder.rsi/icon.png | Bin 0 -> 3801 bytes .../VoiceRecorder/voicerecorder.rsi/meta.json | 97 ++++++++++ .../voicerecorder.rsi/off-inhand-left.png | Bin 0 -> 6980 bytes .../voicerecorder.rsi/off-inhand-right.png | Bin 0 -> 6930 bytes .../voicerecorder.rsi/on-inhand-left.png | Bin 0 -> 7721 bytes .../voicerecorder.rsi/on-inhand-right.png | Bin 0 -> 7711 bytes 16 files changed, 427 insertions(+), 1 deletion(-) create mode 100644 Content.Server/_White/VoiceRecorder/VoiceRecorderComponent.cs create mode 100644 Content.Server/_White/VoiceRecorder/VoiceRecorderSystem.cs create mode 100644 Resources/Locale/en-US/white/voice-recorder.ftl create mode 100644 Resources/Locale/ru-RU/white/voice-recorder.ftl create mode 100644 Resources/Prototypes/Entities/White/voice_recorder.yml create mode 100644 Resources/Textures/Objects/Misc/bureaucracy.rsi/paper_stamp-transcript.png create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/icon-on.png create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/icon.png create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/meta.json create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/off-inhand-left.png create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/off-inhand-right.png create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/on-inhand-left.png create mode 100644 Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/on-inhand-right.png diff --git a/Content.Server/_White/VoiceRecorder/VoiceRecorderComponent.cs b/Content.Server/_White/VoiceRecorder/VoiceRecorderComponent.cs new file mode 100644 index 0000000000..de038e7810 --- /dev/null +++ b/Content.Server/_White/VoiceRecorder/VoiceRecorderComponent.cs @@ -0,0 +1,68 @@ +using Content.Shared.Whitelist; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared._White.VoiceRecorder; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class VoiceRecorderComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)] + [DataField("enabled")] + public bool Enabled { get; set; } = true; + + [DataField("blacklist")] + public EntityWhitelist Blacklist { get; private set; } = new(); + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("range")] + public int Range { get; private set; } = 10; + + [DataField("listening")] + public bool Listening { get; set; } = false; + + /// + /// The sound that's played when the scanner prints off a report. + /// + [DataField("soundPrint")] + public SoundSpecifier SoundPrint = new SoundPathSpecifier("/Audio/Machines/short_print_and_rip.ogg"); + + [DataField("soundEndOfRecording")] + public SoundSpecifier SoundEndOfRecording = new SoundPathSpecifier("/Audio/Machines/id_insert.ogg"); + + [DataField("soundStartOfRecording")] + public SoundSpecifier SoundStartOfRecording = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/pistol_magin.ogg"); + + /// + /// What the machine will print + /// + [DataField("machineOutput", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string MachineOutput = "PaperOffice"; + + [DataField("recordings")] + public List Recordings = new(); + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("maximumEntries")] + public int MaximumEntries = 100; + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("customTitle")] + public string CustomTitle = ""; + + /// + /// When will the recorder be ready to print again? + /// + [ViewVariables(VVAccess.ReadOnly)] + public TimeSpan PrintReadyAt = TimeSpan.Zero; + + /// + /// How often can the recorder print out reports? + /// + [DataField("printCooldown")] + public TimeSpan PrintCooldown = TimeSpan.FromSeconds(5); +} diff --git a/Content.Server/_White/VoiceRecorder/VoiceRecorderSystem.cs b/Content.Server/_White/VoiceRecorder/VoiceRecorderSystem.cs new file mode 100644 index 0000000000..87c42b7ea8 --- /dev/null +++ b/Content.Server/_White/VoiceRecorder/VoiceRecorderSystem.cs @@ -0,0 +1,178 @@ +using System.Text; +using Content.Server.Paper; +using Content.Server.Popups; +using Content.Server.Speech; +using Content.Server.Speech.Components; +using Content.Shared._White.VoiceRecorder; +using Content.Shared.Examine; +using Content.Shared.GameTicking; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Interaction; +using Content.Shared.Item; +using Content.Shared.Paper; +using Content.Shared.Toggleable; +using Content.Shared.Verbs; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Timing; +using Robust.Shared.Utility; + +namespace Content.Server._White.VoiceRecorder; + +/// +/// This handles the voice recorder all itself. +/// +public sealed class VoiceRecorderSystem : EntitySystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly PaperSystem _paperSystem = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly MetaDataSystem _metaData = default!; + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly SharedGameTicker _gameTicker = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnActivate); + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(SaveEntityMessage); + SubscribeLocalEvent(CanListen); + SubscribeLocalEvent>(AddVerbs); + } + + public void OnInit(EntityUid uid, VoiceRecorderComponent component, ComponentInit args) + { + if (!TryComp(uid, out var listener)) + { + RemComp(uid); + component.Listening = false; + return; + } + ToggleListening(uid, component, component.Listening); + + } + + public void OnExamine(EntityUid uid, VoiceRecorderComponent component, ExaminedEvent args) + { + if (args.IsInDetailsRange) + { + var message = $"{Loc.GetString("voice-recorder-state")} {Loc.GetString( component.Listening ? "voice-recorder-state-on" : "voice-recorder-state-off")}"; + args.PushMarkup(message); + } + } + + public void OnActivate(EntityUid uid, VoiceRecorderComponent component, ActivateInWorldEvent args) + { + component.Listening = !component.Listening; + ToggleListening(uid, component, component.Listening); + var message = Loc.GetString(component.Listening ? "voice-recorder-on" : "voice-recorder-off"); + _popup.PopupEntity(message, args.User, args.User); + args.Handled = true; + } + + private void AddVerbs(EntityUid uid, VoiceRecorderComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !component.Enabled || component.Listening || component.Recordings.Count == 0) + return; + AlternativeVerb verb = new(); + verb.Text = Loc.GetString("voice-recorder-print"); + verb.Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")); + verb.Act = () => OnPrint(uid, component, component.Recordings.ToArray(), args.User); + args.Verbs.Add(verb); + } + + public void ToggleListening(EntityUid uid, VoiceRecorderComponent component, bool listening) + { + component.Listening = listening; + if (listening) + { + component.Recordings.Clear(); + EnsureComp(uid).Range = component.Range; + _audioSystem.PlayPvs(component.SoundStartOfRecording, uid, + AudioParams.Default + .WithVariation(0.25f) + .WithVolume(0.3f) + .WithRolloffFactor(2.8f) + .WithMaxDistance(1.5f)); + } + else + { + RemComp(uid); + _audioSystem.PlayPvs(component.SoundEndOfRecording, uid, + AudioParams.Default + .WithVariation(0.25f) + .WithVolume(0.3f) + .WithRolloffFactor(2.8f) + .WithMaxDistance(1.5f)); + } + if (TryComp(uid, out var appearance) && + TryComp(uid, out var item)) + { + _item.SetHeldPrefix(uid, listening ? "on" : "off", false, item); + _appearance.SetData(uid, ToggleVisuals.Toggled, listening, appearance); + } + } + + public void CanListen(EntityUid uid, VoiceRecorderComponent component, ListenAttemptEvent args) + { + if (component.Blacklist.IsValid(args.Source)) + args.Cancel(); + } + + public void SaveEntityMessage(EntityUid uid, VoiceRecorderComponent component, ListenEvent args) + { + if (!component.Listening) + return; + + var message = $"{_gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan).ToString("hh\\:mm\\:ss")} {Name(args.Source)}: {args.Message}"; + component.Recordings.Add(message); + + if (component.Recordings.Count > (component.MaximumEntries - 1)) + { + ToggleListening(uid, component, false); + } + } + + public void OnPrint(EntityUid uid, VoiceRecorderComponent component, string[] messages, EntityUid user) + { + if (_gameTiming.CurTime < component.PrintReadyAt) + { + _popup.PopupEntity(Loc.GetString("forensic-scanner-printer-not-ready"), uid, user); + return; + } + // TEXT TO PRINT + var text = new StringBuilder(); + text.AppendLine(component.CustomTitle == "" ? Loc.GetString("voice-recorder-title") : component.CustomTitle); + text.AppendLine(""); + text.AppendLine(Loc.GetString("voice-recorder-start")); + foreach (var message in messages) + { + text.AppendLine(message); + } + text.AppendLine(Loc.GetString("voice-recorder-end")); + + var printed = EntityManager.SpawnEntity(component.MachineOutput, Transform(uid).Coordinates); + _paperSystem.SetContent(printed, text.ToString()); + var stamp = new StampDisplayInfo(); + stamp.StampedName = Loc.GetString("voice-recorder-stamp"); + stamp.StampedColor = new Color(47, 47, 56); + _paperSystem.TryStamp(printed, stamp, "paper_stamp-transcript", null); + _handsSystem.PickupOrDrop(user, printed, checkActionBlocker: false); + _audioSystem.PlayPvs(component.SoundPrint, uid, + AudioParams.Default + .WithVariation(0.25f) + .WithVolume(3f) + .WithRolloffFactor(2.8f) + .WithMaxDistance(4.5f)); + _metaData.SetEntityName(printed, Loc.GetString("voice-recorder-paper-name")); + _metaData.SetEntityDescription(printed, Loc.GetString("voice-recorder-paper-desc")); + ToggleListening(uid, component, false); + component.PrintReadyAt = _gameTiming.CurTime + component.PrintCooldown; + } +} diff --git a/Resources/Locale/en-US/white/voice-recorder.ftl b/Resources/Locale/en-US/white/voice-recorder.ftl new file mode 100644 index 0000000000..61bf498023 --- /dev/null +++ b/Resources/Locale/en-US/white/voice-recorder.ftl @@ -0,0 +1,15 @@ +voice-recorder-on = recording now +voice-recorder-off = recording stopped +voice-recorder-print = Print recording +voice-recorder-stamp = TRANSCRIPT +voice-recorder-title = NANOTRASEN BLCK-M VOICE RECORDER TRANSCRIPT +voice-recorder-start = *start of recording* +voice-recorder-end = *end of recording* +voice-recorder-paper-name = recorder transcript +voice-recorder-paper-desc = BLCK-M voice recorder transcript +voice-recorder-state = Voice recorder +voice-recorder-state-on = is recording +voice-recorder-state-off = is off + +ent-CrateSecurityVoiceRecorder = voice recorder crate + .desc = Contains 3 voice recorders to ensure that no evidence will be lost. Does not require any access to open. diff --git a/Resources/Locale/ru-RU/white/voice-recorder.ftl b/Resources/Locale/ru-RU/white/voice-recorder.ftl new file mode 100644 index 0000000000..ebea1af1cb --- /dev/null +++ b/Resources/Locale/ru-RU/white/voice-recorder.ftl @@ -0,0 +1,17 @@ +voice-recorder-on = запись включена +voice-recorder-off = запись остановлена +voice-recorder-print = Распечатать +voice-recorder-stamp = СТЕНОГРАММА +voice-recorder-title = NANOTRASEN BLCK-M VOICE RECORDER TRANSCRIPT +voice-recorder-start = *начало записи* +voice-recorder-end = *конец записи* +voice-recorder-paper-name = стенограмма +voice-recorder-paper-desc = копия стенограммы записанной на диктофон типа BLCK-M +voice-recorder-state = Диктофон +voice-recorder-state-on = ведёт запись +voice-recorder-state-off = выключен + +ent-VoiceRecorder = диктофон + .desc = Диктофон типа BLCK-M. Имеет втроенный принтер для печати стенограмм. Каждая новая запись стирает предыдущую. +ent-CrateSecurityVoiceRecorder = ящик с диктофонами + .desc = Ящик с диктофонами типа BLCK-M. Содержит 3 единицы. Не трубует дополнительных доступов. diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_security.yml b/Resources/Prototypes/Catalog/Cargo/cargo_security.yml index f3121395d9..302805c392 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_security.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_security.yml @@ -87,3 +87,13 @@ cost: 2000 category: Security group: market + +- type: cargoProduct + id: SecurityVoiceRecorder + icon: + sprite: White/VoiceRecorder/voicerecorder.rsi + state: icon + product: CrateSecurityVoiceRecorder + cost: 1000 + category: Security + group: market diff --git a/Resources/Prototypes/Catalog/Fills/Crates/security.yml b/Resources/Prototypes/Catalog/Fills/Crates/security.yml index 950b11f1f9..6784ded19d 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/security.yml @@ -123,3 +123,12 @@ contents: - id: BoxBodyCamera amount: 2 + +- type: entity + id: CrateSecurityVoiceRecorder + parent: CrateGenericSteel + components: + - type: StorageFill + contents: + - id: VoiceRecorder + amount: 4 diff --git a/Resources/Prototypes/Entities/White/voice_recorder.yml b/Resources/Prototypes/Entities/White/voice_recorder.yml new file mode 100644 index 0000000000..53b1e02c81 --- /dev/null +++ b/Resources/Prototypes/Entities/White/voice_recorder.yml @@ -0,0 +1,29 @@ +- type: entity + parent: BaseItem + id: VoiceRecorder + name: voice recorder + description: BLCK-M type voice recorder. Has built-in printer for printing transcripts. Each new record erases previous one. + components: + - type: Sprite + sprite: White/VoiceRecorder/voicerecorder.rsi + layers: + - state: icon-on + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: { state: icon-on } + False: { state: icon } + - type: Item + heldPrefix: off + sprite: White/VoiceRecorder/voicerecorder.rsi + - type: Appearance + - type: VoiceRecorder + blacklist: + components: + - SurveillanceCamera + - SurveillanceCameraMonitor + - RadioSpeaker + range: 5 + - type: ActiveListener + range: 5 diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json b/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json index cfa5fb3095..6ceed3d96f 100644 --- a/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json +++ b/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json @@ -256,6 +256,9 @@ }, { "name": "paper_stamp-geraldiy" - } + }, + { + "name": "paper_stamp-transcript" + } ] } diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/paper_stamp-transcript.png b/Resources/Textures/Objects/Misc/bureaucracy.rsi/paper_stamp-transcript.png new file mode 100644 index 0000000000000000000000000000000000000000..f721327a2e780ab086e12c9c40383f1a9f876c96 GIT binary patch literal 1929 zcmb_d&x_nt9M2+@y4oM$Ma4r%DYR;m_g*sDO=z}kXSUr?v#z@XJ4-$EP2S5)*hyYY zvOBW_LMbYG6Qv%+zd`R+s7DVT)I&iETF|3KL@(k&znLFlS9a^N78WSRHY0uf$+MDl;)|%+Dq8+4 zP9S29GSTMRAWi`-NtZ4UQW|XWLT>X;l(@>TpWjpDh`Gu}%}0J(=iO*|nDO=DN;4R4 z1vXPIFUXe$4k(CuLFGZ*OLAx6DkHrPjLT(Rkw=hX%T*RjgL2DXmFptoa!s?;0Gl;= z&epJHn6~}0Oc0*e(Y%fg6z>ckezT%}tSsiW)teqZYwn#ejj zwryKSL?=WAgqrUr1s$kKer~Fv!Sf)C(jpRxTxz6kv0bh;x3gi#MR^0jMMWN)c%VcW7)qT!LdzVCQR zUeF}qUc*%&KUx$qhlU(+Vp}RVd0WMy8LGA!aurjINZYoE#jUA)Lj>C;3#Rf6Eg~ zi{uew92%6B;3`2$0nU`ka&$ljjuydKZNJMw>0@{?hUFqG`ZVK<9mv*EsHY$1e@=HE z?>#Y@Vb5DkWwu>YDK+O*o52lX*fqoExJ?WK=XbdG#BypCtB>jZM19buNr%Jbsw>Bj z=V*L9Jf3}}_rJ!Ym)Gi;YWlxfINIBD1;cTUmf&75ht-1ulj=$038X562j{c9FT4(q z)uz{2Y_{HhbRW;<4M_KKI+znd@i7#h;({&i~MU^vn78Z~gf||NG8Q?|$>ujd$+P zj9xfNy7xr$uix)(-nbn-`0?h#nd{lcmv7$rsPBF7{aYmhxesT~UO4^r!fUe{Oi%Nc c7y7>RB8*R#`|y3Y{$bg9ODl~}uiU)-4~HaGK>z>% literal 0 HcmV?d00001 diff --git a/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/icon-on.png b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/icon-on.png new file mode 100644 index 0000000000000000000000000000000000000000..7a0bcd80c4cb35f41a853361e851a33b4fe1bf74 GIT binary patch literal 4002 zcmcIn3s6+o8NNV66{8TXFVy6^)@Y1}`@VPY9T0gbWLz*nCeWJbx%Zw6tL)x&cX3x# za11pXGh%9^*2kbtRhs%3wee9+NXCpwtF}?&bRxz0Hkv`|#5W>6cNaD^0kvtfGrN24 z+5dI^|NFoH?BdC}6MM%c#t{V3J109cpCF>}k|2A;;?LGUY`TEIdU~>peFV{~pY@I+ zR<9j|7autbi~L27Ns4B=lAvy?C@JXjSh_@VYS06<8OTqnsKn_`u{H0nw~+(NBlh9>K_)Ny2TP{9UV$PdY&tIX|Ff+@C;T?MbLZOTT5MEo;S zY-yH5vdA%+%rL!(6p}=sF}y%ZauOqQyey9;S(>p^w4Gu&z=#S@D=bU4ziil>S2vXW z%n9wj@KcJd)bIBw6cq>rk^)?k=`EocS(Yi9rC1hV3E-RU_QN1>`$lwF$V5KP>-6}Y zrkk`ZLe(tyr`T|$;Ul;_5wmVzdzx^vBb;eg3RjIHLBmbt&yDob5qWKJuC6UJYf?R43pChU8C>dS^{ie6jG|M`wJh{UPnUP^tRVGKj>~!m9!1tUL zWxEc_gnpD_V`-KLGy@o>khV&$aNP4Wr_gj*)PZrNLqGh!Fr%=NBC!7Kg}C+;S)G>{fwz(0`pq!Q zOs~V#an3ob8$zg5vYkF$z1i*kRe)x;ugaWc2#5;QtX@g6X;z()ZfoCmc9EyYizsY1 zP>Qh8hZH|7<}(d{0D4hc3C`)`;EU=mejl9mi0F}|Nl1`^3I!T)EUq%-1QrMqZ*Y)9 z1`XAY({~v?1})Qp#vd4cdvdi>=q^E+ekt1zKaauU= z`E5IQn>QVKot==-*-In@^8e`Xk+^$2cImEbe#|;i)_@FC0`*A`wp_1+!&@KmR+X3;Q?!SH`q}6Twu3&eQNnu!z#vPA}=OBtkUfy5@Nf^N6a7 zEMOT;0GNy+fFiOUd7WkihGTU#Ih5iu=c8;1v>-{e3W3HW+{<`q0F|?gKw#{GqzSsL zsqFV{b>xqcG!;sC%<_h&S3EFWan?jZ#$#9R-nU^Gw4jPA5M+Y} zT8KaGb_8f-Ko;_>Du{X~?NBAdu%I4}pO9pydnhh`XbWF%t!3m^jUOWSa^%L-z>9C) zy&7(%5=4wECo`=uxVC9+eO^B}^ib_L11DC1>ezmu_u5{44^CUqYeP)j@YqT8OmE-V zf@#8}*by@sX6e<1i`(WeX8L3es+(|r{iNz&9Uq^OK5~3j_412T_Eu~STpTlR&ZjB0 z8(WW`AJ_aomAr5N?e|~!^S0L#&N*`TH4^EI=Fmis>-3XEdh(Mo^Aq9^66D7RBU?v) zTXlEiwgLVB(mJp4azR|`;mbaP+$a^iG(EBP#tG^aHEef6-5;|~o}9LR@~GV`LAEB( z$*rGzag3P%H8H<&9ZzHvF9b$!eRjq3(|?9FrVgq4f+#I$xH%(gaJ+xm)ZKfci0hl4 zoqM?S)62fm4zf0n`E}j=*=tUIytDAyv@4ryADp`9idpY){bNYtnwi5t&(B%o`XYO) z78upEx8GNrYb&o;Hq0S5=6DNd1&;S`T3&hY%E0D5y$Q#OxXtm}`C}PRP*V?#IneAF zwc~e9!v}xx=8o&7$4YWHw6)!&9^9$kzHZ&#DrI~dbGzZyXudZ7%DCDE4S{Q_)7i5! zYsWwP5Igq`RTPDmhU{uQl)e6j@z-O|C0GYP-CUaZ+4j+Qgq8s-FI3d^UG~|F!B>vm zI@3I4_iqMEBa;>uj#{lX*S|Qmrn=9R+bzt>qv>zYubFfD`u@f?cT3~7s;4SH`I@+T zZ{b_f(~hu-+sg+utiE_@|FVf^?RU=qwE4?br_PM5Z)k1a{bkdGfoB5;`qF)`9J=xO z&uwqH51)Fo_|>gz24}n$vue>&wbb+B&H+u*((;Pw$HNPoGQD`oE#LjTOLrP#=WlXm zl~y0HhSFU?v87huG6HL^ux740U zt0IeT6pOnqZh8C0iM*<#_fgFH0X3p!;M(2zc|%tvc)e$(=%>!XK}24j0_ z7rhRNgic$Rq{APKsn-fGyodiP_d!KDhQmRO!RsE@e`owUUa;Ky%E`*j+?GCV!M_1s Cg?^0y literal 0 HcmV?d00001 diff --git a/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/icon.png b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3c5b4ff4b70eae4c2cb4e41a7c82b97e4db7ca6e GIT binary patch literal 3801 zcmc&%4Qy3c9lxE^l-arwx` z?!A5QwJ`&c8O@kc=7dp}g_(_+E%T#l%`mZ3iJ8O=!4PPpuuNq{U2zU4WQym$uePRz z#%a9C{W|CO|2Y58bH3EMX?^2OOK)Nrrm_Mkj&!N=^onDgNL?b!{%1s&8{k%ltG4sh%IK)*}yEuxe{NKen-PR$Ce=B z_BhuX31m~rPPX0i2@7K?z@h?K&4`JrtQf{!tR#p!FX+4|15q^`loZ0RZ6ncJ-=cTK$(^=JxZEufa#bEF3 zb+fit2%4j{S7=BAg(S{Nf}{XJ1cK5dKvRY$G+G4N6ofJ~Nu$$7A({ym#U4R4Y3#|u z46tXr&fs;SHZ~p4&mihMH-q{JpUd`@q$QJPM>Ysi7L$%doTIA7T-P=&2SKFiI*_5N z0^3$(U?I^0P=lIEROn!jObf7Dm0(8NViK<$bA&MM3 zCAZy6dw$Zhsm*1MjT~-L_Ec3ArC6M!;L>0!iq`Z%c~FxCdhufPtjuq@&ivH$=B!Ii zEOBfUGGnKsB1xwbF11=vQbev&lxDWfoQaBAl%(bcH=toRSSdH% zqBu6|bSHJWzSH2M#=T?Bw+|7hb9Pu*Z|0}EGTKZffO3Rvw35dvhcrO5B9Qo;!lgP9P$xu zs>BcCoa1{L7Ugnj7njnE&u8sQuc~Dx8+zl!vq{VRbqYTepr#2H0$3psAVTBX zl64h8QHL6awt+2L`O4aO@3rtpVN{E-T32eNoh>SxL8aKVp}tz#xqJ3@C0htumMQ^B zq}eD!1p%az=vT1?5sI>8TdPV2PrFmRs!dANu!S_*;S~pCAWI4amL1h5qC=h9!d5k5 zZfZqAmg-0X&}0DuLKKPCINJh-jz!unEm?EW+|(MhG~1#b8(OjmupHGzM|A);WJ5r< zEMTP1O^qa7RYeg2RS^ill7a!!kO6FB5X)9&!?3PJO^~5thtfbK0V2>XgF$Qq$U614 z3Ju-1jJahyjw3)zr8^A65dg-~7D3ku5Qu{$q(~N2?P=5{>z7^0U)$#;E*pW;sLpR=1mtdG@)+bZP`nPu9I&o_F4(2PL zIeYeC*O@mbFTKdHk2k*V)hU}_T6n(r?%$V$&yE})zN2#`9wfI;uKNvKeHaXS>V?fa zZo9H?SGMignHSqGl7{>K*3?_qaNnPP$vpkt#}<6*72{i1Mw*tghrwSG(nFWSb@lp} zfBT3z4ubl&)D4pxAABx1=&=;qgc_*mTt+THTG-up-QrIyRbm#;bh?FmYk z-u|k#|NG60PaHVz_3u1=>cb7pspiq~{jYBA%bjn&*!{+^@Z{OC3onarU2eR8qPg$l zy~A7T$Cd&?EU80 zxiw?WUu;>qV)xE2<7?l@A8WXsT5H>$*G5i;PwX0dPJiLq9apT6?QZzT^EcG}vwhKy zn-k2!HPqPeGQYU`^5odq;zoMH{18cXILRcll781mM^1X3=zcVMb*$Z#c%g0Eu73ex C*7Sq` literal 0 HcmV?d00001 diff --git a/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/meta.json b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/meta.json new file mode 100644 index 0000000000..8212493b99 --- /dev/null +++ b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/meta.json @@ -0,0 +1,97 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "by Gargrarien", + "size": {"x": 32, "y": 32}, + "states": + [ + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "icon", + "directions": 1 + }, + { + "name": "off-inhand-left", + "directions": 4 + }, + { + "name": "off-inhand-right", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "on-inhand-right", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/off-inhand-left.png b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/off-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..32d397683f7bab59fada83e7cb45f7f3ca35186a GIT binary patch literal 6980 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 U!ROhv*X3U$)z#r${>DrH1>9AaHUIzs literal 0 HcmV?d00001 diff --git a/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/off-inhand-right.png b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/off-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..140c8115b3e1672c5d46a90cce4072666f64645a GIT binary patch literal 6930 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/on-inhand-right.png b/Resources/Textures/White/VoiceRecorder/voicerecorder.rsi/on-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..65fe926d3a527dc26a470ad972e0c0724370d277 GIT binary patch literal 7711 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