From dbc2898a4b076cdd16e4ea75e4ffe5916d135170 Mon Sep 17 00:00:00 2001 From: Mateus Rodrigues Date: Sat, 23 May 2026 12:55:57 -0300 Subject: [PATCH] feat(attributes/ui): toast "LEVEL UP!" no HUD via S_LEVEL_UP delegate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UZMMOHudWidget ganha LevelUpToastContainer (BindWidgetOptional UWidget) e LevelUpToastText (BindWidgetOptional UTextBlock) — both Collapsed por default; HandleLevelUp os mostra com text "LEVEL UP! Lv N" e dispara timer FTimerHandle pra esconder após LevelUpToastDurationSec (2.5s). - WBP_HUD: Border escuro semi-transparente (R=0.05,G=0.04,B=0.10,A=0.85) com TextBlock dourado (R=1.0,G=0.85,B=0.30) fonte 32, slot top-center com padding top=120, visibility default Collapsed. - Snapshot pós-level-up (vem logo após S_LEVEL_UP) atualiza HP/SP/level via HpSpBar automaticamente — toast é só feedback visual instantâneo. Polish futuro (não desta frente): SFX cue + particle aura dourada + animação de fade in/out via UMG. --- Content/ZMMO/UI/HUD/WBP_HUD.uasset | Bin 28757 -> 30345 bytes Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.cpp | 44 +++++++++++++++++-- Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.h | 24 ++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/Content/ZMMO/UI/HUD/WBP_HUD.uasset b/Content/ZMMO/UI/HUD/WBP_HUD.uasset index b3bc8f539d6b63578573d5df1e471d1a7cacd0c5..2c72fabc385e61837be16f613d0c79e10bb0a7a2 100644 GIT binary patch literal 30345 zcmeHQ349dQ{eKIHTw0(YY6S-rIh2H41cIp9WOG0+$bom5?9L_&yF1J7Y+?`<5z%^7 zyen$8REr0#ch%a~QfzCfJ+0PiTa{W{v9|T7)|3D5`CPF}I0(YNjQPaksEvp?K@(8~ln|Cw_F zcb7N5`j@4P@0$6IhriQHuxZb<-1MEsWA3OraOyQbU;m(f9Kl{GeD2C zB<108BrW9yrS9^Qs&Y@M+q0msw4~BAzpA`&Zc#N#>iz3xRtVfwtvQnXaGHrP8yXX^SozAFuh=n3unP;K$F+1|IqZQwN9xiM^`t zjvGpyh+~g!^^_dD%m^BK%$QS>SIYH5{O$B-hGed%Mx3gy?5;xLxO^d6yKR{IC2Q}2 zDQ_UaDUQ1S)pq0i#*ZgZi~MG9G!U`!E6k|T+Sswu@LJ-ZwR2ARjHAvI?hJ$tvGJq} zYY%pSn}fP#h}oWZw}E-p5kt|NDAw1UJ;qVfT3;>Zo$;3D#3q=>7qHBz*mh>^A4d~* zc`&#<;OjK3nAkCW;`Ja{9*yd~O;IyqM6F&?d+#3t;I4x(&7MlqrWG*5V$YigzkV3N z6+t}~TV|||2ckx-LAL_kMoYlEO6)u$uzDgRn4ypnw%qZKj-b&L2!{=ySe-Y$?vOr} zZGl*TaKzH1k3SyD>hPQu(ZfE&R~xQ0Vu8-E5f#_|u)PuH?x@jYwk~T!k)QzzhObEv zge_5D{BaQ0$cVzcE%|O|9aPm(8*9^}0Ubo2`|BTDx#K#cQ}^~Z7>2LKY>G!ajpkKG zaGBwci7UQ#`a&qk9gG{1D3Pj;2YljZ2Oi!!$q8-ljaf#h&4|XJsPnCn$EGxD>5Uj- z%($ywJOCV+W>Dmf_U%3hJ>& z#=g7hH0aXZq+}swv6q4Tc@vKrb7)F!y98#EfsIy2m9M4^yag&8LDELULjd$%&vy_S(+`qhRx-$hiYAXn`)sr&cN zz2^I49e`#tY6ZfbV#2s7KV>*5mWO?f5#1XgZ!2E!J{>`_!gd<5^RRE-f`C@h*ihNt zVA8O7@V&xW3^BtoD;lTq(_?<=Cc6#!0NMY`_49V&9zrfLdc{GH$4^5G+_&juJK_2B z+FK}YiAuw-$AeaNRF8Bum_F)!*Q?zSN>-C# z;dmY>C0tc*nG9>slkfATAvLOhi4lBK`C`6L$2)*D8BAPDPEx$Ch8 z?lG;Rtc*M}s7GQHI{x6XJltc8ahA0>9K%#Qku_~Ofx7K6NPaWV}% z@E`Qh1sIw%%zMnJFD5GHG&~4?>hzdpj~q3qVq(mcAwP#Wb%x&(`5P~O9Z|E+=r)3_ zkrtC0(7>>01|gTxHjg*~9_p-xYl+`zpLrDg))AT>wd3W4idYq3^?D>>ppt9OKOcjr zUXRjbF5da1bpoPny%Fl5P>P6f*^v)?15(D666d~l&hZF~HZbXz=YHeS6Cu5d z-8@B$W&ZKMhB50+Up#2gLWgHx4ib@Rm+DNgx7sj61|t1W#@{1A5Y!WVu77L9V(^Z^ ztzzzqqubwxQUPPr|6<#)yA`0xjGZE)Rc{z@QDDTxqo3RugkCv3zccjv2SIStUfUQ; zuHOSUl<`X~D#~AYU^j!~RwQm=QNe+AOz5h5ED4)*?<&31s58BKFtCPA4X$G}Nf=_h z)q64As!8|xFqIUqJa090)}+(Y#4-|7&$02tw}TU@+J&z_eHkRRZ|%`==^t#Zi23rj;exsXH2|cPPyL+g<@jjn>`0S3DKj59u#dqx-$e}TRzr8~2e66G#RORXttAf8*KDizOFbHvnXQ^G6-u@bQ z7Bnrfbn10iLz-r~iHXMFp867ZZTc<8^mX2sU-&YEBZfEN4^Uv@MaS36uDlwuH(ODq zc(HJM^k^_H4Rg)Z>rUpDJnbj2=8Bs>0t-Aow=Xy;0E^-#f$>C{^)N83E`!!%_x*Am zqhpc!g(Kn(=n_%b5yJD=J`;i^Q^CtAm?-%V{3;%1O)mlp+A|Bd(;CHZxYcV6@ zgZAqmLVv9^$~&>DXd*X`iNlZDQiM6QwH9N{41>FNH|Lr@*41PvX*!@l9(cohHh8pe;h5qI-*wNzOYIO~^_+DjVyIm4wL1pE7jAyqi!DyF ziZ@CLE=1krOBdMdKwd_+w}XS4xKEDL`*%Hl05mAqd}5gS;2HLcj;C0AIJPe-6pw8G z;z3}N7by1nVnbd zF{b1_OFwD-=|SMg5G!KU7f(dL_FjrcA6C>$CT_SGwuYa&gC-4>uk_sT5?E}F8Bry)t)Z*Ew%wS@i-FCws|rD!6^FYL^Rg!QLPjDrChjhY-XhnG_seker;- zDtSV4OkS`o4n)+2r4SNFzbNf|=+uTQ`&8iI3aw_)g_LLkzA{z-BVz>y7h1v8NF3kD zZ#0T=M%0fve5zd|UZy;M_Uut3wb>eiZA`Pe0x_+J2U?z{sm-ny2x~N)>1@HLd2!%i z#E#QC;+Ccdd-UFzM(cziH8r#ducNepIup>bOw2?7OyeY~*F&0CpI8=YE!2t^7StDo z2U;m>elzOiBc-Kd@v3PwBM@0y#}ZxQ$*08vw2RP)L5slNRcM(nPM5+$A5HNNS{vji z#zcN{K;?Cb&r8f7QU0$~$EZ)I2i0n?bU;UPwm0SA4u_CGDR-zKbC5=LKlu!sHclr& z(O@qv`Lr00!lajIu-0YvaBI7Xy(&eMIGKwL%MNGo)-a^^ zY8?hU6HyM)$v}XPme{~C%@?PVso9H8jgF2G zTMDfStHZr_Ef=YHf2j6fq}F|+Qa*;yF+x2=5i`vtJIG5+tBWn(NlP1c1_U2E0-zHh z@<2W+Wgm-DL^HK$JWLUcZK}~qJsy!E#t1~E7c*K1_AgP54wbrTRWH4hq7%0ulY<6r zxcDHHiQ3_&lehT6U@sx)mKFm`b{j7(72xbq`*@bT&;l=rSjTArYla;-$@{41sKEqv zioQlLm<*Y-XD=^b)==9}t->?{H2%Y38=cK+k$BV~+6bCnGe&#OfLDu0eB{;80LBNc zAZRf6YGx0e{c2RBAIAg3tB19)36A~fLHBx%Sd0Yg)mW|6ErtfO6~oaK@obMM4)-za zYrD`ti|sRwSa^n|8E4VPg2Jzfp$x^7%(h{8AlsBN(!EhVW*br34TP9jt*vT1C}0G~ zXs5;6N0hh7WMusgbqGvSla`qWuTJBaB#?bm_%XWaz|o$BH0>1X3Nl;qXjn7-ekSJJ zdpgiDg9jpXVwH0&=IhlKmhy%VlI z%IVWB``w@Si!YDbZ%(}L9awbA*$&IZ0Us>VgvRMhGXEPrp!1a6HwbS_4tTHQ0b-7LH|L0VM~--R=7_f~N4&4)h<9&}c-QBEx102LPY!sm5#D7v z;@#H|-d(Z|*$p}3ZO#!-`D7+Pb<)MQ4QU`eENYMj!o%JTX&^jo<&Xx#yU|9=h|6+RS`kd7@c=29N(mO1T^;_gU9#?FX2tko^JDm%AdEXzs zXJudiAfz`PG}W^#%oSa-<0I8Xn4pkaQ1ttwcZY29j)NA~OKR;rk{;@)uz68DwSU|x z8qS*j=y@fglOB9k(SyGzdVkG8&q+s>bD;-55igNrIfht`@;F(>J)UaBai@FW!peZW44ILe=Ol+o6iaPQ;^_vjBf9-kqhPmC?lQsskDArpA} zBh@RqpojL5E7yd6$I_MdgqG!$&w0fodG@2dG@P`jxR{yLli>>S1hu(X?vX$PdQ<&P zqq2I0pLjnxFRgbmk+3GvRo<-!f_S$OFBSOgH%$o47E3%;tDwVTe*F|RXql*?bJWDE zv3)BYFKnU`8ceiIzJP=(C_YieZ(KP=N~z^nF&NU+a!Qkj-eQf0=xrgGkso;5?-#*p z1;q=B=NFX}vU;ilZoIH69;1EkFft_m4JQXfK97HG7=A}4?hlovYOzw7!Vrt;w?c$O zxA2SAw3G!jE*eA!d7T0ON<)QUkB+iAUuq_ znk>*E)(F-63Q;9`s1+ z=_<*`XvtY$PjgW?QJRf7WNjr{5z-2%t|p8T5^EOe2weDSsogFE=MuIW zP0H7@;kxJr4aKF4LY!T06HPRFRuO0DJ+tp&L?4#Gw+J^TP9`fD91Y@Pp+FSyi%PbG zMg7ExU-ajqsmP{dV@%D6qco;+m-uuxQ$AJ6W5*&-ReEw!?6mpFR5wc2jgxs&r_Pen zuhW{&QJJJMSUD6w%Fk*@o6xpPWUo>2xPKX@NeK%?ftW8!#R5@CSE(o=4=tr~rEpU| zkMdH2AYVX`V)|E2wN=yxc*WFWU#l$Azs%#M%vGepWaM|#a=c2`xJ%$G>mGY`2$B0}Z)@L$4 zXRe(fdFWq~e2F!Sj^a-stK`#oOa7ZfewYbbkrC?70L4tFBKTmnq1rGQ_(?L@zc(oYD^&ZVugjZW-<<| zXz#3@>Zn)qb^ku0;&t}bf?8z^RvN{JS_?Ii?pM-k1$&v~3LqIL2f{mCYFqW2IesZE z%;hz{S|iUDZM1u;p%~Cco|C?Ia?xKR+m;-x%)@0rOIb?zXkW+?5=ZTdglmX|D9M`0 z8{_2J_?^n@eZ=}M_6m#vwO<)5x5^i=qv)jGyUEkzVmX!Uou`ZT%eG#!V@#14HXa>Z zxK!y#SuMvXUQIe1T^{4#YPir6SV_f2B*{-jjkCio` zX#2Otk-?<9Rw~(h`{`NRtF;|`HpJuEC61BUxpCKc8)l-D?qBw1BN#NG+;})^Rz}>&xdH*{*L~QIW2J;_6hI?fvA{ zh$T1+L8Q&giK03&N*xVqt*4^(r(NSI9-SvX&ehOB^>cHQL9H>;S3xZl^RTwG&xtS# zsr(`y)C_%3%L9a;C^9!Bg zTa5N-khF+tml6Isbnnz{vbTXKfM>feTWh&eKrBp`0q1$DH{1T;QOP>63}^I_qlonb z{*+ymmXemoylYb}NLXcmSiYF;1m6DJE#KEJ#R<>MZkJ-V2K2MP?V=*ff4f~$$2`u^ z(??`74kV*Wabn~aCn8|+UX0Ros_+1N6ewRPPK?MT)sn<$DPiA1EG|iSNN%ygo=cK5 z%Q-Z=oI{VO@iIc%lm12mIiBCAKe|~v^=E`cWfl$TB5I~hKgL(qSN zf8Y(Ded7m5P*3l?v1}CH_rb-fOXllkj*8`uvif5YfY#zizMw|rIC$p_Kh$Tu$MKHXfG~y>u)h!zJ>!TL^wNn^WoJ}2+-Kh_ zd!@91lO#JT?0a;!N(9Rkn`P|=?vS+`%p)n?^kgH5w-GyJWj42jFSAQJUo}KDM#AfZ zDXCiCIY&v2gh6&(D)A_(D7rO#h-a1O^0(g3f9azFPYUD5OH^lXr%D)lf*Mq+Lg5s7 z*GKQ~lB6fg$}?q-jHOoZGAr7cIFZt&8(V0@Q$}U6gr)P-XH=F*LNtL>i$k=;R3d1wo0Q6SOi0O)P{HTeEzD*3pqQ*D5@{W{&7To24Ya2cD&D1GBZ zBY){4jF802quH~ZYNB+ndN--0(Y8K7tyNiP478>X84)ghmyQpi!UPErR+wNxD*3oy zgN~(ySOLZ7<%NR{CvS(8x))Mc%Z4KrnXErZtm_{7ss_^bQo^3&H`DbCR# zLprR%K`9{vhFxt;en~*XM-@lmgR_PnrpMD*@*!mvA!~)*j(@?5pV!*SlB(V-ImLd8 zOh-xXlyF%ilP(eKl{l31g!6MM{4Z?%8^YGdGiQ&fTCuZ!!zORw{$)4rQ6_|e)Vzi5 z%J}or|6MlGUCYT?MWJ(Md+z%YKln1Hix#W8_6u|GYnST#%|IkzM z=*8XQk7wWfwM?-8{OO6`3`MxFYC0lCFdH#fg z;qNOG!lE2#DaT?`doemKc=b-t)=R$l+!^(ohGv2dVmK=g0@+;CUJYmP+wqj=;co54 z`m0a+-i~dzTs$!o>_2%pgWsFRjeKhCke#&`c9hjDo%U7!W_vp942K32Vf8z-)~lyi zJ2ZNbYtR}tM86iTYkC+>}7xp&0=4Iol1;;?Ol$&_rb5mbU$DYKpQ&8ZDDU5%*ZopY?-Ham4tZKxWXG%B!L2B%mah%JiFrHP7 z{dR*TcuF@H5CCa|o$+r)q71EzsdN>)3o42ilzNI6R92N1Rn03da2J-&D=#XUKfk2J zT~*41qR!Lisnc4UrfOPUw|1h?(3+C-%wvrW;?eE&H1^K(WTmq~zlY62tUD2h%$skx z;RKYGXi5TSM`vfDJRR_}WTji?$P{~S)hnK;Avs6R0vp8g43%YMJmktGfKTzM>-#npN;#=J*|L+>iVW`pU z&v<8b5X^J`SsY;&OyMX%03@f&;>0sm6%Yj9RIaeUtILx&?llEKzewq-=0EAqSdqd- zRt-YaxnW|CPr>{m$Wm&vGd{m?o}xRWOO3=q#N?PF?^+_^lTX$^e}C1L?)ytG3O{(|qU$dsI6A8yJLInGp4_lxlXd>QJ%=4K zvRUH0mOr}tlJ9-9;-aHo*z?HvN#AOb@DYF8{Y-IHyz1=t>flpQ{_jG;>i>p+H#LJjfO6WRAEw5!UHl6=( zlPMCxIij&R<;08nki5BE=Ezt@M~IQ@pw`v0qK^(0qY;Uq+znzENLacKx#wxJ@-&$< zkjg-I>JgrXl&;5R3OJpsh3LbY68jj5uukU4pdyw~eH}x|F%uP(*72|XGfb5g(vcG2 zSZ#7QGYJT#7um$r`8dx&s!_Na;L`4cqWR%?BFw!TJKjDxjpt2Pd!U6GOmP zDpT!TLSw;)Qe8e>NC(h`Puh!P`PO#bOrslIC~rpRxL3p1F%k9&HDhlRA5*|ClHIGr zT--YO<|kK{L{g07mTir2g5z=|RtM!y2?6JxAr6pXjL*^qBshta6dj}3sSg>LGG{VC y#{LkaaR^;-IVYLz^goro{@vTxT7pPZ@Ln?CW{{8%=!*)JCYp%Qp{{I0VtcqR$ delta 8484 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 OFlC@5ECrm?H2fE&2KpiZ diff --git a/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.cpp b/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.cpp index 378ca3b..1e7c69e 100644 --- a/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.cpp +++ b/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.cpp @@ -1,9 +1,12 @@ #include "ZMMOHudWidget.h" +#include "Components/TextBlock.h" +#include "Components/Widget.h" #include "CommonInputTypeEnum.h" // ECommonInputMode #include "Engine/World.h" #include "GameFramework/PlayerController.h" #include "GameFramework/PlayerState.h" +#include "TimerManager.h" #include "ZMMO.h" #include "ZMMOAttributeComponent.h" #include "ZMMOHudHpSpWidget.h" @@ -32,6 +35,8 @@ void UZMMOHudWidget::NativeOnActivated() // HUD nao intercepta cliques — mouse passa direto pro Pawn (camera, etc.). // Sub-widgets que precisam de click (futuro: hotkeys) podem override. SetVisibility(ESlateVisibility::HitTestInvisible); + // Toast comeca escondido — so' aparece em HandleLevelUp. + HideLevelUpToast(); BindToLocalPlayer(); UE_LOG(LogZMMO, Log, TEXT("ZMMOHudWidget activated (HpSpBar=%s)"), HpSpBar ? *HpSpBar->GetName() : TEXT("none")); @@ -115,8 +120,39 @@ void UZMMOHudWidget::HandleHpSpChanged(int32 Hp, int32 Sp) void UZMMOHudWidget::HandleLevelUp(int32 NewBaseLevel, int32 StatusPointDelta) { - // Snapshot subsequente do AttributeSystem vai disparar HandleAttributesChanged - // e atualizar HpSpBar->LevelText. Aqui e' o ponto pra efeitos visuais - // instantaneos (toast "LEVEL UP", confetti, sound). V1 noop — UI pode - // hook via Blueprint depois. + // Snapshot subsequente atualiza HpSpBar (level/maxhp/maxsp). Aqui mostra + // toast visual instantaneo. StatusPointDelta nao usado no texto (UI mostra + // no StatusWindow). Polish futuro: SFX + particle aura. + UE_LOG(LogZMMO, Log, TEXT("[HUD] LEVEL UP! newLevel=%d +sp=%d"), NewBaseLevel, StatusPointDelta); + ShowLevelUpToast(NewBaseLevel); +} + +void UZMMOHudWidget::ShowLevelUpToast(int32 NewBaseLevel) +{ + if (LevelUpToastText) + { + LevelUpToastText->SetText(FText::FromString( + FString::Printf(TEXT("LEVEL UP! Lv %d"), NewBaseLevel))); + } + if (LevelUpToastContainer) + { + LevelUpToastContainer->SetVisibility(ESlateVisibility::HitTestInvisible); + } + + // Cancela timer anterior (caso level up duplo em sequencia) + agenda hide. + if (UWorld* World = GetWorld()) + { + World->GetTimerManager().ClearTimer(LevelUpToastHideTimer); + World->GetTimerManager().SetTimer(LevelUpToastHideTimer, + FTimerDelegate::CreateUObject(this, &UZMMOHudWidget::HideLevelUpToast), + LevelUpToastDurationSec, /*loop*/ false); + } +} + +void UZMMOHudWidget::HideLevelUpToast() +{ + if (LevelUpToastContainer) + { + LevelUpToastContainer->SetVisibility(ESlateVisibility::Collapsed); + } } diff --git a/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.h b/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.h index 28d6de6..39f3553 100644 --- a/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.h +++ b/Source/ZMMO/Game/UI/InGame/ZMMOHudWidget.h @@ -2,9 +2,12 @@ #include "CommonActivatableWidget.h" #include "CoreMinimal.h" +#include "Engine/TimerHandle.h" #include "ZMMOAttributeTypes.h" #include "ZMMOHudWidget.generated.h" +class UTextBlock; +class UWidget; class UZMMOAttributeComponent; class UZMMOHudHpSpWidget; @@ -71,6 +74,22 @@ protected: UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD") UZMMOHudHpSpWidget* HpSpBar = nullptr; + /// Container do toast "LEVEL UP!" (Fase 3). Hidden por default; em + /// `HandleLevelUp` vira visivel por `LevelUpToastDurationSec` segundos + /// (ver `Show/HideLevelUpToast`). WBP_HUD coloca um Border + Image + TextBlock + /// dentro deste container; este C++ controla apenas o lifecycle visivel/hidden. + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD|LevelUp") + UWidget* LevelUpToastContainer = nullptr; + + /// Texto exibido no toast — formato "LEVEL UP! Lv X" (X = novo level). + /// Tambem BindWidgetOptional; WBP_HUD pode usar texto estatico no design. + UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|HUD|LevelUp") + UTextBlock* LevelUpToastText = nullptr; + + /// Duracao do toast em segundos. Configuravel no BP filho. + UPROPERTY(EditDefaultsOnly, Category = "Zeus|HUD|LevelUp") + float LevelUpToastDurationSec = 2.5f; + // === Futuros sub-widgets === // UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZMMOHudPlayerInfoWidget* PlayerInfo = nullptr; // UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional)) UZMMOHudMinimapWidget* Minimap = nullptr; @@ -99,4 +118,9 @@ private: UPROPERTY(Transient) TWeakObjectPtr BoundComponent; + + void ShowLevelUpToast(int32 NewBaseLevel); + void HideLevelUpToast(); + + FTimerHandle LevelUpToastHideTimer; };