From 73363b9ff550f635526eaafd5eb22aa44fefd264 Mon Sep 17 00:00:00 2001 From: KOTOB <59124164+kotobdev@users.noreply.github.com> Date: Thu, 4 Dec 2025 08:59:08 -0800 Subject: [PATCH] More Chat Indicators (#4679) * emote whisper and OOC bubbles Signed-off-by: Nesoryo-jpeg * Update meta.json added entries for OOC, Emote, and Whisper Signed-off-by: Nesoryo-jpeg * Update meta.json added copyright info for OOC, Emote, and Whispering Signed-off-by: Nesoryo-jpeg * Update typing_indicator.yml Added Whisper, OOC, and Emote indicators Signed-off-by: Nesoryo-jpeg * added indicator logic * added radio sprite state * initialized logic for chat bubbles * refresh indicator change * fixed emote sprite * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * nicer comments * cleaned up and sorted namespaces * oh my god * cleanup... * cleanup two * cleanup 3 (my god) * YESSSS --------- Signed-off-by: Nesoryo-jpeg Co-authored-by: Nesoryo-jpeg Co-authored-by: nkokic Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../Systems/Chat/ChatUIController.cs | 7 ++ .../Systems/Chat/Widgets/ChatBox.xaml.cs | 5 +- .../Systems/Chat/ChatUIController.cs | 43 +++++++++++ .../SharedTypingIndicatorSystem.cs | 4 +- Resources/Prototypes/_DV/typing_indicator.yml | 28 +++++++ .../_DV/Effects/speech.rsi/emote0.png | Bin 0 -> 1052 bytes .../_DV/Effects/speech.rsi/emote1.png | Bin 0 -> 756 bytes .../Textures/_DV/Effects/speech.rsi/meta.json | 70 +++++++++++++++++- .../Textures/_DV/Effects/speech.rsi/ooc0.png | Bin 0 -> 827 bytes .../Textures/_DV/Effects/speech.rsi/ooc1.png | Bin 0 -> 632 bytes .../_DV/Effects/speech.rsi/radio0.png | Bin 0 -> 2946 bytes .../_DV/Effects/speech.rsi/radio1.png | Bin 0 -> 742 bytes .../_DV/Effects/speech.rsi/whisper0.png | Bin 0 -> 738 bytes .../_DV/Effects/speech.rsi/whisper1.png | Bin 0 -> 562 bytes 14 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/emote0.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/emote1.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/ooc0.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/ooc1.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/radio0.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/radio1.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/whisper0.png create mode 100644 Resources/Textures/_DV/Effects/speech.rsi/whisper1.png diff --git a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs index 100841f053..18d8bd604a 100644 --- a/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs +++ b/Content.Client/UserInterface/Systems/Chat/ChatUIController.cs @@ -714,6 +714,13 @@ public sealed partial class ChatUIController : UIController box.ChatInput.ChannelSelector.UpdateChannelSelectButton(box.SelectedChannel, null); else box.ChatInput.ChannelSelector.UpdateChannelSelectButton(prefixChannel, radioChannel); + + // DeltaV begin - refresh indicator change + if (CurrentChannel != prefixChannel) + _typingIndicator?.ClientSubmittedChatText(); + + CurrentChannel = prefixChannel; + // DeltaV end } public (ChatSelectChannel chatChannel, string text, RadioChannelPrototype? radioChannel) SplitInputContents(string text) diff --git a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs index f131cc0604..7ab18a586c 100644 --- a/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs +++ b/Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs @@ -238,6 +238,7 @@ public partial class ChatBox : UIWidget return; ChatInput.ChannelSelector.Select(toSelect); + _controller.CurrentChannel = toSelect; // DeltaV - Alt Chat Indicators } private void OnInputKeyBindDown(GUIBoundKeyEventArgs args) @@ -270,12 +271,14 @@ public partial class ChatBox : UIWidget _controller.UpdateSelectedChannel(this); // Warn typing indicator about change - _controller.NotifyChatTextChange(); + // _controller.NotifyChatTextChange(); // DeltaV + _controller.NotifySpecificChatTextChange(SelectedChannel); // DeltaV - Alt Chat Indicators } private void OnFocusEnter(LineEditEventArgs args) { // Warn typing indicator about focus + _controller.CurrentChannel = SelectedChannel; // DeltaV - Alt Chat Indicators _controller.NotifyChatFocus(true); } diff --git a/Content.Client/_DV/UserInterfaces/Systems/Chat/ChatUIController.cs b/Content.Client/_DV/UserInterfaces/Systems/Chat/ChatUIController.cs index 0fd37a6069..317be86879 100644 --- a/Content.Client/_DV/UserInterfaces/Systems/Chat/ChatUIController.cs +++ b/Content.Client/_DV/UserInterfaces/Systems/Chat/ChatUIController.cs @@ -4,6 +4,9 @@ using Content.Client.CharacterInfo; using Content.Shared.CCVar; using Content.Shared._DV.CCVars; using Content.Shared.Dataset; +using Content.Shared.Chat; +using Content.Shared.Chat.TypingIndicator; +using Robust.Shared.Prototypes; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using static Content.Client.CharacterInfo.CharacterInfoSystem; @@ -12,6 +15,12 @@ namespace Content.Client.UserInterface.Systems.Chat; public sealed partial class ChatUIController : IOnSystemChanged { + public ChatSelectChannel CurrentChannel = ChatSelectChannel.None; + private static readonly ProtoId WhisperID = "whisper"; + private static readonly ProtoId EmoteID = "emote"; + private static readonly ProtoId OocID = "ooc"; + private static readonly ProtoId RadioID = "radio"; + /// /// Gets Invoked whenever the autofilled highlights have changed. /// Used to populate the preview in the channel selector window. @@ -98,4 +107,38 @@ public sealed partial class ChatUIController : IOnSystemChanged + /// Notifies and sets what type of typing indicator should be put. + /// + public void NotifySpecificChatTextChange(ChatSelectChannel selectedChannel) + { + var channel = CurrentChannel; + if (CurrentChannel == ChatSelectChannel.None) + channel = selectedChannel; + + switch (channel) + { + case ChatSelectChannel.Whisper: + _typingIndicator?.ClientAlternateTyping(WhisperID); + break; + + case ChatSelectChannel.Radio: + _typingIndicator?.ClientAlternateTyping(RadioID); + break; + + case ChatSelectChannel.Emotes: + _typingIndicator?.ClientAlternateTyping(EmoteID); + break; + + case ChatSelectChannel.LOOC: + case ChatSelectChannel.OOC: + _typingIndicator?.ClientAlternateTyping(OocID); + break; + + default: + _typingIndicator?.ClientChangedChatText(); + break; + } + } } diff --git a/Content.Shared/Chat/TypingIndicator/SharedTypingIndicatorSystem.cs b/Content.Shared/Chat/TypingIndicator/SharedTypingIndicatorSystem.cs index a878879470..dfae7369a4 100644 --- a/Content.Shared/Chat/TypingIndicator/SharedTypingIndicatorSystem.cs +++ b/Content.Shared/Chat/TypingIndicator/SharedTypingIndicatorSystem.cs @@ -80,7 +80,9 @@ public abstract class SharedTypingIndicatorSystem : EntitySystem return; } - SetTypingOverride(uid.Value, ev.OverrideIndicator); // DeltaV + if(ev.State != TypingIndicatorState.Idle) // DeltaV - don't remove override when transitioning to idle + SetTypingOverride(uid.Value, ev.OverrideIndicator); // DeltaV + SetTypingIndicatorState(uid.Value, ev.State); } diff --git a/Resources/Prototypes/_DV/typing_indicator.yml b/Resources/Prototypes/_DV/typing_indicator.yml index 25ac9338b7..29a04a8c73 100644 --- a/Resources/Prototypes/_DV/typing_indicator.yml +++ b/Resources/Prototypes/_DV/typing_indicator.yml @@ -52,3 +52,31 @@ typingState: paper0 idleState: paper0 offset: 0, 0.1 + +- type: typingIndicator + id: emote + spritePath: /Textures/_DV/Effects/speech.rsi + typingState: emote0 + idleState: emote1 + offset: -0.05, 0.1 + +- type: typingIndicator + id: ooc + spritePath: /Textures/_DV/Effects/speech.rsi + typingState: ooc0 + idleState: ooc1 + offset: -0.05, 0.1 + +- type: typingIndicator + id: whisper + spritePath: /Textures/_DV/Effects/speech.rsi + typingState: whisper0 + idleState: whisper1 + offset: -0.05, 0.1 + +- type: typingIndicator + id: radio + spritePath: /Textures/_DV/Effects/speech.rsi + typingState: radio0 + idleState: radio1 + offset: -0.05, 0.1 diff --git a/Resources/Textures/_DV/Effects/speech.rsi/emote0.png b/Resources/Textures/_DV/Effects/speech.rsi/emote0.png new file mode 100644 index 0000000000000000000000000000000000000000..8848256e14436db9088a37f214c291165f021cce GIT binary patch literal 1052 zcmV+%1mpXOP)Px&)=5M`RCt{2T3d44Fbo8nT%nP_8hIM|g3U2}!X`6K{+eEb{ivzJ>jeloqSBdi zXFQg~2c85dfg=AoQn|Rhf5;b&=}&XcdA@&pc}lvywBb1Yyw)$JB%i;0%}9@p|MmKu zE+%>hZZ(mgKfXVDoriHcYNjpd_M9_Sh8C*a*XZx|hvO3ABKYJH8^-C3ATn(!qV&_A zBOpBXM-1b1M1h$Xy%)DugGY=BpoK*twZ+-8LVCs1YIN7Y>;cF?xz<+D*2n*pk}JG` zXO#X(TSVmT<>|5X)4a6s0J;R;UY;I>#04z~``4C6kH9%lD9gGntgb9e+CfZhIZ%sH>V54d0+wLFYd&N+W84B}597BEZWwe<}9rZM(CLk(_jj^8H-9KdXkmj(g=?QAJc|zkH*0@$UOM}+>WZPDYaqF2t0L3N5 zvIoxD+yj&a`4C#`6Jgle8{ji*->@cb^o_M4VN6QU)mc`s;)AtJHi-eXNF8x~Fa3$3 zjB9vm28%hCx0lWt5xN#+o5I_u2ngaa81(|2v&L5|n6o2c_DP&EXVnAP7_SJr6=rU% zh-*b*@AJ4A*`g*O8;e1+xq@o$&7MW}5Rq$-pH`R)BenAZ#S*_>pOcrTwS}x=D0BUC zK7jSp*Z;)%0FS{0RUuX!6+>YkdOiTHvfCdn>hnT&j8<&W*VelA*7Gn<7v~c;s}5Vl zto4WrVR0dn74UgV>8w27A|6l$c;^E=VFavRt0L=vE!;3p$1=Wkm3UTwW+W*XQwkKrKqM4HIUAnsC|xNPlgdWq|^1b#y^1t)UVS?DR-P zpw>%Zmikl%|J!h4R(pb+^01fAyu5F1oztlT%;qV^C@ENPx%u1Q2eRA_;oT1*9V!Eg+pFl<%GU)W11AG>l5P0wh|TFyth zibA#?^Hh%zBL6v3X>4|feAk&ix^vFc^YwC0y1(?{JpH~lE~O+duirDuWAopCzool{ zzJO;fb zaXg~yhY<~CS@czy4)BDfl%|h>0ous&(Gh3c3gwkdD{Z~@(wH283Y4~vf{s3Zqp^Ap zW`G`#vPDF$m-DHNyI#&Gl)ofs1{9&VFEQfyts|`?j2xhWnXopV*~_jU#^MCsM)E?i zKAeNjV%YAFRDKIk2WWvPoJEWoi6n_UA*5Oq=&aN7TV#oO4k*HkGKCAuIl!y!;uwdH z)ACtgalm$e9COZ#p9AicM=y8%kaNyIih}qN-~twDY+LVed`d|+yTc@ZK~p(cy2_^$ zv;s`=nt|vfHphCm*&Q-wNOM@x^bEE7Jfm?9YhEkdltF8MvSX{Ixb;qeKyeGP>Va!E z&wx2mjvQxM1U(rzkF}eFMaL>-9vMcAnZqUj#Q2CJ*7Mvw8*|@V_IB@L>;C{Y$NLj>Elk>2jBBy5 mcRemfwWt}$<|1h>?V!IEX>4Tx04R}tkv&MmKpe$iQ%glE3Kmgu$WWc^qEZ}76^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|E;uQ=NQwVT3N2ziIPS;0dyl(!fY7Kg)$EA^s%9Cf zcudUZRz?3Sd>FVGd000McNliru=>--SEiF8e)V2Ts02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{009$8L_t(|+U?pg3c@fH#_?BCa2JOtZi0(=8hZylg*fRE zJb+uhgNr8+7ol6x4B{E;q^3&LB}uXW-xdgbXm;!+E{>gULa6*&*^Z=&W3PFo+kj7}!08p3kB0f`a&;fO^!NxC5pN$KDnEKXhUU1{R?=)}Ii1Dn@ei3_ zxB{;s^O5A;j=vvL==`6mQnh>l00000006*0p+CS3r$0cR@AJOj>23M0*YUOi_bT{) zr?=(1UI+aF=79bH`UB_>pg-VSRjQT`00000007{>+yG}T%_(vYgc$$;002ovPDHLk FV1me_YLx&0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Effects/speech.rsi/ooc1.png b/Resources/Textures/_DV/Effects/speech.rsi/ooc1.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9b206d44fe2f5570a11017f70b1b561ce55815 GIT binary patch literal 632 zcmV-;0*C#HP)EX>4Tx04R}tkvT{MQ4~ebOq7Ti6bzzbF@;)bqY^A7ia}727$J!k&XNr><1mw8 zlTxq^ShzH9g^jhg7Pf*QxPaITR*E(vBR>fwi19W5aR0lH|LzC*Ft3|#%M_Sa!HGt~ zN<5KN{4cc9Ll+_XRNb`~mS$r#tpiv}8o&uxfuuyP`5+U5g-(T@BQbZ$94jqLV z)-h2le#9UA&elzjk5wmigrW7>^WKNRzYX7I&-*&^yzgW1J;9|__pcwqFN$vwnMFn9SWZ%-}1AMq`6+3!l-umAu6wn;=mR9J;$U>NCu5t$QTUg%sG-7!XT@n zj-uf4otq4@D(VdF9W$tHHvAIEM!_hcHUIz>zAn@~ Scww^u0000;Y4_<(1pSQ-{kV`Ico zbA+);_0E-6=^oYXJ*Oish61Fi3J#491^iTj-nj=-tiFv;{cQRFml#^W)l8yh0f1k39e1)nO_3>hRR0h7 z?C$GVN)BoKCis}m(6)fSceX1kJ@F@$eCPbG!W$niJM4b50f7F8a9`FE?@(qA)w8=^ z)@vg?k>nCM54Wy$u3Ias@AtbhTUe;;R!j8zbO}-5{fwj|P$-*9r%WbyVO$E}pK@n$ zXwZIUc~4$w_28!b)WS(_&SYVdO@^4;PKX@8_cXh&Wvjg)yl;a_PZ-)!ZUweHMf~dG z!6e0QPNtH40}T^`iS+jQ2L@zTLzbm*paj0_Ozirf0VP@FE%?rcK+htr#;2uc!!2(_>4qq$ zapLR6p;?;J@{`ee1^aNfaQ6C-CW2%CB%0P*|q-G;-sYEw`QN@8!J zwb$BABP|<}flHs?OyD+!*4Im%DRau@9nPgd$%mG+m>Li4hMdya`_iz;ClH&ZJ z{N5#T2xIly*i&|KG+neAzf?`RVs7F#r*^;+=({wEe%fd;=qXXHU7cPUqjC^&rXWPgh9WR~%O|oeRmrE|Pe&HJWQ<$d@RZ%`Aq`u0Eqz z_x@FojF$D@O+TGi1$=wVRyl?}c~i%=?^u5AR8%xKM)%w9Yki(OGI!SzqA|*ENIu@_J#0<)9-eJb7FuV)Ehnbv&ijjtUf7 z*(@%M0T(o}))SFL;AHed!%??_EjkP|bVY_)FrOmbXvNDb1A(HBk9?*zscHE0 z^=B0?x`Ll4tl;x|%@;Y;x!C@1)LvBfT-0>du?x#j{9sBT6KqM=gx_$}GSe4NQW?n| z=Z!M-6RYnjT9_28YrPCuyVb$yw$y(_5|8KF(;_GtWn|cnrrWY=DNIZQD9ZLFU#5)_ z7#pX`RoV(fjT?p;rBz*O?p1taU}j(wqiQ2>&cvb%D#g#ja4}ZnmqW}bdXD$?a|SfM z=l)2KT3?x@=7&QeaeT8^k}$a%D5=B6OmTsqSM+w;09c`+Qi06evoCLOFl+I(5P|28 zq?6PA`0@QNHkh|nG_XD?9zIF!!GubD+j1{8tIfqm-gfTL?y?J;;|Iy*vudd7g7ay(q7lBbnQiF6e~HKtF<`!?P&{{ z1CH zrYKYUwF39s`|3MJ?5(8mBAO^~!OcMdsygF82wGa|fkM7tOCpGCtrfWD8`-me`P(%D zld$Gnq_7z>tCB@nI0G8luuV5VCO(7`aawSjDbI;AL?AbB9mBit`Uom+RJ(x%6?mw`Y2(d|H-@1o5ip1_KtK=T=TUD`Y*=SIhz%TbTuj`9_YS1mt7cj&qAG8pG+W z3S`rCUHVayO4z~|S}!>+&MMq~9o;hLXe_rQQlDf6(~Wa};BAvo5pq)eWaFw^(rJDI z&0w+fe00k|h59k`TC@I?YkgK&n}7-|F&wsUULMBR>8+Lsjek%7BGEKK=`4ZSRTI3{ zV7ZZii6?o*2ZXKsj$B}Up@W>MC4M>RCq zs>xHM89ggLeqD<$0sq*UOk#ZCn6pQ$hvs%OJnLaORF^?D_Td3>tZ{Fn8R1So&QEu1cU zJ)g)1LZ4N)Y_(G4>&~Hv^g0;%9?6}kLTbF>`&A8yE13)8G+pPL&THvpAa!C;7fY(l z(JD1W@;Y$^dGZF6ctDQUC5qaOSX??^kh^fd7({>wigj7*J9^^FU&PNJ=Sx42faA^{ KPGt_~ul*Nfd%;Bj literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Effects/speech.rsi/radio1.png b/Resources/Textures/_DV/Effects/speech.rsi/radio1.png new file mode 100644 index 0000000000000000000000000000000000000000..fac7aa105d239c0d746b30e19c1505f3390fdc4f GIT binary patch literal 742 zcmVPx%ph-kQRA_w;AJV{Z4zbfznMKhJ%b5ZKYvn4E zvZDe}Ra@F-&!)P0KfZ#hhU2)0(TVu$Of=)W7Z?YVKsl!D)^+X~@@M0Fz3t@Bw}GmEe3ni-^eWc54L9 z5+BZ0jq*d{5$k3qm&-*|Rj$|Tun<54$YN<#wP~7GN}wW4Nq^LFePje*^XIlr(?qMr zUTBhFRI;L{Uyu2KDeBiU8jR1V_+J6b)0_tk=UEkq%3IWCW27{O<#!0G9*Fuq1<^>+ z9yaz8FmGmxvbjuYq`~%$LX!h9vH5YV`Al#&CXgpEgre$Ep}8xzc)4;^BM)Xga38i0 zLF64)%CcnGQ>K~&vhm$fiPLI=+TxgbtNYk}L4)^*m!TpA3kRIv zl20mki=n7y^i27RQW^dK<}Q%MWhU5GgH-PaFFggnp;0kf=INtCph0Xi@ zitM5yphzZQ^%Nk@o?N3qsUu_Zf8J_e@AElU6`VV|=7$%dNJv(*qcWK(U#TKEhJ5zK YKig(`Ra`9rB>(^b07*qoM6N<$f}|8=pa1{> literal 0 HcmV?d00001 diff --git a/Resources/Textures/_DV/Effects/speech.rsi/whisper0.png b/Resources/Textures/_DV/Effects/speech.rsi/whisper0.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed0cd7ea7e951e8eab902a381af44368b771a06 GIT binary patch literal 738 zcmV<80v-K{P)EX>4Tx04R}tkv&MmKpe$iQ%glE3Kmgu$WWc^qEZ}76^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|E;uQ=NQwVT3N2ziIPS;0dyl(!fY7Kg)$EA^s%9Cf zcudUZRz?3Sd>FVGd000McNliru=>--SEd$_3*?9l}02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{006p4L_t(|+U?rS4T3-r22hsRk(E${Rapd$Xia$GU=~I_ zxVwaX??^~KGL!vDm|>uAY3JGU<9nr4&A;T~({y|0FU|9PsZ@mO`RQBu+ecgr7okc1 z*!v!ExB{%5?zaG+mO+hEAligVum5KG`6-ar9k)q04v@dwkw@`9KT*mlHxKEX>4Tx04R}tkvT{MQ4~ebOq7Ti6bzzbF@;)bqY^A7ia}727$J!k&XNr><1mw8 zlTxq^ShzH9g^jhg7Pf*QxPaITR*E(vBR>fwi19W5aR0lH|LzC*Ft3|#%M_Sa!HGt~ zN<5KN{4cc9Ll+_XRNb`~mS$r#tpiv}8o&uxfuuyP`5+U5g-(T@BQbZ$94jqLV z)-h2le#9UA&elzjk5wmigrW7>^WKNRzYX7I&-*&^yzgW1J;9|__pcwqFN$vwnMFn9SWZ%-}1AMq`6+3!l-umAu6a7jc#R9J;$U>NCu5sTP=BGpj^u%KHW7?^q%UD5jW zv;Wh|5y*yOwH(P2#AIEM!_f;1;ZZz0DR9Hdy@njWdHyG07*qoM6N<$f+Xwf AJ^%m! literal 0 HcmV?d00001