From 9390ed9da9c38fe95d20a0fb2e44ede955bdd107 Mon Sep 17 00:00:00 2001 From: Mateus Rodrigues Date: Tue, 26 May 2026 00:09:28 -0300 Subject: [PATCH] feat(ui/status): nova janela com sub-widgets StatRow/BonusRow + cleanup - 3 novas classes C++ (UUIPlayerStatus_Window/StatRow/BonusRow) substituem UZMMOStatusWindowWidget (removida); StatRow/BonusRow sao reutilizaveis via BindWidgetOptional + delegate OnPlusClicked(StatId). - Window bindea no UZMMOAttributeComponent (PlayerState) e popula header (CharName, Job via UZMMOJobsSubsystem, BaseLevel/JobLevel) + 14 rows (6 primarios em StatRow com botao "+", 8 derivados em BonusRow). - Fix spam-click do "+": bPlusButtonsLocked desabilita botoes ate OnStatAllocReply do server ou proximo snapshot. - WBPs movidos pra /UI/Screens/PlayerStatus/, material pra /UI/Materials/. - 58 widgets renomeados seguindo convencao (Frame_/Layout_/Panel_/Container_/Border_/Text_/Image_/Spacer_/List_). - DA_InGameScreenSet auto-atualizado pelo move. - Remove WBP_StatusWindow inline (legado). Co-Authored-By: Claude Opus 4.7 (1M context) --- Content/ZMMO/UI/HUD/WBP_StatusWindow.uasset | Bin 84723 -> 0 bytes .../ZMMO/UI/InGame/DA_InGameScreenSet.uasset | Bin 1711 -> 1740 bytes .../M_UI_Gradient_TopToBottom.uasset | Bin 0 -> 16494 bytes .../UI_PlayerStatus_BonusRow.uasset | Bin 0 -> 28362 bytes .../UI_PlayerStatus_StatRow.uasset | Bin 0 -> 35157 bytes .../UI_PlayerStatus_Window.uasset | Bin 0 -> 158027 bytes .../Game/UI/InGame/ZMMOStatusWindowWidget.cpp | 169 -------------- .../Game/UI/InGame/ZMMOStatusWindowWidget.h | 106 --------- .../UI/Widgets/UIPlayerStatus_BonusRow.cpp | 69 ++++++ .../Game/UI/Widgets/UIPlayerStatus_BonusRow.h | 46 ++++ .../UI/Widgets/UIPlayerStatus_StatRow.cpp | 73 ++++++ .../Game/UI/Widgets/UIPlayerStatus_StatRow.h | 68 ++++++ .../Game/UI/Widgets/UIPlayerStatus_Window.cpp | 220 ++++++++++++++++++ .../Game/UI/Widgets/UIPlayerStatus_Window.h | 82 +++++++ 14 files changed, 558 insertions(+), 275 deletions(-) delete mode 100644 Content/ZMMO/UI/HUD/WBP_StatusWindow.uasset create mode 100644 Content/ZMMO/UI/Materials/M_UI_Gradient_TopToBottom.uasset create mode 100644 Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_BonusRow.uasset create mode 100644 Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_StatRow.uasset create mode 100644 Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_Window.uasset delete mode 100644 Source/ZMMO/Game/UI/InGame/ZMMOStatusWindowWidget.cpp delete mode 100644 Source/ZMMO/Game/UI/InGame/ZMMOStatusWindowWidget.h create mode 100644 Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.cpp create mode 100644 Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.h create mode 100644 Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.cpp create mode 100644 Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.h create mode 100644 Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.cpp create mode 100644 Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.h diff --git a/Content/ZMMO/UI/HUD/WBP_StatusWindow.uasset b/Content/ZMMO/UI/HUD/WBP_StatusWindow.uasset deleted file mode 100644 index 53f54bcdc8d16080303dbc0649121bcba08b6aa4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84723 zcmeHw349Yp`~Q~vz63$!2=`5|^a6PyM?(vR7APQy)U@4}K-!cfr4+f5LqHJ)ybuLJ zP(Vab^wn2Ic5`!8>yt+fAt_PmLP(NY5wt zJy%R^o!?1c|6FSKZMM3d*1WNBue~p|eG&EkV~ta9?znI6>pM0L`!luywGHZCx=fQF(Ng5Y;t(gSZnxrb6Un2uiabd8Slu?b`{Z}TGE^J*^=0QTp-OVdv@*VbgB4KG^9c*MILyPsKRE1W~o6xGM0CFbWk@?~kskj2TM zSKKnjY4^&wPcqtP-Kg#vJ7Q>Jw!`akOFJefe_5CAG37c&lh%H^?WKGeAzh}+GriJ- z(|+9F5Z6xUct>`w?Da?oy0yBq37Xt)dvTiERUo^)#ZvNPCmc|-$y1Qc?yOtC^}P&| zcN)9y`@F*rnllNMtH?^i_BveoQpuSn-(7`fi_`A$jFzVtI^42nq}}V7A*VaCrb#ci zb4+i=2DtL_ZigLIy#M`|V;SHSIoF<5JW`gk(_LwW?p%4yG}$>?&hbdA zc1{`yk(!-_a)Fyr4J~wJORv{$JGQmDbxg6xE9Z@q-5yA8fwz92OKwUpE|8^0&2Rs# zHYjkpoKpXW+21w>1iC2IRI^%-Er-U>Czb4*wV5d(b%yMAJF?}BB-xQW#VanQ zcg`+*s|_HEmJG54?-X$*ImU0>2iq#`w-x4RG2J#hciVN)jyX*TgT&9Q8T8L<)x8nm zmi3O1y>_eJYfsGgx{IZ^))mZ$>6zVyo+%cWlZ-VZ_2DAMPq9}n<>%zcelI|i7Bco+ z7v1>l+%*TAsT#((++Ih1uGF%5hu7FZr^_Roz4_9|zu#jA1`8Te?3uDtN-$iEhXM&- zVP3u`$?Tdb9o#zWBUrLUF+l0%tDe0dPSlb*(wZ^SMH6rDuTi~Ni!0ybbr;eMEplyG zuiQiCL#DHFMC|7ZTy{MUa8Ez+%dd zw&LK@?A|HTYo_~|{?U<~?}USk|6t$&1}4RkL+&GwoLfHi!kV6~m3;&PNX*Bi%f?b9 zOZ&Tx`~(be|F|#AdJ>kJ2$5YfaLJI5er~7NGhhI5#~@0(w_iM_U?|KhHNH{r-8Td> zNSs0Z7#Ppe$=^HfVlqG*&2QN)=V!^%)=kH^Gva9idmUMJr^!jK2y&1H9r$)J*2YA| z$C9BHIGp7E@|X)ubIaKdWkzlOX>|KO0Sp{4V7$ZWWG<=j&@)fLA;>f3ENS+)f3$@K z*qpM=ba?8UZ~v%64LMGi-7B>$zV8*d6dSHedAzXo(?7wu&Fzr$vz>~fYaV>LA($L0 zlQ$(3AU;LT@k-%KmVF0L zf(ylUNYAWz{wRn_A;Y!175~-J;<16Kl)`Bs>hl^$Mu8~0WJH<%c>PP?6~JiFsn4B z*~uQg(%f(6TmvtuG?tm^+$WzN3>y&6m@V_t=$sbsL9ZiR*@aG-LM669vw2$3c?I*L zBZ`O0t~?p8`_&e^Bp?L#Qcf2BRBsr#!{igL^oFh(KZAO-F)Mg;N3HFmA|_tt-6hzuat3W&qQ?_S+Vr&YkPiEw~-M^T?$$=0|FAj8{>6L=O#2?r5-oV;gyE} z(PNPyhTtp2JeIIl7L9~}uZK~tnxc^~D2)T&uQg6I5(=g9=_P9qiblerG)DZ?@+sEn zhO6dlW5c(*roqC5W!RkdT#xjTtHa~!R+xiF`gc+7BT%?owmYS9M<4EwP;j(d;3NkM zU6m~WuIHDo#QoGc(&csJ6eA3g>fU?oc9_p-gfvpabG@991-s(&)bmM)#;ncdVlfY` zWYV#%@y}xpjixrmB}g9_Be-Jl$w*{k-gIFBd4sT?Gs(DJX4;lkkpfL za^|-5RD6ul=|_+ z|G|LAxN^Lz<#FD|k2W&IY}1wIa&XUnlt z^E+Se9Nh@rTt90%t-F>XWT8wckO*o0A0Uz4vOi&n1B%5(>4=vGc=ut1cZy8m>F&4Y zv*8HhZ*5mN5+Jc6sg|?w+3(~*p_ev~rfnFl=${UHc{bLIbcdJLLTpCfIC|A!(49`< zY`UXBdg9x<&tZ3*?kbSZXWaP&FpMRqmy56{jb^n+YTIQ~G;1b{jy0B2I=Nty6UH)* zt-%=7&SF=upBDLscc;DEIqWINq=H|Pgz zRV+2#Ez8ohUbmb_Jfk#;H5g2!yTBT)Fw*wjv$sJ8G{##N%|F!r+XMv|cJX5zvt;Sk zmu~wGQKHyZmhDm?XX%@dW?Nx!qMP=XQtb6V8DJiw4JQRsc8^V8LnwU1l8iQ;W z6DlF$^;^QO$Ff$sLbe}oz7fJta=9I|T=`zR6FY)q=g;+nU0l-2_-_1I54NHXkHSKj z!9Yu%#S^cFxD>A-$-_^Ffk5oc;Kfp$?hm0De$C*tUO35#F?`vRJVTeYf})fiFF6Ek zUWT{2i7k83KFHcLV@*xwQj}{3=#jYJ*_H>Xl;rk`;z;CJA7{Htv!}p?HxwT9^sgsZ1-JyJYX@IF%!i-lQxC%DvLwC|gp92O< z+j$A!qEZoWy_J{hVu$*I*98=qRvDE3YW-wHi2DK=99fycQDU$l7g8q2TDHjY0iqwq z=d+XfQ1Z+$44h$!41ppspYEpZCmrRn&T<_%*2G=ml#xpB0BGF~jL_}C?8aT4DI+oO zO(ta^4=%fN5SH~&dZZ_ap77qi8`L-SHdyRV+V&YTiw&7B?-Tew z&!EMhp#%=)4o5!2K@loDTw+K)4%+k?a@qFC=`5xJcCWz$l9YS0XdW9J9)nvs^2#<) zH_?J!ZC``K+rwj^h!iXl8n?_4+C7FM+3D<$3)axP_juFjk;x;6av`KoA%OUgLk2qU zG87cLWx@@PvRobt&K+5X!h&pyTOk1oX$>@W2~DxVRYd1$2I{f*H59uF33C3`%?Sg|5j0!u)$85JJvwTb2&exs8FiH*P%z-Me{yJSy(53fO1;b#CIrn+!R<^~L(lvbEY!EAV`!wWC-pZ%vu_w$iU$khL06aP!iyVSHB zsBQYMx97jamK*$KMjU(trUxgAdk?@rUr7#LY&qLpslf!8L*)MG-VrT2yon!0gl@j z;J6n89JfEfaW4fp?qGo9js!RkvjWMV9Y7y1E5j-r_ul}=y%ONKR|6dPdVu401~Bdm z;`g-x#+{&XZ}=H^i1(q`9pE@I2le!!hDWh7OBId7t`(`GagQs*DjbJ32&p1?dz4|i z;|}w_lO(_Ab;b!CLI=>tzjek5nuSh}(>PIA((z`zwx}@@=;!?pzz1v7=Eu7-wfWa#y2g5_=p#X9&3LWpmc4!*-7#78glv81+_4v+E13X00g6aGbSJ`{!!pWb|U zC4~6&=0g{;@PVoZ>seHXY+{lwd>!z zLBJ>0KQ%ra`Rn0pFM^Y5$Wsp=jO4bzWE`-*T@IH!y&@g*ayBQVngpwnABHUc{cHZZ)}M0HT8jSeTeX3 z@1SQdCqjg;xet83#X$@8`%9J8Ukd`J$KUiI;`>9jJ|Ikajxzw?_B5|Q6$E@jCHU41 z2g~-GSd)-|&&z6(G#yL_ko?KBfZwmh*PXYk@qHOWd`2C76U3op1w2-TzcD)aUJW6> z>vZs$gyDpMzco7eo(LhnZ94dRiG!IS^M_?zZ$8`?LVSAjp}9CH3ITt5^I>ra@#)Qn z-$RH`Z$9LS2LK_Er`~)x9zuM2^I@!buo49R&Z*W1Jc`~=S-W338U%bI{?x;Vb33dL z;(V}~SQM$vU-IX#_3(8eV0!$G4>3M1e;Y!C4`(lW{Cyc>d|LkciUW6l%A>x@>aUv* z{yZVZr{(Y8A;O2XK~H~SFHlDSsj~7E__X{by$}F08d6z&J?I`i{#Jz;pO(LOLxiuV z5B}PN=>Sq?8u-NfCX0^o#tI65_@?lC z)%b88qKEH?AmTf#;xCo(!8C-u^h1Txb?+!;MW6oo>&0QI@ud+!J$%dFtq7CS9|*pm zRs2DJIO9cv{(fOKdPn6wUa6q)hwlu(SB($))5G`3`xPMK-GSiyNyQ(|dX7>S`V;&2 z`#-2YJ_`q-#+U8`-^n22JEP(c`r}ia>2DpUso#gZQbFNQp11RRwfO4ucG%0EynY}E z`0nt556>KtfKTu@@gvq$;YU^Y>&Br1-)3I_F$nk`;IOpvL`;YTe0Q^&B(3?FS1Ks{ z@wb-WtHl?|+tu>y_elkac(*@%zU(DN2j77Z;uCWm{0aM<@M-n=^JSm#*+^=6{ul&& zzT^oXgQUi{g-_`3@gU&yrN0|=@FgGTjTIFB z`16IYP=#+bum3Ly_-^5_wDWzo4!-H1^TrAafBgBvH%A9wjT03h;@wrjH&+MW9U;Uw zPX}MuFG9!Pd>wpGgb<(bJDBeeaNM>pd8LBFpZ?bKd$sl{)+x1rIT-|ef)6de4V(_( z+rsO!Px49yg+Kl_@_V)T9_H<8{yKeC0V3Y*51$@?d+0vBcyM0`@#)2bBfhRae|r8C z{OQGmUjzZ4FL`$3tU!Mv9-Q?}_4#{%gHYQG_|uCAJA7Mxd}5wy@#)2b`+|Vampo%Q zE9&_$;=Ahe=L?@+Ja{4q_hq@;pTWQA#e)|@h)*vbT=`?@_|uCA+l#}f3efsnZ+*#A zFCKg}g!txj9$=qh|1kKc3K-+vRpC$gRp5Jo!+9eJ`1ImI*r!;h)aygR&m3_Dg+KlT zAKLX#FCMIOwgN=F+aEr?co6*Q#e>^}fKTxE0}&;tf1E0Kriui43fY=|VNDf&_~TF5 zo)+H(4i)%r;`MiffNwsBrNy_5w*%iwUY~f5S1Ks{@h9M_@j-uj@;n&?e0uT(K0SHf z_-h4>@osH=>){j6 z;{?99LX58_@uKGMs^0@(j)qi~zgil6H-re^62haWzpWw0r`6y0A;zcGU(ET?=ugN~ ztH0SH##dWoF9$-54`&qW`Ox4(Xymz+!0OrOs1W1R+UH#%#;3K<&q9n(YoFc!2(A9K z_L&!Ad|Lb58)AHQHS^&@i1A_Wspp^h&(P>^8G+TCe>aC1pLYJe5n_DW`PcelXyvJ$ zf0ILm?`9wR+Y(}YTK%00F+Q#SqDyyB{`FYd_)N%CtG`(x#;5h4`$LRR>p$zU2;aXf z(OX%0E~k6+{7Y(x@oDXIU5N2%?emimS6Q*0Uo@oB6|Y=0u35$(YGqeS zzqs~ipVK(3(=_N?70w+B2=>#4iH((u*#iYc-l-`>uRnat;6x~$QsKh8kvmx{eoC>H zBpBbHBp~umD$2L`_n%@*pvDJX3Vg5`f$xQ6J?Le)Ma>_70w36f{~Ajfb@-NXybdgj zc^!R-7g1h8`Bq+UNhNFx?X4)s@cNZh#_@V+?sT|Df z?WnZydV4ApdA$RbI3EJuj+B#m-9Y7VUWebB$m{Sa*}RVVF7rC%n#1e$sm$edJjb5G z>#$`9uQ#G{Iucu@Gw;%?=}2-0F{vWDt>(pm5}>te*G^hA@5E6 zdI*&!%J=hYGnLT67JhA|5_;IouWeL97Z364Br2hgjr@8TmC(t9l%cQAl*g;;&<)zV zP+p>{FXi>FR9>&DLw^|Gjq(kuI&_Kl?v(ASI`oS69+ao4>d-OTds5C*)uC^+_oAGy zszcvs?@jq;Red?H_o33Os>3EQzAxn>RUP($_I{LSs_L*6wD+gHP*sQBpgo-OO{zL< z2y+zngK`8fVMn+gMHvbArcxe*3re`gd`Ca(nD3)`9b<4W+S7T7YuF^p^}Jlm%PV+! zFE8)pC2SPq@8RX$yo9Zy9X5(`9WU?VWlLVR;^mdRY|YCyyoB$-{VRD18^`quUc$z4 z4ckWfC@;72vMn!n^73I`nt8c{m)m&>n+F^lFSqgX5njS)p}!q3;j3^BKZO!L3Z;RU z8+eJig7*7(IgHBMl)(phyM^+tlxtFk-D3{JFJSIszQYHsp&UgSb`HHjrqBaq3b{iE z&<}JMO&Rck4>VwoKR~$_Wx(G^c@t&K)y zb{121s_Ii!bORQ0Z^I_5maETud_RnJt_C#mXLs(Oa1 zK3P@2PF25_*OyVbNL62;s`pma8}a(hRQ6ZZd#UP}&!8D&`l{-ERP}zmzMRSeRlQhM z_o(W#RP`CEdZDWBR@GfpS0~W%KMEX#zkqEDT|$S@ozT@ZsyCoKg>q-g<0;pnoJ|=z z%cI_}VskfBM5020=yapUGq zn|Er_qEll39{m$5ol0Jin%4tOHN!efHJXRjY#v5m<|AJbRy&L(!CF|2nzd@zsavmp zgN8KViDpubu$nb%)T&v#cCA`8dJgqVwVKy%(J9hY=ZaDGx}B%Dj9RdIW4$is-TPaO ze)Gq!(V6ar^&4E-y3JK>yLIo;vsZ6pOl(|y!T^gk(Ka+GdDxirvE#;HJ7HoL{eETc z6vtGLw{S+$%;H&#Zd$x#>9U)b-+srMwd?M@>+X9tJ-B(xLtD2!{K(^b_CE3CzNeo4 z_lpN!I(X>tk)toa_4cuM-hJ==4?aBp`H3&SJo(kv-+X)Kr=QRMa_-mPem@Vsz^6zG zXBxhm6JIrI)v8&mF8B(oQAD|B^IEk#Mb>Fy8dcXm{ff>}3+lBruim(OfBi1eqkn9b z>3*}pm0gX;yPW}RjI+QPTUaH|N*OET>qDs#?Qd!{ui2b}sN+*MEth&;&VQQ>-hA@0 z)(tztMrbUO`QB&SLeLBDI@{cD@9`?m8k6+jQ zRHG&XPLxRRjj88-d*+J9J5Md0`|gs_EwdL&N51(v@4Fu+Tz~I`Ha~sydHWZwX=9hS z`ZTKEx!0zK?>YGAXUE=4?Z0Z8qtS@M+_@brkM(t3Eg$(hBKh>eoJppZGrGO??(yNn z?>f1<-sro&dGD&%e?M(|a9mEt2cKX3;oB(}uF3f1&k?CzT@BZ)y{cW|xHg^d9d>Gl zH6wS$h36lB@YI=kMZd)KYkB?B-koN4X}-JRk-GmGv$Ou-cLu-l?wm;}CwH_Ql{n$9 zQHd?30CL#dQ{J4~{b<)cYrCvWs&j4j_YFqQ>hSU0&Rh20`c2_u^6H7^GseTu)cAVN zfG-}M_OCDr?^hvd!wxz)n{Z+vh~ z;gJ&^Hw+xNZ`pqvepK(os?)u#JHKopWww5_iOn`Le#bNS4%|BP!RtHJd-a*^!&<$u z?uD;Y-?-wlT_?YMI`aLaPrv#~cyY|j&z>By9>I)L`f6DI^)g)jiH{J>T|qAuvbH-U||2j=g(v%TYsW2awy_R>f{I?r*$4 z@>%CAMJ?iL?y1}E%=}pwjy*Yk%=_Q<{dINzz?I)OTVh|6zy9oj+^=hoc{^*y_~hdq_uO>I&}jM*bMD6fHM#N3cN1djEF(8HBsTSz z)Uz@7Pi!&ok$D?;oPVp%*c!`wZjWxzbJP4la-8?i&gU*38$PY+U5mc#G3(ZXL8XO||w``hnRr3cTk(LVc8gRTl#Saq)An^b@ekZ{PLT;A2O1*lL?**d0!L zrc=gm(q`iaK(U#Sq!yG*e+th+Kc&TfUmHExn3wj@Pwr*89R>IWX!L119i9UEH7)j& zz32p2rFWuL`EhS_HBoo5Uo+R`?UG^ar+-;XTKa^v#Eg+HcOLyXH8vdVw@8(rv&McR z(wJb3kB*6An-81AY^7gUl%Dyqq=Z6D_OA~8rYmZ({90)Zqs@q@wc)j)(p1Ss82Yc;P+OShB_S1 zINCxfRF!Y38Dw0kB!hgy7Dn4aMS^85Lgr=+` zMDoidIXdY05o4#51~R2tbhxG9yMc~pis&vENx5unnWXi5Yjfyj6je>ziVcMkZP0Hv z(K?kVguV-iqA+e_zWar&%IIjwDJySjVdQdzWD8WhjwM_LBo$ztP9yMW7yo*Zj6g*W z9bSgfrdw$(!&Ehn1suSZ8P{d7)op?b1uJcqR5MHTrO?roxJOT8HJ6^I> zA*V3%oeCX#eGPbDb6%FoR9zGDRcli{E6Z?Hmk&XYu$d&1CZrukM^XwG<$Hub_Rm9S ze!rExiIM(UNFNDwU>(Cg6G;Cyvef}}J%Aq5*r+#NGE+-5jZEORp;RlI@zv#3(5?20 zWm@y!D>UMt=N6o28%eOtbE@&(K#v)sX_ThdIfM-tiLEaub8e22PC_&NXdx90Sh z(GE_g((Edrc^0l(7jB@V@;IrO#tVqm+&%zf5ZW#t0nPXwRfN?wv}Rj!aq1g#H4`fTf1{g{mDe(T7-7z|E$*gEC;|^HRWq z#;``1DdQewj1#m8Jiv=K;GRwybb%jjJMI-QFc!FRjq#!n?YWd^PzDT)K|f&O8sqXP zqYZT8TF3_U;-ByiLW@;hJH?!U??se>ShLIzi}+97+ey_g)@%PZA^f%PXhB37)#XOe zA!4C4lKoVQRFS>P~Og)@g7j5*teH?1{Yn8rJAz0@8rz=upMYd6bQ(qa8cJHi4mFze6hog;q|Zd!nI@1H%~Uh9y^xKrv2%^0F;+SQ z9Y9yngsX2r_=I06qq85sue@Ioo@^xf)lRh9=g=I7FTq&|JZ=AgFp3kSOD$f+dcs>* zHO3P(s!x2>(NIPG5drZaVhn8*lukYmv88fOgjFD1M^2GGCES$v;Cxy{CWQo1?YEcwPz!$_MpmZy>R{<2ouZvAvQ0%Y`ZgvI(kj1FV!OX6?&pry)((DGwU<*>ll6=%dW3uP{i0c-WSiu zCh+S>jt3ZkL%}8Pg4Y#o0!t*#Q_-ei!o321B+YryjW&TJsuV|5DUPU8F5oE?c<>L( zz3>I1O^+L#p@@EgFRBz@bSXZp8Ok_#AHdF`*SwrG-(|)rPR-C7K`%`Ay+mGR(4tB? zDr-|?0L_qEWidpncoaNDlm8RY6#WCP;I(25*O%iXno$q>1P-Bw?m{VW^Uy?jj?ow zmU$Xu>5MG%G%=;KC5G7!u*Q^HNMOD}Sxd@RmN~S#%%MlrO(|<$0OsEt5&os4 zdxQ_A2kPMyM~p}fADbMWG}aofeSx6AwjsmPgPx?(S2gkqoN}I=@0GKY>BF64&ytn5 z0Pw_~dR=bnDt%z@Veg{%?8Tn6CwuTPJvHB1%-;O9*_|Gly*x0|?sd$N)9h}7%O1zG zZ* zmAyz&UYYD`DMF0&=7)cSVedltdjq7p?^@tJj1jKvLgm#G{dZMhU&@%#vXdK(7jKg* zFQEKQHWUI|=|mizowutc9ludptftsKT#mLoAo}y%-4dsg&L5`g*y1#9@CUQpW!qZXFG@#Do0QrNf`!*qz#bS z0CcFMd)$De8{L2L$fC7N&flN3=$%7|~;Ny%XkO<9u;=DchIO7Q<;x?Z+*90Hu00N1i z&L>WE1X-Wg5J*IPK5?!NKF)s;NW^VEac&Ae&LITSZy7;4JNpQd{4H!&Uf7Dzb954v-1CvcRf7IL%95C1`1V&AFf7IB6 z0|r};z^Lirj~c{#K>*VrU@$%XQIi)OFo;J3W2%=wYTyro0H$%kVBl+f`kR}B17>-^ zVEXu@#v2?kO#%kf*B>=S!2#1WU@-msQ8P0*V6fE+%>4TMqh?`nz+kHy7&YPksJSUP zV6fx8gc^i*Na~$tmeRy_nl*SGg$*B>_@Gp7(Wmclm%v9Ow&DP}!(;kBPH#-b}sw#GzyL zzHQxEug%5BqbOk?Btev6*y$swp(`!)3F}!eN}|7^Qbuk9Xj1C^KZz@`AT>hgfQe0HGIN2)XrCC~M?WhK9peDCWmU2P`K`7e0T zw&BUFNTodBQB1POKz}O2k(+NwcjU-|dZXJ+ zJ$U^2ClhynJ-SeY*0}k=Vt1ilTQ#P$upo{xprTUK8T4jP zb8PSY$CkuR!{y1_8aC~(*Y;1I&Y*XLY2kvJ6Q>T}GU3tRn+@LHS+6ZeCBD)q2VqSd72=Q_Q`j<*~BMvX1>#ta(jX2mv zQL%`^(Sy+n45aB zd+_i*%6aN_Fv;~|vQ4LceEkM{8H|Nwu`j_+#Y3OUE=Sq>;M2hHo@W#QH)M`aH-q^V z!$Q)=78WT)7snJ4o$;1!!WG|k4xwfLZvtQ72%`&xtP0p6(Fi4$)m z-Ojd3pMIy1&Q?CC6E8uaMO9Z5%M|h;@AUb=Ae9FAJO>;@odPuj^nYAfY5s(jt`*iU zCNf=h*RVqFNIJG~+|o|zD}Uy4wXcqVXAJhZt2h+(^ko(tgsJH03s#-K3$J0y!4=?QmTy6anZ3+F;T_{ zA}hgcwnjvoBW>{!HnY)~5Mi>i^~W?O&1x`2_$F&TL9IGjI>Itp>0fMAq|s_Lnj&JN zBOxo3IW{3GGR7Jk7p({@eYjt$)>ezEvKXLLSP_wt@o}+nCZpACjgCl+jI}1jnPcM3 zaZwSmmRMsP`#O$I&YEI(8+w|Y-aaNnxFOM#)yuc!AhoJXZjho)`Yff$!v*;pzw*-u+hosBsvOCd`?sBF{)0Oj!F{~q9dZBVq=UE zwm6H$6k|;^*0a#$oSZJtH~H|Gsni-qD>L;u|`vTOk9LDn$&7zR3(ojgZJZD@$OqtsiJupZB2-d zGA3AKVbf%RVic1gZZH7{#iq3C!qOot%4#;nC78)cB_zhi!cRoTSz;67qN7c* z8Sn{e)7T&g0QmHQ`bBc|OOt2XfqoX2i))-^7Eg~)|AvPi^-fS@%qu3E{ zAK#|llHdiGpvVYoL}GljF(Dx#J~}=wAtBKe7jLpAMq8~hF)`+f2x=8?tWK067$`oO>+7c{Q zOH4%swGK8xafw!w#YhVrx$XEUORU8b7a2=t9T}BK%T8>3MFh18HbK$G_(-EI&T6zq zCYWQ$qenzXT1+NmRHP-=7HKq9L=eKxsvEVH?p9LiEHlL!BPiq>ku}v;am%Mnurk9D$|JNWoTYtjQK_ zjWEVq%t{zP4grIoMG#LqsxCSms)Di;!y6w}r%GoH49-sM(Q1*UBdnn8#Bh#Qbz%KA zJF&LaqA`R!v7OZ-Oh=_b*@-aSVhw{CY@wm+= zEz#5&99l}11Z%`(zMt{~lzrl^MV&rzH>FObASr1hf!ahFuUu@Vj4$~n?z+4v`FxLhQW*Lq2X*Y|417<;Rz<|ua=9FKi8U+mIW*X^JHvNMG zrdM#lga-#q-{64h6C5!80tU03M*7rLL2$qn2L}uSh`_AaFH^IE17=2Wz!U}tj5|1B zTv{-Ii-g!;B+Os7L15b_`oqoiv(b_?)+4(uZW({%ntinx*9Othg5RqRyxD_Q^p)$l zM9~Ojk*-$?_Ix;(*HNh7B|SsTu7I>fr)Y4E_n}^&e8cUNPhBkj+2XH`E!> zVd-N^vveWh!M0N$>puLk8&YpPHfq_2&3OB&-J4!oQ0L`g&xA#1E}Zt-G{8c7vU}K$ zwig~AzNui{$EinJ#$v02v`#8HFl$@$#7DnbeESRU-uL+JO0)F9-K(jO6u&)qKjK`Z{RRIUpE>^hkvIMRXXj(55(n2& znx)fUgk3x_da3#0db{_o$XhWHlL2X0hZpbedgfy4qUX*W+`Q+fI9NB*@Y-wcyrcOW zw);-rHo3)9)3$C?nx(PhzpFET>mKui=a0`{aqP{Z*u@}CPQUf5&9598aZC88Tdr+& zGU`U9S;}b8;>4CKPne$h^NGEEhIE)YpSK@)z_cl5PJ(6Qjd7pW`O!a-{@QP$z4fX7OlG@`Fx``M&6#~dZmNwiGAj+v*#tH9e;9m3~#@^&dhta z{+gTo$f?0kj(XeLxrn!SZZ@%fVbfcN?EP=65qGB!+%TKB&--m&*s07@wq@%Fb-nqj z6<;BkL3-uHO*IyJ&zV+#)UD;bLsz#)0EqPY?Ni;+t4$*|41DsivDx6p zYY%E-dFJ4eru~Y#@0rWn--&#yhdhBW1U%+pOL%9aA1l?Yim) z(@00XK(n^?4Ub0+yZN(5k3R9md|RZ_ES2Ov zd*3~OT${T0+Iw#8`s7zJH}LjxZ`D2OS@3A;rl)Q!YT3HmwQ0P)$MqYAY;1cvb?dqr ziyR#{TZZ!XhqfhO@lkdc)7I}6edSMtu$yhOq71g#r+BXew22hD0ItR0OYK7}%pda&Aac2K$* z5C9kHI%v5SUl1ZD2!97Q|mKk9UgY;^(S- zIc*pRqE=v2v_Xr?4?2u-%#!KXGn8~UFHs0fRQ?3QLf*4UHG)Z~om785$X~)c%85`g zu$T{k!jQoAKvq-gxE6^)?#ZvRdC3~7j)7`DbmaYLSBsIk8Z;tiL@Gy`V7tH4e~F#L zEcAaWK`<1da~HE;w2MJLEo&RUyV91WU0JGaS-%F$vPxaUIEQz%tLU;-DJoV^zEE40 z2+t~QRoZy2+E#TYSXR{pQpEC|?(jP0ba|%tvSI!8h9%aqb@wzX& zEB2?OU{`;oyAr$AN?Vn7ds}U*!W+HHtm2!<=fHR?vd1 z=3uEYYv zJ!Jid+Ez;8w9B^jH`$hWo=|Dq(msIrhuRkX9Pee@`kQP^JWHyyZD}7q{X=cbD$l%Z zTYr;n6%t;gO52w9!S6rRwoJK>%eF=O{X60<@vOVjwxxYIUTxb7{+TJoT9?mE{}!tf zZ_ZTOsJ)Lm9{GF3$4|*s-UfcrB4nmu6(bY?;U4$&AfaB zudGRb@MsxE`tcbuzjT0vU|Ri=f9hMuI$ruDaYt!`B{E$!>Q)i$l5Jvl6m-7QX+ zN4|X4KpOr#Vs|#f33sK}L+uwos%=>pg7vxs9!Imckj=SfmpfZ_UtSC$k-zp0t=bC8 z%G;Ip3pUlZtDr50rLQT|+34lyJ(S)Gf13bF{pP;Ga-W^;Z(Ff zLM&q1HA#d`+9;?yBdh$E3&rM8yVny(5!#alaqy)*#}Y@a+LKdpu&+I*7Y~!P&xXVU zOzrbX@z7lR3|zdZp?&W{yd0!`*JnPLgZBNhWxQScN~3t~R{Iw18a`h8&bIhgf%Z!R z+xU3xS5hA1?bNbm#h~g?AQp;BQBdyn zk?K$&mas}uQ0^sz>QEpS*MKO1C(=BMt}Je~ClU*OK)A60={&HkEPk~g5P?WQ_`$p8 zu~ubqt9ci}QNXx04?n7dTLf$Y;l>J}cSK%U0@Q*Rkz^$ZD1VSzSpwA37a?vy1isSp-g45ks$DND^ZOMg<^Al@PZ zQCzBn)?H{=jt@$Lc+}Y@DwQfA4hhjF68327febRt9fL95F<>!epqWY;d*&sSdr+Q6 z8KK@3%J{DOc*=DsXH)J;Igc`I!9f`YbOU7|&Y|3uGB#`=NTv)6w^N4haw#vR40o4F zc@pI;${Ca=Q-%x1p9_OpCQ??5z&HD8G!od5Dr6sn(ri^&7Kjnp# zp;^Qxy(mMD2!3v)98UQr$}K3*r`(rv5#^?ov5rH;Udl}~9E8&RH4Sz}v I@J5XPe_ish_y7O^ diff --git a/Content/ZMMO/UI/InGame/DA_InGameScreenSet.uasset b/Content/ZMMO/UI/InGame/DA_InGameScreenSet.uasset index 1c5275ba6b7451420d8ba149224afe15024b7433..b16070b14fc75d50317c06671eb458db1df0ab29 100644 GIT binary patch delta 330 zcmZ3_dxm#{gqV?agj1LI!=qoO%-8sSsN(K~tSKAB*e2>_F@0g4%*&!~%K!v2EDQ{c zKzbpNW&+ZIKpF%DSrIfy4Tukt7X{L)Kx{hkU%6rykTHV|q7X*@2Ldsm7(Y;8&g5x~ zx=vO=mcDypZmNEiudly;sHc8#a#3n(Ua@{aPGV(hQE*9ONog@qJRX@JAD)?)l3&j7 zhPyLm^E*aaMq^2!IoK7&J2My->X~u@6@)tl#CwFg07a}gCMiyg(V3jWTrJ86lz{<| qZ$W@}@<$fo$?Pl(nZ(#8GqQ?L{>#EX`2DkM+bC?Nq)X{UpFbN~Gi`>qNaQ#_JPj>RA3~W?*1sU|?ur zVPIea(k4I}1im2AAT=O9Nd5#rZ`sqYc$q95)Q5FcEUSW;RXo|%`DU(Rs*hSjmntW2_ux?DgF zAZehocxMJHj!BBbP!VJeKq7;w#BB1as}cB>I)!2(I7jx#IVf5A~47dxa9_$nFbn%>2Z1nAuAd*xMWfB zsxkK_?x-=rsPQElcj9uBmuJ+(B~cR-y)lU~iB}Ufa_e+g4b3)hNZ`-=tncfo?sHC^ ztKbUr@76^n#mTo{L8Ka|ve{cTF^jh<(tRwwUL zj~s?!(fEi+Wy;uyDOp*Xh`jWOEXK-OIL0VMWEJG47o=Jk1IL=I1v=iW<5PI6l`q3% z5URz;5bOnL3BCvg;a;s)C{j|?DXP)2s`!-11XX-;Y(i9Yd{jzoa%9{ng`M~>_{{nM zLf*JH;=#~r{hNAVNUwDP2*Ggy>>};Rg@Eg}C+BGv`8@1dwI<{R7YqlUpp*ydj@*%Y zpRb!Az8WziPZc*Jmo>7Cz=p?-Oc3!1{rK1^*S7I^kl3F5a3XjO`Gq1hCP@U@e{d8u z!W36y$fGh`AAB95)mu2THA2B#*gQ>PDXX`lU(>@M?JdKpOvRjuMRSwpq=O5S(Y`X} zMesv%Ss{2^qt_d40>_)s-N&xn0?U#u7N#=C!kbx(wGyS*U*dWJR1kPQ$5?@KOHEuL zFiS!H<2PwM;0&9L_HFq#%!^zocq4B?pEaC5hW&{O6^tp15vH?-6c#hGm9YkmnVDf@ z(eMMWGvJ)UG)7R^1U%*36RaUGUqAtsN2m597&T`RtU0Vj;7uBv)oin((?gc~4Io$= zM+!z?!V>&P9$_!xSr_?Id?r(gS)fP1PoB}2qFA9Mhv7_C9a~|wSy*IUi*|_`V|}o| zbdz9ZOnO#QP03gpH0YBLu2H>Y6uFGafaCRv@@E$Z66U!!la(uD^Er#v#u$kNqF?`6 zE2qOWf!$g?YhopbUDd_j>QBJ=*#B%rx(O$VnKv?4?9W#QMNXvNn#fy>h8$kt#3{*( z80-a@luT8&vOs5HOoGvd`C8H7PX=+~tQc97A&WP#==Lqw)!l&>AOe~=^YpWjpoP>= zq93td*}N$)Ux`z+oHeK_%obJ<+f9pm9D9R^B2Sp(!d7SS$MXp|kaaD3OjWGxHY4n9B-g-XvfZOjta6|G`BI zMcI{B)-L;UcKAN9P=PbgqTm@Tx>&#RIhcJrB$u}pmxvsy{r}=Bq98!2mgy#lsR0*9 zML_~IkHat4@clugk}YCvMr%G}#9{06!HpQ;qU3FbMpm*##NhC{^^c3-31y{;DdY4x zj0M*`Jcrr16Hxr(o3)U-1go9NS@k7kWZ%!@^QCd7Rk4Y}16E;z1@c&edn z^ojp5K~&rxOR0J3N|b$J{ajHoJ6M{Iz#lfbiniO~0;(9e;t;5zHsWcv2f&>T=YI#r zYTjhcVTxJe&#?!`3XhsTSU5h6zWdmy$L>UWyPcZ^24) zyoJMswP4o^gQ0Y$+BgGJ=v&(5uX7m zOiJ1(IeZbsXeL)&V&zQ5BF|?xu2#XgOkDpVFQ6dzQ3z^)Wie(uuejP-vtSZwT%aH7 ze~yA|r2w%W80?0tOjb)J>eKu7STL*^k&Y=AP*TImO+#8@^70itZ!vHt>{J0)0Rt=t z=%{eiA1016At9MIprW5#fi|P*%}WQiK&7T*n}}!z?7eyRq9cmQ$n(3s&qKLw%|rCy z&Hm_3h-QkG#|JW9?4H{}e(CrUk( zy8xx6!^PMl2EipvG3M>7ZdzXD+vw7IYkNj|sjD%2Ldi0dJiFTOoO3{i3| z&g~rA0e_gp97aDK=VT_YXN=qv;s!!2g?K27{H&EVuo<(P)ZBCd^{o1)4Cb&60+P~m z;z!p&DYjFHsU|vj>){|BY<27?aF`Y^HRVOUeupw(M~L3Z4B6p5P!83UvzBs>oryyW zucuJLmaMMt0aHOeq2Ns>T-``GS9x9bhMbsymwW7%OtzdgiouTNbAwL7jwu&$FUJjl z)i#$cVl6D*THvJ>uMQ^0sK9G;QxGeRxT@filKkM0IpD@7da{vd@|1wKy%zBi_@EV$ zfIf)65DZlcqb!V6hZ7FI6%JLZX;FOq(&wcx%_KS@!#OP5HZOY`tjKL{WQhBF_qEM{ z1x<^mmuaz}78k^R`k)<$D_TEPC zIw1wj)bd5v77;mh{F}ESPPAsmBCz?q5$`dHqbS4r^ktA4S~IJ+VO3GGc~=Dlu~_KS z4al%=_fnBNF8rLn*~U+ z$n@V}PIY)MD+%oXba681mxtGlm}tA&=N}%GLBa8{cJSlo$Ba9rw4E^N60Y4zpZ{>_S(tQ*jM#SdgV{TyF|gzJiNDP)xG%SfMzR2^UYVp#28fECYyk61YOt-G1gj84nLE%pt`9`z6x#=FXgDcZlcPJ33+V`!wF!8ii6^} zz0ZZT$;=+&bZ3Ap&o5rrwqO!YbT^GchnCks+K}Z138^&@zX^YA#}0ZDWlAJBHjNIm_P%aETtl6R8~zS}|`#5R@p0AaQ@ zmP(R(xeWQaBYC|E;hh%pAV&ZN_8pMeqeF4zgmiKl@^eS>_K>k{$%8GPT;AOH&Xae$ zg?*6Q)IJSSJ}u$T%NtL4wIz?*N8@GLs6Q`{#>;Ol?1P#_?W6J*jqW^ozqXJEwT;T7 z{#-ET& !gy;E`8_0ngN#%vW32tY{N9K5E1T`1f^gP&pTfSdswuz_X--)_4vnP)|=!FVF5h zy?S_g_v-2GJIK$scW>Wd|A0P&!a_z29~LrnXn1r|LU`o3$e}|=WsV-FP^G1(jfmIe zWvg{bsc9-;;?m38+qbuGke^?WYUI$7st&iteaP1nbaHbEMy|dtZoV#!hY-H6aPe>v zn`jPLV22NKb#ZfZb$9ddaL3+oc^c!9yRU~|P*ifa2PQDxgJ<-K zp0#L|=a7`G`}^h|zaA1(Xqnx^t6%>C{s9k#4jmRYJT@*qVbtg`3Z+V&nwFlS)#c?+ zoHTig-oO?WmvE(m)mA>UqVkF7s^`pozGmM1#Y<|J{%zUv6|bybvv%G34Rsqgy}fPw zj(2wc_q*>MIC!YxgTqIT9{c3P$y1+xcKXcOFTc9<^*5KV{OjARKmGj6jep;~_3Ll9 z!7i|qHp#LUcKKqvT;1K>+`EHaF0M1da9?+ipr~$s$rHLWGad+zp5@smWznjw`+E$D z$-UmU&~n_XUr6ki5B&tDiIzEM*z7-Kncc7^yUwCsZZ3H8+JX<@G9BhwY})rg4}TRj^IN=&dgGFL`BU_WG0ClsWWzH|HI;Hm=w40WVD0k#=fe zzVXz+(B<6a<)!{_WdHT*?xhSqmc-Yj=KF0vobOjt{o?D|hDdEg>B7kiB@tMmcfwSG z>-v@)t<7IM<%Lq!X0>ro*nwBV4s7u`B0)B(jmt&trv%lU^4}P+CN@&BF^n7TU$VY5 zCO2RqR%mMMiR{=DIsa5os5`qhZlEqkSsK7?2;km0vuX6@A1B0Rd~r3juBh%p>_JWJ z!O1ZtvqcZpRNr^deFxo-piMQwJw4JQcUjJP4+9KtlcY}k6~)3m zG(&(2(gVy!&Y_d518;4_24W%j!=s|5PdSiFvV=iSYx&gicdooV=~(9MEoXc#Y;$Gv z34>OhI58M1=Nw3=KoK}-gNJC8zS$#bNx5L<(=EIWA%O(e(h@O}pyWcMu}O(&FJW8% zP9`9yBMFiT8Wkj6we?$-IE8?nW=`2SVh$D|RFycB5X+ed5?D*CJD6-R5A;9?zLSF{ z7t~3~R+adm#JlsEfArypx#<)Sg5}zc zhj9QH11Gr2_l)9J7QzVc&sjuY#Mzf&jG*G|sY3MuR$`;Co8-zw5nM}ULNMGDya25g zCkZV6W{~q%s$9db^hJ{}K`Z1w{F*0|jFhY6a1%c3=KKxwX9$W}rQdtcQJI!22?P1; ziCzF>n(5qO%i*>MS~D&Z$o^{}XY%blfPC6@NhJR2pmSYvj^ zFFNlMs=fT13ekDkg2Z+$2y|pYARgM`N!8BF>-puOM>OlQ&pos4?0aRMV?k287VL2p zmasy1*n&4+{a5C$eXEskj?xW?_}Kc1^A^xmRGtA26Oyioj>3{I15Pug0~|4J*PYk! zZFc8|v}Nitt|TyK{EJE4cMsfZ_@WElNf)y}Wclm3gmtdv?6JeWj}#3~UG>Rt92*Mu4hNqmjoKB(B(N3QUIkJ2tHV~TA zOnXZ74ws8|Q|LM#+_~;NeKPmV@qfB1_Kq-}d#-x(Qs>Jti=cc$ll#r#iXNM%tGF9>C#7C}FMf@3%&>NSLvvSa4 zpAAXd$2jk!4p(h=@Cj~?LXH+;x$7J*1@xA}5z}_v`KY5s@DJ_He(e6_@6U&orLK5$ z@0j0|*Y7#+&UTdy#osV?ZeE1OP5*0Tl{tIG-Uvm(jrd*8D@pT0K0PVYtTx-j1IPy- zo@H02CtlEaC!QSf%{X{QGYv4fwaT5RBzVVjXYS#<6P8EpP;I@Gajljau5Z_mRgU&- z^?3d6aPGV(m_0uJCOLiA*xrV21AiIfv>*55e-2o7b6wTQv4@UB8Vw@G)2{sds0r@J L_J+|y0`&g@!emq7 literal 0 HcmV?d00001 diff --git a/Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_BonusRow.uasset b/Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_BonusRow.uasset new file mode 100644 index 0000000000000000000000000000000000000000..1b74989194ab1cc6a542ed5bf9cac8c45d783dd1 GIT binary patch literal 28362 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 literal 0 HcmV?d00001 diff --git a/Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_StatRow.uasset b/Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_StatRow.uasset new file mode 100644 index 0000000000000000000000000000000000000000..34fbf4b4f754618f55b3f718a70d979ac54f2105 GIT binary patch literal 35157 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 literal 0 HcmV?d00001 diff --git a/Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_Window.uasset b/Content/ZMMO/UI/Screens/PlayerStatus/UI_PlayerStatus_Window.uasset new file mode 100644 index 0000000000000000000000000000000000000000..249068670ff3bb678549a0172014889630f73e8c GIT binary patch literal 158027 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 UZMMOStatusWindowWidget::GetDesiredInputConfig() const -{ - // Modo Menu: cursor visivel, input flui pra UI (clicks nos botões), - // movimento bloqueado. Padrao pra menus modais. - return FUIInputConfig(ECommonInputMode::Menu, EMouseCaptureMode::NoCapture); -} - -void UZMMOStatusWindowWidget::NativeOnActivated() -{ - Super::NativeOnActivated(); - BindToLocalPlayer(); - - if (PlusBtn_Str) PlusBtn_Str->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnPlusStr); - if (PlusBtn_Agi) PlusBtn_Agi->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnPlusAgi); - if (PlusBtn_Vit) PlusBtn_Vit->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnPlusVit); - if (PlusBtn_Int) PlusBtn_Int->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnPlusInt); - if (PlusBtn_Dex) PlusBtn_Dex->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnPlusDex); - if (PlusBtn_Luk) PlusBtn_Luk->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnPlusLuk); - if (CloseBtn) CloseBtn->OnClicked.AddDynamic(this, &UZMMOStatusWindowWidget::OnCloseClicked); - - UE_LOG(LogZMMO, Log, TEXT("ZMMOStatusWindow activated")); -} - -void UZMMOStatusWindowWidget::NativeOnDeactivated() -{ - UnbindFromComponent(); - - if (PlusBtn_Str) PlusBtn_Str->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnPlusStr); - if (PlusBtn_Agi) PlusBtn_Agi->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnPlusAgi); - if (PlusBtn_Vit) PlusBtn_Vit->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnPlusVit); - if (PlusBtn_Int) PlusBtn_Int->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnPlusInt); - if (PlusBtn_Dex) PlusBtn_Dex->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnPlusDex); - if (PlusBtn_Luk) PlusBtn_Luk->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnPlusLuk); - if (CloseBtn) CloseBtn->OnClicked.RemoveDynamic(this, &UZMMOStatusWindowWidget::OnCloseClicked); - - Super::NativeOnDeactivated(); -} - -void UZMMOStatusWindowWidget::BindToLocalPlayer() -{ - UWorld* World = GetWorld(); - if (!World) { return; } - APlayerController* PC = World->GetFirstPlayerController(); - if (!PC || !PC->PlayerState) { return; } - UZMMOAttributeComponent* Comp = PC->PlayerState->FindComponentByClass(); - if (!Comp || Comp == BoundComponent.Get()) { return; } - - UnbindFromComponent(); - BoundComponent = Comp; - Comp->OnAttributesChanged.AddDynamic(this, &UZMMOStatusWindowWidget::HandleAttributesChanged); - Comp->OnStatAllocReply.AddDynamic(this, &UZMMOStatusWindowWidget::HandleStatAllocReply); - RefreshFromSnapshot(Comp->GetSnapshot()); -} - -void UZMMOStatusWindowWidget::UnbindFromComponent() -{ - if (UZMMOAttributeComponent* Old = BoundComponent.Get()) - { - Old->OnAttributesChanged.RemoveDynamic(this, &UZMMOStatusWindowWidget::HandleAttributesChanged); - Old->OnStatAllocReply.RemoveDynamic(this, &UZMMOStatusWindowWidget::HandleStatAllocReply); - } - BoundComponent.Reset(); -} - -void UZMMOStatusWindowWidget::HandleAttributesChanged(const FZMMOAttributesSnapshot& Snapshot) -{ - RefreshFromSnapshot(Snapshot); -} - -void UZMMOStatusWindowWidget::HandleStatAllocReply(bool bAccepted, int32 Reason) -{ - UE_LOG(LogZMMO, Log, TEXT("StatusWindow: alloc reply accepted=%d reason=%d"), - bAccepted ? 1 : 0, Reason); - // Snapshot subsequente vai disparar HandleAttributesChanged e atualizar UI. - // Aqui poderia popup de erro visual quando bAccepted=false (TODO polish). -} - -void UZMMOStatusWindowWidget::RefreshFromSnapshot(const FZMMOAttributesSnapshot& S) -{ - if (StrText) StrText->SetText(FText::FromString(FString::Printf(TEXT("STR %d"), S.Str))); - if (AgiText) AgiText->SetText(FText::FromString(FString::Printf(TEXT("AGI %d"), S.Agi))); - if (VitText) VitText->SetText(FText::FromString(FString::Printf(TEXT("VIT %d"), S.Vit))); - if (IntText) IntText->SetText(FText::FromString(FString::Printf(TEXT("INT %d"), S.Int))); - if (DexText) DexText->SetText(FText::FromString(FString::Printf(TEXT("DEX %d"), S.Dex))); - if (LukText) LukText->SetText(FText::FromString(FString::Printf(TEXT("LUK %d"), S.Luk))); - if (StatusPointText) - { - StatusPointText->SetText(FText::FromString( - FString::Printf(TEXT("Status Points: %d"), S.StatusPoint))); - } - - // Derivados — formato RO "STAT base + equip" (ex.: "ATK 51 + 0"). - // Servidor manda os dois separados; cliente NUNCA recalcula. - if (AtkText) AtkText->SetText(FText::FromString(FString::Printf(TEXT("ATK %d + %d"), S.AtkBase, S.AtkEquipBonus))); - // MATK pre-renewal: range "min ~ max + equip" (rathena status_base_matk_min/max). - if (MatkText) MatkText->SetText(FText::FromString(FString::Printf(TEXT("MATK %d ~ %d + %d"), S.MatkBaseMin, S.MatkBaseMax, S.MatkEquipBonus))); - if (DefText) DefText->SetText(FText::FromString(FString::Printf(TEXT("DEF %d + %d"), S.DefBase, S.DefEquipBonus))); - if (MdefText) MdefText->SetText(FText::FromString(FString::Printf(TEXT("MDEF %d + %d"), S.MdefBase, S.MdefEquipBonus))); - if (HitText) HitText->SetText(FText::FromString(FString::Printf(TEXT("HIT %d + %d"), S.HitBase, S.HitEquipBonus))); - if (FleeText) FleeText->SetText(FText::FromString(FString::Printf(TEXT("FLEE %d + %d"), S.FleeBase, S.FleeEquipBonus))); - if (CritText) - { - // CRIT vem ×10 em ambas as camadas — soma X10 antes de converter pra - // decimal (10 = 1.0). Display: "CRIT base + equip" com 1 casa cada. - const int32 BaseInt = S.CritBaseX10 / 10; - const int32 BaseFrac = S.CritBaseX10 % 10; - const int32 EquipInt = S.CritEquipBonusX10 / 10; - const int32 EquipFrac = S.CritEquipBonusX10 % 10; - CritText->SetText(FText::FromString(FString::Printf( - TEXT("CRIT %d.%d + %d.%d"), BaseInt, BaseFrac, EquipInt, EquipFrac))); - } - // ASPD nao splita (calculo nao-linear server-side via aspd_base × stats). - if (AspdText) AspdText->SetText(FText::FromString(FString::Printf(TEXT("ASPD %d"), S.Aspd))); - // Habilita botões `+` somente se ha status_point disponível. - const bool bCanAlloc = S.StatusPoint > 0; - if (PlusBtn_Str) PlusBtn_Str->SetIsEnabled(bCanAlloc); - if (PlusBtn_Agi) PlusBtn_Agi->SetIsEnabled(bCanAlloc); - if (PlusBtn_Vit) PlusBtn_Vit->SetIsEnabled(bCanAlloc); - if (PlusBtn_Int) PlusBtn_Int->SetIsEnabled(bCanAlloc); - if (PlusBtn_Dex) PlusBtn_Dex->SetIsEnabled(bCanAlloc); - if (PlusBtn_Luk) PlusBtn_Luk->SetIsEnabled(bCanAlloc); -} - -void UZMMOStatusWindowWidget::RequestAlloc(int32 StatId) -{ - if (UZMMOAttributeComponent* Comp = BoundComponent.Get()) - { - Comp->RequestStatAlloc(StatId, /*Amount*/ 1); - } -} - -void UZMMOStatusWindowWidget::OnPlusStr() { RequestAlloc(0); } -void UZMMOStatusWindowWidget::OnPlusAgi() { RequestAlloc(1); } -void UZMMOStatusWindowWidget::OnPlusVit() { RequestAlloc(2); } -void UZMMOStatusWindowWidget::OnPlusInt() { RequestAlloc(3); } -void UZMMOStatusWindowWidget::OnPlusDex() { RequestAlloc(4); } -void UZMMOStatusWindowWidget::OnPlusLuk() { RequestAlloc(5); } - -void UZMMOStatusWindowWidget::OnCloseClicked() -{ - if (UGameInstance* GI = GetGameInstance()) - { - if (UUIInGameFlowSubsystem* Flow = GI->GetSubsystem()) - { - Flow->SetState(EZMMOInGameUIState::Playing); - } - } -} diff --git a/Source/ZMMO/Game/UI/InGame/ZMMOStatusWindowWidget.h b/Source/ZMMO/Game/UI/InGame/ZMMOStatusWindowWidget.h deleted file mode 100644 index af8bcef..0000000 --- a/Source/ZMMO/Game/UI/InGame/ZMMOStatusWindowWidget.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once - -#include "CommonActivatableWidget.h" -#include "CoreMinimal.h" -#include "ZMMOAttributeTypes.h" -#include "ZMMOStatusWindowWidget.generated.h" - -class UButton; -class UTextBlock; -class UCommonButtonBase; -class UZMMOAttributeComponent; - -/** - * Tela "Status" — atributos do jogador + alocacao via botões `+`. - * - * Modo Menu: cursor visível, movimento bloqueado, Esc fecha. Push em - * UI.Layer.GameMenu pelo `UUIInGameFlowSubsystem::ToggleScreen(StatusWindow)`. - * HUD continua visível em UI.Layer.Game por baixo. - * - * Composicao do WBP_StatusWindow (BindWidgetOptional pra permitir variantes): - * - Labels de stats primarios: StrText / AgiText / VitText / IntText / DexText / LukText - * - Botões +: PlusBtn_Str / PlusBtn_Agi / PlusBtn_Vit / PlusBtn_Int / PlusBtn_Dex / PlusBtn_Luk - * - Derivados (server-authoritative): AtkText / MatkText / DefText / MdefText / - * HitText / FleeText / CritText / AspdText - * - StatusPointText (pontos disponíveis pra alocar) - * - CloseBtn (fecha — fallback do Esc/back handler) - * - * Workflow: - * 1. NativeOnActivated: busca AttributeComponent (PlayerState do player local) - * 2. Subscreve OnAttributesChanged + OnStatAllocReply - * 3. Refresh inicial via snapshot atual - * 4. Clique no `+X` chama `Comp->RequestStatAlloc(X, 1)` → server valida - * 5. Server responde com S_ATTRIBUTE_STAT_ALLOC_OK + (se ok) snapshot novo - * 6. UI atualiza via delegate - */ -UCLASS(Abstract, Blueprintable, BlueprintType) -class ZMMO_API UZMMOStatusWindowWidget : public UCommonActivatableWidget -{ - GENERATED_BODY() - -public: - UZMMOStatusWindowWidget(const FObjectInitializer& ObjectInitializer); - -protected: - virtual void NativeOnActivated() override; - virtual void NativeOnDeactivated() override; - - /// Modo Menu: cursor visível + bloqueia input de gameplay (movimento). - virtual TOptional GetDesiredInputConfig() const override; - - /// Texto dos stats (label + valor). BindWidgetOptional pra permitir - /// WBPs custom (ex.: sem display de SP em variantes). - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* StrText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* AgiText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* VitText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* IntText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* DexText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* LukText = nullptr; - - /// Pontos restantes pra alocar + label "Status Points: N". - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* StatusPointText = nullptr; - - /// Derivados (sempre calculados pelo servidor — cliente NUNCA recalcula). - /// Mostra `base + bonus` quando aplicavel (camadas equip/buff vem do server - /// pre-somadas no snapshot). BindWidgetOptional pra suportar HUDs minimalistas. - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* AtkText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* MatkText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* DefText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* MdefText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* HitText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* FleeText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* CritText = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* AspdText = nullptr; - - /// Botoes + por stat. - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Str = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Agi = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Vit = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Int = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Dex = nullptr; - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Luk = nullptr; - - /// Botao Close (fallback do Esc/back). - UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* CloseBtn = nullptr; - -private: - void BindToLocalPlayer(); - void UnbindFromComponent(); - void RefreshFromSnapshot(const FZMMOAttributesSnapshot& Snap); - - UFUNCTION() void HandleAttributesChanged(const FZMMOAttributesSnapshot& Snapshot); - UFUNCTION() void HandleStatAllocReply(bool bAccepted, int32 Reason); - - UFUNCTION() void OnPlusStr(); - UFUNCTION() void OnPlusAgi(); - UFUNCTION() void OnPlusVit(); - UFUNCTION() void OnPlusInt(); - UFUNCTION() void OnPlusDex(); - UFUNCTION() void OnPlusLuk(); - UFUNCTION() void OnCloseClicked(); - - void RequestAlloc(int32 StatId); - - UPROPERTY(Transient) - TWeakObjectPtr BoundComponent; -}; diff --git a/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.cpp b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.cpp new file mode 100644 index 0000000..411b4c8 --- /dev/null +++ b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.cpp @@ -0,0 +1,69 @@ +#include "UIPlayerStatus_BonusRow.h" + +#include "Components/TextBlock.h" +#include "Internationalization/Text.h" + +void UUIPlayerStatus_BonusRow::SetStatName(FText DisplayName) +{ + if (Text_StatName) Text_StatName->SetText(DisplayName); +} + +void UUIPlayerStatus_BonusRow::SetValues(int32 Base, int32 Bonus) +{ + if (Text_BasePart) Text_BasePart->SetText(FText::AsNumber(Base)); + + const bool bShowBonus = (Bonus != 0); + SetBonusVisibility(bShowBonus); + if (bShowBonus) + { + if (Text_SplitOp) Text_SplitOp->SetText(FText::FromString(Bonus > 0 ? TEXT("+") : TEXT("-"))); + if (Text_BonusPart) Text_BonusPart->SetText(FText::AsNumber(FMath::Abs(Bonus))); + } +} + +void UUIPlayerStatus_BonusRow::SetRangeValues(int32 MinBase, int32 MaxBase, int32 Bonus) +{ + if (Text_BasePart) + { + Text_BasePart->SetText(FText::FromString(FString::Printf(TEXT("%d~%d"), MinBase, MaxBase))); + } + + const bool bShowBonus = (Bonus != 0); + SetBonusVisibility(bShowBonus); + if (bShowBonus) + { + if (Text_SplitOp) Text_SplitOp->SetText(FText::FromString(Bonus > 0 ? TEXT("+") : TEXT("-"))); + if (Text_BonusPart) Text_BonusPart->SetText(FText::AsNumber(FMath::Abs(Bonus))); + } +} + +void UUIPlayerStatus_BonusRow::SetValuesX10(int32 BaseX10, int32 BonusX10) +{ + auto FormatX10 = [](int32 ValX10) -> FString + { + const int32 Sign = ValX10 < 0 ? -1 : 1; + const int32 Abs = FMath::Abs(ValX10); + return FString::Printf(TEXT("%d.%d"), Sign * (Abs / 10), Abs % 10); + }; + + if (Text_BasePart) Text_BasePart->SetText(FText::FromString(FormatX10(BaseX10))); + + const bool bShowBonus = (BonusX10 != 0); + SetBonusVisibility(bShowBonus); + if (bShowBonus) + { + if (Text_SplitOp) Text_SplitOp->SetText(FText::FromString(BonusX10 > 0 ? TEXT("+") : TEXT("-"))); + if (Text_BonusPart) + { + const int32 Abs = FMath::Abs(BonusX10); + Text_BonusPart->SetText(FText::FromString(FString::Printf(TEXT("%d.%d"), Abs / 10, Abs % 10))); + } + } +} + +void UUIPlayerStatus_BonusRow::SetBonusVisibility(bool bShow) +{ + const ESlateVisibility Vis = bShow ? ESlateVisibility::Visible : ESlateVisibility::Collapsed; + if (Text_SplitOp) Text_SplitOp->SetVisibility(Vis); + if (Text_BonusPart) Text_BonusPart->SetVisibility(Vis); +} diff --git a/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.h b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.h new file mode 100644 index 0000000..95a0c77 --- /dev/null +++ b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_BonusRow.h @@ -0,0 +1,46 @@ +#pragma once + +#include "CoreMinimal.h" +#include "CommonUserWidget.h" +#include "UIPlayerStatus_BonusRow.generated.h" + +class UTextBlock; + +/** + * Linha de um stat derivado (ATK/DEF/HIT/etc.) na janela de Status. + * Layout: nome + valor base + (separador + bônus). Sem botão. + * + * Três modos de valor: + * - SetValues(base, bonus) "10 + 2" + * - SetRangeValues(min, max, bonus) "10~15 + 2" (MATK pre-renewal) + * - SetValuesX10(baseX10, bonusX10) "1.5 + 0.0" (CRIT armazenado ×10) + * + * Pareada com o WBP UI_PlayerStatus_BonusRow. + */ +UCLASS(Abstract, Blueprintable) +class ZMMO_API UUIPlayerStatus_BonusRow : public UCommonUserWidget +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetStatName(FText DisplayName); + + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetValues(int32 Base, int32 Bonus); + + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetRangeValues(int32 MinBase, int32 MaxBase, int32 Bonus); + + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetValuesX10(int32 BaseX10, int32 BonusX10); + +protected: + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_StatName; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_BasePart; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_SplitOp; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_BonusPart; + +private: + void SetBonusVisibility(bool bShow); +}; diff --git a/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.cpp b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.cpp new file mode 100644 index 0000000..7accb9f --- /dev/null +++ b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.cpp @@ -0,0 +1,73 @@ +#include "UIPlayerStatus_StatRow.h" + +#include "Components/Button.h" +#include "Components/HorizontalBox.h" +#include "Components/TextBlock.h" +#include "Internationalization/Text.h" + +void UUIPlayerStatus_StatRow::SetupStat(int32 InStatId, FText IconLetter, FText DisplayName) +{ + StatId = InStatId; + if (Border_StatIconWrap_Label) Border_StatIconWrap_Label->SetText(IconLetter); + if (Text_StatName) Text_StatName->SetText(DisplayName); +} + +void UUIPlayerStatus_StatRow::SetValues(int32 Base, int32 Bonus) +{ + if (Text_StatBase) Text_StatBase->SetText(FText::AsNumber(Base)); + + const bool bShowBonus = (Bonus != 0); + const ESlateVisibility BonusVis = bShowBonus ? ESlateVisibility::Visible : ESlateVisibility::Collapsed; + + if (Layout_BonusGroup) + { + Layout_BonusGroup->SetVisibility(BonusVis); + } + else + { + if (Text_Sign) Text_Sign->SetVisibility(BonusVis); + if (Text_StatBonus) Text_StatBonus->SetVisibility(BonusVis); + } + + if (bShowBonus) + { + if (Text_Sign) Text_Sign->SetText(FText::FromString(Bonus > 0 ? TEXT("+") : TEXT("-"))); + if (Text_StatBonus) Text_StatBonus->SetText(FText::AsNumber(FMath::Abs(Bonus))); + } +} + +void UUIPlayerStatus_StatRow::SetPlusVisible(bool bVisible) +{ + if (Button_PlusBtn) + { + Button_PlusBtn->SetVisibility(bVisible ? ESlateVisibility::Visible : ESlateVisibility::Collapsed); + } +} + +void UUIPlayerStatus_StatRow::SetPlusEnabled(bool bEnabled) +{ + if (Button_PlusBtn) Button_PlusBtn->SetIsEnabled(bEnabled); +} + +void UUIPlayerStatus_StatRow::NativeOnInitialized() +{ + Super::NativeOnInitialized(); + if (Button_PlusBtn) + { + Button_PlusBtn->OnClicked.AddDynamic(this, &UUIPlayerStatus_StatRow::HandlePlusClicked); + } +} + +void UUIPlayerStatus_StatRow::NativeDestruct() +{ + if (Button_PlusBtn) + { + Button_PlusBtn->OnClicked.RemoveDynamic(this, &UUIPlayerStatus_StatRow::HandlePlusClicked); + } + Super::NativeDestruct(); +} + +void UUIPlayerStatus_StatRow::HandlePlusClicked() +{ + OnPlusClicked.Broadcast(StatId); +} diff --git a/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.h b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.h new file mode 100644 index 0000000..ae9ce20 --- /dev/null +++ b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_StatRow.h @@ -0,0 +1,68 @@ +#pragma once + +#include "CoreMinimal.h" +#include "CommonUserWidget.h" +#include "UIPlayerStatus_StatRow.generated.h" + +class UButton; +class UHorizontalBox; +class UTextBlock; + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FZMMOOnStatRowPlusClicked, int32, StatId); + +/** + * Linha de um stat primário (STR/AGI/VIT/INT/DEX/LUK) na janela de Status. + * Layout: ícone + nome + valor base + (sinal + bônus) + botão "+". + * + * Sem lógica de domínio — a janela (UUIPlayerStatus_Window) injeta o + * StatId e os valores via Setup/SetValues; o clique no "+" é re-emitido + * como OnPlusClicked(StatId). + * + * Pareada com o WBP UI_PlayerStatus_StatRow. + */ +UCLASS(Abstract, Blueprintable) +class ZMMO_API UUIPlayerStatus_StatRow : public UCommonUserWidget +{ + GENERATED_BODY() + +public: + /** Setup único chamado pela window quando inicializa a linha. */ + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetupStat(int32 InStatId, FText IconLetter, FText DisplayName); + + /** Atualiza valores. Bonus=0 esconde a parte "+N". */ + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetValues(int32 Base, int32 Bonus); + + /** Mostra/esconde o botão "+". */ + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetPlusVisible(bool bVisible); + + /** Habilita/desabilita o botão "+" (independente da visibilidade). */ + UFUNCTION(BlueprintCallable, Category = "Zeus|Status") + void SetPlusEnabled(bool bEnabled); + + /** Disparado quando o usuário clica em "+". */ + UPROPERTY(BlueprintAssignable, Category = "Zeus|Status") + FZMMOOnStatRowPlusClicked OnPlusClicked; + +protected: + virtual void NativeOnInitialized() override; + virtual void NativeDestruct() override; + + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Border_StatIconWrap_Label; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_StatName; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_StatBase; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_Sign; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Text_StatBonus; + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Button_PlusBtn; + + /** HBox que envolve sinal+bonus; ocultado quando bonus = 0. Bind opcional — + * se o WBP não expuser, cai pra ocultar Text_Sign/Text_StatBonus individualmente. */ + UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr Layout_BonusGroup; + +private: + UFUNCTION() void HandlePlusClicked(); + + int32 StatId = 0; +}; diff --git a/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.cpp b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.cpp new file mode 100644 index 0000000..2a8c682 --- /dev/null +++ b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.cpp @@ -0,0 +1,220 @@ +#include "UIPlayerStatus_Window.h" + +#include "CommonInputTypeEnum.h" +#include "Components/Button.h" +#include "Components/TextBlock.h" +#include "Engine/World.h" +#include "GameFramework/PlayerController.h" +#include "GameFramework/PlayerState.h" +#include "Internationalization/Text.h" +#include "ZMMO.h" +#include "ZMMOAttributeComponent.h" +#include "ZMMOJobDataAsset.h" +#include "ZMMOJobsSubsystem.h" +#include "UI/InGame/UIInGameFlowSubsystem.h" +#include "UI/InGameTypes.h" +#include "UI/Widgets/UIPlayerStatus_BonusRow.h" +#include "UI/Widgets/UIPlayerStatus_StatRow.h" + +UUIPlayerStatus_Window::UUIPlayerStatus_Window(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ + bIsBackHandler = true; + bAutoActivate = true; +} + +TOptional UUIPlayerStatus_Window::GetDesiredInputConfig() const +{ + return FUIInputConfig(ECommonInputMode::Menu, EMouseCaptureMode::NoCapture); +} + +void UUIPlayerStatus_Window::NativeOnActivated() +{ + Super::NativeOnActivated(); + + BindRow(Row_Str, 0, TEXT("S"), TEXT("STR")); + BindRow(Row_Agi, 1, TEXT("A"), TEXT("AGI")); + BindRow(Row_Vit, 2, TEXT("V"), TEXT("VIT")); + BindRow(Row_Int, 3, TEXT("I"), TEXT("INT")); + BindRow(Row_Dex, 4, TEXT("D"), TEXT("DEX")); + BindRow(Row_Luk, 5, TEXT("L"), TEXT("LUK")); + + if (Row_Atk) Row_Atk->SetStatName(FText::FromString(TEXT("ATK"))); + if (Row_Matk) Row_Matk->SetStatName(FText::FromString(TEXT("MATK"))); + if (Row_Def) Row_Def->SetStatName(FText::FromString(TEXT("DEF"))); + if (Row_Mdef) Row_Mdef->SetStatName(FText::FromString(TEXT("MDEF"))); + if (Row_Hit) Row_Hit->SetStatName(FText::FromString(TEXT("HIT"))); + if (Row_Flee) Row_Flee->SetStatName(FText::FromString(TEXT("FLEE"))); + if (Row_Crit) Row_Crit->SetStatName(FText::FromString(TEXT("CRIT"))); + if (Row_Aspd) Row_Aspd->SetStatName(FText::FromString(TEXT("ASPD"))); + + if (TitleText) TitleText->SetText(FText::FromString(TEXT("Status"))); + + if (CloseBtn) CloseBtn->OnClicked.AddDynamic(this, &UUIPlayerStatus_Window::OnCloseClicked); + + BindToLocalPlayer(); + + UE_LOG(LogZMMO, Log, TEXT("UIPlayerStatus_Window activated")); +} + +void UUIPlayerStatus_Window::NativeOnDeactivated() +{ + UnbindFromComponent(); + + auto UnbindRow = [this](UUIPlayerStatus_StatRow* Row) + { + if (Row) Row->OnPlusClicked.RemoveDynamic(this, &UUIPlayerStatus_Window::HandleRowPlusClicked); + }; + UnbindRow(Row_Str); UnbindRow(Row_Agi); UnbindRow(Row_Vit); + UnbindRow(Row_Int); UnbindRow(Row_Dex); UnbindRow(Row_Luk); + + if (CloseBtn) CloseBtn->OnClicked.RemoveDynamic(this, &UUIPlayerStatus_Window::OnCloseClicked); + + Super::NativeOnDeactivated(); +} + +void UUIPlayerStatus_Window::BindRow(UUIPlayerStatus_StatRow* Row, int32 StatId, const TCHAR* IconLetter, const TCHAR* DisplayName) +{ + if (!Row) return; + Row->SetupStat(StatId, FText::FromString(IconLetter), FText::FromString(DisplayName)); + Row->OnPlusClicked.AddDynamic(this, &UUIPlayerStatus_Window::HandleRowPlusClicked); +} + +void UUIPlayerStatus_Window::BindToLocalPlayer() +{ + UWorld* World = GetWorld(); + if (!World) return; + APlayerController* PC = World->GetFirstPlayerController(); + if (!PC || !PC->PlayerState) return; + + // CharName vem do PlayerState (estável por sessão) — popula uma vez. + if (Text_CharName) + { + Text_CharName->SetText(FText::FromString(PC->PlayerState->GetPlayerName())); + } + + UZMMOAttributeComponent* Comp = PC->PlayerState->FindComponentByClass(); + if (!Comp || Comp == BoundComponent.Get()) return; + + UnbindFromComponent(); + BoundComponent = Comp; + Comp->OnAttributesChanged.AddDynamic(this, &UUIPlayerStatus_Window::HandleAttributesChanged); + Comp->OnStatAllocReply.AddDynamic(this, &UUIPlayerStatus_Window::HandleStatAllocReply); + RefreshFromSnapshot(Comp->GetSnapshot()); +} + +void UUIPlayerStatus_Window::UnbindFromComponent() +{ + if (UZMMOAttributeComponent* Old = BoundComponent.Get()) + { + Old->OnAttributesChanged.RemoveDynamic(this, &UUIPlayerStatus_Window::HandleAttributesChanged); + Old->OnStatAllocReply.RemoveDynamic(this, &UUIPlayerStatus_Window::HandleStatAllocReply); + } + BoundComponent.Reset(); +} + +void UUIPlayerStatus_Window::HandleAttributesChanged(const FZMMOAttributesSnapshot& Snapshot) +{ + bPlusButtonsLocked = false; + RefreshFromSnapshot(Snapshot); +} + +void UUIPlayerStatus_Window::HandleStatAllocReply(bool bAccepted, int32 Reason) +{ + UE_LOG(LogZMMO, Log, TEXT("UIPlayerStatus_Window: alloc reply accepted=%d reason=%d"), + bAccepted ? 1 : 0, Reason); + + bPlusButtonsLocked = false; + if (UZMMOAttributeComponent* Comp = BoundComponent.Get()) + { + const FZMMOAttributesSnapshot& S = Comp->GetSnapshot(); + SetAllPrimaryRowsPlusEnabled(S.StatusPoint > 0); + } +} + +void UUIPlayerStatus_Window::HandleRowPlusClicked(int32 StatId) +{ + if (bPlusButtonsLocked) return; + UZMMOAttributeComponent* Comp = BoundComponent.Get(); + if (!Comp) return; + + bPlusButtonsLocked = true; + SetAllPrimaryRowsPlusEnabled(false); + + Comp->RequestStatAlloc(StatId, /*Amount*/ 1); +} + +void UUIPlayerStatus_Window::SetAllPrimaryRowsPlusEnabled(bool bEnabled) +{ + auto Set = [bEnabled](UUIPlayerStatus_StatRow* Row) + { + if (Row) Row->SetPlusEnabled(bEnabled); + }; + Set(Row_Str); Set(Row_Agi); Set(Row_Vit); + Set(Row_Int); Set(Row_Dex); Set(Row_Luk); +} + +void UUIPlayerStatus_Window::RefreshFromSnapshot(const FZMMOAttributesSnapshot& S) +{ + // Primários: snapshot atual não splita base/bonus de primários (só derivados). + if (Row_Str) Row_Str->SetValues(S.Str, 0); + if (Row_Agi) Row_Agi->SetValues(S.Agi, 0); + if (Row_Vit) Row_Vit->SetValues(S.Vit, 0); + if (Row_Int) Row_Int->SetValues(S.Int, 0); + if (Row_Dex) Row_Dex->SetValues(S.Dex, 0); + if (Row_Luk) Row_Luk->SetValues(S.Luk, 0); + + // Header (level/job). + if (Text_BaseLevel_Value) Text_BaseLevel_Value->SetText(FText::AsNumber(S.BaseLevel)); + if (Text_JobLevel_Value) Text_JobLevel_Value->SetText(FText::AsNumber(S.JobLevel)); + if (Text_Job) + { + FText JobName; + if (UGameInstance* GI = GetGameInstance()) + { + if (const UZMMOJobsSubsystem* Jobs = GI->GetSubsystem()) + { + if (const UZMMOJobDataAsset* Data = Jobs->GetJobData(S.ClassId)) + { + JobName = Data->DisplayName; + } + } + } + if (JobName.IsEmpty()) + { + JobName = FText::FromString(FString::Printf(TEXT("Job %d"), S.ClassId)); + } + Text_Job->SetText(JobName); + } + + if (StatusPointText) + { + StatusPointText->SetText(FText::FromString( + FString::Printf(TEXT("Status Points: %d"), S.StatusPoint))); + } + + // Derivados (server-authoritative: base + equip). + if (Row_Atk) Row_Atk->SetValues(S.AtkBase, S.AtkEquipBonus); + if (Row_Matk) Row_Matk->SetRangeValues(S.MatkBaseMin, S.MatkBaseMax, S.MatkEquipBonus); + if (Row_Def) Row_Def->SetValues(S.DefBase, S.DefEquipBonus); + if (Row_Mdef) Row_Mdef->SetValues(S.MdefBase, S.MdefEquipBonus); + if (Row_Hit) Row_Hit->SetValues(S.HitBase, S.HitEquipBonus); + if (Row_Flee) Row_Flee->SetValues(S.FleeBase, S.FleeEquipBonus); + if (Row_Crit) Row_Crit->SetValuesX10(S.CritBaseX10, S.CritEquipBonusX10); + // ASPD não splita. + if (Row_Aspd) Row_Aspd->SetValues(S.Aspd, 0); + + const bool bCanAlloc = !bPlusButtonsLocked && S.StatusPoint > 0; + SetAllPrimaryRowsPlusEnabled(bCanAlloc); +} + +void UUIPlayerStatus_Window::OnCloseClicked() +{ + if (UGameInstance* GI = GetGameInstance()) + { + if (UUIInGameFlowSubsystem* Flow = GI->GetSubsystem()) + { + Flow->SetState(EZMMOInGameUIState::Playing); + } + } +} diff --git a/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.h b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.h new file mode 100644 index 0000000..6440ed9 --- /dev/null +++ b/Source/ZMMO/Game/UI/Widgets/UIPlayerStatus_Window.h @@ -0,0 +1,82 @@ +#pragma once + +#include "CoreMinimal.h" +#include "CommonActivatableWidget.h" +#include "ZMMOAttributeTypes.h" +#include "UIPlayerStatus_Window.generated.h" + +class UButton; +class UTextBlock; +class UUIPlayerStatus_BonusRow; +class UUIPlayerStatus_StatRow; +class UZMMOAttributeComponent; + +/** + * Janela de Status do player — composta por instâncias dos sub-widgets + * UUIPlayerStatus_StatRow (6 primários) e UUIPlayerStatus_BonusRow (8 derivados). + * + * Consome o UZMMOAttributeComponent do PlayerState e a pipeline de + * C_STAT_ALLOC (RequestStatAlloc → server valida → OnStatAllocReply). + * + * Pareada com o WBP UI_PlayerStatus_Window. Os 14 rows são BindWidgetOptional + * pra suportar variantes (ex.: HUD compacto sem CRIT/ASPD). + */ +UCLASS(Abstract, Blueprintable, BlueprintType) +class ZMMO_API UUIPlayerStatus_Window : public UCommonActivatableWidget +{ + GENERATED_BODY() + +public: + UUIPlayerStatus_Window(const FObjectInitializer& ObjectInitializer); + +protected: + virtual void NativeOnActivated() override; + virtual void NativeOnDeactivated() override; + virtual TOptional GetDesiredInputConfig() const override; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr TitleText; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr StatusPointText; + + // Header: identidade do char. + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Header") TObjectPtr Text_CharName; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Header") TObjectPtr Text_Job; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Header") TObjectPtr Text_BaseLevel_Value; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Header") TObjectPtr Text_JobLevel_Value; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr Row_Str; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr Row_Agi; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr Row_Vit; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr Row_Int; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr Row_Dex; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr Row_Luk; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Atk; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Matk; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Def; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Mdef; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Hit; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Flee; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Crit; + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") TObjectPtr Row_Aspd; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") TObjectPtr CloseBtn; + +private: + void BindToLocalPlayer(); + void UnbindFromComponent(); + void RefreshFromSnapshot(const FZMMOAttributesSnapshot& Snap); + void SetAllPrimaryRowsPlusEnabled(bool bEnabled); + void BindRow(UUIPlayerStatus_StatRow* Row, int32 StatId, const TCHAR* IconLetter, const TCHAR* DisplayName); + + UFUNCTION() void HandleAttributesChanged(const FZMMOAttributesSnapshot& Snapshot); + UFUNCTION() void HandleStatAllocReply(bool bAccepted, int32 Reason); + UFUNCTION() void HandleRowPlusClicked(int32 StatId); + UFUNCTION() void OnCloseClicked(); + + UPROPERTY(Transient) + TWeakObjectPtr BoundComponent; + + /** Trava local pra evitar spam-click: vira true ao clicar, false ao + * receber StatAllocReply (ou snapshot novo, o que vier primeiro). */ + bool bPlusButtonsLocked = false; +};